Skip to content

Commit

Permalink
Clean up VM
Browse files Browse the repository at this point in the history
  • Loading branch information
toluo-stripe committed Feb 4, 2025
1 parent d1418ef commit 89303e9
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 60 deletions.
31 changes: 4 additions & 27 deletions paymentsheet/src/main/java/com/stripe/android/link/LinkActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,11 @@ import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.core.os.bundleOf
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModelProvider
import com.stripe.android.core.Logger
import com.stripe.android.link.ui.FullScreenContent
import com.stripe.android.link.ui.verification.VerificationDialog
import com.stripe.android.paymentsheet.BuildConfig
import com.stripe.android.uicore.utils.collectAsState

internal class LinkActivity : ComponentActivity() {
@VisibleForTesting
Expand Down Expand Up @@ -54,28 +49,10 @@ internal class LinkActivity : ComponentActivity() {
lifecycle.addObserver(vm)

setContent {
val screenState by vm.linkScreenState.collectAsState()

when (val state = screenState) {
ScreenState.FullScreen -> {
FullScreenContent(
modifier = Modifier
.testTag(FULL_SCREEN_CONTENT_TAG),
viewModel = vm,
onBackPressed = onBackPressedDispatcher::onBackPressed
)
}
ScreenState.Loading -> Unit
is ScreenState.VerificationDialog -> {
VerificationDialog(
modifier = Modifier
.testTag(VERIFICATION_DIALOG_CONTENT_TAG),
linkAccount = state.linkAccount,
onVerificationSucceeded = vm::onVerificationSucceeded,
onDismissClicked = vm::onDismissVerificationClicked
)
}
}
LinkScreenContent(
viewModel = vm,
onBackPressed = onBackPressedDispatcher::onBackPressed
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,9 @@ internal class LinkActivityViewModel @Inject constructor(
get() = linkAccountManager.linkAccount.value

var navController: NavHostController? = null
set(value) {
listenToNavController(value)
field = value
}
var dismissWithResult: ((LinkActivityResult) -> Unit)? = null
var launchWebFlow: ((LinkConfiguration) -> Unit)? = null

private fun listenToNavController(navController: NavHostController?) {
viewModelScope.launch {
navController?.currentBackStackEntryFlow?.first { entry ->
entry.destination.route == LinkScreen.Loading.route
}
linkScreenScreenCreated()
}
}

fun handleViewAction(action: LinkAction) {
when (action) {
LinkAction.BackPressed -> handleBackPressed()
Expand Down Expand Up @@ -132,6 +119,7 @@ internal class LinkActivityViewModel @Inject constructor(

private fun navigate(screen: LinkScreen, clearStack: Boolean, launchSingleTop: Boolean) {
val navController = navController ?: return
navController.currentBackStackEntry ?: return
navController.navigate(screen.route) {
this.launchSingleTop = launchSingleTop
if (clearStack) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.stripe.android.link

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.navigation.NavHostController
import com.stripe.android.link.model.LinkAccount
import com.stripe.android.link.ui.FullScreenContent
import com.stripe.android.link.ui.LinkAppBarState
import com.stripe.android.link.ui.verification.VerificationDialog
import com.stripe.android.paymentsheet.analytics.EventReporter
import com.stripe.android.uicore.utils.collectAsState

@Composable
internal fun LinkScreenContent(
viewModel: LinkActivityViewModel,
onBackPressed: () -> Unit
) {
val screenState by viewModel.linkScreenState.collectAsState()
val appBarState by viewModel.linkAppBarState.collectAsState()

LinkScreenContentBody(
screenState = screenState,
appBarState = appBarState,
eventReporter = viewModel.eventReporter,
onVerificationSucceeded = viewModel::onVerificationSucceeded,
onDismissClicked = viewModel::onDismissVerificationClicked,
onBackPressed = onBackPressed,
onLinkScreenScreenCreated = {
viewModel.linkScreenScreenCreated()
},
onNavControllerCreated = { navController ->
viewModel.navController = navController
},
navigate = viewModel::navigate,
dismissWithResult = { result ->
viewModel.dismissWithResult?.invoke(result)
},
getLinkAccount = {
viewModel.linkAccount
},
handleViewAction = viewModel::handleViewAction,
moveToWeb = viewModel::moveToWeb,
goBack = viewModel::goBack
)
}

@Composable
internal fun LinkScreenContentBody(
screenState: ScreenState,
appBarState: LinkAppBarState,
eventReporter: EventReporter,
onVerificationSucceeded: () -> Unit,
onDismissClicked: () -> Unit,
onBackPressed: () -> Unit,
onLinkScreenScreenCreated: () -> Unit,
onNavControllerCreated: (NavHostController) -> Unit,
navigate: (route: LinkScreen, clearStack: Boolean) -> Unit,
dismissWithResult: ((LinkActivityResult) -> Unit)?,
getLinkAccount: () -> LinkAccount?,
handleViewAction: (LinkAction) -> Unit,
moveToWeb: () -> Unit,
goBack: () -> Unit
) {
when (screenState) {
ScreenState.FullScreen -> {
FullScreenContent(
modifier = Modifier
.testTag(FULL_SCREEN_CONTENT_TAG),
onBackPressed = onBackPressed,
appBarState = appBarState,
navigate = navigate,
dismissWithResult = dismissWithResult,
getLinkAccount = getLinkAccount,
moveToWeb = moveToWeb,
goBack = goBack,
eventReporter = eventReporter,
onLinkScreenScreenCreated = onLinkScreenScreenCreated,
onNavControllerCreated = onNavControllerCreated,
handleViewAction = handleViewAction
)
}
ScreenState.Loading -> Unit
is ScreenState.VerificationDialog -> {
VerificationDialog(
modifier = Modifier
.testTag(VERIFICATION_DIALOG_CONTENT_TAG),
linkAccount = screenState.linkAccount,
onVerificationSucceeded = onVerificationSucceeded,
onDismissClicked = onDismissClicked
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,35 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.stripe.android.link.LinkActivityViewModel
import com.stripe.android.link.LinkAction
import com.stripe.android.link.LinkActivityResult
import com.stripe.android.link.LinkScreen
import com.stripe.android.link.model.LinkAccount
import com.stripe.android.paymentsheet.analytics.EventReporter
import com.stripe.android.paymentsheet.utils.EventReporterProvider
import com.stripe.android.uicore.utils.collectAsState
import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterialApi::class)
@Composable
internal fun FullScreenContent(
modifier: Modifier,
viewModel: LinkActivityViewModel,
onBackPressed: () -> Unit
appBarState: LinkAppBarState,
eventReporter: EventReporter,
onBackPressed: () -> Unit,
moveToWeb: () -> Unit,
goBack: () -> Unit,
handleViewAction: (LinkAction) -> Unit,
onLinkScreenScreenCreated: () -> Unit,
onNavControllerCreated: (NavHostController) -> Unit,
navigate: (route: LinkScreen, clearStack: Boolean) -> Unit,
dismissWithResult: ((LinkActivityResult) -> Unit)?,
getLinkAccount: () -> LinkAccount?,
) {
var bottomSheetContent by remember { mutableStateOf<BottomSheetContent?>(null) }
val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
val coroutineScope = rememberCoroutineScope()
val appBarState by viewModel.linkAppBarState.collectAsState()
val navController = rememberNavController()

if (bottomSheetContent != null) {
Expand All @@ -45,10 +57,9 @@ internal fun FullScreenContent(
modifier = modifier
) {
EventReporterProvider(
eventReporter = viewModel.eventReporter
eventReporter = eventReporter
) {
LinkContent(
viewModel = viewModel,
navController = navController,
appBarState = appBarState,
sheetState = sheetState,
Expand All @@ -57,12 +68,18 @@ internal fun FullScreenContent(
bottomSheetContent = it
},
onBackPressed = onBackPressed,
moveToWeb = viewModel::moveToWeb
moveToWeb = moveToWeb,
handleViewAction = handleViewAction,
navigate = navigate,
dismissWithResult = dismissWithResult,
getLinkAccount = getLinkAccount,
goBack = goBack
)
}
}

LaunchedEffect(Unit) {
viewModel.navController = navController
onNavControllerCreated(navController)
onLinkScreenScreenCreated()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import androidx.navigation.compose.composable
import com.stripe.android.link.LinkAccountUpdate
import com.stripe.android.link.LinkAction
import com.stripe.android.link.LinkActivityResult
import com.stripe.android.link.LinkActivityViewModel
import com.stripe.android.link.LinkScreen
import com.stripe.android.link.NoLinkAccountFoundException
import com.stripe.android.link.linkViewModel
Expand All @@ -47,14 +46,18 @@ import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterialApi::class)
@Composable
internal fun LinkContent(
viewModel: LinkActivityViewModel,
navController: NavHostController,
appBarState: LinkAppBarState,
sheetState: ModalBottomSheetState,
bottomSheetContent: BottomSheetContent?,
onUpdateSheetContent: (BottomSheetContent?) -> Unit,
handleViewAction: (LinkAction) -> Unit,
navigate: (route: LinkScreen, clearStack: Boolean) -> Unit,
dismissWithResult: ((LinkActivityResult) -> Unit)?,
getLinkAccount: () -> LinkAccount?,
onBackPressed: () -> Unit,
moveToWeb: () -> Unit
moveToWeb: () -> Unit,
goBack: () -> Unit
) {
val coroutineScope = rememberCoroutineScope()
DefaultLinkTheme {
Expand All @@ -77,7 +80,7 @@ internal fun LinkContent(
.fillMaxWidth()
) {
BackHandler {
viewModel.handleViewAction(LinkAction.BackPressed)
handleViewAction(LinkAction.BackPressed)
}

LinkAppBar(
Expand All @@ -97,20 +100,18 @@ internal fun LinkContent(

Screens(
navController = navController,
goBack = viewModel::goBack,
goBack = goBack,
moveToWeb = moveToWeb,
navigate = { screen ->
viewModel.navigate(screen, clearStack = false)
navigate(screen, false)
},
navigateAndClearStack = { screen ->
viewModel.navigate(screen, clearStack = true)
navigate(screen, true)
},
dismissWithResult = { result ->
viewModel.dismissWithResult?.invoke(result)
},
getLinkAccount = {
viewModel.linkAccount
dismissWithResult?.invoke(result)
},
getLinkAccount = getLinkAccount,
showBottomSheetContent = onUpdateSheetContent,
hideBottomSheetContent = {
onUpdateSheetContent(null)
Expand Down

0 comments on commit 89303e9

Please sign in to comment.