mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 20:48:43 +00:00
Add support for upgrades from warning sheet.
This commit is contained in:
committed by
Greyson Parrelli
parent
7f1d59f40a
commit
445b7ef76f
@@ -139,7 +139,7 @@ object BackupRepository {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun skipMediaRestore() {
|
fun skipMediaRestore() {
|
||||||
// TODO [backups] -- Clear the error as necessary
|
// TODO [backups] -- Clear the error as necessary, cancel anything remaining in the restore
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -49,9 +49,10 @@ import org.signal.core.ui.Previews
|
|||||||
import org.signal.core.ui.SignalPreview
|
import org.signal.core.ui.SignalPreview
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.backup.v2.BackupRepository
|
import org.thoughtcrime.securesms.backup.v2.BackupRepository
|
||||||
|
import org.thoughtcrime.securesms.backup.v2.ui.subscription.MessageBackupsType
|
||||||
import org.thoughtcrime.securesms.billing.launchManageBackupsSubscription
|
import org.thoughtcrime.securesms.billing.launchManageBackupsSubscription
|
||||||
|
import org.thoughtcrime.securesms.billing.upgrade.UpgradeToPaidTierBottomSheet
|
||||||
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
|
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
|
||||||
import org.thoughtcrime.securesms.compose.ComposeBottomSheetDialogFragment
|
|
||||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||||
import org.thoughtcrime.securesms.jobs.BackupMessagesJob
|
import org.thoughtcrime.securesms.jobs.BackupMessagesJob
|
||||||
import org.thoughtcrime.securesms.jobs.BackupRestoreMediaJob
|
import org.thoughtcrime.securesms.jobs.BackupRestoreMediaJob
|
||||||
@@ -61,7 +62,7 @@ import org.signal.core.ui.R as CoreUiR
|
|||||||
/**
|
/**
|
||||||
* Notifies the user of an issue with their backup.
|
* Notifies the user of an issue with their backup.
|
||||||
*/
|
*/
|
||||||
class BackupAlertBottomSheet : ComposeBottomSheetDialogFragment() {
|
class BackupAlertBottomSheet : UpgradeToPaidTierBottomSheet() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ARG_ALERT = "alert"
|
private const val ARG_ALERT = "alert"
|
||||||
@@ -79,24 +80,33 @@ class BackupAlertBottomSheet : ComposeBottomSheetDialogFragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun SheetContent() {
|
override fun UpgradeSheetContent(
|
||||||
|
paidBackupType: MessageBackupsType.Paid,
|
||||||
|
freeBackupType: MessageBackupsType.Free,
|
||||||
|
isSubscribeEnabled: Boolean,
|
||||||
|
onSubscribeClick: () -> Unit
|
||||||
|
) {
|
||||||
var pricePerMonth by remember { mutableStateOf("-") }
|
var pricePerMonth by remember { mutableStateOf("-") }
|
||||||
val resources = LocalContext.current.resources
|
val resources = LocalContext.current.resources
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(paidBackupType.pricePerMonth) {
|
||||||
val price = AppDependencies.billingApi.queryProduct()?.price ?: return@LaunchedEffect
|
pricePerMonth = FiatMoneyUtil.format(resources, paidBackupType.pricePerMonth, FiatMoneyUtil.formatOptions().trimZerosAfterDecimal())
|
||||||
pricePerMonth = FiatMoneyUtil.format(resources, price, FiatMoneyUtil.formatOptions().trimZerosAfterDecimal())
|
}
|
||||||
|
|
||||||
|
val performPrimaryAction = remember(onSubscribeClick) {
|
||||||
|
createPrimaryAction(onSubscribeClick)
|
||||||
}
|
}
|
||||||
|
|
||||||
BackupAlertSheetContent(
|
BackupAlertSheetContent(
|
||||||
backupAlert = backupAlert,
|
backupAlert = backupAlert,
|
||||||
onPrimaryActionClick = this::performPrimaryAction,
|
isSubscribeEnabled = isSubscribeEnabled,
|
||||||
|
onPrimaryActionClick = performPrimaryAction,
|
||||||
onSecondaryActionClick = this::performSecondaryAction
|
onSecondaryActionClick = this::performSecondaryAction
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
private fun performPrimaryAction() {
|
private fun createPrimaryAction(onSubscribeClick: () -> Unit): () -> Unit = {
|
||||||
when (backupAlert) {
|
when (backupAlert) {
|
||||||
is BackupAlert.CouldNotCompleteBackup -> {
|
is BackupAlert.CouldNotCompleteBackup -> {
|
||||||
BackupMessagesJob.enqueue()
|
BackupMessagesJob.enqueue()
|
||||||
@@ -104,11 +114,14 @@ class BackupAlertBottomSheet : ComposeBottomSheetDialogFragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BackupAlert.FailedToRenew -> launchManageBackupsSubscription()
|
BackupAlert.FailedToRenew -> launchManageBackupsSubscription()
|
||||||
BackupAlert.MediaBackupsAreOff, BackupAlert.MediaWillBeDeletedToday -> {
|
BackupAlert.MediaBackupsAreOff -> {
|
||||||
|
onSubscribeClick()
|
||||||
|
}
|
||||||
|
BackupAlert.MediaWillBeDeletedToday -> {
|
||||||
performFullMediaDownload()
|
performFullMediaDownload()
|
||||||
}
|
}
|
||||||
|
|
||||||
is BackupAlert.DiskFull -> Unit
|
is BackupAlert.DiskFull -> Unit // dismiss the sheet and keep your restore paused until you free up space.
|
||||||
}
|
}
|
||||||
|
|
||||||
dismissAllowingStateLoss()
|
dismissAllowingStateLoss()
|
||||||
@@ -119,10 +132,7 @@ class BackupAlertBottomSheet : ComposeBottomSheetDialogFragment() {
|
|||||||
when (backupAlert) {
|
when (backupAlert) {
|
||||||
is BackupAlert.CouldNotCompleteBackup -> Unit
|
is BackupAlert.CouldNotCompleteBackup -> Unit
|
||||||
BackupAlert.FailedToRenew -> Unit
|
BackupAlert.FailedToRenew -> Unit
|
||||||
BackupAlert.MediaBackupsAreOff -> {
|
BackupAlert.MediaBackupsAreOff -> Unit
|
||||||
// TODO [backups] - Silence and remind on last day
|
|
||||||
}
|
|
||||||
|
|
||||||
BackupAlert.MediaWillBeDeletedToday -> {
|
BackupAlert.MediaWillBeDeletedToday -> {
|
||||||
displayLastChanceDialog()
|
displayLastChanceDialog()
|
||||||
}
|
}
|
||||||
@@ -182,6 +192,7 @@ class BackupAlertBottomSheet : ComposeBottomSheetDialogFragment() {
|
|||||||
private fun BackupAlertSheetContent(
|
private fun BackupAlertSheetContent(
|
||||||
backupAlert: BackupAlert,
|
backupAlert: BackupAlert,
|
||||||
pricePerMonth: String = "",
|
pricePerMonth: String = "",
|
||||||
|
isSubscribeEnabled: Boolean = true,
|
||||||
onPrimaryActionClick: () -> Unit = {},
|
onPrimaryActionClick: () -> Unit = {},
|
||||||
onSecondaryActionClick: () -> Unit = {}
|
onSecondaryActionClick: () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
@@ -250,6 +261,7 @@ private fun BackupAlertSheetContent(
|
|||||||
val padBottom = if (secondaryActionResource > 0) 16.dp else 56.dp
|
val padBottom = if (secondaryActionResource > 0) 16.dp else 56.dp
|
||||||
|
|
||||||
Buttons.LargeTonal(
|
Buttons.LargeTonal(
|
||||||
|
enabled = isSubscribeEnabled,
|
||||||
onClick = onPrimaryActionClick,
|
onClick = onPrimaryActionClick,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.defaultMinSize(minWidth = 220.dp)
|
.defaultMinSize(minWidth = 220.dp)
|
||||||
@@ -259,7 +271,11 @@ private fun BackupAlertSheetContent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (secondaryActionResource > 0) {
|
if (secondaryActionResource > 0) {
|
||||||
TextButton(onClick = onSecondaryActionClick, modifier = Modifier.padding(bottom = 32.dp)) {
|
TextButton(
|
||||||
|
enabled = isSubscribeEnabled,
|
||||||
|
onClick = onSecondaryActionClick,
|
||||||
|
modifier = Modifier.padding(bottom = 32.dp)
|
||||||
|
) {
|
||||||
Text(text = stringResource(id = secondaryActionResource))
|
Text(text = stringResource(id = secondaryActionResource))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -447,14 +463,28 @@ private fun BackupAlertSheetContentPreviewDiskFull() {
|
|||||||
@Parcelize
|
@Parcelize
|
||||||
sealed class BackupAlert : Parcelable {
|
sealed class BackupAlert : Parcelable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This value is driven by a watermarking system and will be dismissed and snoozed whenever the sheet is closed.
|
||||||
|
* This value is driven by failure to complete a backup within a timeout based on the user's chosen backup frequency.
|
||||||
|
*/
|
||||||
data class CouldNotCompleteBackup(
|
data class CouldNotCompleteBackup(
|
||||||
val daysSinceLastBackup: Int
|
val daysSinceLastBackup: Int
|
||||||
) : BackupAlert()
|
) : BackupAlert()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This value is driven by InAppPayment state, and will be automatically cleared when the sheet is displayed.
|
||||||
|
*/
|
||||||
data object FailedToRenew : BackupAlert()
|
data object FailedToRenew : BackupAlert()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This value is driven by InAppPayment state, and will be automatically cleared when the sheet is displayed.
|
||||||
|
* This value is displayed if we hit an 'unexpected cancellation' of a user's backup.
|
||||||
|
*/
|
||||||
data object MediaBackupsAreOff : BackupAlert()
|
data object MediaBackupsAreOff : BackupAlert()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO [backups] - This value is driven as "60D after the last time the user pinged their backup"
|
||||||
|
*/
|
||||||
data object MediaWillBeDeletedToday : BackupAlert()
|
data object MediaWillBeDeletedToday : BackupAlert()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ object BackupAlertDelegate {
|
|||||||
BackupAlertBottomSheet.create(BackupAlert.CouldNotCompleteBackup(daysSinceLastBackup = SignalStore.backup.daysSinceLastBackup)).show(fragmentManager, null)
|
BackupAlertBottomSheet.create(BackupAlert.CouldNotCompleteBackup(daysSinceLastBackup = SignalStore.backup.daysSinceLastBackup)).show(fragmentManager, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO [backups] Check if media will be deleted within 24hrs and display warning sheet.
|
||||||
|
|
||||||
// TODO [backups]
|
// TODO [backups]
|
||||||
// Get unnotified backup download failures & display sheet
|
// Get unnotified backup download failures & display sheet
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ class InAppPaymentsBottomSheetDelegate(
|
|||||||
}.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribeBy { inAppPayments ->
|
}.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribeBy { inAppPayments ->
|
||||||
for (payment in inAppPayments) {
|
for (payment in inAppPayments) {
|
||||||
if (isPaymentProcessingError(payment.state, payment.data)) {
|
if (isPaymentProcessingError(payment.state, payment.data)) {
|
||||||
BackupAlertBottomSheet.create(BackupAlert.CouldNotCompleteBackup(daysSinceLastBackup = SignalStore.backup.daysSinceLastBackup)).show(fragmentManager, null)
|
BackupAlertBottomSheet.create(BackupAlert.FailedToRenew).show(fragmentManager, null)
|
||||||
} else if (isUnexpectedCancellation(payment.state, payment.data)) {
|
} else if (isUnexpectedCancellation(payment.state, payment.data)) {
|
||||||
BackupAlertBottomSheet.create(BackupAlert.MediaBackupsAreOff).show(fragmentManager, null)
|
BackupAlertBottomSheet.create(BackupAlert.MediaBackupsAreOff).show(fragmentManager, null)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user