From e14078d2ec28a212ecdd6bd2a059a1d39ef82764 Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Fri, 20 Sep 2024 11:08:22 -0300 Subject: [PATCH] Allow free tier to be enabled when Google Play Billing isn't available. --- .../MessageBackupsFlowFragment.kt | 3 ++- .../subscription/MessageBackupsFlowState.kt | 1 + .../MessageBackupsFlowViewModel.kt | 21 ++++++++++++------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowFragment.kt index 15be083462..9d68e3de52 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowFragment.kt @@ -16,6 +16,7 @@ import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.backup.v2.MessageBackupTier import org.thoughtcrime.securesms.compose.ComposeFragment import org.thoughtcrime.securesms.compose.Nav import org.thoughtcrime.securesms.dependencies.AppDependencies @@ -84,7 +85,7 @@ class MessageBackupsFlowFragment : ComposeFragment() { MessageBackupsTypeSelectionScreen( currentBackupTier = state.currentMessageBackupTier, selectedBackupTier = state.selectedMessageBackupTier, - availableBackupTypes = state.availableBackupTypes, + availableBackupTypes = state.availableBackupTypes.filter { it.tier == MessageBackupTier.FREE || state.hasBackupSubscriberAvailable }, onMessageBackupsTierSelected = { tier -> val type = state.availableBackupTypes.first { it.tier == tier } val label = when (type) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowState.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowState.kt index 85a884a20c..96dd825735 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowState.kt @@ -11,6 +11,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.whispersystems.signalservice.api.backup.BackupKey data class MessageBackupsFlowState( + val hasBackupSubscriberAvailable: Boolean = false, val selectedMessageBackupTierLabel: String? = null, val selectedMessageBackupTier: MessageBackupTier? = SignalStore.backup.backupTier, val currentMessageBackupTier: MessageBackupTier? = SignalStore.backup.backupTier, diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowViewModel.kt index dd64bc64ff..53e6da0a50 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/subscription/MessageBackupsFlowViewModel.kt @@ -20,7 +20,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.reactive.asFlow import kotlinx.coroutines.withContext import org.signal.core.util.billing.BillingPurchaseResult -import org.signal.core.util.money.FiatMoney +import org.signal.core.util.logging.Log import org.signal.donations.InAppPaymentType import org.thoughtcrime.securesms.backup.v2.BackupRepository import org.thoughtcrime.securesms.backup.v2.MessageBackupTier @@ -38,11 +38,14 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.util.RemoteConfig import org.whispersystems.signalservice.internal.push.SubscriptionsConfiguration -import java.math.BigDecimal import kotlin.time.Duration.Companion.seconds class MessageBackupsFlowViewModel : ViewModel() { + companion object { + private val TAG = Log.tag(MessageBackupsFlowViewModel::class) + } + private val internalStateFlow = MutableStateFlow( MessageBackupsFlowState( availableBackupTypes = emptyList(), @@ -59,13 +62,13 @@ class MessageBackupsFlowViewModel : ViewModel() { viewModelScope.launch { try { ensureSubscriberIdForBackups() - } catch (e: Exception) { internalStateFlow.update { it.copy( - stage = MessageBackupsStage.FAILURE, - failure = e + hasBackupSubscriberAvailable = true ) } + } catch (e: Exception) { + Log.w(TAG, "Failed to ensure a subscriber id exists.", e) } internalStateFlow.update { @@ -168,7 +171,7 @@ class MessageBackupsFlowViewModel : ViewModel() { SignalStore.backup.areBackupsEnabled = true SignalStore.backup.backupTier = MessageBackupTier.FREE - state.copy(stage = MessageBackupsStage.PROCESS_FREE) + state.copy(stage = MessageBackupsStage.COMPLETED) } MessageBackupTier.PAID -> state.copy(stage = MessageBackupsStage.CHECKOUT_SHEET) @@ -176,7 +179,9 @@ class MessageBackupsFlowViewModel : ViewModel() { } private fun validateGatewayAndUpdateState(state: MessageBackupsFlowState): MessageBackupsFlowState { - val backupsType = state.availableBackupTypes.first { it.tier == state.selectedMessageBackupTier } + check(state.selectedMessageBackupTier == MessageBackupTier.PAID) + check(state.availableBackupTypes.any { it.tier == state.selectedMessageBackupTier }) + check(state.hasBackupSubscriberAvailable) viewModelScope.launch(Dispatchers.IO) { withContext(Dispatchers.Main) { @@ -194,7 +199,7 @@ class MessageBackupsFlowViewModel : ViewModel() { inAppPaymentData = InAppPaymentData( badge = null, label = state.selectedMessageBackupTierLabel!!, - amount = if (backupsType is MessageBackupsType.Paid) paidFiat.toFiatValue() else FiatMoney(BigDecimal.ZERO, paidFiat.currency).toFiatValue(), + amount = paidFiat.toFiatValue(), level = SubscriptionsConfiguration.BACKUPS_LEVEL.toLong(), recipientId = Recipient.self().id.serialize(), paymentMethodType = InAppPaymentData.PaymentMethodType.GOOGLE_PLAY_BILLING,