Add dialog and observer for pending backup payment for storage optimization.

This commit is contained in:
Alex Hart 2024-10-21 11:39:10 -03:00 committed by Greyson Parrelli
parent b9474a75a4
commit 481d022b82
3 changed files with 61 additions and 2 deletions

View file

@ -116,7 +116,9 @@ class ManageStorageSettingsFragment : ComposeFragment() {
onSyncTrimThreadDeletes = { viewModel.setSyncTrimDeletes(it) },
onDeleteChatHistory = { navController.navigate("confirm-delete-chat-history") },
onToggleOnDeviceStorageOptimization = { enabled ->
if (state.onDeviceStorageOptimizationState == ManageStorageSettingsViewModel.OnDeviceStorageOptimizationState.REQUIRES_PAID_TIER) {
if (state.isPaidTierPending) {
navController.navigate("paid-tier-pending")
} else if (state.onDeviceStorageOptimizationState == ManageStorageSettingsViewModel.OnDeviceStorageOptimizationState.REQUIRES_PAID_TIER) {
UpgradeToEnableOptimizedStorageSheet().show(parentFragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG)
} else {
viewModel.setOptimizeStorage(enabled)
@ -237,6 +239,19 @@ class ManageStorageSettingsFragment : ComposeFragment() {
onDismiss = { navController.popBackStack() }
)
}
dialog(
route = "paid-tier-pending"
) {
// TODO [backups] Finalized copy
Dialogs.SimpleAlertDialog(
title = "Paid tier pending",
body = "TODO",
confirm = stringResource(android.R.string.ok),
onConfirm = {},
onDismiss = { navController.popBackStack() }
)
}
}
}
}

View file

@ -8,12 +8,16 @@ package org.thoughtcrime.securesms.components.settings.app.storage
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.signal.core.util.concurrent.SignalExecutors
import org.thoughtcrime.securesms.backup.v2.MessageBackupTier
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository
import org.thoughtcrime.securesms.database.InAppPaymentTable
import org.thoughtcrime.securesms.database.MediaTable
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.media
@ -37,6 +41,17 @@ class ManageStorageSettingsViewModel : ViewModel() {
)
val state = store.asStateFlow()
init {
if (RemoteConfig.messageBackups) {
viewModelScope.launch(Dispatchers.IO) {
InAppPaymentsRepository.observeLatestBackupPayment()
.collectLatest { payment ->
store.update { it.copy(isPaidTierPending = payment.state == InAppPaymentTable.State.PENDING) }
}
}
}
}
fun refresh() {
viewModelScope.launch {
val breakdown: MediaTable.StorageBreakdown = media.getStorageBreakdown()
@ -158,7 +173,8 @@ class ManageStorageSettingsViewModel : ViewModel() {
val syncTrimDeletes: Boolean,
val breakdown: MediaTable.StorageBreakdown? = null,
val onDeviceStorageOptimizationState: OnDeviceStorageOptimizationState,
val storageOptimizationStateChanged: Boolean = false
val storageOptimizationStateChanged: Boolean = false,
val isPaidTierPending: Boolean = false
) {
companion object {
const val NO_LIMIT = 0

View file

@ -14,6 +14,12 @@ import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.processors.PublishProcessor
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.distinctUntilChanged
import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.logging.Log
import org.signal.donations.InAppPaymentType
@ -78,6 +84,28 @@ object InAppPaymentsRepository {
}.subscribeOn(Schedulers.io())
}
/**
* Returns a flow of InAppPayment objects for the latest RECURRING_BACKUP object.
*/
fun observeLatestBackupPayment(): Flow<InAppPaymentTable.InAppPayment> {
return callbackFlow {
fun refresh() {
val latest = SignalDatabase.inAppPayments.getLatestInAppPaymentByType(InAppPaymentType.RECURRING_BACKUP)
if (latest != null) {
trySendBlocking(latest)
}
}
val observer = InAppPaymentObserver {
refresh()
}
AppDependencies.databaseObserver.registerInAppPaymentObserver(observer)
awaitClose {
AppDependencies.databaseObserver.unregisterObserver(observer)
}
}.conflate().distinctUntilChanged()
}
/**
* Common logic for handling errors coming from the Rx chains that handle payments. These errors
* are analyzed and then either written to the database or dispatched to the temporary error processor.