feat(plan): Remove asteriks from the price disclaimers and fix yearly/2 years disclaimer text in subscription including the prices for the unsupported currencies on our API.

This commit is contained in:
dkadrikj
2025-03-12 16:03:53 +01:00
committed by Dino Kadrikj
parent 5520c7f923
commit e57ee51471
5 changed files with 49 additions and 27 deletions
@@ -51,7 +51,8 @@ class GetDynamicSubscriptionAdjustedPrices @Inject constructor(
return dynamicSubscription.copy(
amount = storePrice.priceAmountCents.toLong(),
currency = storePrice.currency,
renewAmount = storePrice.defaultPriceAmountCents?.toLong(),
currency = storePrice.currency
)
}
}
@@ -102,14 +102,14 @@ class GetDynamicSubscriptionAdjustedPricesTest {
provider = PaymentProvider.GoogleInAppPurchase,
priceAmountMicros = 1000000,
currency = "USD",
formattedPriceAndCurrency = "USD 100"
formattedPriceAndCurrency = "USD 100",
)
coEvery { getProductIdForCurrentSubscription(testUserId) } returns testProductId
coEvery { repository.getDynamicSubscriptions(testUserId) } returns testPaidSubscriptions
// WHEN
val result = useCase.invoke(testUserId)
// THEN
assertEquals(testPaidSubscription.copy(amount = 100L, currency = "USD"), result)
assertEquals(testPaidSubscription.copy(amount = 100L, currency = "USD", renewAmount = null), result)
}
@Test
@@ -30,6 +30,7 @@ import me.proton.core.plan.domain.entity.DynamicSubscription
import me.proton.core.plan.presentation.R
import me.proton.core.plan.presentation.databinding.FragmentDynamicSubscriptionBinding
import me.proton.core.plan.presentation.entity.DynamicUser
import me.proton.core.plan.presentation.entity.PlanCycle
import me.proton.core.plan.presentation.entity.toStringRes
import me.proton.core.plan.presentation.view.formatRenew
import me.proton.core.plan.presentation.view.toView
@@ -123,7 +124,7 @@ class DynamicSubscriptionFragment : ProtonFragment(R.layout.fragment_dynamic_sub
description = subscription.description
starred = subscription.decorations.filterIsInstance<DynamicDecoration.Starred>().isNotEmpty()
val price = subscription.amount?.toDouble()
val renewPrice = subscription.renewAmount?.toDouble()
val renewPrice = subscription.renewAmount?.toDouble() ?: price // if renew price (from google) is null, the assumption is they are equal
val currency = subscription.currency ?: userCurrency
priceText = price?.formatCentsPriceDefaultLocale(currency)
val renewPriceText = renewPrice?.formatCentsPriceDefaultLocale(currency)
@@ -131,7 +132,14 @@ class DynamicSubscriptionFragment : ProtonFragment(R.layout.fragment_dynamic_sub
renewalText = when {
subscription.renew == null -> null
subscription.periodEnd == null -> null
else -> formatRenew(context, subscription.renew ?: false, requireNotNull(subscription.periodEnd), priceText, renewPriceText)
else -> formatRenew(
context,
subscription.renew ?: false,
requireNotNull(subscription.periodEnd),
priceText,
renewPriceText,
PlanCycle.map[subscription.cycleMonths] ?: PlanCycle.FREE
)
}
isCollapsable = false
entitlements.removeAllViews()
@@ -28,6 +28,7 @@ import androidx.annotation.ArrayRes
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.text.HtmlCompat
import me.proton.core.plan.presentation.R
import me.proton.core.plan.presentation.entity.PlanCycle
import me.proton.core.presentation.utils.formatByteToHumanReadable
import me.proton.core.user.domain.entity.User
import me.proton.core.util.kotlin.CoreLogger
@@ -101,27 +102,38 @@ internal fun formatUsedSpace(context: Context, usedBytes: Long, maxBytes: Long):
internal fun formatRenew(
context: Context, renew: Boolean, periodEnd: Instant,
price: CharSequence?, renewPrice: CharSequence?
price: CharSequence?, renewPrice: CharSequence?, cycle: PlanCycle?
): Spanned {
val date = Calendar.getInstance().apply { timeInMillis = periodEnd.toEpochMilli() }.time
val renewalText = when {
price != renewPrice -> String.format(
context.getString(R.string.subscription_renewal_info_monthly),
price,
DateFormat.getDateInstance().format(date),
renewPrice
)
renew ->
String.format(
context.getString(R.string.plans_renewal_date),
DateFormat.getDateInstance().format(date)
)
else -> String.format(
!renew -> String.format(
context.getString(R.string.plans_expiration_date),
DateFormat.getDateInstance().format(date)
)
renew -> {
if (price != renewPrice) {
val renewalText = when (cycle) {
PlanCycle.MONTHLY -> context.getString(R.string.subscription_renewal_info_monthly)
PlanCycle.YEARLY -> context.getString(R.string.subscription_renewal_info_annual)
PlanCycle.TWO_YEARS -> context.getString(R.string.subscription_renewal_info_two_years)
else -> ""
}
String.format(
renewalText,
price,
DateFormat.getDateInstance().format(date),
renewPrice
)
} else {
String.format(
context.getString(R.string.plans_renewal_date),
DateFormat.getDateInstance().format(date)
)
}
}
else -> ""
}
return HtmlCompat.fromHtml(renewalText, HtmlCompat.FROM_HTML_MODE_LEGACY)
@@ -177,13 +177,14 @@
<string name="plan_manage_subscription_no_app_subtitle">You can manage your subscription in %1$s application. Download and install the latest version of %2$s to upgrade to %3$s.</string>
<string name="plan_manage_subscription_app_missing_got_it">Got it</string>
<string name="plan_welcome_price_message_monthly">* Welcome offer. Auto renews at %1$s/month</string>
<string name="plan_welcome_price_message_annual">* Welcome offer. Auto renews at %1$s/year</string>
<string name="plan_welcome_price_message_two_year">* Welcome offer. Auto renews at %1$s/2 years</string>
<string name="plan_auto_renew_message_monthly">* Subscription auto renews at %1$s/month</string>
<string name="plan_auto_renew_message_annual">* Subscription auto renews at %1$s/year</string>
<string name="plan_auto_renew_message_two_years">* Subscription auto renews at %1$s/2 years</string>
<string name="plan_welcome_price_message_other_fallback">* Subscription auto renews</string>
<string name="plan_welcome_price_message_monthly">Welcome offer. Auto renews at %1$s/month</string>
<string name="plan_welcome_price_message_annual">Welcome offer. Auto renews at %1$s/year</string>
<string name="plan_welcome_price_message_two_year">Welcome offer. Auto renews at %1$s/2 years</string>
<string name="plan_auto_renew_message_monthly">Subscription auto renews at %1$s/month</string>
<string name="plan_auto_renew_message_annual">Subscription auto renews at %1$s/year</string>
<string name="plan_auto_renew_message_two_years">Subscription auto renews at %1$s/2 years</string>
<string name="plan_welcome_price_message_other_fallback">Subscription auto renews</string>
<string name="subscription_renewal_info_monthly">The discounted price of %1$s is valid for the first month. Your subscription automatically renews on &lt;b&gt;%2$s&lt;/b&gt; at &lt;b&gt;%3$s&lt;/b&gt; every month.</string>
<string name="subscription_renewal_info_annual">The discounted price of %1$s is valid for the first year. Your subscription automatically renews on &lt;b&gt;%2$s&lt;/b&gt; at &lt;b&gt;%3$s&lt;/b&gt; every year.</string>
<string name="subscription_renewal_info_two_years">The discounted price of %1$s is valid for the first year. Your subscription automatically renews on &lt;b&gt;%2$s&lt;/b&gt; at &lt;b&gt;%3$s&lt;/b&gt; every 2 years.</string>
</resources>