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
}
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
}

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.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) {

Wyświetl plik

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

Wyświetl plik

@ -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) {

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

Wyświetl plik

@ -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.