Hide receipts item if user has none.

This commit is contained in:
Alex Hart 2022-05-06 10:01:14 -03:00
parent f73c5dde6b
commit cffbfcb957
6 changed files with 80 additions and 15 deletions

View file

@ -0,0 +1,37 @@
package org.thoughtcrime.securesms.database
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.signal.core.util.money.FiatMoney
import org.thoughtcrime.securesms.database.model.DonationReceiptRecord
import java.math.BigDecimal
import java.util.Currency
class DonationReceiptDatabaseTest {
private val records = listOf(
DonationReceiptRecord.createForBoost(FiatMoney(BigDecimal.valueOf(100), Currency.getInstance("USD"))),
DonationReceiptRecord.createForBoost(FiatMoney(BigDecimal.valueOf(200), Currency.getInstance("USD")))
)
@Test
fun givenNoReceipts_whenICheckHasReceipts_thenIExpectFalse() {
assertFalse(SignalDatabase.donationReceipts.hasReceipts())
}
@Test
fun givenOneReceipt_whenICheckHasReceipts_thenIExpectTrue() {
SignalDatabase.donationReceipts.addReceipt(records.first())
assertTrue(SignalDatabase.donationReceipts.hasReceipts())
}
@Test
fun givenMultipleReceipts_whenICheckHasReceipts_thenIExpectTrue() {
records.forEach {
SignalDatabase.donationReceipts.addReceipt(it)
}
assertTrue(SignalDatabase.donationReceipts.hasReceipts())
}
}

View file

@ -39,12 +39,13 @@ object MmsHelper {
emptyList(), emptyList(),
emptyList(), emptyList(),
emptySet(), emptySet(),
emptySet() emptySet(),
null
) )
return insert( return insert(
message = message, message = message,
threadId = threadId, threadId = threadId
) )
} }

View file

