Skip to content

Commit d53c047

Browse files
committed
Add paywall-tester sample for web_view manual QA.
Uses example.com as placeholder content until the real bundle URL is available.
1 parent 38a6f6f commit d53c047

3 files changed

Lines changed: 182 additions & 9 deletions

File tree

examples/paywall-tester/src/main/java/com/revenuecat/paywallstester/SamplePaywalls.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.compose.ui.graphics.Color
66
import androidx.compose.ui.graphics.toArgb
77
import com.revenuecat.paywallstester.paywalls.tabsWithButtons
88
import com.revenuecat.paywallstester.paywalls.tabsWithToggle
9+
import com.revenuecat.paywallstester.paywalls.webViewSample
910
import com.revenuecat.purchases.FontAlias
1011
import com.revenuecat.purchases.InternalRevenueCatAPI
1112
import com.revenuecat.purchases.Offering
@@ -101,6 +102,7 @@ class SamplePaywallsLoader {
101102

102103
SamplePaywalls.SampleTemplate.TABS_BUTTONS -> tabsWithButtons()
103104
SamplePaywalls.SampleTemplate.TABS_TOGGLE -> tabsWithToggle()
105+
SamplePaywalls.SampleTemplate.COMPONENTS_WEB_VIEW -> webViewSample()
104106
SamplePaywalls.SampleTemplate.UNRECOGNIZED_TEMPLATE -> SamplePaywalls.unrecognizedTemplate()
105107
}
106108
}
@@ -128,6 +130,7 @@ object SamplePaywalls {
128130
COMPONENTS_BLESS_GOOGLE_FONT("#11: Components - bless. - Google font"),
129131
TABS_BUTTONS("#12: Tabs - buttons"),
130132
TABS_TOGGLE("#13 Tabs - toggle"),
133+
COMPONENTS_WEB_VIEW("#14: Components - web_view"),
131134
UNRECOGNIZED_TEMPLATE("Default template"),
132135
}
133136

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package com.revenuecat.paywallstester.paywalls
2+
3+
import androidx.compose.ui.graphics.Color
4+
import androidx.compose.ui.graphics.toArgb
5+
import com.revenuecat.paywallstester.SampleData
6+
import com.revenuecat.purchases.InternalRevenueCatAPI
7+
import com.revenuecat.purchases.paywalls.components.ButtonComponent
8+
import com.revenuecat.purchases.paywalls.components.StackComponent
9+
import com.revenuecat.purchases.paywalls.components.TextComponent
10+
import com.revenuecat.purchases.paywalls.components.WebViewComponent
11+
import com.revenuecat.purchases.paywalls.components.common.Background
12+
import com.revenuecat.purchases.paywalls.components.common.ComponentsConfig
13+
import com.revenuecat.purchases.paywalls.components.common.LocaleId
14+
import com.revenuecat.purchases.paywalls.components.common.LocalizationData
15+
import com.revenuecat.purchases.paywalls.components.common.LocalizationKey
16+
import com.revenuecat.purchases.paywalls.components.common.PaywallComponentsConfig
17+
import com.revenuecat.purchases.paywalls.components.common.PaywallComponentsData
18+
import com.revenuecat.purchases.paywalls.components.properties.ColorInfo
19+
import com.revenuecat.purchases.paywalls.components.properties.ColorScheme
20+
import com.revenuecat.purchases.paywalls.components.properties.Dimension.Vertical
21+
import com.revenuecat.purchases.paywalls.components.properties.Dimension.ZLayer
22+
import com.revenuecat.purchases.paywalls.components.properties.FlexDistribution.END
23+
import com.revenuecat.purchases.paywalls.components.properties.FontWeight
24+
import com.revenuecat.purchases.paywalls.components.properties.HorizontalAlignment.LEADING
25+
import com.revenuecat.purchases.paywalls.components.properties.Padding
26+
import com.revenuecat.purchases.paywalls.components.properties.Shape
27+
import com.revenuecat.purchases.paywalls.components.properties.Size
28+
import com.revenuecat.purchases.paywalls.components.properties.SizeConstraint.Fill
29+
import com.revenuecat.purchases.paywalls.components.properties.SizeConstraint.Fixed
30+
import com.revenuecat.purchases.paywalls.components.properties.SizeConstraint.Fit
31+
import com.revenuecat.purchases.paywalls.components.properties.TwoDimensionalAlignment
32+
import java.net.URL
33+
34+
private const val PLACEHOLDER_WEB_VIEW_URL = "https://example.com"
35+
36+
@OptIn(InternalRevenueCatAPI::class)
37+
internal fun webViewSample(): SampleData.Components {
38+
val textColor = ColorScheme(
39+
light = ColorInfo.Hex(Color.Black.toArgb()),
40+
dark = ColorInfo.Hex(Color.White.toArgb()),
41+
)
42+
val backgroundColor = ColorScheme(
43+
light = ColorInfo.Hex(Color.White.toArgb()),
44+
dark = ColorInfo.Hex(Color.Black.toArgb()),
45+
)
46+
val accentColor = ColorScheme(
47+
light = ColorInfo.Hex(Color(red = 5, green = 124, blue = 91).toArgb()),
48+
)
49+
50+
return SampleData.Components(
51+
data = PaywallComponentsData(
52+
id = "sample_web_view_paywall_id",
53+
templateName = "template",
54+
assetBaseURL = URL("https://assets.pawwalls.com"),
55+
componentsConfig = ComponentsConfig(
56+
base = PaywallComponentsConfig(
57+
stack = StackComponent(
58+
components = listOf(
59+
TextComponent(
60+
text = LocalizationKey("title"),
61+
color = textColor,
62+
fontWeight = FontWeight.BOLD,
63+
fontSize = 24,
64+
horizontalAlignment = LEADING,
65+
size = Size(width = Fill, height = Fit),
66+
margin = Padding(top = 16.0, bottom = 8.0, leading = 16.0, trailing = 16.0),
67+
),
68+
WebViewComponent(
69+
id = "sample_web_view",
70+
url = PLACEHOLDER_WEB_VIEW_URL,
71+
size = Size(width = Fill, height = Fixed(400u)),
72+
fallback = StackComponent(
73+
components = listOf(
74+
TextComponent(
75+
text = LocalizationKey("fallback"),
76+
color = textColor,
77+
horizontalAlignment = LEADING,
78+
size = Size(width = Fill, height = Fit),
79+
padding = Padding(
80+
top = 16.0,
81+
bottom = 16.0,
82+
leading = 16.0,
83+
trailing = 16.0,
84+
),
85+
),
86+
),
87+
dimension = ZLayer(alignment = TwoDimensionalAlignment.CENTER),
88+
size = Size(width = Fill, height = Fixed(400u)),
89+
),
90+
),
91+
ButtonComponent(
92+
action = ButtonComponent.Action.RestorePurchases,
93+
stack = StackComponent(
94+
components = listOf(
95+
TextComponent(
96+
text = LocalizationKey("cta"),
97+
color = ColorScheme(light = ColorInfo.Hex(Color.White.toArgb())),
98+
fontWeight = FontWeight.BOLD,
99+
),
100+
),
101+
dimension = ZLayer(alignment = TwoDimensionalAlignment.CENTER),
102+
size = Size(width = Fit, height = Fit),
103+
backgroundColor = accentColor,
104+
padding = Padding(
105+
top = 8.0,
106+
bottom = 8.0,
107+
leading = 32.0,
108+
trailing = 32.0,
109+
),
110+
margin = Padding(top = 16.0, bottom = 16.0, leading = 16.0, trailing = 16.0),
111+
shape = Shape.Pill,
112+
),
113+
),
114+
),
115+
dimension = Vertical(alignment = LEADING, distribution = END),
116+
size = Size(width = Fill, height = Fill),
117+
backgroundColor = backgroundColor,
118+
),
119+
background = Background.Color(backgroundColor),
120+
stickyFooter = null,
121+
),
122+
),
123+
componentsLocalizations = mapOf(
124+
LocaleId("en_US") to mapOf(
125+
LocalizationKey("title") to LocalizationData.Text("Web view placeholder"),
126+
LocalizationKey("fallback") to LocalizationData.Text("Could not load the web view."),
127+
LocalizationKey("cta") to LocalizationData.Text("Restore purchases"),
128+
),
129+
),
130+
defaultLocaleIdentifier = LocaleId("en_US"),
131+
),
132+
)
133+
}

