Skip to content

Commit

Permalink
Paywalls: Update paywall tester to be able to display paywall footer (#…
Browse files Browse the repository at this point in the history
…1315)

### Description
Followup to #1314 in order to be able to use the new `PaywallFooter` in
the paywalls tester app
  • Loading branch information
tonidero authored Oct 6, 2023
1 parent 4b105c8 commit 58c3502
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.revenuecat.paywallstester.ui.screens.AppScreen
import com.revenuecat.paywallstester.ui.screens.main.MainScreen
import com.revenuecat.paywallstester.ui.screens.paywall.PaywallScreen
import com.revenuecat.paywallstester.ui.screens.paywall.PaywallScreenViewModel
import com.revenuecat.paywallstester.ui.screens.paywallfooter.PaywallFooterScreen

@Composable
fun PaywallTesterApp(
Expand All @@ -31,15 +32,26 @@ private fun AppNavHost(
modifier = modifier,
) {
composable(AppScreen.Main.route) {
MainScreen(navigateToPaywallScreen = { offering ->
navController.navigate(AppScreen.Paywall.route.plus("/${offering?.identifier}"))
})
MainScreen(
navigateToPaywallScreen = { offering ->
navController.navigate(AppScreen.Paywall.route.plus("/${offering?.identifier}"))
},
navigateToPaywallFooterScreen = { offering ->
navController.navigate(AppScreen.PaywallFooter.route.plus("/${offering?.identifier}"))
},
)
}
composable(
route = AppScreen.Paywall.route.plus("/{${PaywallScreenViewModel.OFFERING_ID_KEY}}"),
arguments = listOf(navArgument(PaywallScreenViewModel.OFFERING_ID_KEY) { type = NavType.StringType }),
) {
PaywallScreen()
}
composable(
route = AppScreen.PaywallFooter.route.plus("/{${PaywallScreenViewModel.OFFERING_ID_KEY}}"),
arguments = listOf(navArgument(PaywallScreenViewModel.OFFERING_ID_KEY) { type = NavType.StringType }),
) {
PaywallFooterScreen()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ package com.revenuecat.paywallstester.ui.screens
sealed class AppScreen(val route: String) {
object Main : AppScreen("main")
object Paywall : AppScreen("paywall")
object PaywallFooter : AppScreen("paywall_footer")
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,20 @@ import com.revenuecat.purchases.Offering
@Composable
fun MainScreen(
navigateToPaywallScreen: (Offering?) -> Unit,
navigateToPaywallFooterScreen: (Offering?) -> Unit,
navController: NavHostController = rememberNavController(),
) {
Scaffold(
bottomBar = { BottomBarNavigation(navController) },
) {
MainNavHost(navController, navigateToPaywallScreen, Modifier.padding(it))
MainNavHost(navController, navigateToPaywallScreen, navigateToPaywallFooterScreen, Modifier.padding(it))
}
}

@Preview
@Composable
fun MainScreenPreview() {
MainScreen(navigateToPaywallScreen = {})
MainScreen(navigateToPaywallScreen = {}, navigateToPaywallFooterScreen = {})
}

private val bottomNavigationItems = listOf(
Expand All @@ -50,6 +51,7 @@ private val bottomNavigationItems = listOf(
private fun MainNavHost(
navController: NavHostController,
navigateToPaywallScreen: (Offering?) -> Unit,
navigateToPaywallFooterScreen: (Offering?) -> Unit,
modifier: Modifier = Modifier,
) {
NavHost(
Expand All @@ -64,7 +66,10 @@ private fun MainNavHost(
PaywallsScreen()
}
composable(Tab.Offerings.route) {
OfferingsScreen(tappedOnOffering = { offering -> navigateToPaywallScreen(offering) })
OfferingsScreen(
tappedOnOffering = { offering -> navigateToPaywallScreen(offering) },
tappedOnOfferingFooter = { offering -> navigateToPaywallFooterScreen(offering) },
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ import kotlinx.coroutines.flow.asStateFlow
@Composable
fun OfferingsScreen(
tappedOnOffering: (Offering) -> Unit,
tappedOnOfferingFooter: (Offering) -> Unit,
viewModel: OfferingsViewModel = viewModel<OfferingsViewModelImpl>(),
) {
when (val state = viewModel.offeringsState.collectAsState().value) {
is OfferingsState.Error -> ErrorOfferingsScreen(errorState = state)
is OfferingsState.Loaded -> OfferingsListScreen(
offeringsState = state,
tappedOnNavigateToOffering = tappedOnOffering,
tappedOnNavigateToOfferingFooter = tappedOnOfferingFooter,
)
OfferingsState.Loading -> LoadingOfferingsScreen()
}
Expand Down Expand Up @@ -74,6 +76,7 @@ private fun LoadingOfferingsScreen() {
private fun OfferingsListScreen(
offeringsState: OfferingsState.Loaded,
tappedOnNavigateToOffering: (Offering) -> Unit,
tappedOnNavigateToOfferingFooter: (Offering) -> Unit,
) {
var dropdownExpandedOffering by remember { mutableStateOf<Offering?>(null) }
var displayPaywallDialogOffering by remember { mutableStateOf<Offering?>(null) }
Expand All @@ -86,6 +89,7 @@ private fun OfferingsListScreen(
offering = offering,
tappedOnNavigateToOffering = tappedOnNavigateToOffering,
tappedOnDisplayOfferingAsDialog = { displayPaywallDialogOffering = it },
tappedOnDisplayOfferingAsFooter = tappedOnNavigateToOfferingFooter,
dismissed = { dropdownExpandedOffering = null },
)
}
Expand Down Expand Up @@ -127,6 +131,7 @@ private fun DisplayOfferingMenu(
offering: Offering,
tappedOnNavigateToOffering: (Offering) -> Unit,
tappedOnDisplayOfferingAsDialog: (Offering) -> Unit,
tappedOnDisplayOfferingAsFooter: (Offering) -> Unit,
dismissed: () -> Unit,
) {
DropdownMenu(expanded = true, onDismissRequest = { dismissed() }) {
Expand All @@ -138,6 +143,10 @@ private fun DisplayOfferingMenu(
text = { Text(text = "Display paywall as dialog") },
onClick = { tappedOnDisplayOfferingAsDialog(offering) },
)
DropdownMenuItem(
text = { Text(text = "Display paywall as footer") },
onClick = { tappedOnDisplayOfferingAsFooter(offering) },
)
}
}

Expand All @@ -146,6 +155,7 @@ private fun DisplayOfferingMenu(
fun OfferingsScreenPreview() {
OfferingsScreen(
tappedOnOffering = {},
tappedOnOfferingFooter = {},
viewModel = object : OfferingsViewModel() {
private val _offeringsState = MutableStateFlow<OfferingsState>(
OfferingsState.Loaded(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.revenuecat.paywallstester.ui.screens.paywallfooter

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.AlertDialog
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.lifecycle.viewmodel.compose.viewModel
import com.revenuecat.paywallstester.ui.screens.paywall.PaywallScreenState
import com.revenuecat.paywallstester.ui.screens.paywall.PaywallScreenViewModel
import com.revenuecat.paywallstester.ui.screens.paywall.PaywallScreenViewModelImpl
import com.revenuecat.purchases.ui.revenuecatui.PaywallFooter
import com.revenuecat.purchases.ui.revenuecatui.PaywallViewOptions

@Composable
fun PaywallFooterScreen(
viewModel: PaywallScreenViewModel = viewModel<PaywallScreenViewModelImpl>(),
) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
when (val state = viewModel.state.collectAsState().value) {
is PaywallScreenState.Loading -> {
Text(text = "Loading...")
}
is PaywallScreenState.Error -> {
Text(text = "Error: ${state.errorMessage}")
}
is PaywallScreenState.Loaded -> {
PaywallFooter(
options = PaywallViewOptions.Builder()
.setOffering(state.offering)
.setListener(viewModel)
.build(),
) {
SamplePaywall(paddingValues = it)
}
state.dialogText?.let {
PurchaseAlertDialog(viewModel, it)
}
}
}
}
}

@Suppress("MagicNumber")
@Composable
private fun SamplePaywall(paddingValues: PaddingValues) {
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
.padding(paddingValues),
) {
// TODO-Paywalls: Implement an actual sample paywall
for (i in 1..50) {
Text(text = "Main content $i")
}
}
}

@Composable
private fun PurchaseAlertDialog(
viewModel: PaywallScreenViewModel,
text: String,
) {
AlertDialog(
onDismissRequest = {
viewModel.onDialogDismissed()
},
buttons = {
TextButton(
onClick = {
viewModel.onDialogDismissed()
},
) {
Text("Ok")
}
},
text = {
Text(text)
},
)
}

0 comments on commit 58c3502

Please sign in to comment.