Skip to content

Commit

Permalink
[move] Paywalls: created LoadingPaywallView
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoSoto committed Sep 21, 2023
1 parent 07d5535 commit 38d82e9
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal fun InternalPaywallView(

when (val state = viewModel.state.collectAsState().value) {
is PaywallViewState.Loading -> {
Text(text = "Loading...")
LoadingPaywallView(mode = mode)
}
is PaywallViewState.Error -> {
Text(text = "Error: ${state.errorMessage}")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package com.revenuecat.purchases.ui.revenuecatui

import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.ViewModel
import com.revenuecat.purchases.Offering
import com.revenuecat.purchases.Package
import com.revenuecat.purchases.PackageType
import com.revenuecat.purchases.models.Period
import com.revenuecat.purchases.models.Price
import com.revenuecat.purchases.paywalls.PaywallData
import com.revenuecat.purchases.ui.revenuecatui.data.MockApplicationContext
import com.revenuecat.purchases.ui.revenuecatui.data.PaywallViewModel
import com.revenuecat.purchases.ui.revenuecatui.data.PaywallViewState
import com.revenuecat.purchases.ui.revenuecatui.data.TestStoreProduct
import com.revenuecat.purchases.ui.revenuecatui.data.processed.TemplateConfiguration
import com.revenuecat.purchases.ui.revenuecatui.data.processed.VariableDataProvider
import com.revenuecat.purchases.ui.revenuecatui.helpers.toAndroidContext
import com.revenuecat.purchases.ui.revenuecatui.helpers.toPaywallViewState
import com.revenuecat.purchases.ui.revenuecatui.templates.Template2
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import java.net.URL

@Composable
internal fun LoadingPaywallView(mode: PaywallViewMode) {
val provider = VariableDataProvider(LocalContext.current.applicationContext.toAndroidContext())
val offering = LoadingPaywallConstants.offering

Template2(
state = offering.toPaywallViewState(
provider,
LoadingPaywallConstants.paywallData!!,
mode
),
viewModel = LoadingViewModel(mode, offering)
)
}

private object LoadingPaywallConstants {
private const val offeringIdentifier = "loading_offering"

// TODO: use .createDefault()
val paywallData: PaywallData? = null

val offering = Offering(
identifier = this.offeringIdentifier,
serverDescription = "Loading paywall",
metadata = emptyMap(),
availablePackages = listOf(
Package(
identifier = "weekly",
packageType = PackageType.WEEKLY,
offering = this.offeringIdentifier,
product = TestStoreProduct(
id = "com.revenuecat.weekly",
title = "Weekly",
price = Price(formatted = "$1.99", currencyCode = "USD", amountMicros = 1_990_000),
description = "Weekly",
period = Period(value = 1, unit = Period.Unit.WEEK, iso8601 = "P1W"),
)
),
Package(
identifier = "monthly",
packageType = PackageType.MONTHLY,
offering = this.offeringIdentifier,
product = TestStoreProduct(
id = "com.revenuecat.monthly",
title = "Monthly",
price = Price(formatted = "$5.99", currencyCode = "USD", amountMicros = 5_990_000),
description = "Monthly",
period = Period(value = 1, unit = Period.Unit.MONTH, iso8601 = "P1M"),
)
),
Package(
identifier = "annual",
packageType = PackageType.ANNUAL,
offering = this.offeringIdentifier,
product = TestStoreProduct(
id = "com.revenuecat.annual",
title = "Annual",
price = Price(formatted = "$15.99", currencyCode = "USD", amountMicros = 5_990_000),
description = "Annual",
period = Period(value = 1, unit = Period.Unit.YEAR, iso8601 = "P1Y"),
)
),
),
paywall = paywallData
)
}

private class LoadingViewModel(
mode: PaywallViewMode = PaywallViewMode.default,
offering: Offering,
) : ViewModel(), PaywallViewModel {
override val state: StateFlow<PaywallViewState>
get() = _state.asStateFlow()
private val _state =
MutableStateFlow(offering.toPaywallViewState(VariableDataProvider(MockApplicationContext()), mode))

override fun refreshState() = Unit

override fun selectPackage(packageToSelect: TemplateConfiguration.PackageInfo) {
error("Not supported")
}

override fun purchaseSelectedPackage(context: Context) {
error("Can't purchase loading view model")
}

override fun restorePurchases() {
error("Can't restore purchases")
}

override fun openURL(url: URL, context: Context) {
error("Can't open URL")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.revenuecat.purchases.paywalls.PaywallColor
import com.revenuecat.purchases.paywalls.PaywallData
import com.revenuecat.purchases.ui.revenuecatui.PaywallViewMode
import com.revenuecat.purchases.ui.revenuecatui.R
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
import com.revenuecat.purchases.ui.revenuecatui.helpers.ApplicationContext
Expand All @@ -27,7 +28,7 @@ import java.net.URL

internal object TestData {
val template1 = PaywallData(
templateName = "1", // TODO-PAYWALLS: use enum
templateName = PaywallTemplate.TEMPLATE_1.id,
config = PaywallData.Configuration(
packages = listOf(
PackageType.MONTHLY.identifier!!,
Expand Down Expand Up @@ -68,7 +69,7 @@ internal object TestData {
assetBaseURL = Constants.assetBaseURL,
)
val template2 = PaywallData(
templateName = "2", // TODO-PAYWALLS: use enum
templateName = PaywallTemplate.TEMPLATE_2.id,
config = PaywallData.Configuration(
packages = listOf(
PackageType.WEEKLY.identifier!!,
Expand Down Expand Up @@ -246,8 +247,8 @@ internal class MockApplicationContext : ApplicationContext {
}

internal class MockViewModel(
private val mode: PaywallViewMode = PaywallViewMode.default,
private val offering: Offering,
mode: PaywallViewMode = PaywallViewMode.default,
offering: Offering,
) : ViewModel(), PaywallViewModel {
override val state: StateFlow<PaywallViewState>
get() = _state.asStateFlow()
Expand Down Expand Up @@ -283,7 +284,7 @@ private object Constants {
val assetBaseURL = URL("https://assets.pawwalls.com")
}

private data class TestStoreProduct(
internal data class TestStoreProduct(
override val id: String,
override val title: String,
override val price: Price,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.revenuecat.purchases.ui.revenuecatui.helpers

import com.revenuecat.purchases.Offering
import com.revenuecat.purchases.paywalls.PaywallData
import com.revenuecat.purchases.ui.revenuecatui.PaywallViewMode
import com.revenuecat.purchases.ui.revenuecatui.data.PaywallViewState
import com.revenuecat.purchases.ui.revenuecatui.data.processed.TemplateConfiguration
import com.revenuecat.purchases.ui.revenuecatui.data.processed.TemplateConfigurationFactory
import com.revenuecat.purchases.ui.revenuecatui.data.processed.VariableDataProvider

Expand All @@ -14,19 +14,25 @@ internal fun Offering.toPaywallViewState(
): PaywallViewState {
val paywallData = this.paywall
?: return PaywallViewState.Error("No paywall data for offering: $identifier")
return try {
val templateConfiguration = TemplateConfigurationFactory.create(
variableDataProvider = variableDataProvider,
mode = mode,
paywallData = paywallData,
packages = availablePackages,
activelySubscribedProductIdentifiers = emptySet(), // TODO-PAYWALLS: Check for active subscriptions
)
PaywallViewState.Loaded(
templateConfiguration = templateConfiguration,
selectedPackage = templateConfiguration.packages.default,
)
} catch (e: Exception) {
PaywallViewState.Error("Error creating paywall: ${e.message}")
}

return toPaywallViewState(variableDataProvider, paywallData, mode)
}

internal fun Offering.toPaywallViewState(
variableDataProvider: VariableDataProvider,
paywallData: PaywallData,
mode: PaywallViewMode,
): PaywallViewState.Loaded {
val templateConfiguration = TemplateConfigurationFactory.create(
variableDataProvider = variableDataProvider,
mode = mode,
paywallData = paywallData,
packages = availablePackages,
activelySubscribedProductIdentifiers = emptySet(), // TODO-PAYWALLS: Check for active subscriptions
)

return PaywallViewState.Loaded(
templateConfiguration = templateConfiguration,
selectedPackage = templateConfiguration.packages.default,
)
}

0 comments on commit 38d82e9

Please sign in to comment.