examples/paywall-tester/src/main/java/com/revenuecat/paywallstester/ui/screens/main/paywalls/PaywallsScreen.kt

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import com.revenuecat.paywallstester.SamplePaywalls
3636
import com.revenuecat.paywallstester.SamplePaywallsLoader
3737
import com.revenuecat.paywallstester.ui.screens.main.customvariables.CustomVariablesHolder
3838
import com.revenuecat.paywallstester.ui.screens.paywallfooter.SamplePaywall
39+
import com.revenuecat.purchases.ui.revenuecatui.Paywall
40+
import com.revenuecat.purchases.ui.revenuecatui.PaywallWebViewMessageHandler
3941
import com.revenuecat.paywallstester.ui.theme.bundledLobsterTwoFontFamily
4042
import com.revenuecat.purchases.CustomerInfo
4143
import com.revenuecat.purchases.InternalRevenueCatAPI
@@ -53,6 +55,8 @@ import com.revenuecat.purchases.ui.revenuecatui.PurchaseLogicWithCallback
5355
import com.revenuecat.purchases.ui.revenuecatui.fonts.CustomFontProvider
5456
import com.revenuecat.purchases.ui.revenuecatui.fonts.FontProvider
5557

58+
private const val TAG = "PaywallTester"
59+
5660
private class TestAppPurchaseLogicSuspend : PurchaseLogic {
5761

5862
companion object {
@@ -127,6 +131,16 @@ fun PaywallsScreen(
127131
}
128132
}
129133

134+
val webViewMessageHandler = remember {
135+
PaywallWebViewMessageHandler { message, _ ->
136+
Log.d(
137+
TAG,
138+
"web_view message: type=${message.type} componentId=${message.componentId} " +
139+
"error=${message.error}",
140+
)
141+
}
142+
}
143+
130144
LazyColumn(
131145
modifier = modifier.testTag("paywall_screen"),
132146
) {
@@ -144,6 +158,11 @@ fun PaywallsScreen(
144158
displayPaywallState = DisplayPaywallState.FullScreen(
145159
offering,
146160
purchaseLogic = myAppPurchaseLogic,
161+
webViewMessageHandler = if (template == SamplePaywalls.SampleTemplate.COMPONENTS_WEB_VIEW) {
162+
webViewMessageHandler
163+
} else {
164+
null
165+
},
147166
)
148167
},
149168
emoji = "\uD83D\uDCF1",
@@ -207,15 +226,32 @@ fun PaywallsScreen(
207226

208227
@Composable
209228
private fun FullScreenDialog(currentState: DisplayPaywallState.FullScreen, onDismiss: () -> Unit) {
210-
PaywallDialog(
211-
PaywallDialogOptions.Builder()
212-
.setDismissRequest(onDismiss)
213-
.setOffering(currentState.offering)
214-
.setFontProvider(currentState.fontProvider)
215-
.setCustomVariables(CustomVariablesHolder.customVariables)
216-
.setCustomPurchaseLogic(currentState.purchaseLogic)
217-
.build(),
218-
)
229+
val paywallOptions = PaywallOptions.Builder(onDismiss)
230+
.setOffering(currentState.offering)
231+
.setFontProvider(currentState.fontProvider)
232+
.setCustomVariables(CustomVariablesHolder.customVariables)
233+
.setPurchaseLogic(currentState.purchaseLogic)
234+
.setWebViewMessageHandler(currentState.webViewMessageHandler)
235+
.build()
236+
237+
if (currentState.webViewMessageHandler != null) {
238+
Dialog(
239+
onDismissRequest = onDismiss,
240+
properties = DialogProperties(usePlatformDefaultWidth = false),
241+
) {
242+
Paywall(paywallOptions)
243+
}
244+
} else {
245+
PaywallDialog(
246+
PaywallDialogOptions.Builder()
247+
.setDismissRequest(onDismiss)
248+
.setOffering(currentState.offering)
249+
.setFontProvider(currentState.fontProvider)
250+
.setCustomVariables(CustomVariablesHolder.customVariables)
251+
.setCustomPurchaseLogic(currentState.purchaseLogic)
252+
.build(),
253+
)
254+
}
219255
}
220256

221257
@Composable
@@ -251,6 +287,7 @@ private sealed class DisplayPaywallState {
251287
val offering: Offering? = null,
252288
val fontProvider: FontProvider? = null,
253289
var purchaseLogic: PurchaseLogic? = null,
290+
val webViewMessageHandler: PaywallWebViewMessageHandler? = null,
254291
) : DisplayPaywallState()
255292

256293
data class Footer(

0 commit comments

Comments
 (0)