Implement further features for badges.

* Add Subscriptions API
* Add Accept-Language header to profile requests
* Fix several UI bugs, add error dialogs, etc.
This commit is contained in:
Alex Hart
2021-10-21 16:39:02 -03:00
committed by Greyson Parrelli
parent d88999d6d4
commit c1820459b7
91 changed files with 2765 additions and 696 deletions

View File

@@ -0,0 +1,13 @@
package org.thoughtcrime.securesms.subscription
import org.whispersystems.signalservice.api.subscriptions.IdempotencyKey
/**
* Binds a Subscription level update with an idempotency key.
*
* We are to use the same idempotency key whenever we want to retry updating to a particular level.
*/
data class LevelUpdateOperation(
val idempotencyKey: IdempotencyKey,
val level: String
)

View File

@@ -0,0 +1,8 @@
package org.thoughtcrime.securesms.subscription
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
data class Subscriber(
val subscriberId: SubscriberId,
val currencyCode: String
)

View File

@@ -23,10 +23,9 @@ data class Subscription(
val title: String,
val badge: Badge,
val price: FiatMoney,
val level: Int,
) {
val renewalTimestamp = badge.expirationTimestamp
companion object {
fun register(adapter: MappingAdapter) {
adapter.registerFactory(Model::class.java, MappingAdapter.LayoutFactory({ ViewHolder(it) }, R.layout.subscription_preference))
@@ -37,8 +36,10 @@ data class Subscription(
val subscription: Subscription,
val isSelected: Boolean,
val isActive: Boolean,
val willRenew: Boolean,
override val isEnabled: Boolean,
val onClick: () -> Unit
val onClick: () -> Unit,
val renewalTimestamp: Long
) : PreferenceModel<Model>(isEnabled = isEnabled) {
override fun areItemsTheSame(newItem: Model): Boolean {
@@ -49,7 +50,17 @@ data class Subscription(
return super.areContentsTheSame(newItem) &&
newItem.subscription == subscription &&
newItem.isSelected == isSelected &&
newItem.isActive == isActive
newItem.isActive == isActive &&
newItem.renewalTimestamp == renewalTimestamp &&
newItem.willRenew == willRenew
}
override fun getChangePayload(newItem: Model): Any? {
return if (newItem.subscription.badge == subscription.badge) {
Unit
} else {
null
}
}
}
@@ -65,9 +76,13 @@ data class Subscription(
itemView.isEnabled = model.isEnabled
itemView.setOnClickListener { model.onClick() }
itemView.isSelected = model.isSelected
badge.setBadge(model.subscription.badge)
if (payload.isEmpty()) {
badge.setBadge(model.subscription.badge)
}
title.text = model.subscription.title
tagline.text = model.subscription.id
tagline.text = context.getString(R.string.Subscription__earn_a_s_badge, model.subscription.badge.name)
val formattedPrice = FiatMoneyUtil.format(
context.resources,
@@ -75,11 +90,17 @@ data class Subscription(
FiatMoneyUtil.formatOptions()
)
if (model.isActive) {
if (model.isActive && model.willRenew) {
price.text = context.getString(
R.string.Subscription__s_per_month_dot_renews_s,
formattedPrice,
DateUtils.formatDate(Locale.getDefault(), model.subscription.renewalTimestamp)
DateUtils.formatDateWithYear(Locale.getDefault(), model.renewalTimestamp)
)
} else if (model.isActive) {
price.text = context.getString(
R.string.Subscription__s_per_month_dot_expires_s,
formattedPrice,
DateUtils.formatDateWithYear(Locale.getDefault(), model.renewalTimestamp)
)
} else {
price.text = context.getString(

View File

@@ -0,0 +1,42 @@
package org.thoughtcrime.securesms.subscription
import android.app.PendingIntent
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
import org.thoughtcrime.securesms.help.HelpFragment
import org.thoughtcrime.securesms.notifications.NotificationChannels
import org.thoughtcrime.securesms.notifications.NotificationIds
sealed class SubscriptionNotification {
object VerificationFailed : SubscriptionNotification() {
override fun show(context: Context) {
val notification = NotificationCompat.Builder(context, NotificationChannels.FAILURES)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(context.getString(R.string.Subscription__verification_failed))
.setContentText(context.getString(R.string.Subscription__please_contact_support_for_more_information))
.addAction(
NotificationCompat.Action.Builder(
null,
context.getString(R.string.Subscription__contact_support),
PendingIntent.getActivity(
context,
0,
AppSettingsActivity.help(context, HelpFragment.DONATION_INDEX),
if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_ONE_SHOT else 0
)
).build()
)
.build()
NotificationManagerCompat
.from(context)
.notify(NotificationIds.SUBSCRIPTION_VERIFY_FAILED, notification)
}
}
abstract fun show(context: Context)
}