Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Paywalls V2] Adds deserialization of TabsComponent #2101

Merged
merged 108 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from 93 commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
a0b0911
Fixes compilation of IconComponentView.
JayShortway Jan 22, 2025
fbb2cb6
ColorInfo.Alias has a ColorAlias value now.
JayShortway Jan 22, 2025
6357b73
Adds ColorStyles and a way to look them up.
JayShortway Jan 22, 2025
c0c801a
Adds UiConfig to StyleFactory and uses it to build StackComponentStyle.
JayShortway Jan 22, 2025
3dd6bf8
Adds PresentedStackPartialTests and a fix to ColorStyle.
JayShortway Jan 22, 2025
9946cc8
Adds ColorStyleTests
JayShortway Jan 22, 2025
ee91fd8
Merge branch 'main' into pw2-colorstyles
JayShortway Jan 22, 2025
d3e81c2
Updates documentation for a function.
JayShortway Jan 23, 2025
b148227
Renames a parameter.
JayShortway Jan 23, 2025
ab6a491
Fixes a compilation error.
JayShortway Jan 23, 2025
044b221
Fixes test compilation.
JayShortway Jan 23, 2025
8aeedbb
Adds ColorStyles to IconComponentStyle.
JayShortway Jan 23, 2025
ba778c0
Adds ColorStyles to IconComponentStyle.Background.
JayShortway Jan 23, 2025
0b36305
Adds PresentedIconPartialTests.
JayShortway Jan 23, 2025
fe11b77
Merge branch 'main' into pw2-colorstyles-icon
JayShortway Jan 23, 2025
f21353d
ImageComponentStyle.overlay is a ColorStyles now.
JayShortway Jan 23, 2025
240f508
Adds PresentedImagePartialTests.
JayShortway Jan 23, 2025
8e814c9
Changes ColorScheme properties to ColorStyles in TextComponentStyle.
JayShortway Jan 23, 2025
a733f8b
Adds more LocalizedTextPartialTests.
JayShortway Jan 23, 2025
89c5286
Introduces BorderStyles and adds it to StackComponentStyle.
JayShortway Jan 24, 2025
0b25b3b
Adds BorderStyles to IconComponentStyle.Background.
JayShortway Jan 24, 2025
7be4c38
Adds BorderStyles to ImageComponentStyle.
JayShortway Jan 24, 2025
7ab352b
Introduces ShadowStyles and adds it to StackComponentStyle.
JayShortway Jan 24, 2025
a508cf5
Adds ShadowStyles to IconComponentStyle.Background.
JayShortway Jan 24, 2025
da30ef7
Adds ShadowStyles to ImageComponentStyle.
JayShortway Jan 24, 2025
56e6b80
Adds BackgroundStyles and uses it for the main paywall.
JayShortway Jan 24, 2025
a7f46a8
Removes a bunch of functions that are not needed anymore.
JayShortway Jan 24, 2025
8b20983
Merge branch 'main' into pw2-colorstyles-icon
JayShortway Jan 24, 2025
27dd90f
Merge branch 'pw2-colorstyles-icon' into pw2-colorstyles-image
JayShortway Jan 24, 2025
199816c
Merge branch 'pw2-colorstyles-image' into pw2-colorstyles-text
JayShortway Jan 24, 2025
5300158
Merge branch 'pw2-colorstyles-text' into pw2-colorstyles-border
JayShortway Jan 24, 2025
967b4f0
Merge branch 'pw2-colorstyles-border' into pw2-colorstyles-shadow
JayShortway Jan 24, 2025
5891761
Merge branch 'pw2-colorstyles-shadow' into pw2-colorstyles-background
JayShortway Jan 24, 2025
e9a081f
Merge branch 'pw2-colorstyles-background' into pw2-color-alias-cleanup
JayShortway Jan 24, 2025
b5d90c1
Adds getResourceIdentifier() to ResourceProvider.
JayShortway Jan 27, 2025
44d9af5
Merge branch 'main' into pw2-colorstyles-background
JayShortway Jan 27, 2025
11eb74a
Re-reverts an unintended change.
JayShortway Jan 27, 2025
3ce1c66
Fixes a test.
JayShortway Jan 27, 2025
ae87952
Merge branch 'main' into pw2-colorstyles-background
JayShortway Jan 27, 2025
0ee2a8c
Merge branch 'pw2-colorstyles-background' into pw2-color-alias-cleanup
JayShortway Jan 27, 2025
24d01d6
Merge branch 'pw2-color-alias-cleanup' into pw2-fonts-uiconfig
JayShortway Jan 27, 2025
70cf708
Adds FontSpec.
JayShortway Jan 27, 2025
2388bd8
Adds fontAliases parameter to StyleFactory.
JayShortway Jan 27, 2025
36c3352
Adds fontAliases parameter to StyleFactory.
JayShortway Jan 27, 2025
926775f
StyleFactory resolves FontSpecs.
JayShortway Jan 27, 2025
841357e
Merge branch 'main' into pw2-fonts-uiconfig
JayShortway Jan 27, 2025
31a43ad
TextComponent.fontName is a FontAlias now.
JayShortway Jan 27, 2025
4ac6a5f
Adds FontSpec to TextComponentStyle and LocalizedTextPartial.
JayShortway Jan 27, 2025
ad309de
Adds more tests to StyleFactoryTests.
JayShortway Jan 27, 2025
fc6cbf3
Deletes SystemFontFamily.
JayShortway Jan 27, 2025
d5791da
Fixes LocalizedTextPartialTests.
JayShortway Jan 27, 2025
6b31f04
Adds some LocalizedTextPartialTests.
JayShortway Jan 27, 2025
79e61f6
Renames FontSpec.Device to FontSpec.System.
JayShortway Jan 27, 2025
5874fc0
Adds some PaywallComponentDataValidationTests.
JayShortway Jan 27, 2025
1868c25
Merge branch 'main' into pw2-fonts-uiconfig
JayShortway Jan 28, 2025
9b7cb53
Fixes FontFamily not getting applied in the Markdown composable.
JayShortway Jan 28, 2025
6dc16a1
Adds custom font paywall to PaywallsTester.
JayShortway Jan 28, 2025
4779152
Removes passing the MockResourceProvider by default. Resolves a TODO.
JayShortway Jan 28, 2025
6c020e6
Adds a Google Font paywall to PaywallsTester.
JayShortway Jan 28, 2025
314b364
Merge branch 'main' into pw2-fonts-uiconfig
JayShortway Jan 28, 2025
1ba3c5b
Fixes compilation after merge.
JayShortway Jan 28, 2025
9a0ce39
Adds localizedPricePerDay() and localizedPricePerYear() to VariableDa…
JayShortway Jan 29, 2025
39566ae
Adds a new PaywallValidationError.
JayShortway Jan 29, 2025
488bf38
Adds StyleFactory and UiConfig convenience constructors for tests.
JayShortway Jan 29, 2025
aa7071d
Adds pricePerPeriod extensions.
JayShortway Jan 29, 2025
b87e977
Uses the new UiConfig and StyleFactory test helpers.
JayShortway Jan 30, 2025
54089c1
Adds ComposeLocale.toJavaLocale().
JayShortway Jan 30, 2025
bb56c91
Adds variableLocalizationKeysForEnUs() to PreviewHelpers.kt.
JayShortway Jan 30, 2025
64dc407
Adds Period.valueInDays.
JayShortway Jan 30, 2025
552c32f
Uses previewTextComponentStyle in more places.
JayShortway Jan 30, 2025
2561714
Adds pricePerDay to StoreProduct.
JayShortway Jan 30, 2025
bf0fe56
TextComponentView processes variables with VariableProcessorV2.
JayShortway Jan 30, 2025
7529ab7
Adds a failing TextComponentViewVariablesTests.
JayShortway Jan 30, 2025
82f08dd
Fixes a few tests.
JayShortway Jan 30, 2025
57f7af0
Fixes another test.
JayShortway Jan 30, 2025
d4059ae
Passes Date around.
JayShortway Jan 30, 2025
d57fe0b
Fixes the final test.
JayShortway Jan 30, 2025
f0dfde4
Adds V2 variables to TextComponentViewTests.
JayShortway Jan 30, 2025
fdf5019
Adds a bunch more test cases.
JayShortway Jan 30, 2025
c722cd4
Adds a bunch more test cases, some failing.
JayShortway Jan 30, 2025
faa6184
Fixes tests.
JayShortway Jan 30, 2025
d42258a
TextComponentView longer processes V1 variables.
JayShortway Jan 30, 2025
6bd4cc9
Some cleanup.
JayShortway Jan 30, 2025
96dbfdd
Adds some tests.
JayShortway Jan 30, 2025
dbb2ac3
Some optimizations.
JayShortway Jan 30, 2025
89dbac0
Some cleanup.
JayShortway Jan 30, 2025
4343164
Merge branch 'main' into pw2-variables-v2
JayShortway Jan 30, 2025
307cbd5
Fixes previews.
JayShortway Jan 30, 2025
aba0a43
Adds StyleFactory and UiConfig convenience constructors for tests.
JayShortway Jan 30, 2025
707955a
Adds variableLocalizations to TextComponentStyle, and uses previewTex…
JayShortway Jan 30, 2025
6b027d5
Adds new price calculations needed for Variables V2.
JayShortway Jan 30, 2025
31ba3f7
Merge branch 'pw2-variables-v2-2' into pw2-variables-v2-3
JayShortway Jan 30, 2025
88bdc28
Adds deserialization of TabsComponent.
JayShortway Jan 30, 2025
3c7056f
Attempts to fix broken previews.
JayShortway Jan 31, 2025
69cf097
Fixes a compiler error.
JayShortway Jan 31, 2025
e295e57
Merge branch 'main' into pw2-variables-v2-3
JayShortway Jan 31, 2025
8c32df8
Merge branch 'main' into pw2-variables-v2-3
JayShortway Feb 4, 2025
3fa78e3
Merge branch 'pw2-variables-v2-3' into pw2-tabs-1
JayShortway Feb 4, 2025
64b9fec
Fixes detekt.
JayShortway Feb 4, 2025
843ff8d
Fixes compilation.
JayShortway Feb 4, 2025
523097d
Merge branch 'main' into pw2-variables-v2-3
JayShortway Feb 4, 2025
f467192
Merge branch 'pw2-variables-v2-3' into pw2-tabs-1
JayShortway Feb 4, 2025
8189144
Fixes compilation.
JayShortway Feb 5, 2025
eb7529a
Adds tests for a lifetime product.
JayShortway Feb 5, 2025
f0c0e39
Corrects the lifetime product's description.
JayShortway Feb 5, 2025
6484ed8
Merge branch 'main' into pw2-variables-v2-3
JayShortway Feb 5, 2025
63c98f4
Merge branch 'pw2-variables-v2-3' into pw2-tabs-1
JayShortway Feb 5, 2025
d772abb
Merge branch 'main' into pw2-tabs-1
JayShortway Feb 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ static void checkPricingPhase(PricingPhase pricingPhase) {
Price price = pricingPhase.getPrice();
String pricePerMonthString = pricingPhase.formattedPriceInMonths(locale);
String pricePerMonthStringNoLocale = pricingPhase.formattedPriceInMonths();
Price pricePerDay = pricingPhase.pricePerDay(locale);
Price pricePerWeek = pricingPhase.pricePerWeek(locale);
Price pricePerMonth = pricingPhase.pricePerMonth(locale);
Price pricePerYear = pricingPhase.pricePerYear(locale);
Price pricePerDayNoLocale = pricingPhase.pricePerDay();
Price pricePerWeekNoLocale = pricingPhase.pricePerWeek();
Price pricePerMonthNoLocale = pricingPhase.pricePerMonth();
Price pricePerYearNoLocale = pricingPhase.pricePerYear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ static void check(final StoreProduct product) {
final String description = product.getDescription();
final Period period = product.getPeriod();
final String formattedPricePerMonth = product.formattedPricePerMonth(locale);
final Price pricePerDay = product.pricePerDay(locale);
final Price pricePerWeek = product.pricePerWeek(locale);
final Price pricePerMonth = product.pricePerMonth(locale);
final Price pricePerYear = product.pricePerYear(locale);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ private class PricingPhaseAPI {
val price: Price = pricingPhase.price
val pricePerMonthString: String = pricingPhase.formattedPriceInMonths(locale)
val pricePerMonthStringNoLocale: String = pricingPhase.formattedPriceInMonths()
val pricePerDay = pricingPhase.pricePerDay(locale)
val pricePerWeek = pricingPhase.pricePerWeek(locale)
val pricePerMonth = pricingPhase.pricePerMonth(locale)
val pricePerYear = pricingPhase.pricePerYear(locale)
val pricePerDayNoLocale = pricingPhase.pricePerDay()
val pricePerWeekNoLocale = pricingPhase.pricePerWeek()
val pricePerMonthNoLocale = pricingPhase.pricePerMonth()
val pricePerYearNoLocale = pricingPhase.pricePerYear()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ private class StoreProductAPI {
val price: Price = price
val formattedPricePerMonth: String? = formattedPricePerMonth(locale)
val formattedPricePerMonthNoLocale: String? = formattedPricePerMonth()
val pricePerDay: Price? = pricePerDay(locale)
val pricePerWeek: Price? = pricePerWeek(locale)
val pricePerMonth: Price? = pricePerMonth(locale)
val pricePerYear: Price? = pricePerYear(locale)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.revenuecat.purchases.models

import android.os.Parcelable
import com.revenuecat.purchases.InternalRevenueCatAPI
import com.revenuecat.purchases.common.errorLog
import kotlinx.parcelize.Parcelize
import kotlin.math.roundToInt
Expand Down Expand Up @@ -60,17 +61,31 @@ data class Period(
UNKNOWN,
}

@InternalRevenueCatAPI
val valueInDays: Double
get() = when (unit) {
Unit.DAY -> value.toDouble()
Unit.WEEK -> value * PeriodConstants.DAYS_PER_WEEK
Unit.MONTH -> value * PeriodConstants.DAYS_PER_MONTH
Unit.YEAR -> value * PeriodConstants.DAYS_PER_YEAR
Unit.UNKNOWN -> {
errorLog("Unknown period unit trying to get value in days: $unit")
0.0
}
}

/**
* The period value in week units. This is an approximated value.
*/
internal val valueInWeeks: Double
@InternalRevenueCatAPI
val valueInWeeks: Double
get() = when (unit) {
Unit.DAY -> value / PeriodConstants.DAYS_PER_WEEK
Unit.WEEK -> value.toDouble()
Unit.MONTH -> value.toDouble() * PeriodConstants.WEEKS_PER_MONTH
Unit.YEAR -> value * PeriodConstants.WEEKS_PER_YEAR
Unit.UNKNOWN -> {
errorLog("Unknown period unit trying to get value in months: $unit")
errorLog("Unknown period unit trying to get value in weeks: $unit")
0.0
}
}
Expand All @@ -93,14 +108,15 @@ data class Period(
/**
* The period value in week units. This is an approximated value.
*/
internal val valueInYears: Double
@InternalRevenueCatAPI
val valueInYears: Double
get() = when (unit) {
Unit.DAY -> value / PeriodConstants.DAYS_PER_YEAR
Unit.WEEK -> value / PeriodConstants.WEEKS_PER_YEAR
Unit.MONTH -> value / PeriodConstants.MONTHS_PER_YEAR
Unit.YEAR -> value.toDouble()
Unit.UNKNOWN -> {
errorLog("Unknown period unit trying to get value in months: $unit")
errorLog("Unknown period unit trying to get value in years: $unit")
0.0
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.revenuecat.purchases.models

import android.os.Parcelable
import com.revenuecat.purchases.utils.pricePerDay
import com.revenuecat.purchases.utils.pricePerMonth
import com.revenuecat.purchases.utils.pricePerWeek
import com.revenuecat.purchases.utils.pricePerYear
Expand Down Expand Up @@ -56,6 +57,16 @@ data class PricingPhase(
}
}

/**
* Gives the price of the [PricingPhase] in the given locale in a daily recurrence. This means that for example,
* if the period is weekly, the price will be divided by 7. It uses a currency formatter to format the price in
* the given locale. Note that this value may be an approximation.
* @param locale Locale to use for formatting the price. Default is the system default locale.
*/
@JvmOverloads
fun pricePerDay(locale: Locale = Locale.getDefault()): Price =
price.pricePerDay(billingPeriod, locale)

/**
* Gives the price of the [PricingPhase] in the given locale in a weekly recurrence. This means that for example,
* if the period is monthly, the price will be divided by 4. It uses a currency formatter to format the price in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.revenuecat.purchases.models

import com.revenuecat.purchases.PresentedOfferingContext
import com.revenuecat.purchases.ProductType
import com.revenuecat.purchases.utils.pricePerDay
import com.revenuecat.purchases.utils.pricePerMonth
import com.revenuecat.purchases.utils.pricePerWeek
import com.revenuecat.purchases.utils.pricePerYear
Expand Down Expand Up @@ -134,6 +135,18 @@ interface StoreProduct {
*/
fun copyWithPresentedOfferingContext(presentedOfferingContext: PresentedOfferingContext?): StoreProduct

/**
* Null for INAPP products. The price of the [StoreProduct] in the given locale in a daily recurrence.
* This means that, for example, if the period is weekly, the price will be divided by 7.
* It uses a currency formatter to format the price in the given locale.
* Note that this value may be an approximation.
* For Google subscriptions, this value will use the basePlan to calculate the value.
* @param locale Locale to use for formatting the price. Default is the system default locale.
*/
fun pricePerDay(locale: Locale = Locale.getDefault()): Price? {
return period?.let { price.pricePerDay(it, locale) }
}

/**
* Null for INAPP products. The price of the [StoreProduct] in the given locale in a weekly recurrence.
* This means that, for example, if the period is monthly, the price will be divided by 4.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ internal class PaywallComponentSerializer : KSerializer<PaywallComponent> {
"text" -> jsonDecoder.json.decodeFromString<TextComponent>(json.toString())
"icon" -> jsonDecoder.json.decodeFromString<IconComponent>(json.toString())
"timeline" -> jsonDecoder.json.decodeFromString<TimelineComponent>(json.toString())
"tab_control_button" -> jsonDecoder.json.decodeFromString<TabControlButtonComponent>(json.toString())
"tab_control_toggle" -> jsonDecoder.json.decodeFromString<TabControlToggleComponent>(json.toString())
"tab_control" -> jsonDecoder.json.decodeFromString<TabControlComponent>(json.toString())
"tabs" -> jsonDecoder.json.decodeFromString<TabsComponent>(json.toString())
else -> json["fallback"]
?.let { it as? JsonObject }
?.toString()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
@file:Suppress("LongParameterList")

package com.revenuecat.purchases.paywalls.components

import com.revenuecat.purchases.InternalRevenueCatAPI
import com.revenuecat.purchases.paywalls.components.common.ComponentOverrides
import com.revenuecat.purchases.paywalls.components.properties.Border
import com.revenuecat.purchases.paywalls.components.properties.ColorScheme
import com.revenuecat.purchases.paywalls.components.properties.Padding
import com.revenuecat.purchases.paywalls.components.properties.Shadow
import com.revenuecat.purchases.paywalls.components.properties.Shape
import com.revenuecat.purchases.paywalls.components.properties.Size
import com.revenuecat.purchases.paywalls.components.properties.SizeConstraint.Fill
import com.revenuecat.purchases.paywalls.components.properties.SizeConstraint.Fit
import dev.drewhamilton.poko.Poko
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@InternalRevenueCatAPI
@Poko
@Serializable
@SerialName("tab_control_button")
class TabControlButtonComponent(
@get:JvmSynthetic
@SerialName("tab_index")
val tabIndex: Int,
@get:JvmSynthetic
val stack: StackComponent,
) : PaywallComponent

@InternalRevenueCatAPI
@Poko
@Serializable
@SerialName("tab_control_toggle")
class TabControlToggleComponent(
@get:JvmSynthetic
@SerialName("default_value")
val defaultValue: Boolean,
@get:JvmSynthetic
@SerialName("thumb_color_on")
val thumbColorOn: ColorScheme,
@get:JvmSynthetic
@SerialName("thumb_color_off")
val thumbColorOff: ColorScheme,
@get:JvmSynthetic
@SerialName("track_color_on")
val trackColorOn: ColorScheme,
@get:JvmSynthetic
@SerialName("track_color_off")
val trackColorOff: ColorScheme,
) : PaywallComponent

@InternalRevenueCatAPI
@Serializable
@SerialName("tab_control")
object TabControlComponent : PaywallComponent

@InternalRevenueCatAPI
@Poko
@Serializable
@SerialName("tabs")
class TabsComponent(
@get:JvmSynthetic
val size: Size = Size(width = Fill, height = Fit),
@get:JvmSynthetic
val padding: Padding = Padding.zero,
@get:JvmSynthetic
val margin: Padding = Padding.zero,
@get:JvmSynthetic
@SerialName("background_color")
val backgroundColor: ColorScheme? = null,
@get:JvmSynthetic
val shape: Shape? = null,
@get:JvmSynthetic
val border: Border? = null,
@get:JvmSynthetic
val shadow: Shadow? = null,
@get:JvmSynthetic
val control: TabControl,
@get:JvmSynthetic
val tabs: List<Tab>,
@get:JvmSynthetic
val overrides: ComponentOverrides<PartialTabsComponent>? = null,
) : PaywallComponent {
@InternalRevenueCatAPI
@Poko
@Serializable
class Tab(
@get:JvmSynthetic
val stack: StackComponent,
)

@InternalRevenueCatAPI
@Serializable
sealed interface TabControl {
@InternalRevenueCatAPI
@Poko
@Serializable
@SerialName("buttons")
class Buttons(@get:JvmSynthetic val stack: StackComponent) : TabControl

@InternalRevenueCatAPI
@Poko
@Serializable
@SerialName("toggle")
class Toggle(@get:JvmSynthetic val stack: StackComponent) : TabControl
}
}

@InternalRevenueCatAPI
@Poko
@Serializable
class PartialTabsComponent(
@get:JvmSynthetic
val visible: Boolean? = true,
@get:JvmSynthetic
val size: Size? = null,
@get:JvmSynthetic
val padding: Padding? = null,
@get:JvmSynthetic
val margin: Padding? = null,
@get:JvmSynthetic
@SerialName("background_color")
val backgroundColor: ColorScheme? = null,
@get:JvmSynthetic
val shape: Shape? = null,
@get:JvmSynthetic
val border: Border? = null,
@get:JvmSynthetic
val shadow: Shadow? = null,
) : PartialComponent
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.revenuecat.purchases.utils

import com.revenuecat.purchases.InternalRevenueCatAPI
import com.revenuecat.purchases.models.Period
import com.revenuecat.purchases.models.Price
import java.text.NumberFormat
Expand All @@ -8,6 +9,13 @@ import java.util.Locale

private const val MICRO_MULTIPLIER = 1_000_000.0

@JvmSynthetic
@OptIn(InternalRevenueCatAPI::class)
internal fun Price.pricePerDay(billingPeriod: Period, locale: Locale): Price {
return pricePerPeriod(billingPeriod.valueInDays, locale)
}

@OptIn(InternalRevenueCatAPI::class)
internal fun Price.pricePerWeek(billingPeriod: Period, locale: Locale): Price {
return pricePerPeriod(billingPeriod.valueInWeeks, locale)
}
Expand All @@ -16,6 +24,7 @@ internal fun Price.pricePerMonth(billingPeriod: Period, locale: Locale): Price {
return pricePerPeriod(billingPeriod.valueInMonths, locale)
}

@OptIn(InternalRevenueCatAPI::class)
internal fun Price.pricePerYear(billingPeriod: Period, locale: Locale): Price {
return pricePerPeriod(billingPeriod.valueInYears, locale)
}
Expand Down
Loading