mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 04:58:45 +00:00
Add support for several backup alert sheets.
This commit is contained in:
@@ -31,6 +31,7 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.os.BundleCompat
|
||||
import androidx.core.os.bundleOf
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.signal.core.ui.BottomSheets
|
||||
import org.signal.core.ui.Buttons
|
||||
@@ -82,8 +83,7 @@ class BackupAlertBottomSheet : ComposeBottomSheetDialogFragment() {
|
||||
}
|
||||
BackupAlert.PAYMENT_PROCESSING -> Unit
|
||||
BackupAlert.MEDIA_BACKUPS_ARE_OFF, BackupAlert.MEDIA_WILL_BE_DELETED_TODAY -> {
|
||||
// TODO [message-backups] -- We need to force this to download everything.
|
||||
AppDependencies.jobManager.add(BackupRestoreMediaJob())
|
||||
performFullMediaDownload()
|
||||
}
|
||||
BackupAlert.DISK_FULL -> Unit
|
||||
}
|
||||
@@ -102,13 +102,29 @@ class BackupAlertBottomSheet : ComposeBottomSheetDialogFragment() {
|
||||
// TODO [message-backups] - Silence and remind on last day
|
||||
}
|
||||
BackupAlert.MEDIA_WILL_BE_DELETED_TODAY -> {
|
||||
// TODO [message-backups] - Silence forever
|
||||
displayLastChanceDialog()
|
||||
}
|
||||
BackupAlert.DISK_FULL -> Unit
|
||||
}
|
||||
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
private fun displayLastChanceDialog() {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.BackupAlertBottomSheet__media_will_be_deleted)
|
||||
.setMessage(R.string.BackupAlertBottomSheet__the_media_stored_in_your_backup)
|
||||
.setPositiveButton(R.string.BackupAlertBottomSheet__download) { _, _ ->
|
||||
performFullMediaDownload()
|
||||
}
|
||||
.setNegativeButton(R.string.BackupAlertBottomSheet__dont_download, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun performFullMediaDownload() {
|
||||
// TODO [message-backups] -- We need to force this to download everything
|
||||
AppDependencies.jobManager.add(BackupRestoreMediaJob())
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
import org.thoughtcrime.securesms.components.settings.PreferenceModel
|
||||
import org.thoughtcrime.securesms.components.settings.PreferenceViewHolder
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.completed.TerminalDonationDelegate
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.completed.InAppPaymentsBottomSheetDelegate
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.database.model.InAppPaymentSubscriberRecord
|
||||
import org.thoughtcrime.securesms.events.ReminderUpdateEvent
|
||||
@@ -61,7 +61,7 @@ class AppSettingsFragment : DSLSettingsFragment(
|
||||
private lateinit var reminderView: Stub<ReminderView>
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
viewLifecycleOwner.lifecycle.addObserver(TerminalDonationDelegate(childFragmentManager, viewLifecycleOwner))
|
||||
viewLifecycleOwner.lifecycle.addObserver(InAppPaymentsBottomSheetDelegate(childFragmentManager, viewLifecycleOwner))
|
||||
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
reminderView = ViewUtil.findStubById(view, R.id.reminder_stub)
|
||||
|
||||
@@ -53,6 +53,7 @@ import java.util.Optional
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.days
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
/**
|
||||
@@ -63,6 +64,9 @@ object InAppPaymentsRepository {
|
||||
private const val JOB_PREFIX = "InAppPayments__"
|
||||
private val TAG = Log.tag(InAppPaymentsRepository::class.java)
|
||||
|
||||
private val backupExpirationTimeout = 30.days
|
||||
private val backupExpirationDeletion = 60.days
|
||||
|
||||
private val temporaryErrorProcessor = PublishProcessor.create<Pair<InAppPaymentTable.InAppPaymentId, Throwable>>()
|
||||
|
||||
/**
|
||||
@@ -347,6 +351,32 @@ object InAppPaymentsRepository {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if we are in the timeout period to display the "your backup will be deleted today" message
|
||||
*/
|
||||
@WorkerThread
|
||||
fun getExpiredBackupDeletionState(): ExpiredBackupDeletionState {
|
||||
val inAppPayment = SignalDatabase.inAppPayments.getByLatestEndOfPeriod(InAppPaymentType.RECURRING_BACKUP)
|
||||
if (inAppPayment == null) {
|
||||
Log.w(TAG, "InAppPayment for recurring backup not found for last day check. Clearing check.")
|
||||
SignalStore.inAppPayments.showLastDayToDownloadMediaDialog = false
|
||||
return ExpiredBackupDeletionState.NONE
|
||||
}
|
||||
|
||||
val now = SignalStore.misc.estimatedServerTime.milliseconds
|
||||
val lastEndOfPeriod = inAppPayment.endOfPeriod
|
||||
val displayDialogStart = lastEndOfPeriod + backupExpirationTimeout
|
||||
val displayDialogEnd = lastEndOfPeriod + backupExpirationDeletion
|
||||
|
||||
return if (now in displayDialogStart..displayDialogEnd) {
|
||||
ExpiredBackupDeletionState.DELETE_TODAY
|
||||
} else if (now > displayDialogEnd) {
|
||||
ExpiredBackupDeletionState.EXPIRED
|
||||
} else {
|
||||
ExpiredBackupDeletionState.NONE
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@WorkerThread
|
||||
fun setShouldCancelSubscriptionBeforeNextSubscribeAttempt(subscriber: InAppPaymentSubscriberRecord, shouldCancel: Boolean) {
|
||||
@@ -623,4 +653,10 @@ object InAppPaymentsRepository {
|
||||
InAppPaymentData.PaymentMethodType.PAYPAL -> DonationProcessor.PAYPAL
|
||||
}
|
||||
}
|
||||
|
||||
enum class ExpiredBackupDeletionState {
|
||||
NONE,
|
||||
DELETE_TODAY,
|
||||
EXPIRED
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.components.settings.app.subscription.completed
|
||||
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import org.signal.core.util.concurrent.LifecycleDisposable
|
||||
import org.thoughtcrime.securesms.backup.v2.ui.BackupAlert
|
||||
import org.thoughtcrime.securesms.backup.v2.ui.BackupAlertBottomSheet
|
||||
import org.thoughtcrime.securesms.badges.Badges
|
||||
import org.thoughtcrime.securesms.badges.self.expired.MonthlyDonationCanceledBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPendingBottomSheet
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPendingBottomSheetArgs
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.thanks.ThanksForYourSupportBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.thanks.ThanksForYourSupportBottomSheetDialogFragmentArgs
|
||||
import org.thoughtcrime.securesms.database.InAppPaymentTable
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.database.model.InAppPaymentSubscriberRecord
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.DonationErrorValue
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
|
||||
/**
|
||||
* Handles displaying bottom sheets for in-app payments. The current policy is to "fire and forget".
|
||||
*/
|
||||
class InAppPaymentsBottomSheetDelegate(
|
||||
private val fragmentManager: FragmentManager,
|
||||
private val lifecycleOwner: LifecycleOwner,
|
||||
private vararg val supportedTypes: InAppPaymentSubscriberRecord.Type = arrayOf(InAppPaymentSubscriberRecord.Type.DONATION)
|
||||
) : DefaultLifecycleObserver {
|
||||
|
||||
companion object {
|
||||
|
||||
private val inAppPaymentProcessingErrors = listOf(
|
||||
InAppPaymentData.Error.Type.PAYMENT_PROCESSING,
|
||||
InAppPaymentData.Error.Type.STRIPE_FAILURE,
|
||||
InAppPaymentData.Error.Type.STRIPE_CODED_ERROR,
|
||||
InAppPaymentData.Error.Type.STRIPE_DECLINED_ERROR,
|
||||
InAppPaymentData.Error.Type.PAYPAL_CODED_ERROR,
|
||||
InAppPaymentData.Error.Type.PAYPAL_DECLINED_ERROR
|
||||
)
|
||||
}
|
||||
|
||||
private val lifecycleDisposable = LifecycleDisposable().apply {
|
||||
bindTo(lifecycleOwner)
|
||||
}
|
||||
|
||||
private val badgeRepository = TerminalDonationRepository()
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
if (InAppPaymentSubscriberRecord.Type.DONATION in supportedTypes) {
|
||||
handleLegacyTerminalDonationSheets()
|
||||
handleLegacyVerifiedMonthlyDonationSheets()
|
||||
handleInAppPaymentDonationSheets()
|
||||
}
|
||||
|
||||
if (InAppPaymentSubscriberRecord.Type.BACKUP in supportedTypes) {
|
||||
handleInAppPaymentBackupsSheets()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles terminal donations consumed from the InAppPayments values. These are only ever set by the legacy jobs,
|
||||
* and will be completely removed close to when the jobs are removed. (We might want an additional 90 days?)
|
||||
*/
|
||||
private fun handleLegacyTerminalDonationSheets() {
|
||||
val donations = SignalStore.inAppPayments.consumeTerminalDonations()
|
||||
for (donation in donations) {
|
||||
if (donation.isLongRunningPaymentMethod && (donation.error == null || donation.error.type != DonationErrorValue.Type.REDEMPTION)) {
|
||||
TerminalDonationBottomSheet.show(fragmentManager, donation)
|
||||
} else if (donation.error != null) {
|
||||
lifecycleDisposable += badgeRepository.getBadge(donation).observeOn(AndroidSchedulers.mainThread()).subscribe { badge ->
|
||||
val args = ThanksForYourSupportBottomSheetDialogFragmentArgs.Builder(badge).build().toBundle()
|
||||
val sheet = ThanksForYourSupportBottomSheetDialogFragment()
|
||||
|
||||
sheet.arguments = args
|
||||
sheet.show(fragmentManager, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the 'verified' sheet that appears after a user externally verifies a payment and returns to the application.
|
||||
* These are only ever set by the legacy jobs, and will be completely removed close to when the jobs are removed. (We might
|
||||
* want an additional 90 days?)
|
||||
*/
|
||||
private fun handleLegacyVerifiedMonthlyDonationSheets() {
|
||||
SignalStore.inAppPayments.consumeVerifiedSubscription3DSData()?.also {
|
||||
DonationPendingBottomSheet().apply {
|
||||
arguments = DonationPendingBottomSheetArgs.Builder(it.inAppPayment).build().toBundle()
|
||||
}.show(fragmentManager, null)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the new in-app payment sheets for donations.
|
||||
*/
|
||||
private fun handleInAppPaymentDonationSheets() {
|
||||
lifecycleDisposable += Single.fromCallable {
|
||||
SignalDatabase.inAppPayments.consumeDonationPaymentsToNotifyUser()
|
||||
}.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribeBy { inAppPayments ->
|
||||
for (payment in inAppPayments) {
|
||||
if (payment.data.error == null && payment.state == InAppPaymentTable.State.END) {
|
||||
ThanksForYourSupportBottomSheetDialogFragment()
|
||||
.apply { arguments = ThanksForYourSupportBottomSheetDialogFragmentArgs.Builder(Badges.fromDatabaseBadge(payment.data.badge!!)).build().toBundle() }
|
||||
.show(fragmentManager, null)
|
||||
} else if (payment.data.error != null && payment.state == InAppPaymentTable.State.PENDING) {
|
||||
DonationPendingBottomSheet().apply {
|
||||
arguments = DonationPendingBottomSheetArgs.Builder(payment).build().toBundle()
|
||||
}.show(fragmentManager, null)
|
||||
} else if (isUnexpectedCancellation(payment.state, payment.data) && SignalStore.inAppPayments.showMonthlyDonationCanceledDialog) {
|
||||
MonthlyDonationCanceledBottomSheetDialogFragment.show(fragmentManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the new in-app payment sheets for backups.
|
||||
*/
|
||||
private fun handleInAppPaymentBackupsSheets() {
|
||||
lifecycleDisposable += Single.fromCallable {
|
||||
SignalDatabase.inAppPayments.consumeBackupPaymentsToNotifyUser()
|
||||
}.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)
|
||||
} else if (isUnexpectedCancellation(payment.state, payment.data)) {
|
||||
BackupAlertBottomSheet.create(BackupAlert.MEDIA_BACKUPS_ARE_OFF).show(fragmentManager, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SignalStore.inAppPayments.showLastDayToDownloadMediaDialog) {
|
||||
lifecycleDisposable += Single.fromCallable {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isUnexpectedCancellation(inAppPaymentState: InAppPaymentTable.State, inAppPaymentData: InAppPaymentData): Boolean {
|
||||
return inAppPaymentState == InAppPaymentTable.State.END && inAppPaymentData.error != null && inAppPaymentData.cancellation != null && inAppPaymentData.cancellation.reason != InAppPaymentData.Cancellation.Reason.MANUAL
|
||||
}
|
||||
|
||||
private fun isPaymentProcessingError(inAppPaymentState: InAppPaymentTable.State, inAppPaymentData: InAppPaymentData): Boolean {
|
||||
return inAppPaymentState == InAppPaymentTable.State.END && inAppPaymentData.error != null && (inAppPaymentData.error.type in inAppPaymentProcessingErrors)
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.components.settings.app.subscription.completed
|
||||
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import org.signal.core.util.concurrent.LifecycleDisposable
|
||||
import org.thoughtcrime.securesms.badges.Badges
|
||||
import org.thoughtcrime.securesms.badges.self.expired.MonthlyDonationCanceledBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPendingBottomSheet
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPendingBottomSheetArgs
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.donate.stripe.Stripe3DSData
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.thanks.ThanksForYourSupportBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.thanks.ThanksForYourSupportBottomSheetDialogFragmentArgs
|
||||
import org.thoughtcrime.securesms.database.InAppPaymentTable
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.DonationErrorValue
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
|
||||
/**
|
||||
* Handles displaying the "Thank You" or "Donation completed" sheet when the user navigates to an appropriate screen.
|
||||
* These sheets are one-shot.
|
||||
*/
|
||||
class TerminalDonationDelegate(
|
||||
private val fragmentManager: FragmentManager,
|
||||
private val lifecycleOwner: LifecycleOwner
|
||||
) : DefaultLifecycleObserver {
|
||||
|
||||
private val lifecycleDisposable = LifecycleDisposable().apply {
|
||||
bindTo(lifecycleOwner)
|
||||
}
|
||||
|
||||
private val badgeRepository = TerminalDonationRepository()
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
val donations = SignalStore.inAppPayments.consumeTerminalDonations()
|
||||
for (donation in donations) {
|
||||
if (donation.isLongRunningPaymentMethod && (donation.error == null || donation.error.type != DonationErrorValue.Type.REDEMPTION)) {
|
||||
TerminalDonationBottomSheet.show(fragmentManager, donation)
|
||||
} else if (donation.error != null) {
|
||||
lifecycleDisposable += badgeRepository.getBadge(donation).observeOn(AndroidSchedulers.mainThread()).subscribe { badge ->
|
||||
val args = ThanksForYourSupportBottomSheetDialogFragmentArgs.Builder(badge).build().toBundle()
|
||||
val sheet = ThanksForYourSupportBottomSheetDialogFragment()
|
||||
|
||||
sheet.arguments = args
|
||||
sheet.show(fragmentManager, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val verifiedMonthlyDonation: Stripe3DSData? = SignalStore.inAppPayments.consumeVerifiedSubscription3DSData()
|
||||
if (verifiedMonthlyDonation != null) {
|
||||
DonationPendingBottomSheet().apply {
|
||||
arguments = DonationPendingBottomSheetArgs.Builder(verifiedMonthlyDonation.inAppPayment).build().toBundle()
|
||||
}.show(fragmentManager, null)
|
||||
}
|
||||
|
||||
handleInAppPaymentSheets()
|
||||
}
|
||||
|
||||
private fun handleInAppPaymentSheets() {
|
||||
lifecycleDisposable += Single.fromCallable {
|
||||
SignalDatabase.inAppPayments.consumeDonationPaymentsToNotifyUser()
|
||||
}.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribeBy { inAppPayments ->
|
||||
for (payment in inAppPayments) {
|
||||
if (payment.data.error == null && payment.state == InAppPaymentTable.State.END) {
|
||||
ThanksForYourSupportBottomSheetDialogFragment()
|
||||
.apply { arguments = ThanksForYourSupportBottomSheetDialogFragmentArgs.Builder(Badges.fromDatabaseBadge(payment.data.badge!!)).build().toBundle() }
|
||||
.show(fragmentManager, null)
|
||||
} else if (payment.data.error != null && payment.state == InAppPaymentTable.State.PENDING) {
|
||||
DonationPendingBottomSheet().apply {
|
||||
arguments = DonationPendingBottomSheetArgs.Builder(payment).build().toBundle()
|
||||
}.show(fragmentManager, null)
|
||||
} else if (payment.data.error != null && payment.data.cancellation != null && payment.data.cancellation.reason != InAppPaymentData.Cancellation.Reason.MANUAL && SignalStore.inAppPayments.showMonthlyDonationCanceledDialog) {
|
||||
MonthlyDonationCanceledBottomSheetDialogFragment.show(fragmentManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsIcon
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationSerializationHelper.toFiatMoney
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.completed.TerminalDonationDelegate
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.completed.InAppPaymentsBottomSheetDelegate
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.models.NetworkFailure
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.components.settings.models.IndeterminateLoadingCircle
|
||||
@@ -67,7 +67,7 @@ class ManageDonationsFragment :
|
||||
private val viewModel: ManageDonationsViewModel by viewModels()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
viewLifecycleOwner.lifecycle.addObserver(TerminalDonationDelegate(childFragmentManager, viewLifecycleOwner))
|
||||
viewLifecycleOwner.lifecycle.addObserver(InAppPaymentsBottomSheetDelegate(childFragmentManager, viewLifecycleOwner))
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ import org.thoughtcrime.securesms.components.reminder.UnauthorizedReminder;
|
||||
import org.thoughtcrime.securesms.components.reminder.UsernameOutOfSyncReminder;
|
||||
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity;
|
||||
import org.thoughtcrime.securesms.components.settings.app.notifications.manual.NotificationProfileSelectionFragment;
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.completed.TerminalDonationDelegate;
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.completed.InAppPaymentsBottomSheetDelegate;
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.errors.UnexpectedSubscriptionCancellation;
|
||||
import org.thoughtcrime.securesms.components.spoiler.SpoilerAnnotation;
|
||||
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaControllerOwner;
|
||||
@@ -277,7 +277,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
getViewLifecycleOwner().getLifecycle().addObserver(new TerminalDonationDelegate(getParentFragmentManager(), getViewLifecycleOwner()));
|
||||
getViewLifecycleOwner().getLifecycle().addObserver(new InAppPaymentsBottomSheetDelegate(getParentFragmentManager(), getViewLifecycleOwner()));
|
||||
BackupAlertDelegate.delegate(getParentFragmentManager(), getViewLifecycleOwner().getLifecycle());
|
||||
|
||||
lifecycleDisposable = new LifecycleDisposable();
|
||||
|
||||
@@ -70,6 +70,7 @@ class InAppPaymentValues internal constructor(store: KeyValueStore) : SignalStor
|
||||
private const val SUBSCRIPTION_CANCELATION_TIMESTAMP = "donation.subscription.cancelation.timestamp"
|
||||
private const val SUBSCRIPTION_CANCELATION_WATERMARK = "donation.subscription.cancelation.watermark"
|
||||
private const val SHOW_CANT_PROCESS_DIALOG = "show.cant.process.dialog"
|
||||
private const val SHOW_LAST_DAY_TO_DOWNLOAD_MEDIA_DIALOG = "inapppayment.show.last.day.to.download.media.dialog"
|
||||
|
||||
/**
|
||||
* The current request context for subscription. This should be stored until either
|
||||
@@ -160,7 +161,8 @@ class InAppPaymentValues internal constructor(store: KeyValueStore) : SignalStor
|
||||
SUBSCRIPTION_EOP_STARTED_TO_CONVERT,
|
||||
SUBSCRIPTION_EOP_STARTED_TO_REDEEM,
|
||||
SUBSCRIPTION_EOP_REDEEMED,
|
||||
SUBSCRIPTION_PAYMENT_SOURCE_TYPE
|
||||
SUBSCRIPTION_PAYMENT_SOURCE_TYPE,
|
||||
SHOW_LAST_DAY_TO_DOWNLOAD_MEDIA_DIALOG
|
||||
)
|
||||
|
||||
private val recurringDonationCurrencyPublisher: Subject<Currency> by lazy { BehaviorSubject.createDefault(getSubscriptionCurrency(InAppPaymentSubscriberRecord.Type.DONATION)) }
|
||||
@@ -417,6 +419,9 @@ class InAppPaymentValues internal constructor(store: KeyValueStore) : SignalStor
|
||||
@get:JvmName("showCantProcessDialog")
|
||||
var showMonthlyDonationCanceledDialog: Boolean by booleanValue(SHOW_CANT_PROCESS_DIALOG, true)
|
||||
|
||||
@get:JvmName("showLastDayToDownloadMediaDialog")
|
||||
var showLastDayToDownloadMediaDialog: Boolean by booleanValue(SHOW_LAST_DAY_TO_DOWNLOAD_MEDIA_DIALOG, false)
|
||||
|
||||
/**
|
||||
* Denotes that the previous attempt to subscribe failed in some way. Either an
|
||||
* automatic renewal failed resulting in an unexpected expiration, or payment failed
|
||||
|
||||
@@ -7149,6 +7149,14 @@
|
||||
<string name="BackupAlertBottomSheet__download_later">Download later</string>
|
||||
<!-- Secondary action button text to dismiss sheet, skipping media download -->
|
||||
<string name="BackupAlertBottomSheet__dont_download_media">Don\'t download media</string>
|
||||
<!-- Dialog title for last chance to download backup -->
|
||||
<string name="BackupAlertBottomSheet__media_will_be_deleted">Media will be deleted</string>
|
||||
<!-- Dialog message for last chance to download backup -->
|
||||
<string name="BackupAlertBottomSheet__the_media_stored_in_your_backup">The media stored in your backup will be permanently deleted today. This is your last chance to download it.</string>
|
||||
<!-- Dialog action to download now -->
|
||||
<string name="BackupAlertBottomSheet__download">Download</string>
|
||||
<!-- Dialog action to not download now -->
|
||||
<string name="BackupAlertBottomSheet__dont_download">Don\'t download</string>
|
||||
|
||||
<!-- BackupStatus -->
|
||||
<!-- Status title when user does not have enough free space to download their media. Placeholder is required disk space. -->
|
||||
|
||||
Reference in New Issue
Block a user