Surface retryable failure for slow donations config load.
This commit is contained in:
parent
41260f37c9
commit
d447af36ba
@ -70,6 +70,12 @@ object InAppPaymentsRepository {
|
||||
private const val JOB_PREFIX = "InAppPayments__"
|
||||
private val TAG = Log.tag(InAppPaymentsRepository::class.java)
|
||||
|
||||
/**
|
||||
* Upper bound on how long we'll wait for the donations configuration before surfacing a retryable
|
||||
* failure rather than leaving the user on an indefinite loading spinner (e.g. on a slow VPN).
|
||||
*/
|
||||
const val DONATIONS_CONFIGURATION_TIMEOUT_SECONDS = 30L
|
||||
|
||||
private val backupExpirationTimeout = 30.days
|
||||
private val backupExpirationDeletion = 60.days
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import java.util.Currency
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Shared one-time payment methods that apply to both Stripe and PayPal payments.
|
||||
@ -77,6 +78,7 @@ object OneTimeInAppPaymentRepository {
|
||||
fun getBoosts(): Single<Map<Currency, List<Boost>>> {
|
||||
return Single.fromCallable { AppDependencies.donationsService.getDonationsConfiguration(Locale.getDefault()) }
|
||||
.subscribeOn(Schedulers.io())
|
||||
.timeout(InAppPaymentsRepository.DONATIONS_CONFIGURATION_TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||
.flatMap { it.flattenResult() }
|
||||
.map { config ->
|
||||
config.getBoostAmounts().mapValues { (_, value) ->
|
||||
@ -97,6 +99,7 @@ object OneTimeInAppPaymentRepository {
|
||||
.getDonationsConfiguration(Locale.getDefault())
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.timeout(InAppPaymentsRepository.DONATIONS_CONFIGURATION_TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||
.flatMap { it.flattenResult() }
|
||||
.map { it.getBoostBadges().first() }
|
||||
}
|
||||
@ -107,8 +110,9 @@ object OneTimeInAppPaymentRepository {
|
||||
*/
|
||||
fun getMinimumDonationAmounts(): Single<Map<Currency, FiatMoney>> {
|
||||
return Single.fromCallable { AppDependencies.donationsService.getDonationsConfiguration(Locale.getDefault()) }
|
||||
.flatMap { it.flattenResult() }
|
||||
.subscribeOn(Schedulers.io())
|
||||
.timeout(InAppPaymentsRepository.DONATIONS_CONFIGURATION_TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||
.flatMap { it.flattenResult() }
|
||||
.map { it.getMinimumDonationAmounts() }
|
||||
}
|
||||
|
||||
|
||||
@ -39,6 +39,7 @@ import org.whispersystems.signalservice.internal.ServiceResponse
|
||||
import org.whispersystems.signalservice.internal.push.SubscriptionsConfiguration
|
||||
import java.math.BigDecimal
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
/**
|
||||
@ -109,6 +110,7 @@ object RecurringInAppPaymentRepository {
|
||||
return Single
|
||||
.fromCallable { donationsService.getDonationsConfiguration(Locale.getDefault()) }
|
||||
.subscribeOn(Schedulers.io())
|
||||
.timeout(InAppPaymentsRepository.DONATIONS_CONFIGURATION_TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||
.flatMap { it.flattenResult() }
|
||||
.map { config ->
|
||||
config.getSubscriptionLevels().map { (level, levelConfig) ->
|
||||
|
||||
@ -18,6 +18,7 @@ import org.signal.core.util.money.PlatformCurrencyUtil
|
||||
import org.signal.core.util.orNull
|
||||
import org.signal.donations.InAppPaymentType
|
||||
import org.thoughtcrime.securesms.badges.Badges
|
||||
import org.thoughtcrime.securesms.badges.models.Badge
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationSerializationHelper.toFiatValue
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.OneTimeInAppPaymentRepository
|
||||
@ -265,15 +266,6 @@ class DonateToSignalViewModel(
|
||||
store.update { it.copy(oneTimeDonationState = it.oneTimeDonationState.copy(pendingOneTimeDonation = pendingOneTimeDonation.orNull())) }
|
||||
}
|
||||
|
||||
oneTimeDonationDisposables += oneTimeInAppPaymentRepository.getBoostBadge().subscribeBy(
|
||||
onSuccess = { badge ->
|
||||
store.update { it.copy(oneTimeDonationState = it.oneTimeDonationState.copy(badge = badge)) }
|
||||
},
|
||||
onError = {
|
||||
Log.w(TAG, "Could not load boost badge", it)
|
||||
}
|
||||
)
|
||||
|
||||
oneTimeDonationDisposables += oneTimeInAppPaymentRepository.getMinimumDonationAmounts().subscribeBy(
|
||||
onSuccess = { amountMap ->
|
||||
store.update { it.copy(oneTimeDonationState = it.oneTimeDonationState.copy(minimumDonationAmounts = amountMap)) }
|
||||
@ -283,10 +275,14 @@ class DonateToSignalViewModel(
|
||||
}
|
||||
)
|
||||
|
||||
val boosts: Observable<Map<Currency, List<Boost>>> = oneTimeInAppPaymentRepository.getBoosts().toObservable()
|
||||
val boostsAndBadge: Observable<Pair<Map<Currency, List<Boost>>, Badge>> = Single.zip(
|
||||
oneTimeInAppPaymentRepository.getBoosts(),
|
||||
oneTimeInAppPaymentRepository.getBoostBadge()
|
||||
) { boosts, badge -> boosts to badge }.toObservable()
|
||||
|
||||
val oneTimeCurrency: Observable<Currency> = SignalStore.inAppPayments.observableOneTimeCurrency
|
||||
|
||||
oneTimeDonationDisposables += Observable.combineLatest(boosts, oneTimeCurrency) { boostMap, currency ->
|
||||
oneTimeDonationDisposables += Observable.combineLatest(boostsAndBadge, oneTimeCurrency) { (boostMap, badge), currency ->
|
||||
val boostList = if (currency in boostMap) {
|
||||
boostMap[currency]!!
|
||||
} else {
|
||||
@ -294,12 +290,13 @@ class DonateToSignalViewModel(
|
||||
listOf()
|
||||
}
|
||||
|
||||
Triple(boostList, currency, boostMap.keys)
|
||||
OneTimeConfiguration(boostList, badge, currency, boostMap.keys)
|
||||
}.subscribeBy(
|
||||
onNext = { (boostList, currency, availableCurrencies) ->
|
||||
onNext = { (boostList, badge, currency, availableCurrencies) ->
|
||||
store.update { state ->
|
||||
state.copy(
|
||||
oneTimeDonationState = state.oneTimeDonationState.copy(
|
||||
badge = badge,
|
||||
boosts = boostList,
|
||||
selectedBoost = null,
|
||||
selectedCurrency = currency,
|
||||
@ -321,6 +318,13 @@ class DonateToSignalViewModel(
|
||||
)
|
||||
}
|
||||
|
||||
private data class OneTimeConfiguration(
|
||||
val boosts: List<Boost>,
|
||||
val badge: Badge,
|
||||
val currency: Currency,
|
||||
val availableCurrencies: Set<Currency>
|
||||
)
|
||||
|
||||
private fun initializeMonthlyDonationState(subscriptionsRepository: RecurringInAppPaymentRepository) {
|
||||
monitorLevelUpdateProcessing()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user