mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 17:29:32 +01:00
Replace monthly badge expires with cancellation dialogs.
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
package org.thoughtcrime.securesms.badges.self.expired
|
||||
|
||||
import androidx.core.content.ContextCompat
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsBottomSheetFragment
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.components.settings.models.SplashImage
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
|
||||
class CantProcessSubscriptionPaymentBottomSheetDialogFragment : DSLSettingsBottomSheetFragment() {
|
||||
override fun bindAdapter(adapter: DSLSettingsAdapter) {
|
||||
SplashImage.register(adapter)
|
||||
adapter.submitList(getConfiguration().toMappingModelList())
|
||||
}
|
||||
|
||||
private fun getConfiguration(): DSLConfiguration {
|
||||
return configure {
|
||||
customPref(SplashImage.Model(R.drawable.ic_card_process))
|
||||
|
||||
sectionHeaderPref(
|
||||
title = DSLSettingsText.from(R.string.CantProcessSubscriptionPaymentBottomSheetDialogFragment__cant_process_subscription_payment, DSLSettingsText.CenterModifier)
|
||||
)
|
||||
|
||||
textPref(
|
||||
summary = DSLSettingsText.from(
|
||||
requireContext().getString(R.string.CantProcessSubscriptionPaymentBottomSheetDialogFragment__were_having_trouble),
|
||||
DSLSettingsText.LearnMoreModifier(ContextCompat.getColor(requireContext(), R.color.signal_accent_primary)) {
|
||||
CommunicationActions.openBrowserLink(requireContext(), requireContext().getString(R.string.donation_decline_code_error_url))
|
||||
},
|
||||
DSLSettingsText.CenterModifier
|
||||
)
|
||||
)
|
||||
|
||||
primaryButton(
|
||||
text = DSLSettingsText.from(android.R.string.ok)
|
||||
) {
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
secondaryButtonNoOutline(
|
||||
text = DSLSettingsText.from(R.string.CantProcessSubscriptionPaymentBottomSheetDialogFragment__dont_show_this_again)
|
||||
) {
|
||||
SignalStore.donationsValues().showCantProcessDialog = false
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
package org.thoughtcrime.securesms.badges.self.expired
|
||||
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import org.signal.core.util.DimensionUnit
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.donations.StripeDeclineCode
|
||||
import org.signal.donations.StripeFailureCode
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.badges.models.Badge
|
||||
import org.thoughtcrime.securesms.badges.models.ExpiredBadge
|
||||
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsBottomSheetFragment
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.errors.UnexpectedSubscriptionCancellation
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.errors.mapToErrorStringResource
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.errors.shouldRouteToGooglePay
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription
|
||||
|
||||
/**
|
||||
* Bottom sheet displaying a fading badge with a notice and action for becoming a subscriber again.
|
||||
*/
|
||||
class ExpiredBadgeBottomSheetDialogFragment : DSLSettingsBottomSheetFragment(
|
||||
peekHeightPercentage = 1f
|
||||
) {
|
||||
override fun bindAdapter(adapter: DSLSettingsAdapter) {
|
||||
ExpiredBadge.register(adapter)
|
||||
|
||||
adapter.submitList(getConfiguration().toMappingModelList())
|
||||
}
|
||||
|
||||
private fun getConfiguration(): DSLConfiguration {
|
||||
val args = ExpiredBadgeBottomSheetDialogFragmentArgs.fromBundle(requireArguments())
|
||||
val badge: Badge = args.badge
|
||||
val cancellationReason = UnexpectedSubscriptionCancellation.fromStatus(args.cancelationReason)
|
||||
val declineCode: StripeDeclineCode? = args.chargeFailure?.let { StripeDeclineCode.getFromCode(it) }
|
||||
val failureCode: StripeFailureCode? = args.chargeFailure?.let { StripeFailureCode.getFromCode(it) }
|
||||
val isLikelyASustainer = SignalStore.donationsValues().isLikelyASustainer()
|
||||
val inactive = cancellationReason == UnexpectedSubscriptionCancellation.INACTIVE
|
||||
|
||||
Log.d(TAG, "Displaying Expired Badge Fragment with bundle: ${requireArguments()}", true)
|
||||
|
||||
return configure {
|
||||
customPref(ExpiredBadge.Model(badge))
|
||||
|
||||
sectionHeaderPref(
|
||||
DSLSettingsText.from(
|
||||
if (badge.isBoost()) {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__boost_badge_expired
|
||||
} else {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__monthly_donation_cancelled
|
||||
},
|
||||
DSLSettingsText.CenterModifier
|
||||
)
|
||||
)
|
||||
|
||||
space(DimensionUnit.DP.toPixels(4f).toInt())
|
||||
|
||||
noPadTextPref(
|
||||
DSLSettingsText.from(
|
||||
if (badge.isBoost()) {
|
||||
getString(R.string.ExpiredBadgeBottomSheetDialogFragment__your_boost_badge_has_expired_and)
|
||||
} else if (declineCode != null) {
|
||||
getString(
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__your_recurring_monthly_donation_was_canceled_s,
|
||||
getString(declineCode.mapToErrorStringResource()),
|
||||
badge.name
|
||||
)
|
||||
} else if (failureCode != null) {
|
||||
getString(
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__your_recurring_monthly_donation_was_canceled_s,
|
||||
getString(failureCode.mapToErrorStringResource()),
|
||||
badge.name
|
||||
)
|
||||
} else if (inactive) {
|
||||
getString(R.string.ExpiredBadgeBottomSheetDialogFragment__your_recurring_monthly_donation_was_automatically, badge.name)
|
||||
} else {
|
||||
getString(R.string.ExpiredBadgeBottomSheetDialogFragment__your_recurring_monthly_donation_was_canceled)
|
||||
},
|
||||
DSLSettingsText.CenterModifier
|
||||
)
|
||||
)
|
||||
|
||||
space(DimensionUnit.DP.toPixels(16f).toInt())
|
||||
|
||||
if (badge.isSubscription() && declineCode?.shouldRouteToGooglePay() == true) {
|
||||
space(DimensionUnit.DP.toPixels(68f).toInt())
|
||||
|
||||
secondaryButtonNoOutline(
|
||||
text = DSLSettingsText.from(R.string.ExpiredBadgeBottomSheetDialogFragment__go_to_google_pay),
|
||||
onClick = {
|
||||
CommunicationActions.openBrowserLink(requireContext(), getString(R.string.google_pay_url))
|
||||
}
|
||||
)
|
||||
} else {
|
||||
noPadTextPref(
|
||||
DSLSettingsText.from(
|
||||
if (badge.isBoost()) {
|
||||
if (isLikelyASustainer) {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__you_can_reactivate
|
||||
} else {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__you_can_keep
|
||||
}
|
||||
} else {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__you_can
|
||||
},
|
||||
DSLSettingsText.CenterModifier
|
||||
)
|
||||
)
|
||||
|
||||
space(DimensionUnit.DP.toPixels(92f).toInt())
|
||||
}
|
||||
|
||||
primaryButton(
|
||||
text = DSLSettingsText.from(
|
||||
if (badge.isBoost()) {
|
||||
if (isLikelyASustainer) {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__add_a_boost
|
||||
} else {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__become_a_sustainer
|
||||
}
|
||||
} else {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__renew_subscription
|
||||
}
|
||||
),
|
||||
onClick = {
|
||||
dismiss()
|
||||
if (isLikelyASustainer) {
|
||||
requireActivity().startActivity(AppSettingsActivity.boost(requireContext()))
|
||||
} else {
|
||||
requireActivity().startActivity(AppSettingsActivity.subscriptions(requireContext()))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
secondaryButtonNoOutline(
|
||||
text = DSLSettingsText.from(R.string.ExpiredBadgeBottomSheetDialogFragment__not_now),
|
||||
onClick = {
|
||||
dismiss()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(ExpiredBadgeBottomSheetDialogFragment::class.java)
|
||||
|
||||
@JvmStatic
|
||||
fun show(
|
||||
badge: Badge,
|
||||
cancellationReason: UnexpectedSubscriptionCancellation?,
|
||||
chargeFailure: ActiveSubscription.ChargeFailure?,
|
||||
fragmentManager: FragmentManager
|
||||
) {
|
||||
val args = ExpiredBadgeBottomSheetDialogFragmentArgs.Builder(badge, cancellationReason?.status, chargeFailure?.code).build()
|
||||
val fragment = ExpiredBadgeBottomSheetDialogFragment()
|
||||
fragment.arguments = args.toBundle()
|
||||
|
||||
fragment.show(fragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package org.thoughtcrime.securesms.badges.self.expired
|
||||
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import org.signal.core.util.DimensionUnit
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.badges.models.Badge
|
||||
import org.thoughtcrime.securesms.badges.models.ExpiredBadge
|
||||
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsBottomSheetFragment
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.errors.UnexpectedSubscriptionCancellation
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
||||
import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription
|
||||
|
||||
/**
|
||||
* Bottom sheet displaying a fading badge with a notice and action for becoming a subscriber again.
|
||||
*/
|
||||
class ExpiredOneTimeBadgeBottomSheetDialogFragment : DSLSettingsBottomSheetFragment(
|
||||
peekHeightPercentage = 1f
|
||||
) {
|
||||
override fun bindAdapter(adapter: DSLSettingsAdapter) {
|
||||
ExpiredBadge.register(adapter)
|
||||
|
||||
adapter.submitList(getConfiguration().toMappingModelList())
|
||||
}
|
||||
|
||||
private fun getConfiguration(): DSLConfiguration {
|
||||
val args = ExpiredOneTimeBadgeBottomSheetDialogFragmentArgs.fromBundle(requireArguments())
|
||||
val badge: Badge = args.badge
|
||||
val isLikelyASustainer = SignalStore.donationsValues().isLikelyASustainer()
|
||||
|
||||
Log.d(TAG, "Displaying Expired Badge Fragment with bundle: ${requireArguments()}", true)
|
||||
|
||||
return configure {
|
||||
customPref(ExpiredBadge.Model(badge))
|
||||
|
||||
sectionHeaderPref(
|
||||
DSLSettingsText.from(
|
||||
if (badge.isBoost()) {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__boost_badge_expired
|
||||
} else {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__monthly_donation_cancelled
|
||||
},
|
||||
DSLSettingsText.CenterModifier
|
||||
)
|
||||
)
|
||||
|
||||
space(DimensionUnit.DP.toPixels(4f).toInt())
|
||||
|
||||
noPadTextPref(
|
||||
DSLSettingsText.from(
|
||||
getString(R.string.ExpiredBadgeBottomSheetDialogFragment__your_boost_badge_has_expired_and),
|
||||
DSLSettingsText.CenterModifier
|
||||
)
|
||||
)
|
||||
|
||||
space(DimensionUnit.DP.toPixels(16f).toInt())
|
||||
|
||||
noPadTextPref(
|
||||
DSLSettingsText.from(
|
||||
if (isLikelyASustainer) {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__you_can_reactivate
|
||||
} else {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__you_can_keep
|
||||
},
|
||||
DSLSettingsText.CenterModifier
|
||||
)
|
||||
)
|
||||
|
||||
space(DimensionUnit.DP.toPixels(92f).toInt())
|
||||
|
||||
primaryButton(
|
||||
text = DSLSettingsText.from(
|
||||
if (isLikelyASustainer) {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__add_a_boost
|
||||
} else {
|
||||
R.string.ExpiredBadgeBottomSheetDialogFragment__become_a_sustainer
|
||||
}
|
||||
),
|
||||
onClick = {
|
||||
dismiss()
|
||||
if (isLikelyASustainer) {
|
||||
requireActivity().startActivity(AppSettingsActivity.boost(requireContext()))
|
||||
} else {
|
||||
requireActivity().startActivity(AppSettingsActivity.subscriptions(requireContext()))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
secondaryButtonNoOutline(
|
||||
text = DSLSettingsText.from(R.string.ExpiredBadgeBottomSheetDialogFragment__not_now),
|
||||
onClick = {
|
||||
dismiss()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(ExpiredOneTimeBadgeBottomSheetDialogFragment::class.java)
|
||||
|
||||
@JvmStatic
|
||||
fun show(
|
||||
badge: Badge,
|
||||
cancellationReason: UnexpectedSubscriptionCancellation?,
|
||||
chargeFailure: ActiveSubscription.ChargeFailure?,
|
||||
fragmentManager: FragmentManager
|
||||
) {
|
||||
val args = ExpiredOneTimeBadgeBottomSheetDialogFragmentArgs.Builder(badge, cancellationReason?.status, chargeFailure?.code).build()
|
||||
val fragment = ExpiredOneTimeBadgeBottomSheetDialogFragment()
|
||||
fragment.arguments = args.toBundle()
|
||||
|
||||
fragment.show(fragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
package org.thoughtcrime.securesms.badges.self.expired
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import org.signal.core.ui.BottomSheets
|
||||
import org.signal.core.ui.Buttons
|
||||
import org.signal.core.ui.Texts
|
||||
import org.signal.core.ui.theme.SignalTheme
|
||||
import org.signal.donations.StripeDeclineCode
|
||||
import org.signal.donations.StripeFailureCode
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.badges.models.Badge
|
||||
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.BadgeImage112
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.errors.mapToErrorStringResource
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.manage.ManageDonationsFragment
|
||||
import org.thoughtcrime.securesms.compose.ComposeBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
import org.thoughtcrime.securesms.util.SpanUtil
|
||||
import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription
|
||||
|
||||
class MonthlyDonationCanceledBottomSheetDialogFragment : ComposeBottomSheetDialogFragment() {
|
||||
|
||||
override val peekHeightPercentage: Float = 1f
|
||||
|
||||
@Composable
|
||||
override fun SheetContent() {
|
||||
val chargeFailure: ActiveSubscription.ChargeFailure? = SignalStore.donationsValues().getUnexpectedSubscriptionCancelationChargeFailure()
|
||||
val declineCode: StripeDeclineCode = StripeDeclineCode.getFromCode(chargeFailure?.outcomeNetworkReason)
|
||||
val failureCode: StripeFailureCode = StripeFailureCode.getFromCode(chargeFailure?.code)
|
||||
|
||||
val errorMessage = if (declineCode.isKnown()) {
|
||||
declineCode.mapToErrorStringResource()
|
||||
} else if (failureCode.isKnown) {
|
||||
failureCode.mapToErrorStringResource()
|
||||
} else {
|
||||
declineCode.mapToErrorStringResource()
|
||||
}
|
||||
|
||||
MonthlyDonationCanceled(
|
||||
badge = SignalStore.donationsValues().getExpiredBadge(),
|
||||
errorMessageRes = errorMessage,
|
||||
onRenewClicked = {
|
||||
startActivity(AppSettingsActivity.subscriptions(requireContext()))
|
||||
dismissAllowingStateLoss()
|
||||
},
|
||||
onNotNowClicked = {
|
||||
SignalStore.donationsValues().showMonthlyDonationCanceledDialog = false
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun show(fragmentManager: FragmentManager) {
|
||||
val fragment = MonthlyDonationCanceledBottomSheetDialogFragment()
|
||||
|
||||
fragment.show(fragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(name = "Light Theme", group = "ShortName", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(name = "Dark Theme", group = "ShortName", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
fun MonthlyDonationCanceledPreview() {
|
||||
SignalTheme {
|
||||
Surface {
|
||||
MonthlyDonationCanceled(
|
||||
badge = Badge(
|
||||
id = "",
|
||||
category = Badge.Category.Donor,
|
||||
name = "Signal Star",
|
||||
description = "",
|
||||
imageUrl = Uri.EMPTY,
|
||||
imageDensity = "",
|
||||
expirationTimestamp = 0L,
|
||||
visible = true,
|
||||
duration = 0L
|
||||
),
|
||||
errorMessageRes = R.string.StripeFailureCode__verify_your_bank_details_are_correct,
|
||||
onRenewClicked = {},
|
||||
onNotNowClicked = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MonthlyDonationCanceled(
|
||||
badge: Badge?,
|
||||
@StringRes errorMessageRes: Int,
|
||||
onRenewClicked: () -> Unit,
|
||||
onNotNowClicked: () -> Unit
|
||||
) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier.padding(horizontal = 34.dp)
|
||||
) {
|
||||
BottomSheets.Handle()
|
||||
|
||||
if (badge != null) {
|
||||
Box(modifier = Modifier.padding(top = 21.dp, bottom = 16.dp)) {
|
||||
BadgeImage112(
|
||||
badge = badge,
|
||||
modifier = Modifier
|
||||
.size(80.dp)
|
||||
)
|
||||
|
||||
Image(
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.symbol_error_circle_fill_24),
|
||||
contentScale = ContentScale.Inside,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.error),
|
||||
modifier = Modifier
|
||||
.size(24.dp)
|
||||
.align(Alignment.TopEnd)
|
||||
.background(
|
||||
color = SignalTheme.colors.colorSurface1,
|
||||
shape = CircleShape
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.MonthlyDonationCanceled__title),
|
||||
style = MaterialTheme.typography.titleLarge.copy(textAlign = TextAlign.Center, color = MaterialTheme.colorScheme.onSurface),
|
||||
modifier = Modifier.padding(bottom = 20.dp)
|
||||
)
|
||||
|
||||
val context = LocalContext.current
|
||||
val learnMore = stringResource(id = R.string.MonthlyDonationCanceled__learn_more)
|
||||
val errorMessage = stringResource(id = errorMessageRes)
|
||||
val fullString = stringResource(id = R.string.MonthlyDonationCanceled__message, errorMessage, learnMore)
|
||||
val spanned = SpanUtil.urlSubsequence(fullString, learnMore, ManageDonationsFragment.DONATE_TROUBLESHOOTING_URL)
|
||||
Texts.LinkifiedText(
|
||||
textWithUrlSpans = spanned,
|
||||
onUrlClick = { CommunicationActions.openBrowserLink(context, it) },
|
||||
style = MaterialTheme.typography.bodyLarge.copy(textAlign = TextAlign.Center, color = MaterialTheme.colorScheme.onSurfaceVariant),
|
||||
modifier = Modifier.padding(bottom = 36.dp)
|
||||
)
|
||||
|
||||
Buttons.LargeTonal(
|
||||
onClick = onRenewClicked,
|
||||
modifier = Modifier
|
||||
.defaultMinSize(minWidth = 220.dp)
|
||||
.padding(bottom = 16.dp)
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.MonthlyDonationCanceled__renew_button))
|
||||
}
|
||||
|
||||
TextButton(
|
||||
onClick = onNotNowClicked,
|
||||
modifier = Modifier
|
||||
.defaultMinSize(minWidth = 220.dp)
|
||||
.padding(bottom = 56.dp)
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.MonthlyDonationCanceled__not_now_button))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user