Skip to content

Commit

Permalink
[Paywalls V2] Adds PaywallState.Loaded.Components (#1969)
Browse files Browse the repository at this point in the history
  • Loading branch information
JayShortway authored Dec 10, 2024
1 parent b793940 commit 9bf19f5
Show file tree
Hide file tree
Showing 18 changed files with 113 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ internal fun InternalPaywall(
}

AnimatedVisibility(
visible = state is PaywallState.Loaded,
visible = state is PaywallState.Loaded.Legacy,
enter = fadeIn(animationSpec = defaultAnimation()),
exit = fadeOut(animationSpec = defaultAnimation()),
) {
if (state is PaywallState.Loaded) {
if (state is PaywallState.Loaded.Legacy) {
LoadedPaywall(state = state, viewModel = viewModel)
} else {
Logger.e(
Expand Down Expand Up @@ -117,7 +117,7 @@ internal fun InternalPaywall(
}

@Composable
private fun LoadedPaywall(state: PaywallState.Loaded, viewModel: PaywallViewModel) {
private fun LoadedPaywall(state: PaywallState.Loaded.Legacy, viewModel: PaywallViewModel) {
viewModel.trackPaywallImpressionIfNeeded()
val backgroundColor = state.templateConfiguration.getCurrentColors().background
Box(
Expand Down Expand Up @@ -157,7 +157,7 @@ private fun LoadedPaywall(state: PaywallState.Loaded, viewModel: PaywallViewMode
}

@Composable
private fun TemplatePaywall(state: PaywallState.Loaded, viewModel: PaywallViewModel) {
private fun TemplatePaywall(state: PaywallState.Loaded.Legacy, viewModel: PaywallViewModel) {
when (state.templateConfiguration.template) {
PaywallTemplate.TEMPLATE_1 -> Template1(state = state, viewModel = viewModel)
PaywallTemplate.TEMPLATE_2 -> Template2(state = state, viewModel = viewModel)
Expand Down Expand Up @@ -191,7 +191,7 @@ internal fun getPaywallViewModel(

@ReadOnlyComposable
@Composable
private fun PaywallState.Loaded.contextWithConfiguration(configuration: Configuration): Context {
private fun PaywallState.Loaded.Legacy.contextWithConfiguration(configuration: Configuration): Context {
val context = LocalContext.current

// Context.createConfigurationContext returns `null` with Paparazzi
Expand All @@ -200,7 +200,7 @@ private fun PaywallState.Loaded.contextWithConfiguration(configuration: Configur

@ReadOnlyComposable
@Composable
private fun PaywallState.Loaded.configurationWithOverriddenLocale(): Configuration {
private fun PaywallState.Loaded.Legacy.configurationWithOverriddenLocale(): Configuration {
val configuration = Configuration(LocalConfiguration.current)
configuration.setLocale(templateConfiguration.locale)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,16 @@ internal fun LoadingPaywall(
// and snapshots ensure that these 2 states are impossible.
is PaywallState.Error,
is PaywallState.Loading,
is PaywallState.Loaded.Components,
-> Box {}

is PaywallState.Loaded -> LoadingPaywall(state, LoadingViewModel(state, resourceProvider), onDismiss)
is PaywallState.Loaded.Legacy -> LoadingPaywall(state, LoadingViewModel(state, resourceProvider), onDismiss)
}
}

@Composable
private fun LoadingPaywall(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
viewModel: PaywallViewModel,
onDismiss: () -> Unit,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import com.revenuecat.purchases.ui.revenuecatui.data.processed.TemplateConfigura

@Composable
internal fun ConsistentPackageContentView(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
creator: @Composable (TemplateConfiguration.PackageInfo) -> Unit,
) {
ConsistentPackageContentView(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import com.revenuecat.purchases.ui.revenuecatui.extensions.introEligibility
*/
@Composable
internal fun OfferDetails(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
colors: TemplateConfiguration.Colors = state.templateConfiguration.getCurrentColors(),
) {
OfferDetails(state = state, color = colors.text1)
Expand All @@ -33,7 +33,7 @@ internal fun OfferDetails(
*/
@Composable
internal fun OfferDetails(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
color: Color,
) {
Box(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import com.revenuecat.purchases.ui.revenuecatui.helpers.TestTag

@Composable
internal fun PurchaseButton(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
viewModel: PaywallViewModel,
childModifier: Modifier = Modifier,
horizontalPadding: Dp = UIConstant.defaultHorizontalPadding,
Expand Down Expand Up @@ -199,7 +199,7 @@ private fun BoxScope.LoadingSpinner(shouldShow: Boolean, colors: TemplateConfigu
@Composable
private fun PurchaseButtonPreview() {
val viewModel = MockViewModel(offering = TestData.template2Offering, allowsPurchases = true)
val state = viewModel.loadedState()
val state = viewModel.loadedLegacyState()

if (state != null) {
PurchaseButton(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,54 +10,67 @@ import com.revenuecat.purchases.ui.revenuecatui.data.processed.TemplateConfigura
import com.revenuecat.purchases.ui.revenuecatui.helpers.Logger
import com.revenuecat.purchases.ui.revenuecatui.isFullScreen

internal sealed class PaywallState {
object Loading : PaywallState()
internal sealed interface PaywallState {
object Loading : PaywallState

data class Error(val errorMessage: String) : PaywallState() {
data class Error(val errorMessage: String) : PaywallState {
init {
Logger.e("Paywall transitioned to error state: $errorMessage")
}
}

data class Loaded(
val offering: Offering,
val templateConfiguration: TemplateConfiguration,
val selectedPackage: MutableState<TemplateConfiguration.PackageInfo>,
val shouldDisplayDismissButton: Boolean,
) : PaywallState() {
constructor(
offering: Offering,
templateConfiguration: TemplateConfiguration,
selectedPackage: TemplateConfiguration.PackageInfo,
shouldDisplayDismissButton: Boolean,
) :
this(
offering,
templateConfiguration,
mutableStateOf(selectedPackage),
shouldDisplayDismissButton,
)

fun selectPackage(packageInfo: TemplateConfiguration.PackageInfo) {
selectedPackage.value = packageInfo
sealed interface Loaded : PaywallState {
val offering: Offering

data class Legacy(
override val offering: Offering,
val templateConfiguration: TemplateConfiguration,
val selectedPackage: MutableState<TemplateConfiguration.PackageInfo>,
val shouldDisplayDismissButton: Boolean,
) : Loaded {

constructor(
offering: Offering,
templateConfiguration: TemplateConfiguration,
selectedPackage: TemplateConfiguration.PackageInfo,
shouldDisplayDismissButton: Boolean,
) :
this(
offering,
templateConfiguration,
mutableStateOf(selectedPackage),
shouldDisplayDismissButton,
)

fun selectPackage(packageInfo: TemplateConfiguration.PackageInfo) {
selectedPackage.value = packageInfo
}
}

data class Components(
override val offering: Offering,
// TODO val data: PaywallComponentsData,
) : Loaded
}
}

internal fun PaywallState.loaded(): PaywallState.Loaded? {
internal fun PaywallState.loadedLegacy(): PaywallState.Loaded.Legacy? {
return when (val state = this) {
is PaywallState.Error -> null
is PaywallState.Loaded -> state
is PaywallState.Loaded -> when (state) {
is PaywallState.Loaded.Legacy -> state
is PaywallState.Loaded.Components -> null
}
is PaywallState.Loading -> null
}
}

internal val PaywallState.Loaded.selectedLocalization: ProcessedLocalizedConfiguration
internal val PaywallState.Loaded.Legacy.selectedLocalization: ProcessedLocalizedConfiguration
get() = selectedPackage.value.localization

internal val PaywallState.Loaded.currentColors: TemplateConfiguration.Colors
internal val PaywallState.Loaded.Legacy.currentColors: TemplateConfiguration.Colors
@Composable @ReadOnlyComposable
get() = templateConfiguration.getCurrentColors()

internal val PaywallState.Loaded.isInFullScreenMode: Boolean
internal val PaywallState.Loaded.Legacy.isInFullScreenMode: Boolean
get() = templateConfiguration.mode.isFullScreen
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ internal class PaywallViewModelImpl(

override fun selectPackage(packageToSelect: TemplateConfiguration.PackageInfo) {
when (val currentState = _state.value) {
is PaywallState.Loaded -> {
is PaywallState.Loaded.Legacy -> {
currentState.selectPackage(packageToSelect)
}

Expand Down Expand Up @@ -248,7 +248,7 @@ internal class PaywallViewModelImpl(

private suspend fun handlePackagePurchase(activity: Activity) {
when (val currentState = _state.value) {
is PaywallState.Loaded -> {
is PaywallState.Loaded.Legacy -> {
val selectedPackage = currentState.selectedPackage.value
if (!selectedPackage.currentlySubscribed) {
performPurchase(activity, selectedPackage.rcPackage)
Expand Down Expand Up @@ -441,7 +441,7 @@ internal class PaywallViewModelImpl(
@Suppress("ReturnCount")
private fun createEventData(): PaywallEvent.Data? {
val currentState = state.value
if (currentState !is PaywallState.Loaded) {
if (currentState !is PaywallState.Loaded.Legacy) {
Logger.e("Unexpected state trying to create event data: $currentState")
return null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import com.revenuecat.purchases.ui.revenuecatui.PaywallMode
import com.revenuecat.purchases.ui.revenuecatui.R
import com.revenuecat.purchases.ui.revenuecatui.data.PaywallState
import com.revenuecat.purchases.ui.revenuecatui.data.PaywallViewModel
import com.revenuecat.purchases.ui.revenuecatui.data.loaded
import com.revenuecat.purchases.ui.revenuecatui.data.loadedLegacy
import com.revenuecat.purchases.ui.revenuecatui.data.processed.PaywallTemplate
import com.revenuecat.purchases.ui.revenuecatui.data.processed.TemplateConfiguration
import com.revenuecat.purchases.ui.revenuecatui.data.processed.VariableDataProvider
Expand Down Expand Up @@ -436,8 +436,8 @@ internal class MockViewModel(
override val actionError: State<PurchasesError?>
get() = _actionError

fun loadedState(): PaywallState.Loaded? {
return state.value.loaded()
fun loadedLegacyState(): PaywallState.Loaded.Legacy? {
return state.value.loadedLegacy()
}

private val _state = MutableStateFlow(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal fun PaywallViewModel.packageButtonActionInProgressOpacityAnimation(): F
}

@Composable
internal fun PaywallState.Loaded.packageButtonColorAnimation(
internal fun PaywallState.Loaded.Legacy.packageButtonColorAnimation(
packageInfo: TemplateConfiguration.PackageInfo,
selectedColor: Color,
unselectedColor: Color,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ internal fun Offering.toPaywallState(
return PaywallState.Error(it.message ?: "Unknown error")
}

return PaywallState.Loaded(
return PaywallState.Loaded.Legacy(
offering = this,
templateConfiguration = templateConfiguration,
selectedPackage = templateConfiguration.packages.default,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal fun hasCompactDimension(): Boolean {

@Composable
@ReadOnlyComposable
internal fun PaywallState.Loaded.shouldUseLandscapeLayout(): Boolean {
internal fun PaywallState.Loaded.Legacy.shouldUseLandscapeLayout(): Boolean {
return shouldUseLandscapeLayout(mode = templateConfiguration.mode)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import com.revenuecat.purchases.ui.revenuecatui.extensions.conditional
import com.revenuecat.purchases.ui.revenuecatui.helpers.shouldUseLandscapeLayout

@Composable
internal fun Template1(state: PaywallState.Loaded, viewModel: PaywallViewModel) {
internal fun Template1(state: PaywallState.Loaded.Legacy, viewModel: PaywallViewModel) {
Column(
modifier = Modifier
.fillMaxWidth(),
Expand All @@ -72,7 +72,7 @@ internal fun Template1(state: PaywallState.Loaded, viewModel: PaywallViewModel)

@SuppressWarnings("LongMethod")
@Composable
private fun ColumnScope.Template1MainContent(state: PaywallState.Loaded) {
private fun ColumnScope.Template1MainContent(state: PaywallState.Loaded.Legacy) {
val localizedConfig = state.selectedLocalization
val colors = state.currentColors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private object Template2UIConstants {
*/
@Composable
internal fun Template2(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
viewModel: PaywallViewModel,
childModifier: Modifier = Modifier,
) {
Expand Down Expand Up @@ -132,7 +132,7 @@ internal fun Template2(
@Suppress("LongMethod")
@Composable
private fun ColumnScope.Template2PortraitContent(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
viewModel: PaywallViewModel,
packageSelectionVisible: Boolean,
childModifier: Modifier,
Expand Down Expand Up @@ -182,7 +182,7 @@ private fun ColumnScope.Template2PortraitContent(
@Suppress("LongMethod")
@Composable
private fun ColumnScope.Template2LandscapeContent(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
viewModel: PaywallViewModel,
packageSelectionVisible: Boolean,
childModifier: Modifier,
Expand Down Expand Up @@ -245,7 +245,7 @@ private fun ColumnScope.Template2LandscapeContent(

@Composable
private fun IconImage(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
childModifier: Modifier,
) {
IconImage(
Expand All @@ -258,7 +258,7 @@ private fun IconImage(

@Composable
private fun Title(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
childModifier: Modifier,
textAlign: TextAlign = TextAlign.Center,
) {
Expand All @@ -275,7 +275,7 @@ private fun Title(

@Composable
private fun Subtitle(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
childModifier: Modifier,
textAlign: TextAlign = TextAlign.Center,
) {
Expand All @@ -292,7 +292,7 @@ private fun Subtitle(

@Composable
private fun AnimatedPackages(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
packageSelectionVisible: Boolean,
landscapeLayout: Boolean,
viewModel: PaywallViewModel,
Expand Down Expand Up @@ -340,7 +340,7 @@ private fun AnimatedPackages(
@SuppressWarnings("LongMethod")
@Composable
private fun ColumnScope.SelectPackageButton(
state: PaywallState.Loaded,
state: PaywallState.Loaded.Legacy,
packageInfo: TemplateConfiguration.PackageInfo,
viewModel: PaywallViewModel,
childModifier: Modifier,
Expand Down
Loading

0 comments on commit 9bf19f5

Please sign in to comment.