Add better onBack handling for donations webviews.

main
Alex Hart 2022-12-07 12:12:28 -04:00
rodzic 961057f620
commit e846b4e20a
7 zmienionych plików z 52 dodań i 10 usunięć

Wyświetl plik

@ -235,9 +235,9 @@ class DonationCheckoutDelegate(
return return
} }
if (throwable is DonationError.PayPalError.UserCancelledPaymentError) { if (throwable is DonationError.UserCancelledPaymentError) {
Log.d(TAG, "User cancelled out of paypal flow.", true) Log.d(TAG, "User cancelled out of payment flow.", true)
fragment?.findNavController()?.popBackStack() fragment?.findNavController()?.popBackStack(R.id.donateToSignalFragment, false)
return return
} }

Wyświetl plik

@ -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()
}
}
}

Wyświetl plik

@ -8,6 +8,7 @@ import android.view.View
import android.webkit.WebSettings import android.webkit.WebSettings
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
import androidx.activity.ComponentDialog
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.fragment.app.setFragmentResult 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.R
import org.thoughtcrime.securesms.components.ViewBinderDelegate import org.thoughtcrime.securesms.components.ViewBinderDelegate
import org.thoughtcrime.securesms.components.settings.app.subscription.PayPalRepository 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.databinding.DonationWebviewFragmentBinding
import org.thoughtcrime.securesms.util.visible 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.javaScriptEnabled = true
binding.webView.settings.cacheMode = WebSettings.LOAD_NO_CACHE binding.webView.settings.cacheMode = WebSettings.LOAD_NO_CACHE
binding.webView.loadUrl(args.uri.toString()) binding.webView.loadUrl(args.uri.toString())
(requireDialog() as ComponentDialog).onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
DonationWebViewOnBackPressedCallback(
this::dismissAllowingStateLoss,
binding.webView
)
)
} }
override fun onDismiss(dialog: DialogInterface) { override fun onDismiss(dialog: DialogInterface) {

Wyświetl plik

@ -130,7 +130,7 @@ class PayPalPaymentInProgressFragment : DialogFragment(R.layout.donation_in_prog
if (result != null) { if (result != null) {
emitter.onSuccess(result) emitter.onSuccess(result)
} else { } 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) { if (result) {
emitter.onSuccess(PayPalPaymentMethodId(createPaymentIntentResponse.token)) emitter.onSuccess(PayPalPaymentMethodId(createPaymentIntentResponse.token))
} else { } 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...") Log.d(TAG, "User confirmed order. Continuing...")
emitter.onSuccess(confirmationData) emitter.onSuccess(confirmationData)
} else { } else {
emitter.onError(DonationError.PayPalError.UserCancelledPaymentError(args.request.donateToSignalType.toErrorSource())) emitter.onError(DonationError.UserCancelledPaymentError(args.request.donateToSignalType.toErrorSource()))
} }
} }

Wyświetl plik

@ -8,6 +8,7 @@ import android.view.View
import android.webkit.WebSettings import android.webkit.WebSettings
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
import androidx.activity.ComponentDialog
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.fragment.app.setFragmentResult import androidx.fragment.app.setFragmentResult
@ -15,6 +16,7 @@ import androidx.navigation.fragment.navArgs
import org.signal.donations.StripeIntentAccessor import org.signal.donations.StripeIntentAccessor
import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.ViewBinderDelegate 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.databinding.DonationWebviewFragmentBinding
import org.thoughtcrime.securesms.util.visible 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.javaScriptEnabled = true
binding.webView.settings.cacheMode = WebSettings.LOAD_NO_CACHE binding.webView.settings.cacheMode = WebSettings.LOAD_NO_CACHE
binding.webView.loadUrl(args.uri.toString()) binding.webView.loadUrl(args.uri.toString())
(requireDialog() as ComponentDialog).onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
DonationWebViewOnBackPressedCallback(
this::dismissAllowingStateLoss,
binding.webView
)
)
} }
override fun onDismiss(dialog: DialogInterface) { override fun onDismiss(dialog: DialogInterface) {

Wyświetl plik

@ -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.DonationProcessorAction
import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonationProcessorActionResult 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.donate.DonationProcessorStage
import org.thoughtcrime.securesms.components.settings.app.subscription.errors.DonationError
import org.thoughtcrime.securesms.databinding.DonationInProgressFragmentBinding import org.thoughtcrime.securesms.databinding.DonationInProgressFragmentBinding
import org.thoughtcrime.securesms.util.LifecycleDisposable import org.thoughtcrime.securesms.util.LifecycleDisposable
import org.thoughtcrime.securesms.util.fragments.requireListener import org.thoughtcrime.securesms.util.fragments.requireListener
@ -128,7 +129,7 @@ class StripePaymentInProgressFragment : DialogFragment(R.layout.donation_in_prog
if (result != null) { if (result != null) {
emitter.onSuccess(result) emitter.onSuccess(result)
} else { } else {
emitter.onError(Exception("User did not complete 3DS Authorization.")) emitter.onError(DonationError.UserCancelledPaymentError(args.request.donateToSignalType.toErrorSource()))
} }
} }

Wyświetl plik

@ -19,9 +19,10 @@ sealed class DonationError(val source: DonationErrorSource, cause: Throwable) :
class RequestTokenError(source: DonationErrorSource, cause: Throwable) : GooglePayError(source, cause) 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. * Gifting recipient validation errors, which occur before the user could be charged for a gift.