diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonationCheckoutDelegate.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonationCheckoutDelegate.kt index f0a1f4bb4..8b3bac840 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonationCheckoutDelegate.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonationCheckoutDelegate.kt @@ -235,9 +235,9 @@ class DonationCheckoutDelegate( return } - if (throwable is DonationError.PayPalError.UserCancelledPaymentError) { - Log.d(TAG, "User cancelled out of paypal flow.", true) - fragment?.findNavController()?.popBackStack() + if (throwable is DonationError.UserCancelledPaymentError) { + Log.d(TAG, "User cancelled out of payment flow.", true) + fragment?.findNavController()?.popBackStack(R.id.donateToSignalFragment, false) return } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonationWebViewOnBackPressedCallback.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonationWebViewOnBackPressedCallback.kt new file mode 100644 index 000000000..c813bfed7 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonationWebViewOnBackPressedCallback.kt @@ -0,0 +1,20 @@ +package org.thoughtcrime.securesms.components.settings.app.subscription.donate + +import android.webkit.WebView +import androidx.activity.OnBackPressedCallback + +/** + * Utilized in the 3DS and PayPal WebView fragments to handle WebView back navigation. + */ +class DonationWebViewOnBackPressedCallback( + private val dismissAllowingStateLoss: () -> Unit, + private val webView: WebView, +) : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + if (webView.canGoBack()) { + webView.goBack() + } else { + dismissAllowingStateLoss() + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalConfirmationDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalConfirmationDialogFragment.kt index 4386f3b8a..fc975e2fa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalConfirmationDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalConfirmationDialogFragment.kt @@ -8,6 +8,7 @@ import android.view.View import android.webkit.WebSettings import android.webkit.WebView import android.webkit.WebViewClient +import androidx.activity.ComponentDialog import androidx.core.os.bundleOf import androidx.fragment.app.DialogFragment import androidx.fragment.app.setFragmentResult @@ -18,6 +19,7 @@ import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.ViewBinderDelegate import org.thoughtcrime.securesms.components.settings.app.subscription.PayPalRepository +import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonationWebViewOnBackPressedCallback import org.thoughtcrime.securesms.databinding.DonationWebviewFragmentBinding import org.thoughtcrime.securesms.util.visible @@ -55,6 +57,14 @@ class PayPalConfirmationDialogFragment : DialogFragment(R.layout.donation_webvie binding.webView.settings.javaScriptEnabled = true binding.webView.settings.cacheMode = WebSettings.LOAD_NO_CACHE binding.webView.loadUrl(args.uri.toString()) + + (requireDialog() as ComponentDialog).onBackPressedDispatcher.addCallback( + viewLifecycleOwner, + DonationWebViewOnBackPressedCallback( + this::dismissAllowingStateLoss, + binding.webView + ) + ) } override fun onDismiss(dialog: DialogInterface) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalPaymentInProgressFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalPaymentInProgressFragment.kt index c9d9b8624..c77870d81 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalPaymentInProgressFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalPaymentInProgressFragment.kt @@ -130,7 +130,7 @@ class PayPalPaymentInProgressFragment : DialogFragment(R.layout.donation_in_prog if (result != null) { emitter.onSuccess(result) } else { - emitter.onError(DonationError.PayPalError.UserCancelledPaymentError(args.request.donateToSignalType.toErrorSource())) + emitter.onError(DonationError.UserCancelledPaymentError(args.request.donateToSignalType.toErrorSource())) } } @@ -158,7 +158,7 @@ class PayPalPaymentInProgressFragment : DialogFragment(R.layout.donation_in_prog if (result) { emitter.onSuccess(PayPalPaymentMethodId(createPaymentIntentResponse.token)) } else { - emitter.onError(DonationError.PayPalError.UserCancelledPaymentError(args.request.donateToSignalType.toErrorSource())) + emitter.onError(DonationError.UserCancelledPaymentError(args.request.donateToSignalType.toErrorSource())) } } @@ -187,7 +187,7 @@ class PayPalPaymentInProgressFragment : DialogFragment(R.layout.donation_in_prog Log.d(TAG, "User confirmed order. Continuing...") emitter.onSuccess(confirmationData) } else { - emitter.onError(DonationError.PayPalError.UserCancelledPaymentError(args.request.donateToSignalType.toErrorSource())) + emitter.onError(DonationError.UserCancelledPaymentError(args.request.donateToSignalType.toErrorSource())) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/Stripe3DSDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/Stripe3DSDialogFragment.kt index 55edb67b8..23bb4caf5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/Stripe3DSDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/Stripe3DSDialogFragment.kt @@ -8,6 +8,7 @@ import android.view.View import android.webkit.WebSettings import android.webkit.WebView import android.webkit.WebViewClient +import androidx.activity.ComponentDialog import androidx.core.os.bundleOf import androidx.fragment.app.DialogFragment import androidx.fragment.app.setFragmentResult @@ -15,6 +16,7 @@ import androidx.navigation.fragment.navArgs import org.signal.donations.StripeIntentAccessor import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.ViewBinderDelegate +import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonationWebViewOnBackPressedCallback import org.thoughtcrime.securesms.databinding.DonationWebviewFragmentBinding import org.thoughtcrime.securesms.util.visible @@ -47,6 +49,14 @@ class Stripe3DSDialogFragment : DialogFragment(R.layout.donation_webview_fragmen binding.webView.settings.javaScriptEnabled = true binding.webView.settings.cacheMode = WebSettings.LOAD_NO_CACHE binding.webView.loadUrl(args.uri.toString()) + + (requireDialog() as ComponentDialog).onBackPressedDispatcher.addCallback( + viewLifecycleOwner, + DonationWebViewOnBackPressedCallback( + this::dismissAllowingStateLoss, + binding.webView + ) + ) } override fun onDismiss(dialog: DialogInterface) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/StripePaymentInProgressFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/StripePaymentInProgressFragment.kt index e024c87a0..6861a31bb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/StripePaymentInProgressFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/StripePaymentInProgressFragment.kt @@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.components.settings.app.subscription.DonationP import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonationProcessorAction import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonationProcessorActionResult import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonationProcessorStage +import org.thoughtcrime.securesms.components.settings.app.subscription.errors.DonationError import org.thoughtcrime.securesms.databinding.DonationInProgressFragmentBinding import org.thoughtcrime.securesms.util.LifecycleDisposable import org.thoughtcrime.securesms.util.fragments.requireListener @@ -128,7 +129,7 @@ class StripePaymentInProgressFragment : DialogFragment(R.layout.donation_in_prog if (result != null) { emitter.onSuccess(result) } else { - emitter.onError(Exception("User did not complete 3DS Authorization.")) + emitter.onError(DonationError.UserCancelledPaymentError(args.request.donateToSignalType.toErrorSource())) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/errors/DonationError.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/errors/DonationError.kt index 8747160d6..01d65c94b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/errors/DonationError.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/errors/DonationError.kt @@ -19,9 +19,10 @@ sealed class DonationError(val source: DonationErrorSource, cause: Throwable) : class RequestTokenError(source: DonationErrorSource, cause: Throwable) : GooglePayError(source, cause) } - sealed class PayPalError(source: DonationErrorSource, cause: Throwable) : DonationError(source, cause) { - class UserCancelledPaymentError(source: DonationErrorSource) : DonationError(source, Exception("User cancelled payment.")) - } + /** + * Utilized when the user cancels the payment flow, by either exiting a WebView or not confirming on the complete order sheet. + */ + class UserCancelledPaymentError(source: DonationErrorSource) : DonationError(source, Exception("User cancelled payment.")) /** * Gifting recipient validation errors, which occur before the user could be charged for a gift.