mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-03-02 15:36:32 +00:00
Update backups bottom sheet data handling.
This commit is contained in:
committed by
Greyson Parrelli
parent
3901c52e45
commit
f14f7f7478
@@ -125,6 +125,11 @@ object BackupRepository {
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun skipMediaRestore() {
|
||||
// TODO [backups] -- Clear the error as necessary
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the yellow dot should be displayed on the conversation list avatar.
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
package org.thoughtcrime.securesms.backup.v2.ui
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -37,6 +37,7 @@ import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.os.BundleCompat
|
||||
import androidx.core.os.bundleOf
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
@@ -46,6 +47,7 @@ import org.signal.core.ui.Buttons
|
||||
import org.signal.core.ui.Previews
|
||||
import org.signal.core.ui.SignalPreview
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.backup.v2.BackupRepository
|
||||
import org.thoughtcrime.securesms.billing.launchManageBackupsSubscription
|
||||
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
|
||||
import org.thoughtcrime.securesms.compose.ComposeBottomSheetDialogFragment
|
||||
@@ -63,6 +65,7 @@ class BackupAlertBottomSheet : ComposeBottomSheetDialogFragment() {
|
||||
companion object {
|
||||
private const val ARG_ALERT = "alert"
|
||||
|
||||
@JvmStatic
|
||||
fun create(backupAlert: BackupAlert): BackupAlertBottomSheet {
|
||||
return BackupAlertBottomSheet().apply {
|
||||
arguments = bundleOf(ARG_ALERT to backupAlert)
|
||||
@@ -94,17 +97,17 @@ class BackupAlertBottomSheet : ComposeBottomSheetDialogFragment() {
|
||||
@Stable
|
||||
private fun performPrimaryAction() {
|
||||
when (backupAlert) {
|
||||
BackupAlert.COULD_NOT_COMPLETE_BACKUP -> {
|
||||
BackupAlert.CouldNotCompleteBackup -> {
|
||||
BackupMessagesJob.enqueue()
|
||||
startActivity(AppSettingsActivity.remoteBackups(requireContext()))
|
||||
}
|
||||
|
||||
BackupAlert.PAYMENT_PROCESSING -> launchManageBackupsSubscription()
|
||||
BackupAlert.MEDIA_BACKUPS_ARE_OFF, BackupAlert.MEDIA_WILL_BE_DELETED_TODAY -> {
|
||||
BackupAlert.FailedToRenew -> launchManageBackupsSubscription()
|
||||
BackupAlert.MediaBackupsAreOff, BackupAlert.MediaWillBeDeletedToday -> {
|
||||
performFullMediaDownload()
|
||||
}
|
||||
|
||||
BackupAlert.DISK_FULL -> Unit
|
||||
is BackupAlert.DiskFull -> Unit
|
||||
}
|
||||
|
||||
dismissAllowingStateLoss()
|
||||
@@ -113,20 +116,22 @@ class BackupAlertBottomSheet : ComposeBottomSheetDialogFragment() {
|
||||
@Stable
|
||||
private fun performSecondaryAction() {
|
||||
when (backupAlert) {
|
||||
BackupAlert.COULD_NOT_COMPLETE_BACKUP -> {
|
||||
BackupAlert.CouldNotCompleteBackup -> {
|
||||
// TODO [backups] - Dismiss and notify later
|
||||
}
|
||||
|
||||
BackupAlert.PAYMENT_PROCESSING -> Unit
|
||||
BackupAlert.MEDIA_BACKUPS_ARE_OFF -> {
|
||||
BackupAlert.FailedToRenew -> Unit
|
||||
BackupAlert.MediaBackupsAreOff -> {
|
||||
// TODO [backups] - Silence and remind on last day
|
||||
}
|
||||
|
||||
BackupAlert.MEDIA_WILL_BE_DELETED_TODAY -> {
|
||||
BackupAlert.MediaWillBeDeletedToday -> {
|
||||
displayLastChanceDialog()
|
||||
}
|
||||
|
||||
BackupAlert.DISK_FULL -> Unit
|
||||
is BackupAlert.DiskFull -> {
|
||||
displaySkipRestoreDialog()
|
||||
}
|
||||
}
|
||||
|
||||
dismissAllowingStateLoss()
|
||||
@@ -143,6 +148,23 @@ class BackupAlertBottomSheet : ComposeBottomSheetDialogFragment() {
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun displaySkipRestoreDialog() {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle((R.string.BackupAlertBottomSheet__skip_restore_question))
|
||||
.setMessage(R.string.BackupAlertBottomSheet__if_you_skip_restore)
|
||||
.setPositiveButton(R.string.BackupAlertBottomSheet__skip) { _, _ ->
|
||||
BackupRepository.skipMediaRestore()
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.create()
|
||||
.apply {
|
||||
setOnShowListener {
|
||||
getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(ContextCompat.getColor(requireContext(), R.color.signal_colorError))
|
||||
}
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun performFullMediaDownload() {
|
||||
// TODO [backups] -- We need to force this to download everything
|
||||
AppDependencies.jobManager.add(BackupRestoreMediaJob())
|
||||
@@ -167,7 +189,7 @@ private fun BackupAlertSheetContent(
|
||||
Spacer(modifier = Modifier.size(26.dp))
|
||||
|
||||
when (backupAlert) {
|
||||
BackupAlert.PAYMENT_PROCESSING, BackupAlert.MEDIA_BACKUPS_ARE_OFF -> {
|
||||
BackupAlert.FailedToRenew, BackupAlert.MediaBackupsAreOff -> {
|
||||
Box {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.image_signal_backups),
|
||||
@@ -200,24 +222,21 @@ private fun BackupAlertSheetContent(
|
||||
}
|
||||
|
||||
Text(
|
||||
text = stringResource(id = rememberTitleResource(backupAlert = backupAlert)),
|
||||
text = titleString(backupAlert = backupAlert),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.padding(top = 16.dp, bottom = 6.dp)
|
||||
)
|
||||
|
||||
when (backupAlert) {
|
||||
BackupAlert.COULD_NOT_COMPLETE_BACKUP -> CouldNotCompleteBackup(
|
||||
BackupAlert.CouldNotCompleteBackup -> CouldNotCompleteBackup(
|
||||
daysSinceLastBackup = 7 // TODO [backups]
|
||||
)
|
||||
|
||||
BackupAlert.PAYMENT_PROCESSING -> PaymentProcessingBody()
|
||||
BackupAlert.MEDIA_BACKUPS_ARE_OFF -> MediaBackupsAreOffBody(30) // TODO [backups] -- Get this value from backend
|
||||
BackupAlert.MEDIA_WILL_BE_DELETED_TODAY -> MediaWillBeDeletedTodayBody()
|
||||
BackupAlert.DISK_FULL -> DiskFullBody(
|
||||
requiredSpace = "12 GB", // TODO [backups] Where does this value come from?
|
||||
daysUntilDeletion = 30 // TODO [backups] Where does this value come from?
|
||||
)
|
||||
BackupAlert.FailedToRenew -> PaymentProcessingBody()
|
||||
BackupAlert.MediaBackupsAreOff -> MediaBackupsAreOffBody(30) // TODO [backups] -- Get this value from backend
|
||||
BackupAlert.MediaWillBeDeletedToday -> MediaWillBeDeletedTodayBody()
|
||||
is BackupAlert.DiskFull -> DiskFullBody(requiredSpace = backupAlert.requiredSpace)
|
||||
}
|
||||
|
||||
val secondaryActionResource = rememberSecondaryActionResource(backupAlert = backupAlert)
|
||||
@@ -299,19 +318,16 @@ private fun MediaWillBeDeletedTodayBody() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DiskFullBody(
|
||||
requiredSpace: String,
|
||||
daysUntilDeletion: Long
|
||||
) {
|
||||
private fun DiskFullBody(requiredSpace: String) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.BackupAlertBottomSheet__your_device_does_not_have_enough_free_space, requiredSpace),
|
||||
text = stringResource(id = R.string.BackupAlertBottomSheet__to_finish_downloading_your_signal_backup, requiredSpace),
|
||||
textAlign = TextAlign.Center,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(bottom = 24.dp)
|
||||
)
|
||||
|
||||
Text(
|
||||
text = pluralStringResource(id = R.plurals.BackupAlertBottomSheet__if_you_choose_skip, daysUntilDeletion.toInt(), daysUntilDeletion), // TODO [backups] Learn More link
|
||||
text = stringResource(R.string.BackupAlertBottomSheet__to_free_up_space_offload),
|
||||
textAlign = TextAlign.Center,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(bottom = 36.dp)
|
||||
@@ -322,24 +338,21 @@ private fun DiskFullBody(
|
||||
private fun rememberBackupsIconColors(backupAlert: BackupAlert): BackupsIconColors {
|
||||
return remember(backupAlert) {
|
||||
when (backupAlert) {
|
||||
BackupAlert.PAYMENT_PROCESSING, BackupAlert.MEDIA_BACKUPS_ARE_OFF -> error("Not icon-based options.")
|
||||
BackupAlert.COULD_NOT_COMPLETE_BACKUP, BackupAlert.DISK_FULL -> BackupsIconColors.Warning
|
||||
BackupAlert.MEDIA_WILL_BE_DELETED_TODAY -> BackupsIconColors.Error
|
||||
BackupAlert.FailedToRenew, BackupAlert.MediaBackupsAreOff -> error("Not icon-based options.")
|
||||
BackupAlert.CouldNotCompleteBackup, is BackupAlert.DiskFull -> BackupsIconColors.Warning
|
||||
BackupAlert.MediaWillBeDeletedToday -> BackupsIconColors.Error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@StringRes
|
||||
private fun rememberTitleResource(backupAlert: BackupAlert): Int {
|
||||
return remember(backupAlert) {
|
||||
when (backupAlert) {
|
||||
BackupAlert.COULD_NOT_COMPLETE_BACKUP -> R.string.BackupAlertBottomSheet__couldnt_complete_backup
|
||||
BackupAlert.PAYMENT_PROCESSING -> R.string.BackupAlertBottomSheet__your_backups_subscription_failed_to_renew
|
||||
BackupAlert.MEDIA_BACKUPS_ARE_OFF -> R.string.BackupAlertBottomSheet__your_backups_subscription_expired
|
||||
BackupAlert.MEDIA_WILL_BE_DELETED_TODAY -> R.string.BackupAlertBottomSheet__your_media_will_be_deleted_today
|
||||
BackupAlert.DISK_FULL -> R.string.BackupAlertBottomSheet__cant_complete_download
|
||||
}
|
||||
private fun titleString(backupAlert: BackupAlert): String {
|
||||
return when (backupAlert) {
|
||||
BackupAlert.CouldNotCompleteBackup -> stringResource(R.string.BackupAlertBottomSheet__couldnt_complete_backup)
|
||||
BackupAlert.FailedToRenew -> stringResource(R.string.BackupAlertBottomSheet__your_backups_subscription_failed_to_renew)
|
||||
BackupAlert.MediaBackupsAreOff -> stringResource(R.string.BackupAlertBottomSheet__your_backups_subscription_expired)
|
||||
BackupAlert.MediaWillBeDeletedToday -> stringResource(R.string.BackupAlertBottomSheet__your_media_will_be_deleted_today)
|
||||
is BackupAlert.DiskFull -> stringResource(R.string.BackupAlertBottomSheet__free_up_s_on_this_device, backupAlert.requiredSpace)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,11 +362,11 @@ private fun primaryActionString(
|
||||
pricePerMonth: String
|
||||
): String {
|
||||
return when (backupAlert) {
|
||||
BackupAlert.COULD_NOT_COMPLETE_BACKUP -> stringResource(R.string.BackupAlertBottomSheet__back_up_now)
|
||||
BackupAlert.PAYMENT_PROCESSING -> stringResource(R.string.BackupAlertBottomSheet__manage_subscription)
|
||||
BackupAlert.MEDIA_BACKUPS_ARE_OFF -> stringResource(R.string.BackupAlertBottomSheet__subscribe_for_s_month, pricePerMonth)
|
||||
BackupAlert.MEDIA_WILL_BE_DELETED_TODAY -> stringResource(R.string.BackupAlertBottomSheet__download_media_now)
|
||||
BackupAlert.DISK_FULL -> stringResource(android.R.string.ok)
|
||||
BackupAlert.CouldNotCompleteBackup -> stringResource(R.string.BackupAlertBottomSheet__back_up_now)
|
||||
BackupAlert.FailedToRenew -> stringResource(R.string.BackupAlertBottomSheet__manage_subscription)
|
||||
BackupAlert.MediaBackupsAreOff -> stringResource(R.string.BackupAlertBottomSheet__subscribe_for_s_month, pricePerMonth)
|
||||
BackupAlert.MediaWillBeDeletedToday -> stringResource(R.string.BackupAlertBottomSheet__download_media_now)
|
||||
is BackupAlert.DiskFull -> stringResource(R.string.BackupAlertBottomSheet__got_it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,11 +374,11 @@ private fun primaryActionString(
|
||||
private fun rememberSecondaryActionResource(backupAlert: BackupAlert): Int {
|
||||
return remember(backupAlert) {
|
||||
when (backupAlert) {
|
||||
BackupAlert.COULD_NOT_COMPLETE_BACKUP -> android.R.string.cancel // TODO [backups] -- Finalized copy
|
||||
BackupAlert.PAYMENT_PROCESSING -> R.string.BackupAlertBottomSheet__not_now
|
||||
BackupAlert.MEDIA_BACKUPS_ARE_OFF -> R.string.BackupAlertBottomSheet__not_now
|
||||
BackupAlert.MEDIA_WILL_BE_DELETED_TODAY -> R.string.BackupAlertBottomSheet__dont_download_media
|
||||
BackupAlert.DISK_FULL -> R.string.BackupAlertBottomSheet__skip
|
||||
BackupAlert.CouldNotCompleteBackup -> R.string.BackupAlertBottomSheet__try_later
|
||||
BackupAlert.FailedToRenew -> R.string.BackupAlertBottomSheet__not_now
|
||||
BackupAlert.MediaBackupsAreOff -> R.string.BackupAlertBottomSheet__not_now
|
||||
BackupAlert.MediaWillBeDeletedToday -> R.string.BackupAlertBottomSheet__dont_download_media
|
||||
is BackupAlert.DiskFull -> R.string.BackupAlertBottomSheet__skip_restore
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -375,7 +388,7 @@ private fun rememberSecondaryActionResource(backupAlert: BackupAlert): Int {
|
||||
private fun BackupAlertSheetContentPreviewGeneric() {
|
||||
Previews.BottomSheetPreview {
|
||||
BackupAlertSheetContent(
|
||||
backupAlert = BackupAlert.COULD_NOT_COMPLETE_BACKUP
|
||||
backupAlert = BackupAlert.CouldNotCompleteBackup
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -385,7 +398,7 @@ private fun BackupAlertSheetContentPreviewGeneric() {
|
||||
private fun BackupAlertSheetContentPreviewPayment() {
|
||||
Previews.BottomSheetPreview {
|
||||
BackupAlertSheetContent(
|
||||
backupAlert = BackupAlert.PAYMENT_PROCESSING
|
||||
backupAlert = BackupAlert.FailedToRenew
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -395,7 +408,7 @@ private fun BackupAlertSheetContentPreviewPayment() {
|
||||
private fun BackupAlertSheetContentPreviewMedia() {
|
||||
Previews.BottomSheetPreview {
|
||||
BackupAlertSheetContent(
|
||||
backupAlert = BackupAlert.MEDIA_BACKUPS_ARE_OFF,
|
||||
backupAlert = BackupAlert.MediaBackupsAreOff,
|
||||
pricePerMonth = "$2.99"
|
||||
)
|
||||
}
|
||||
@@ -406,7 +419,7 @@ private fun BackupAlertSheetContentPreviewMedia() {
|
||||
private fun BackupAlertSheetContentPreviewDelete() {
|
||||
Previews.BottomSheetPreview {
|
||||
BackupAlertSheetContent(
|
||||
backupAlert = BackupAlert.MEDIA_WILL_BE_DELETED_TODAY
|
||||
backupAlert = BackupAlert.MediaWillBeDeletedToday
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -416,16 +429,28 @@ private fun BackupAlertSheetContentPreviewDelete() {
|
||||
private fun BackupAlertSheetContentPreviewDiskFull() {
|
||||
Previews.BottomSheetPreview {
|
||||
BackupAlertSheetContent(
|
||||
backupAlert = BackupAlert.DISK_FULL
|
||||
backupAlert = BackupAlert.DiskFull(requiredSpace = "12GB")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All necessary information to display the sheet should be handed in through the specific alert.
|
||||
*/
|
||||
@Parcelize
|
||||
enum class BackupAlert : Parcelable {
|
||||
COULD_NOT_COMPLETE_BACKUP,
|
||||
PAYMENT_PROCESSING,
|
||||
MEDIA_BACKUPS_ARE_OFF,
|
||||
MEDIA_WILL_BE_DELETED_TODAY,
|
||||
DISK_FULL
|
||||
sealed class BackupAlert : Parcelable {
|
||||
|
||||
data object CouldNotCompleteBackup : BackupAlert()
|
||||
|
||||
data object FailedToRenew : BackupAlert()
|
||||
|
||||
data object MediaBackupsAreOff : BackupAlert()
|
||||
|
||||
data object MediaWillBeDeletedToday : BackupAlert()
|
||||
|
||||
/**
|
||||
* The disk is full. Contains a value representing the amount of space that must be freed.
|
||||
*
|
||||
*/
|
||||
data class DiskFull(val requiredSpace: String) : BackupAlert()
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.coroutineScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import kotlinx.coroutines.launch
|
||||
import org.thoughtcrime.securesms.backup.v2.BackupRepository
|
||||
|
||||
/**
|
||||
* Delegate that controls whether and which backup alert sheet is displayed.
|
||||
@@ -19,12 +20,12 @@ object BackupAlertDelegate {
|
||||
fun delegate(fragmentManager: FragmentManager, lifecycle: Lifecycle) {
|
||||
lifecycle.coroutineScope.launch {
|
||||
lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
// TODO [backups]
|
||||
// 1. Get unnotified backup upload failures
|
||||
// 2. Get unnotified backup download failures
|
||||
// 3. Get unnotified backup payment failures
|
||||
if (BackupRepository.shouldDisplayBackupFailedSheet()) {
|
||||
BackupAlertBottomSheet.create(BackupAlert.CouldNotCompleteBackup).show(fragmentManager, null)
|
||||
}
|
||||
|
||||
// Decide which do display
|
||||
// TODO [backups]
|
||||
// Get unnotified backup download failures & display sheet
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ private const val NONE = -1
|
||||
@Composable
|
||||
fun BackupStatusBanner(
|
||||
data: BackupStatusData,
|
||||
onSkipClick: () -> Unit = {},
|
||||
onActionClick: (BackupStatusData) -> Unit = {},
|
||||
onDismissClick: () -> Unit = {},
|
||||
contentPadding: PaddingValues = PaddingValues(horizontal = 12.dp, vertical = 8.dp)
|
||||
) {
|
||||
@@ -119,7 +119,7 @@ fun BackupStatusBanner(
|
||||
|
||||
if (data.actionRes != NONE) {
|
||||
Buttons.Small(
|
||||
onClick = onSkipClick,
|
||||
onClick = { onActionClick(data) },
|
||||
modifier = Modifier.padding(start = 8.dp)
|
||||
) {
|
||||
Text(text = stringResource(id = data.actionRes))
|
||||
@@ -250,7 +250,7 @@ sealed interface BackupStatusData {
|
||||
get() = stringResource(R.string.BackupStatus__free_up_s_of_space_to_download_your_media, requiredSpace)
|
||||
|
||||
override val iconColors: BackupsIconColors = BackupsIconColors.Warning
|
||||
override val actionRes: Int = R.string.registration_activity__skip
|
||||
override val actionRes: Int = R.string.BackupStatus__details
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -73,7 +73,7 @@ class MediaRestoreProgressBanner(private val listener: RestoreProgressBannerList
|
||||
override fun DisplayBanner(model: BackupStatusData, contentPadding: PaddingValues) {
|
||||
BackupStatusBanner(
|
||||
data = model,
|
||||
onSkipClick = listener::onSkip,
|
||||
onActionClick = listener::onActionClick,
|
||||
onDismissClick = listener::onDismissComplete
|
||||
)
|
||||
}
|
||||
@@ -124,12 +124,12 @@ class MediaRestoreProgressBanner(private val listener: RestoreProgressBannerList
|
||||
}
|
||||
|
||||
interface RestoreProgressBannerListener {
|
||||
fun onSkip()
|
||||
fun onActionClick(data: BackupStatusData)
|
||||
fun onDismissComplete()
|
||||
}
|
||||
|
||||
private object EmptyListener : RestoreProgressBannerListener {
|
||||
override fun onSkip() = Unit
|
||||
override fun onActionClick(data: BackupStatusData) = Unit
|
||||
override fun onDismissComplete() = Unit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ class RemoteBackupsSettingsViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
fun skipMediaRestore() {
|
||||
// TODO [backups] -- Clear the error as necessary
|
||||
BackupRepository.skipMediaRestore()
|
||||
}
|
||||
|
||||
fun cancelMediaRestore() {
|
||||
|
||||
@@ -5,7 +5,6 @@ import org.signal.donations.InAppPaymentType
|
||||
import org.signal.donations.PaymentSourceType
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.database.model.InAppPaymentReceiptRecord
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.util.Environment
|
||||
import org.thoughtcrime.securesms.util.LocaleRemoteConfig
|
||||
@@ -28,9 +27,9 @@ object InAppDonations {
|
||||
return isCreditCardAvailable() || isPayPalAvailable() || isGooglePayAvailable() || isSEPADebitAvailable() || isIDEALAvailable()
|
||||
}
|
||||
|
||||
fun isPaymentSourceAvailable(paymentSourceType: PaymentSourceType, inAppPaymentType: InAppPaymentType): Boolean {
|
||||
fun isDonationsPaymentSourceAvailable(paymentSourceType: PaymentSourceType, inAppPaymentType: InAppPaymentType): Boolean {
|
||||
if (inAppPaymentType == InAppPaymentType.RECURRING_BACKUP) {
|
||||
return paymentSourceType == PaymentSourceType.GooglePlayBilling && AppDependencies.billingApi.isApiAvailable()
|
||||
error("Not supported.")
|
||||
}
|
||||
|
||||
return when (paymentSourceType) {
|
||||
|
||||
@@ -134,9 +134,9 @@ class InAppPaymentsBottomSheetDelegate(
|
||||
}.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribeBy { inAppPayments ->
|
||||
for (payment in inAppPayments) {
|
||||
if (isPaymentProcessingError(payment.state, payment.data)) {
|
||||
BackupAlertBottomSheet.create(BackupAlert.COULD_NOT_COMPLETE_BACKUP).show(fragmentManager, null)
|
||||
BackupAlertBottomSheet.create(BackupAlert.CouldNotCompleteBackup).show(fragmentManager, null)
|
||||
} else if (isUnexpectedCancellation(payment.state, payment.data)) {
|
||||
BackupAlertBottomSheet.create(BackupAlert.MEDIA_BACKUPS_ARE_OFF).show(fragmentManager, null)
|
||||
BackupAlertBottomSheet.create(BackupAlert.MediaBackupsAreOff).show(fragmentManager, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,7 +146,7 @@ class InAppPaymentsBottomSheetDelegate(
|
||||
InAppPaymentsRepository.getExpiredBackupDeletionState()
|
||||
}.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribeBy {
|
||||
if (it == InAppPaymentsRepository.ExpiredBackupDeletionState.DELETE_TODAY) {
|
||||
BackupAlertBottomSheet.create(BackupAlert.MEDIA_WILL_BE_DELETED_TODAY).show(fragmentManager, null)
|
||||
BackupAlertBottomSheet.create(BackupAlert.MediaWillBeDeletedToday).show(fragmentManager, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ class InAppPaymentCheckoutDelegate(
|
||||
}
|
||||
|
||||
fun handleGatewaySelectionResponse(inAppPayment: InAppPaymentTable.InAppPayment) {
|
||||
if (InAppDonations.isPaymentSourceAvailable(inAppPayment.data.paymentMethodType.toPaymentSourceType(), inAppPayment.type)) {
|
||||
if (InAppDonations.isDonationsPaymentSourceAvailable(inAppPayment.data.paymentMethodType.toPaymentSourceType(), inAppPayment.type)) {
|
||||
when (inAppPayment.data.paymentMethodType) {
|
||||
InAppPaymentData.PaymentMethodType.GOOGLE_PAY -> launchGooglePay(inAppPayment)
|
||||
InAppPaymentData.PaymentMethodType.PAYPAL -> launchPayPal(inAppPayment)
|
||||
|
||||
@@ -26,11 +26,11 @@ class GatewaySelectorViewModel(
|
||||
GatewaySelectorState(
|
||||
gatewayOrderStrategy = GatewayOrderStrategy.getStrategy(),
|
||||
inAppPayment = args.inAppPayment,
|
||||
isCreditCardAvailable = InAppDonations.isPaymentSourceAvailable(PaymentSourceType.Stripe.CreditCard, args.inAppPayment.type),
|
||||
isGooglePayAvailable = InAppDonations.isPaymentSourceAvailable(PaymentSourceType.Stripe.GooglePay, args.inAppPayment.type),
|
||||
isPayPalAvailable = InAppDonations.isPaymentSourceAvailable(PaymentSourceType.PayPal, args.inAppPayment.type),
|
||||
isSEPADebitAvailable = InAppDonations.isPaymentSourceAvailable(PaymentSourceType.Stripe.SEPADebit, args.inAppPayment.type),
|
||||
isIDEALAvailable = InAppDonations.isPaymentSourceAvailable(PaymentSourceType.Stripe.IDEAL, args.inAppPayment.type)
|
||||
isCreditCardAvailable = InAppDonations.isDonationsPaymentSourceAvailable(PaymentSourceType.Stripe.CreditCard, args.inAppPayment.type),
|
||||
isGooglePayAvailable = InAppDonations.isDonationsPaymentSourceAvailable(PaymentSourceType.Stripe.GooglePay, args.inAppPayment.type),
|
||||
isPayPalAvailable = InAppDonations.isDonationsPaymentSourceAvailable(PaymentSourceType.PayPal, args.inAppPayment.type),
|
||||
isSEPADebitAvailable = InAppDonations.isDonationsPaymentSourceAvailable(PaymentSourceType.Stripe.SEPADebit, args.inAppPayment.type),
|
||||
isIDEALAvailable = InAppDonations.isDonationsPaymentSourceAvailable(PaymentSourceType.Stripe.IDEAL, args.inAppPayment.type)
|
||||
)
|
||||
)
|
||||
private val disposables = CompositeDisposable()
|
||||
|
||||
@@ -33,7 +33,6 @@ import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
@@ -94,11 +93,10 @@ import org.thoughtcrime.securesms.MainNavigator;
|
||||
import org.thoughtcrime.securesms.MuteDialog;
|
||||
import org.thoughtcrime.securesms.NewConversationActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.backup.v2.ArchiveValidator;
|
||||
import org.thoughtcrime.securesms.backup.v2.BackupRepository;
|
||||
import org.thoughtcrime.securesms.backup.v2.ui.BackupAlert;
|
||||
import org.thoughtcrime.securesms.backup.v2.ui.BackupAlertBottomSheet;
|
||||
import org.thoughtcrime.securesms.backup.v2.ui.BackupAlertDelegate;
|
||||
import org.thoughtcrime.securesms.backup.v2.ui.status.BackupStatusData;
|
||||
import org.thoughtcrime.securesms.badges.models.Badge;
|
||||
import org.thoughtcrime.securesms.badges.self.expired.ExpiredOneTimeBadgeBottomSheetDialogFragment;
|
||||
import org.thoughtcrime.securesms.badges.self.expired.MonthlyDonationCanceledBottomSheetDialogFragment;
|
||||
@@ -163,7 +161,6 @@ import org.thoughtcrime.securesms.notifications.MarkReadReceiver;
|
||||
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.profiles.manage.UsernameEditFragment;
|
||||
import org.thoughtcrime.securesms.providers.BlobProvider;
|
||||
import org.thoughtcrime.securesms.ratelimit.RecaptchaProofBottomSheetFragment;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
@@ -178,12 +175,10 @@ import org.thoughtcrime.securesms.util.AppStartup;
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil;
|
||||
import org.thoughtcrime.securesms.util.CachedInflater;
|
||||
import org.thoughtcrime.securesms.util.ConversationUtil;
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.SignalLocalMetrics;
|
||||
import org.thoughtcrime.securesms.util.SignalProxyUtil;
|
||||
import org.thoughtcrime.securesms.util.SnapToTopDataObserver;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.WindowUtil;
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.PagingMappingAdapter;
|
||||
@@ -193,10 +188,6 @@ import org.thoughtcrime.securesms.util.views.Stub;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
||||
import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -581,10 +572,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||
if (this.bannerManager != null) {
|
||||
this.bannerManager.updateContent(bannerView.get());
|
||||
}
|
||||
|
||||
if (BackupRepository.shouldDisplayBackupFailedSheet()) {
|
||||
BackupAlertBottomSheet.Companion.create(BackupAlert.COULD_NOT_COMPLETE_BACKUP).show(getParentFragmentManager(), null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -928,8 +915,11 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||
}),
|
||||
new MediaRestoreProgressBanner(new MediaRestoreProgressBanner.RestoreProgressBannerListener() {
|
||||
@Override
|
||||
public void onSkip() {
|
||||
// TODO [backups] add skip restore ability
|
||||
public void onActionClick(@NonNull BackupStatusData backupStatusData) {
|
||||
if (backupStatusData instanceof BackupStatusData.NotEnoughFreeSpace) {
|
||||
BackupAlertBottomSheet.create(new BackupAlert.DiskFull(((BackupStatusData.NotEnoughFreeSpace) backupStatusData).getRequiredSpace()))
|
||||
.show(getParentFragmentManager(), null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,20 +6,31 @@
|
||||
package org.thoughtcrime.securesms.dependencies
|
||||
|
||||
import android.content.Context
|
||||
import org.signal.billing.BillingError
|
||||
import org.signal.core.util.billing.BillingDependencies
|
||||
import org.whispersystems.signalservice.internal.push.SubscriptionsConfiguration
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* Dependency object for Google Play Billing.
|
||||
*/
|
||||
object GooglePlayBillingDependencies : BillingDependencies {
|
||||
|
||||
private const val BILLING_PRODUCT_ID_NOT_AVAILABLE = -1000
|
||||
|
||||
override val context: Context get() = AppDependencies.application
|
||||
|
||||
override suspend fun getProductId(): String {
|
||||
return "backup" // TODO [backups] This really shouldn't be hardcoded into the app.
|
||||
val config = AppDependencies.donationsService.getDonationsConfiguration(Locale.getDefault())
|
||||
|
||||
if (config.result.isPresent) {
|
||||
return config.result.get().backupConfiguration.backupLevelConfigurationMap[SubscriptionsConfiguration.BACKUPS_LEVEL]?.playProductId ?: throw BillingError(BILLING_PRODUCT_ID_NOT_AVAILABLE)
|
||||
} else {
|
||||
throw BillingError(BILLING_PRODUCT_ID_NOT_AVAILABLE)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getBasePlanId(): String {
|
||||
return "monthly" // TODO [backups] This really shouldn't be hardcoded into the app.
|
||||
return "monthly"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user