@ -98,31 +98,31 @@ class ManageDonationsFragment : DSLSettingsFragment(), ExpiredGiftSheet.Callback
if (activeSubscription != null) { if (activeSubscription != null) {
val subscription: Subscription? = state.availableSubscriptions.firstOrNull { activeSubscription.level == it.level } val subscription: Subscription? = state.availableSubscriptions.firstOrNull { activeSubscription.level == it.level }
if (subscription != null) { if (subscription != null) {
presentSubscriptionSettings(activeSubscription, subscription, state.getRedemptionState()) presentSubscriptionSettings(state.hasReceipts, activeSubscription, subscription, state.getRedemptionState())
} else { } else {
customPref(IndeterminateLoadingCircle) customPref(IndeterminateLoadingCircle)
} }
} else { } else {
presentNoSubscriptionSettings() presentNoSubscriptionSettings(state.hasReceipts)
} }
} else if (state.transactionState == ManageDonationsState.TransactionState.NetworkFailure) { } else if (state.transactionState == ManageDonationsState.TransactionState.NetworkFailure) {
presentNetworkFailureSettings(state.getRedemptionState()) presentNetworkFailureSettings(state.hasReceipts, state.getRedemptionState())
} else { } else {
customPref(IndeterminateLoadingCircle) customPref(IndeterminateLoadingCircle)
} }
} }
} }
private fun DSLConfiguration.presentNetworkFailureSettings(redemptionState: ManageDonationsState.SubscriptionRedemptionState) { private fun DSLConfiguration.presentNetworkFailureSettings(hasReceipts: Boolean, redemptionState: ManageDonationsState.SubscriptionRedemptionState) {
if (SignalStore.donationsValues().isLikelyASustainer()) { if (SignalStore.donationsValues().isLikelyASustainer()) {
presentSubscriptionSettingsWithNetworkError(redemptionState) presentSubscriptionSettingsWithNetworkError(hasReceipts, redemptionState)
} else { } else {
presentNoSubscriptionSettings() presentNoSubscriptionSettings(hasReceipts)
} }
} }
private fun DSLConfiguration.presentSubscriptionSettingsWithNetworkError(redemptionState: ManageDonationsState.SubscriptionRedemptionState) { private fun DSLConfiguration.presentSubscriptionSettingsWithNetworkError(hasReceipts: Boolean, redemptionState: ManageDonationsState.SubscriptionRedemptionState) {
presentSubscriptionSettingsWithState(redemptionState) { presentSubscriptionSettingsWithState(hasReceipts, redemptionState) {
customPref( customPref(
NetworkFailure.Model( NetworkFailure.Model(
onRetryClick = { onRetryClick = {
@ -134,11 +134,12 @@ class ManageDonationsFragment : DSLSettingsFragment(), ExpiredGiftSheet.Callback
} }
private fun DSLConfiguration.presentSubscriptionSettings( private fun DSLConfiguration.presentSubscriptionSettings(
hasReceipts: Boolean,
activeSubscription: ActiveSubscription.Subscription, activeSubscription: ActiveSubscription.Subscription,
subscription: Subscription, subscription: Subscription,
redemptionState: ManageDonationsState.SubscriptionRedemptionState redemptionState: ManageDonationsState.SubscriptionRedemptionState
) { ) {
presentSubscriptionSettingsWithState(redemptionState) { presentSubscriptionSettingsWithState(hasReceipts, redemptionState) {
val activeCurrency = Currency.getInstance(activeSubscription.currency) val activeCurrency = Currency.getInstance(activeSubscription.currency)
val activeAmount = activeSubscription.amount.movePointLeft(activeCurrency.defaultFractionDigits) val activeAmount = activeSubscription.amount.movePointLeft(activeCurrency.defaultFractionDigits)
@ -159,6 +160,7 @@ class ManageDonationsFragment : DSLSettingsFragment(), ExpiredGiftSheet.Callback
} }
private fun DSLConfiguration.presentSubscriptionSettingsWithState( private fun DSLConfiguration.presentSubscriptionSettingsWithState(
hasReceipts: Boolean,
redemptionState: ManageDonationsState.SubscriptionRedemptionState, redemptionState: ManageDonationsState.SubscriptionRedemptionState,
subscriptionBlock: DSLConfiguration.() -> Unit subscriptionBlock: DSLConfiguration.() -> Unit
) { ) {
@ -196,7 +198,9 @@ class ManageDonationsFragment : DSLSettingsFragment(), ExpiredGiftSheet.Callback
sectionHeaderPref(R.string.ManageDonationsFragment__more) sectionHeaderPref(R.string.ManageDonationsFragment__more)
presentDonationReceipts() if (hasReceipts) {
presentDonationReceipts()
}
externalLinkPref( externalLinkPref(
title = DSLSettingsText.from(R.string.ManageDonationsFragment__subscription_faq), title = DSLSettingsText.from(R.string.ManageDonationsFragment__subscription_faq),
@ -205,7 +209,7 @@ class ManageDonationsFragment : DSLSettingsFragment(), ExpiredGiftSheet.Callback
) )
} }
private fun DSLConfiguration.presentNoSubscriptionSettings() { private fun DSLConfiguration.presentNoSubscriptionSettings(hasReceipts: Boolean) {
space(DimensionUnit.DP.toPixels(16f).toInt()) space(DimensionUnit.DP.toPixels(16f).toInt())
noPadTextPref( noPadTextPref(
@ -223,9 +227,11 @@ class ManageDonationsFragment : DSLSettingsFragment(), ExpiredGiftSheet.Callback
presentOtherWaysToGive() presentOtherWaysToGive()
sectionHeaderPref(R.string.ManageDonationsFragment__receipts) if (hasReceipts) {
sectionHeaderPref(R.string.ManageDonationsFragment__receipts)
presentDonationReceipts() presentDonationReceipts()
}
} }
private fun DSLConfiguration.presentOtherWaysToGive() { private fun DSLConfiguration.presentOtherWaysToGive() {

View file

@ -8,6 +8,7 @@ data class ManageDonationsState(
val featuredBadge: Badge? = null, val featuredBadge: Badge? = null,
val transactionState: TransactionState = TransactionState.Init, val transactionState: TransactionState = TransactionState.Init,
val availableSubscriptions: List<Subscription> = emptyList(), val availableSubscriptions: List<Subscription> = emptyList(),
val hasReceipts: Boolean = false,
private val subscriptionRedemptionState: SubscriptionRedemptionState = SubscriptionRedemptionState.NONE private val subscriptionRedemptionState: SubscriptionRedemptionState = SubscriptionRedemptionState.NONE
) { ) {

View file

@ -9,8 +9,10 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.kotlin.subscribeBy import io.reactivex.rxjava3.kotlin.subscribeBy
import io.reactivex.rxjava3.schedulers.Schedulers
import org.signal.core.util.logging.Log import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.components.settings.app.subscription.SubscriptionsRepository import org.thoughtcrime.securesms.components.settings.app.subscription.SubscriptionsRepository
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.jobmanager.JobTracker import org.thoughtcrime.securesms.jobmanager.JobTracker
import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.subscription.LevelUpdate import org.thoughtcrime.securesms.subscription.LevelUpdate
@ -105,6 +107,14 @@ class ManageDonationsViewModel(
Log.w(TAG, "Error retrieving subscriptions data", it) Log.w(TAG, "Error retrieving subscriptions data", it)
} }
) )
disposables += Single.fromCallable { SignalDatabase.donationReceipts.hasReceipts() }
.subscribeOn(Schedulers.io())
.subscribe { hasReceipts ->
store.update {
it.copy(hasReceipts = hasReceipts)
}
}
} }
class Factory( class Factory(

View file

@ -6,6 +6,7 @@ import androidx.core.content.contentValuesOf
import org.signal.core.util.CursorUtil import org.signal.core.util.CursorUtil
import org.signal.core.util.SqlUtil import org.signal.core.util.SqlUtil
import org.signal.core.util.money.FiatMoney import org.signal.core.util.money.FiatMoney
import org.signal.core.util.select
import org.thoughtcrime.securesms.database.model.DonationReceiptRecord import org.thoughtcrime.securesms.database.model.DonationReceiptRecord
import java.math.BigDecimal import java.math.BigDecimal
import java.util.Currency import java.util.Currency
@ -39,6 +40,15 @@ class DonationReceiptDatabase(context: Context, databaseHelper: SignalDatabase)
) )
} }
fun hasReceipts(): Boolean {
return readableDatabase.select("1")
.from(TABLE_NAME)
.where("")
.limit(1)
.run()
.use { it.moveToFirst() }
}
fun addReceipt(record: DonationReceiptRecord) { fun addReceipt(record: DonationReceiptRecord) {
require(record.id == -1L) require(record.id == -1L)