Update payment failure ux.
This commit is contained in:
parent
8a00caabd7
commit
f260633c9d
8 changed files with 81 additions and 22 deletions
|
@ -21,7 +21,6 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter
|
|||
import org.thoughtcrime.securesms.components.settings.DSLSettingsBottomSheetFragment
|
||||
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.DonationEvent
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationExceptions
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
|
||||
|
@ -31,7 +30,6 @@ import org.thoughtcrime.securesms.components.settings.app.subscription.models.Ne
|
|||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.components.settings.models.Progress
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.help.HelpFragment
|
||||
import org.thoughtcrime.securesms.keyboard.findListener
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil.requireCoordinatorLayout
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
|
@ -251,7 +249,7 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
|
|||
} else if (throwable is DonationExceptions.SetupFailed) {
|
||||
Log.w(TAG, "Error occurred while processing payment", throwable, true)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.DonationsErrors__payment_failed)
|
||||
.setTitle(R.string.DonationsErrors__error_processing_payment)
|
||||
.setMessage(R.string.DonationsErrors__your_payment)
|
||||
.setPositiveButton(android.R.string.ok) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
|
@ -265,8 +263,7 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
|
|||
.setMessage(R.string.DonationsErrors__your_badge_could_not)
|
||||
.setPositiveButton(R.string.Subscription__contact_support) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
requireActivity().finish()
|
||||
requireActivity().startActivity(AppSettingsActivity.help(requireContext(), HelpFragment.DONATION_INDEX))
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package org.thoughtcrime.securesms.components.settings.app.subscription.manage
|
||||
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.View
|
||||
import android.widget.ProgressBar
|
||||
|
@ -11,6 +10,7 @@ import org.signal.core.util.money.FiatMoney
|
|||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.badges.BadgeImageView
|
||||
import org.thoughtcrime.securesms.components.settings.PreferenceModel
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.payments.FiatMoneyUtil
|
||||
import org.thoughtcrime.securesms.subscription.Subscription
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
|
@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.util.MappingAdapter
|
|||
import org.thoughtcrime.securesms.util.MappingViewHolder
|
||||
import org.thoughtcrime.securesms.util.SpanUtil
|
||||
import org.thoughtcrime.securesms.util.visible
|
||||
import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
|
@ -32,6 +33,7 @@ object ActiveSubscriptionPreference {
|
|||
val onAddBoostClick: () -> Unit,
|
||||
val renewalTimestamp: Long = -1L,
|
||||
val redemptionState: ManageDonationsState.SubscriptionRedemptionState,
|
||||
val activeSubscription: ActiveSubscription.Subscription,
|
||||
val onContactSupport: () -> Unit
|
||||
) : PreferenceModel<Model>() {
|
||||
override fun areItemsTheSame(newItem: Model): Boolean {
|
||||
|
@ -42,7 +44,9 @@ object ActiveSubscriptionPreference {
|
|||
return super.areContentsTheSame(newItem) &&
|
||||
subscription == newItem.subscription &&
|
||||
renewalTimestamp == newItem.renewalTimestamp &&
|
||||
redemptionState == newItem.redemptionState
|
||||
redemptionState == newItem.redemptionState &&
|
||||
FiatMoney.equals(price, newItem.price) &&
|
||||
activeSubscription == newItem.activeSubscription
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,14 +103,35 @@ object ActiveSubscriptionPreference {
|
|||
}
|
||||
|
||||
private fun presentFailureState(model: Model) {
|
||||
expiry.text = SpannableStringBuilder(context.getString(R.string.MySupportPreference__couldnt_add_badge))
|
||||
.append(" ")
|
||||
.append(
|
||||
SpanUtil.clickable(
|
||||
context.getString(R.string.MySupportPreference__please_contact_support),
|
||||
ContextCompat.getColor(context, R.color.signal_accent_primary)
|
||||
) { model.onContactSupport() }
|
||||
)
|
||||
if (model.activeSubscription.isFailedPayment || SignalStore.donationsValues().shouldCancelSubscriptionBeforeNextSubscribeAttempt) {
|
||||
presentPaymentFailureState(model)
|
||||
} else {
|
||||
presentRedemptionFailureState(model)
|
||||
}
|
||||
}
|
||||
|
||||
private fun presentPaymentFailureState(model: Model) {
|
||||
expiry.text = SpanUtil.clickSubstring(
|
||||
context.getString(R.string.DonationsErrors__error_processing_payment_s),
|
||||
context.getString(R.string.MySupportPreference__please_contact_support),
|
||||
{
|
||||
model.onContactSupport()
|
||||
},
|
||||
ContextCompat.getColor(context, R.color.signal_accent_primary)
|
||||
)
|
||||
badge.alpha = 0.2f
|
||||
progress.visible = false
|
||||
}
|
||||
|
||||
private fun presentRedemptionFailureState(model: Model) {
|
||||
expiry.text = SpanUtil.clickSubstring(
|
||||
context.getString(R.string.MySupportPreference__couldnt_add_badge_s),
|
||||
context.getString(R.string.MySupportPreference__please_contact_support),
|
||||
{
|
||||
model.onContactSupport()
|
||||
},
|
||||
ContextCompat.getColor(context, R.color.signal_accent_primary)
|
||||
)
|
||||
badge.alpha = 0.2f
|
||||
progress.visible = false
|
||||
}
|
||||
|
|
|
@ -108,7 +108,8 @@ class ManageDonationsFragment : DSLSettingsFragment() {
|
|||
onContactSupport = {
|
||||
requireActivity().finish()
|
||||
requireActivity().startActivity(AppSettingsActivity.help(requireContext(), HelpFragment.DONATION_INDEX))
|
||||
}
|
||||
},
|
||||
activeSubscription = activeSubscription
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.thoughtcrime.securesms.components.settings.models.Progress
|
|||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.help.HelpFragment
|
||||
import org.thoughtcrime.securesms.keyboard.findListener
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.payments.FiatMoneyUtil
|
||||
import org.thoughtcrime.securesms.subscription.Subscription
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||
|
@ -181,7 +182,7 @@ class SubscribeFragment : DSLSettingsFragment(
|
|||
|
||||
customPref(
|
||||
Subscription.Model(
|
||||
activePrice = if (isActive) { activePrice } else null,
|
||||
activePrice = if (isActive) activePrice else null,
|
||||
subscription = it,
|
||||
isSelected = state.selectedSubscription == it,
|
||||
isEnabled = areFieldsEnabled,
|
||||
|
@ -289,12 +290,23 @@ class SubscribeFragment : DSLSettingsFragment(
|
|||
} else if (throwable is DonationExceptions.SetupFailed) {
|
||||
Log.w(TAG, "Error occurred while processing payment", throwable, true)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.DonationsErrors__payment_failed)
|
||||
.setTitle(R.string.DonationsErrors__error_processing_payment)
|
||||
.setMessage(R.string.DonationsErrors__your_payment)
|
||||
.setPositiveButton(android.R.string.ok) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
}
|
||||
.show()
|
||||
} else if (SignalStore.donationsValues().shouldCancelSubscriptionBeforeNextSubscribeAttempt) {
|
||||
Log.w(TAG, "Stripe failed to process payment", throwable, true)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.DonationsErrors__error_processing_payment)
|
||||
.setMessage(R.string.DonationsErrors__your_badge_could_not_be_added)
|
||||
.setPositiveButton(R.string.Subscription__contact_support) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
requireActivity().finish()
|
||||
requireActivity().startActivity(AppSettingsActivity.help(requireContext(), HelpFragment.DONATION_INDEX))
|
||||
}
|
||||
.show()
|
||||
} else {
|
||||
Log.w(TAG, "Error occurred while trying to redeem token", throwable, true)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
|
|
|
@ -42,8 +42,8 @@ sealed class DonorBadgeNotifications {
|
|||
override fun show(context: Context) {
|
||||
val notification = NotificationCompat.Builder(context, NotificationChannels.FAILURES)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setContentTitle(context.getString(R.string.DonationsErrors__payment_failed))
|
||||
.setContentText(context.getString(R.string.Subscription__please_contact_support_for_more_information))
|
||||
.setContentTitle(context.getString(R.string.DonationsErrors__error_processing_payment))
|
||||
.setContentText(context.getString(R.string.DonationsErrors__your_badge_could_not_be_added))
|
||||
.addAction(
|
||||
NotificationCompat.Action.Builder(
|
||||
null,
|
||||
|
|
|
@ -3983,7 +3983,8 @@
|
|||
<string name="MySupportPreference__s_per_month">%1$s/month</string>
|
||||
<string name="MySupportPreference__renews_s">Renews %1$s</string>
|
||||
<string name="MySupportPreference__processing_transaction">Processing transaction…</string>
|
||||
<string name="MySupportPreference__couldnt_add_badge">Couldn\'t add badge.</string>
|
||||
<!-- Displayed on "My Support" screen when user badge failed to be added to their account -->
|
||||
<string name="MySupportPreference__couldnt_add_badge_s">Couldn\'t add badge. %1$s</string>
|
||||
<string name="MySupportPreference__please_contact_support">Please contact support.</string>
|
||||
|
||||
<string name="ExpiredBadgeBottomSheetDialogFragment__your_badge_has_expired">Your Badge has Expired</string>
|
||||
|
@ -4002,7 +4003,11 @@
|
|||
<string name="Subscription__earn_a_s_badge">Earn a %1$s badge</string>
|
||||
|
||||
<string name="SubscribeFragment__processing_payment">Processing payment…</string>
|
||||
<string name="DonationsErrors__payment_failed">Payment failed</string>
|
||||
<!-- Displayed in notification when user payment fails to process on Stripe -->
|
||||
<string name="DonationsErrors__error_processing_payment">Error processing payment</string>
|
||||
<!-- Displayed on "My Support" screen when user subscription payment method failed. -->
|
||||
<string name="DonationsErrors__error_processing_payment_s">Error processing payment. $1$s</string>
|
||||
<string name="DonationsErrors__your_badge_could_not_be_added">Your badge could not be added to your account, but you may have been charged. Please contact support.</string>
|
||||
<string name="DonationsErrors__your_payment">Your payment couldn\'t be processed and you have not been charged. Please try again.</string>
|
||||
<string name="DonationsErrors__still_processing">Still processing</string>
|
||||
<string name="DonationsErrors__couldnt_add_badge">Couldn\'t add badge</string>
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.math.BigDecimal;
|
|||
import java.text.NumberFormat;
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
public class FiatMoney {
|
||||
private final BigDecimal amount;
|
||||
|
@ -64,4 +65,10 @@ public class FiatMoney {
|
|||
|
||||
return formatter.format(amount.multiply(multiplicand));
|
||||
}
|
||||
|
||||
public static boolean equals(FiatMoney left, FiatMoney right) {
|
||||
return Objects.equals(left.amount, right.amount) &&
|
||||
Objects.equals(left.currency, right.currency) &&
|
||||
Objects.equals(left.timestamp, right.timestamp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,5 +178,17 @@ public final class ActiveSubscription {
|
|||
public boolean isFailedPayment() {
|
||||
return Status.isPaymentFailed(getStatus());
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final Subscription that = (Subscription) o;
|
||||
return level == that.level && endOfCurrentPeriod == that.endOfCurrentPeriod && isActive == that.isActive && billingCycleAnchor == that.billingCycleAnchor && willCancelAtPeriodEnd == that.willCancelAtPeriodEnd && currency
|
||||
.equals(that.currency) && amount.equals(that.amount) && status.equals(that.status);
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
return Objects.hash(level, currency, amount, endOfCurrentPeriod, isActive, billingCycleAnchor, willCancelAtPeriodEnd, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue