Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class LobbyScreenTest {
LobbyScreen(
state = LobbyUiState.Success(previewLobbyData()),
onNavigate = {},
onOpenWallet = {},
onRetry = {},
onUseCache = {},
)
Expand All @@ -49,6 +50,7 @@ class LobbyScreenTest {
LobbyScreen(
state = LobbyUiState.Success(previewLobbyData()),
onNavigate = { navigated = it },
onOpenWallet = {},
onRetry = {},
onUseCache = {},
)
Expand Down Expand Up @@ -76,6 +78,7 @@ class LobbyScreenTest {
lastSyncedLabel = "Last synced 4 minutes ago",
),
onNavigate = {},
onOpenWallet = {},
onRetry = { retried = true },
onUseCache = { usedCache = true },
)
Expand Down
5 changes: 4 additions & 1 deletion app/src/main/java/com/plainstudio/stackcasino/StackApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ fun StackApp(startDestination: StartDestination) {
StackBottomBar(
currentRoute = currentRoute,
onTabSelected = { tab ->
navController.navigate(tab.route.path) {
// defaultPath instead of path so parametric tabs
// (Wallet) navigate to the bare destination
// without dragging the {tab} placeholder along.
navController.navigate(tab.route.defaultPath) {
popUpTo(Route.Lobby.path) { saveState = true }
launchSingleTop = true
restoreState = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,15 @@ import com.plainstudio.stackcasino.ui.theme.TextMedium
fun LobbyScreen(
state: LobbyUiState,
onNavigate: (Route) -> Unit,
onOpenWallet: (initialTab: String?) -> Unit,
onRetry: () -> Unit,
onUseCache: () -> Unit,
modifier: Modifier = Modifier,
) {
LobbyContent(
state = state,
onNavigate = onNavigate,
onOpenWallet = onOpenWallet,
onRetry = onRetry,
onUseCache = onUseCache,
modifier = modifier,
Expand All @@ -101,6 +103,7 @@ fun LobbyScreen(
private fun LobbyContent(
state: LobbyUiState,
onNavigate: (Route) -> Unit,
onOpenWallet: (initialTab: String?) -> Unit,
onRetry: () -> Unit,
onUseCache: () -> Unit,
modifier: Modifier = Modifier,
Expand All @@ -112,6 +115,7 @@ private fun LobbyContent(
SuccessContent(
data = state.data,
onNavigate = onNavigate,
onOpenWallet = onOpenWallet,
)
LobbyUiState.Loading -> LoadingContent()
is LobbyUiState.Error ->
Expand Down Expand Up @@ -139,6 +143,7 @@ private fun LobbyContent(
private fun SuccessContent(
data: LobbyData,
onNavigate: (Route) -> Unit,
onOpenWallet: (initialTab: String?) -> Unit,
) {
var isBalanceHidden by rememberSaveable { mutableStateOf(false) }
Column(
Expand All @@ -161,7 +166,10 @@ private fun SuccessContent(
onSelectGame = { onNavigate(it.toRoute()) },
)
Divider()
QuickActionsSection(onOpenWallet = { onNavigate(Route.Wallet) })
QuickActionsSection(
onOpenDeposit = { onOpenWallet(QUICK_ACTION_TAB_DEPOSIT) },
onOpenWithdraw = { onOpenWallet(QUICK_ACTION_TAB_WITHDRAW) },
)
Divider()
RecentActivitySection(
rounds = data.recentActivity,
Expand Down Expand Up @@ -584,7 +592,10 @@ private fun CoinflipCard(
// ---------------------------------------------------------------------------

@Composable
private fun QuickActionsSection(onOpenWallet: () -> Unit) {
private fun QuickActionsSection(
onOpenDeposit: () -> Unit,
onOpenWithdraw: () -> Unit,
) {
Column(
modifier =
Modifier
Expand All @@ -607,21 +618,26 @@ private fun QuickActionsSection(onOpenWallet: () -> Unit) {
subtitle = "Receive crypto",
accent = SemanticOk,
isDeposit = true,
onClick = onOpenWallet,
onClick = onOpenDeposit,
modifier = Modifier.weight(1f),
)
QuickActionCard(
title = "Withdraw",
subtitle = "Send to address",
accent = SemanticWarn,
isDeposit = false,
onClick = onOpenWallet,
onClick = onOpenWithdraw,
modifier = Modifier.weight(1f),
)
}
}
}

// Tab keys the lobby passes back to the nav-host so wallet deep-links
// land on the right pane. Match [WalletTab.name.lowercase()].
internal const val QUICK_ACTION_TAB_DEPOSIT = "Deposit"
internal const val QUICK_ACTION_TAB_WITHDRAW = "Withdraw"

@Composable
private fun QuickActionCard(
title: String,
Expand Down Expand Up @@ -1050,6 +1066,7 @@ private fun LobbyScreenSuccessPreview() {
LobbyScreen(
state = LobbyUiState.Success(previewLobbyData()),
onNavigate = {},
onOpenWallet = {},
onRetry = {},
onUseCache = {},
)
Expand All @@ -1063,6 +1080,7 @@ private fun LobbyScreenLoadingPreview() {
LobbyScreen(
state = LobbyUiState.Loading,
onNavigate = {},
onOpenWallet = {},
onRetry = {},
onUseCache = {},
)
Expand All @@ -1080,6 +1098,7 @@ private fun LobbyScreenErrorPreview() {
lastSyncedLabel = "Last synced 4 minutes ago",
),
onNavigate = {},
onOpenWallet = {},
onRetry = {},
onUseCache = {},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ fun WalletScreen(
data: WalletData,
onNavigate: (Route) -> Unit,
modifier: Modifier = Modifier,
initialTab: WalletTab = WalletTab.Deposit,
) {
var selectedTab by rememberSaveable { mutableStateOf(WalletTab.Deposit) }
var selectedTab by rememberSaveable { mutableStateOf(initialTab) }
Surface(modifier = modifier.fillMaxSize(), color = SurfaceBase) {
Column(
modifier =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,32 @@ package com.plainstudio.stackcasino.navigation
*/
sealed class Route(
val path: String,
// Used by call sites that just want to "go to this destination"
// without supplying an argument. Defaults to [path] so static
// routes stay one-liners; parametric routes whose pattern carries
// optional query args (e.g. wallet?tab={tab}) override it to the
// bare path that produces the default landing state.
val defaultPath: String = path,
) {
data object Login : Route("login")

data object Lobby : Route("lobby")

data object Wallet : Route("wallet")
/**
* Wallet has three top-level tabs (Deposit / Withdraw / Transactions)
* and the lobby's quick actions deep-link to one of the first two.
* The optional `tab` query arg surfaces that choice without spinning
* up a second route; navigating to `"wallet"` lands on the default
* Deposit tab.
*/
data object Wallet : Route(
path = "wallet?tab={tab}",
defaultPath = "wallet",
) {
const val ARG_TAB = "tab"

fun build(tab: String? = null): String = if (tab.isNullOrBlank()) defaultPath else "wallet?tab=$tab"
}

data object HouseWallet : Route("house_wallet")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.plainstudio.stackcasino.feature.lobby.previewLobbyData
import com.plainstudio.stackcasino.feature.news.NewsDetailScreen
import com.plainstudio.stackcasino.feature.news.NewsScreen
import com.plainstudio.stackcasino.feature.wallet.WalletScreen
import com.plainstudio.stackcasino.feature.wallet.WalletTab
import com.plainstudio.stackcasino.feature.wallet.previewWalletData

/**
Expand Down Expand Up @@ -63,20 +64,16 @@ fun StackNavHost(
LobbyScreen(
state = LobbyUiState.Success(previewLobbyData()),
onNavigate = { route ->
navController.navigate(route.path) { launchSingleTop = true }
navController.navigate(route.defaultPath) { launchSingleTop = true }
},
onOpenWallet = { tab ->
navController.navigate(Route.Wallet.build(tab)) { launchSingleTop = true }
},
onRetry = {},
onUseCache = {},
)
}
composable(Route.Wallet.path) {
WalletScreen(
data = previewWalletData(),
onNavigate = { route ->
navController.navigate(route.path) { launchSingleTop = true }
},
)
}
addWalletRoute(navController)
composable(Route.History.path) {
HistoryScreen(
data = historyPreviewData(),
Expand Down Expand Up @@ -106,6 +103,38 @@ fun StackNavHost(
}
}

/**
* Wallet has an optional `tab` query arg so the lobby quick actions
* can deep-link to Deposit / Withdraw; navigating to plain "wallet"
* lands on the default Deposit tab. Pulled out of [StackNavHost] so
* the entry function stays under the detekt LongMethod budget.
*/
private fun NavGraphBuilder.addWalletRoute(navController: NavHostController) {
composable(
route = Route.Wallet.path,
arguments =
listOf(
navArgument(Route.Wallet.ARG_TAB) {
type = NavType.StringType
nullable = true
defaultValue = null
},
),
) { entry ->
val tabName = entry.arguments?.getString(Route.Wallet.ARG_TAB)
val initialTab =
tabName?.let { runCatching { WalletTab.valueOf(it) }.getOrNull() }
?: WalletTab.Deposit
WalletScreen(
data = previewWalletData(),
initialTab = initialTab,
onNavigate = { route ->
navController.navigate(route.defaultPath) { launchSingleTop = true }
},
)
}
}

/**
* Routes with placeholders for their string argument. Kept out of the
* main [StackNavHost] body so the entry function stays under the
Expand Down
Loading