This commit is contained in:
spaced4ndy
2026-08-17 16:49:48 +04:00
parent 0ef81d2fbe
commit 05b44f5f96
2 changed files with 5 additions and 11 deletions
@@ -70,9 +70,9 @@ data class BadgeStoreReceipt(
val environment: String? = null
)
// TODO [badges] Play Billing has no offline configuration, so there is no analogue of the iOS
// .storekit file. Set to true to price the screens and walk the purchase flow without Play Console
// products; the purchase is simulated and its receipt says so.
// TODO [badges] Play Billing has no offline product configuration. Set to true to price the screens
// and walk the purchase flow without Play Console products; the purchase is simulated and its
// receipt says so.
const val useBadgeTestProducts = false
private fun testProduct(level: BadgeLevel, period: BadgePeriod, priceMicros: Long) =
@@ -110,8 +110,7 @@ object BadgeStore {
private enum class LoadState { NotLoaded, Loading, Loaded, Failed }
private val state = mutableStateOf(LoadState.NotLoaded)
// snapshot state, unlike the plain dictionary on iOS: Compose tracks reads per value, so a
// composable that only reads the products would not recompose when they arrive
// snapshot state so a composable reading only the products still recomposes when they arrive
private val products = mutableStateOf<Map<String, BadgeProduct>>(emptyMap())
fun price(level: BadgeLevel, period: BadgePeriod): BadgePrice = when (state.value) {
@@ -122,7 +121,6 @@ object BadgeStore {
}
}
// percentage the annual subscription saves against 12 monthly payments
fun annualSavings(level: BadgeLevel): Int? {
val monthly = products.value[badgeProductId(level, BadgePeriod.Monthly)] ?: return null
val annual = products.value[badgeProductId(level, BadgePeriod.Annual)] ?: return null
@@ -56,8 +56,6 @@ enum class BadgePeriod {
}
}
// OnboardingActionButton takes a resource id, so the price states map to (id, arg) here rather
// than to a formatted string as on iOS
fun payLabel(price: BadgePrice): Pair<StringResource, String?> = when (price) {
is BadgePrice.Loading -> MR.strings.badges_price_loading to null
is BadgePrice.Unavailable -> MR.strings.badges_price_unavailable to null
@@ -163,8 +161,7 @@ private fun PeriodCard(level: BadgeLevel, period: BadgePeriod, selectedPeriod: B
val percent = savingsPercent(level, period)
if (percent != null) {
Text(
// the percent sign is in the argument, not the resource: adjustFormatting rejects %%
stringResource(MR.strings.badges_savings).format("$percent%"),
stringResource(MR.strings.badges_savings).format("${percent}%"),
style = MaterialTheme.typography.body2,
color = if (isSelected) MaterialTheme.colors.primary else MaterialTheme.colors.secondary,
textAlign = TextAlign.Center
@@ -235,7 +232,6 @@ private fun showPurchasedAlert(receipt: BadgeStoreReceipt, invoiceId: String, cl
if (receipt.environment != null) lines.add("Environment: ${receipt.environment}")
lines.add("Token: ${receipt.token.length} bytes")
val summary = lines.joinToString("\n")
// logged as well as shown: the log always lands even when the alert is missed
Log.d(TAG, "badge purchase succeeded\n$summary")
AlertManager.shared.showAlertDialog(
title = generalGetString(MR.strings.badges_purchase_successful),