Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ jobs:
command: sudo pip install awscli
- run:
name: Deploy to S3
command: aws s3 sync ~/project/docs/9.29.0 s3://purchases-docs/android/9.29.0 --delete
command: aws s3 sync ~/project/docs/9.29.1 s3://purchases-docs/android/9.29.1 --delete
- run:
name: Update index.html
command: aws s3 cp ~/project/docs/index.html s3://purchases-docs/android/index.html
Expand Down
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9.29.0
9.29.1
17 changes: 2 additions & 15 deletions CHANGELOG.latest.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,4 @@
## RevenueCat SDK
### ✨ New Features
* Use Amazon deep link for Amazon subscription management (#3291) via Cesar de la Vega (@vegaro)
* Introduce purchases codegen package (#3163) via Jaewoong Eum (@skydoves)
### 🐞 Bugfixes
* Fix Test Store Purchase dialog not cancelling purchase on outside tap (#3289) via Antonio Pallares (@ajpallares)

## RevenueCatUI SDK
### Paywallv2
#### 🐞 Bugfixes
* Fix mixed currencies in paywall price variables (PW-133) (#3119) via Facundo Menzella (@facumenzella)

### 🔄 Other Changes
* Add docs for the codegen plugin (#3288) via Jaewoong Eum (@skydoves)
* Run integration tests against all backend environments (#3278) via Toni Rico (@tonidero)
* Use merge queue for release PR merging (#3281) via Antonio Pallares (@ajpallares)
* ci: warn when pre-built material-icons are imported in :ui:revenuecatui (#3282) via Facundo Menzella (@facumenzella)
#### ✨ New Features
* PW-1178 | Support package-level visibility via visible property and overrides (#3279) via Facundo Menzella (@facumenzella)
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 9.29.1
## RevenueCatUI SDK
### Paywallv2
#### ✨ New Features
* PW-1178 | Support package-level visibility via visible property and overrides (#3279) via Facundo Menzella (@facumenzella)

## 9.29.0
## RevenueCat SDK
### ✨ New Features
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[versions]
agp = "8.13.2"
kotlin = "1.8.22"
purchases = "9.29.0"
purchases = "9.29.1"
androidxCore = "1.10.1"

[plugins]
Expand Down
2 changes: 1 addition & 1 deletion examples/MagicWeather/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
agp = "8.13.2"
androidxNavigation = "2.6.0"
kotlin = "1.9.0"
purchases = "9.29.0"
purchases = "9.29.1"
lifecycle = "2.6.1"
androidxCore = "1.10.1"

Expand Down
2 changes: 1 addition & 1 deletion examples/MagicWeatherCompose/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
agp = "8.13.2"
androidxNavigation = "2.5.3"
kotlin = "1.8.22"
purchases = "9.29.0"
purchases = "9.29.1"
lifecycle = "2.5.0"
androidxCore = "1.10.1"

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#Fri Mar 31 10:31:20 PDT 2023
GROUP=com.revenuecat.purchases

VERSION_NAME=9.29.0
VERSION_NAME=9.29.1

POM_DESCRIPTION=Mobile subscriptions in hours, not months.
POM_URL=https://github.com/RevenueCat/purchases-android
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ import com.revenuecat.purchases.api.BuildConfig
public object Config {
public var logLevel: LogLevel = LogLevel.debugLogsEnabled(BuildConfig.DEBUG)

internal const val frameworkVersion = "9.29.0"
internal const val frameworkVersion = "9.29.1"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.revenuecat.purchases.paywalls.components

import androidx.compose.runtime.Immutable
import com.revenuecat.purchases.InternalRevenueCatAPI
import com.revenuecat.purchases.paywalls.components.common.ComponentOverride
import com.revenuecat.purchases.paywalls.components.common.PromoOfferConfig
import com.revenuecat.purchases.paywalls.components.common.ResilientPromoOfferConfigSerializer
import dev.drewhamilton.poko.Poko
Expand All @@ -26,4 +27,17 @@ public class PackageComponent(
@Serializable(with = ResilientPromoOfferConfigSerializer::class)
@SerialName("play_store_offer")
public val playStoreOffer: PromoOfferConfig? = null,
@get:JvmSynthetic
public val visible: Boolean? = null,
@get:JvmSynthetic
public val overrides: List<ComponentOverride<PartialPackageComponent>> = emptyList(),
) : PaywallComponent

@InternalRevenueCatAPI
@Poko
@Serializable
@Immutable
public class PartialPackageComponent(
@get:JvmSynthetic
public val visible: Boolean? = null,
) : PartialComponent
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.revenuecat.purchases.ColorAlias
import com.revenuecat.purchases.JsonTools
import com.revenuecat.purchases.LogHandler
import com.revenuecat.purchases.common.currentLogHandler
import com.revenuecat.purchases.paywalls.components.common.ComponentOverride
import com.revenuecat.purchases.paywalls.components.common.LocalizationKey
import com.revenuecat.purchases.paywalls.components.common.PromoOfferConfig
import com.revenuecat.purchases.paywalls.components.properties.ColorInfo
Expand Down Expand Up @@ -187,6 +188,87 @@ internal class PackageComponentTests(@Suppress("UNUSED_PARAMETER") name: String,
)
),
),
arrayOf(
"visible = true",
Args(
json = """
{
"type": "package",
"package_id": "${"$"}rc_weekly",
"is_selected_by_default": true,
"visible": true,
"stack": {
"type": "stack",
"components": []
}
}
""".trimIndent(),
expected = PackageComponent(
packageId = "${"$"}rc_weekly",
isSelectedByDefault = true,
stack = StackComponent(components = emptyList()),
visible = true,
)
),
),
arrayOf(
"visible = false",
Args(
json = """
{
"type": "package",
"package_id": "${"$"}rc_weekly",
"is_selected_by_default": true,
"visible": false,
"stack": {
"type": "stack",
"components": []
}
}
""".trimIndent(),
expected = PackageComponent(
packageId = "${"$"}rc_weekly",
isSelectedByDefault = true,
stack = StackComponent(components = emptyList()),
visible = false,
)
),
),
arrayOf(
"overrides with visible = false",
Args(
json = """
{
"type": "package",
"package_id": "${"$"}rc_weekly",
"is_selected_by_default": true,
"stack": {
"type": "stack",
"components": []
},
"overrides": [
{
"conditions": [{"type": "intro_offer"}],
"properties": {"visible": false}
}
]
}
""".trimIndent(),
expected = PackageComponent(
packageId = "${"$"}rc_weekly",
isSelectedByDefault = true,
stack = StackComponent(components = emptyList()),
overrides = listOf(
ComponentOverride(
conditions = listOf(
ComponentOverride.Condition.IntroOffer
),
properties = PartialPackageComponent(visible = false),
)
),
)
),
),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"statusCode": 200,
"headers": {
"Connection": "keep-alive",
"Content-Length": "23399",
"Content-Length": "23378",
"Content-Type": "application\/json",
"access-control-allow-origin": "*",
"access-control-expose-headers": "X-Request-Id",
Expand Down Expand Up @@ -2085,7 +2085,6 @@
"exit_offers": {},
"id": "pw13dea1ae2d694a7c",
"play_store_product_change_mode": {},
"published_fonts": {},
"revision": 2,
"template_name": "components",
"zero_decimal_place_countries": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"statusCode": 200,
"headers": {
"Connection": "keep-alive",
"Content-Length": "23399",
"Content-Length": "23378",
"Content-Type": "application\/json",
"access-control-allow-origin": "*",
"access-control-expose-headers": "X-Request-Id",
Expand Down Expand Up @@ -2085,7 +2085,6 @@
"exit_offers": {},
"id": "pw13dea1ae2d694a7c",
"play_store_product_change_mode": {},
"published_fonts": {},
"revision": 2,
"template_name": "components",
"zero_decimal_place_countries": {
Expand Down
2 changes: 1 addition & 1 deletion test-apps/sdksizetesting/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ espressoCore = "3.7.0"
lifecycleRuntimeKtx = "2.10.0"
activityCompose = "1.12.2"
composeBom = "2024.09.00"
purchases = "9.29.0"
purchases = "9.29.1"
emergeGradlePlugin = "4.4.0"

[libraries]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.revenuecat.purchases.ui.revenuecatui.components

import com.revenuecat.purchases.paywalls.components.PartialPackageComponent
import com.revenuecat.purchases.ui.revenuecatui.errors.PaywallValidationError
import com.revenuecat.purchases.ui.revenuecatui.helpers.NonEmptyList
import com.revenuecat.purchases.ui.revenuecatui.helpers.Result
import dev.drewhamilton.poko.Poko

@Poko
internal class PresentedPackagePartial(
@get:JvmSynthetic val partial: PartialPackageComponent,
) : PresentedPartial<PresentedPackagePartial> {

companion object {
@JvmSynthetic
operator fun invoke(
from: PartialPackageComponent,
): Result<PresentedPackagePartial, NonEmptyList<PaywallValidationError>> =
Result.Success(PresentedPackagePartial(partial = from))
}

override fun combine(with: PresentedPackagePartial?): PresentedPackagePartial {
val otherPartial = with?.partial
return PresentedPackagePartial(
partial = PartialPackageComponent(
visible = otherPartial?.visible ?: partial.visible,
),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
@file:JvmSynthetic

package com.revenuecat.purchases.ui.revenuecatui.components.pkg

import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.window.core.layout.WindowWidthSizeClass
import com.revenuecat.purchases.ui.revenuecatui.CustomVariableValue
import com.revenuecat.purchases.ui.revenuecatui.components.ComponentViewState
import com.revenuecat.purchases.ui.revenuecatui.components.ConditionContext
import com.revenuecat.purchases.ui.revenuecatui.components.ScreenCondition
import com.revenuecat.purchases.ui.revenuecatui.components.buildPresentedPartial
import com.revenuecat.purchases.ui.revenuecatui.components.state.PackageAwareDelegate
import com.revenuecat.purchases.ui.revenuecatui.components.style.PackageComponentStyle
import com.revenuecat.purchases.ui.revenuecatui.composables.OfferEligibility
import com.revenuecat.purchases.ui.revenuecatui.data.PaywallState

@Stable
@JvmSynthetic
@Composable
internal fun rememberUpdatedPackageComponentState(
style: PackageComponentStyle,
paywallState: PaywallState.Loaded.Components,
): PackageComponentState = rememberUpdatedPackageComponentState(
style = style,
selectedPackageInfoProvider = { paywallState.selectedPackageInfo },
selectedTabIndexProvider = { paywallState.selectedTabIndex },
selectedOfferEligibilityProvider = { paywallState.selectedOfferEligibility },
customVariablesProvider = { paywallState.mergedCustomVariables },
)

@Suppress("LongParameterList")
@Stable
@JvmSynthetic
@Composable
private fun rememberUpdatedPackageComponentState(
style: PackageComponentStyle,
selectedPackageInfoProvider: () -> PaywallState.Loaded.Components.SelectedPackageInfo?,
selectedTabIndexProvider: () -> Int,
selectedOfferEligibilityProvider: () -> OfferEligibility,
customVariablesProvider: () -> Map<String, CustomVariableValue>,
): PackageComponentState {
val windowSize = currentWindowAdaptiveInfo().windowSizeClass.windowWidthSizeClass

return remember(style) {
PackageComponentState(
initialWindowSize = windowSize,
style = style,
selectedPackageInfoProvider = selectedPackageInfoProvider,
selectedTabIndexProvider = selectedTabIndexProvider,
selectedOfferEligibilityProvider = selectedOfferEligibilityProvider,
customVariablesProvider = customVariablesProvider,
)
}.apply {
update(windowSize = windowSize)
}
}

@Suppress("LongParameterList")
@Stable
internal class PackageComponentState(
initialWindowSize: WindowWidthSizeClass,
private val style: PackageComponentStyle,
private val selectedPackageInfoProvider: () -> PaywallState.Loaded.Components.SelectedPackageInfo?,
private val selectedTabIndexProvider: () -> Int,
private val selectedOfferEligibilityProvider: () -> OfferEligibility,
private val customVariablesProvider: () -> Map<String, CustomVariableValue> = { emptyMap() },
) {
private var windowSize by mutableStateOf(initialWindowSize)

private val packageAwareDelegate = PackageAwareDelegate(
style = style,
selectedPackageInfoProvider = selectedPackageInfoProvider,
selectedTabIndexProvider = selectedTabIndexProvider,
selectedOfferEligibilityProvider = selectedOfferEligibilityProvider,
)

private val presentedPartial by derivedStateOf {
val windowCondition = ScreenCondition.from(windowSize)
val componentState =
if (packageAwareDelegate.isSelected) ComponentViewState.SELECTED else ComponentViewState.DEFAULT

style.overrides.buildPresentedPartial(
windowCondition,
packageAwareDelegate.offerEligibility,
componentState,
conditionContext = ConditionContext(
selectedPackageId = selectedPackageInfoProvider()?.rcPackage?.identifier,
customVariables = customVariablesProvider(),
),
)
}

@get:JvmSynthetic
val visible by derivedStateOf { presentedPartial?.partial?.visible ?: style.visible }

@JvmSynthetic
fun update(windowSize: WindowWidthSizeClass) {
this.windowSize = windowSize
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ internal fun PackageComponentView(
clickHandler: suspend (PaywallAction) -> Unit,
modifier: Modifier = Modifier,
) {
val packageState = rememberUpdatedPackageComponentState(style = style, paywallState = state)

if (!packageState.visible) return

StackComponentView(
style = style.stackComponentStyle,
state = state,
Expand Down
Loading