This commit is contained in:
callebtc
2025-07-15 15:55:48 +02:00
parent 54a6f5a0d0
commit df377b8ee6
@@ -18,7 +18,7 @@ import com.bitchat.android.wallet.ui.WalletScreen
import com.bitchat.android.wallet.viewmodel.WalletViewModel import com.bitchat.android.wallet.viewmodel.WalletViewModel
/** /**
* Main app screen with bottom navigation between Chat and Wallet * Main app screen with wallet access via header button only
*/ */
@Composable @Composable
fun MainAppScreen( fun MainAppScreen(
@@ -26,23 +26,26 @@ fun MainAppScreen(
onBackPress: (backHandler: () -> Boolean) -> Unit = {}, onBackPress: (backHandler: () -> Boolean) -> Unit = {},
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
var selectedTab by remember { mutableStateOf(0) } var showWallet by remember { mutableStateOf(false) }
// Get wallet ViewModel scoped to this composable // Get wallet ViewModel scoped to this composable
val walletViewModel: WalletViewModel = viewModel() val walletViewModel: WalletViewModel = viewModel()
// Handle back navigation // Handle back navigation
fun handleBackPress(): Boolean { fun handleBackPress(): Boolean {
return when (selectedTab) { return when {
0 -> { showWallet -> {
// Chat tab - let ChatViewModel handle it // Wallet is showing - let WalletViewModel handle it first
walletViewModel.handleBackPress().takeIf { it } ?: run {
// If wallet doesn't handle it, close wallet
showWallet = false
true
}
}
else -> {
// Chat is showing - let ChatViewModel handle it
chatViewModel.handleBackPressed() chatViewModel.handleBackPressed()
} }
1 -> {
// Wallet tab - let WalletViewModel handle it
walletViewModel.handleBackPress()
}
else -> false
} }
} }
@@ -51,179 +54,51 @@ fun MainAppScreen(
onBackPress { handleBackPress() } onBackPress { handleBackPress() }
} }
Column(modifier = modifier.fillMaxSize()) { Box(modifier = modifier.fillMaxSize()) {
// Animated content with slide transitions // Chat is always the base view
AnimatedContent( ChatScreen(
targetState = selectedTab, viewModel = chatViewModel,
transitionSpec = { onWalletClick = { showWallet = true },
// Slide in from right when going to wallet (0 -> 1) onWalletClickWithToken = { parsedToken ->
// Slide out to right when going back to chat (1 -> 0) // Open wallet and show receive dialog with the parsed token immediately
if (targetState > initialState) { showWallet = true
// Going forward (chat -> wallet) walletViewModel.openReceiveDialogWithParsedToken(parsedToken)
slideInHorizontally(
initialOffsetX = { fullWidth -> fullWidth },
animationSpec = tween(
durationMillis = 300,
easing = FastOutSlowInEasing
)
) + fadeIn(
animationSpec = tween(
durationMillis = 300,
easing = FastOutSlowInEasing
)
) togetherWith slideOutHorizontally(
targetOffsetX = { fullWidth -> -fullWidth },
animationSpec = tween(
durationMillis = 300,
easing = FastOutSlowInEasing
)
) + fadeOut(
animationSpec = tween(
durationMillis = 300,
easing = FastOutSlowInEasing
)
)
} else {
// Going back (wallet -> chat)
slideInHorizontally(
initialOffsetX = { fullWidth -> -fullWidth },
animationSpec = tween(
durationMillis = 300,
easing = FastOutSlowInEasing
)
) + fadeIn(
animationSpec = tween(
durationMillis = 300,
easing = FastOutSlowInEasing
)
) togetherWith slideOutHorizontally(
targetOffsetX = { fullWidth -> fullWidth },
animationSpec = tween(
durationMillis = 300,
easing = FastOutSlowInEasing
)
) + fadeOut(
animationSpec = tween(
durationMillis = 300,
easing = FastOutSlowInEasing
)
)
}
},
label = "tab_transition",
modifier = Modifier.weight(1f)
) { tabIndex ->
when (tabIndex) {
0 -> ChatScreen(
viewModel = chatViewModel,
onWalletClick = { selectedTab = 1 }, // Switch to wallet tab when header button is clicked
onWalletClickWithToken = { parsedToken ->
// Switch to wallet and open receive dialog with the parsed token immediately
selectedTab = 1
walletViewModel.openReceiveDialogWithParsedToken(parsedToken)
}
)
1 -> WalletScreen(
walletViewModel = walletViewModel,
onBackToChat = { selectedTab = 0 }
)
} }
}
// Bottom Navigation
AppBottomNavigation(
selectedTab = selectedTab,
onTabSelected = { selectedTab = it }
) )
}
// Set up back handler for wallet // Wallet slides in from right when needed
LaunchedEffect(selectedTab) { AnimatedVisibility(
if (selectedTab == 1) { visible = showWallet,
// When wallet is active, set up its back handler enter = slideInHorizontally(
walletViewModel.setBackHandler { initialOffsetX = { fullWidth -> fullWidth },
// This will be called when back is pressed in wallet animationSpec = tween(
// Return true if handled, false to pass to system durationMillis = 300,
when { easing = FastOutSlowInEasing
// Let wallet handle its internal navigation first )
walletViewModel.showSendDialog.value == true -> { ) + fadeIn(
walletViewModel.hideSendDialog() animationSpec = tween(
true durationMillis = 300,
} easing = FastOutSlowInEasing
walletViewModel.showReceiveDialog.value == true -> { )
walletViewModel.hideReceiveDialog() ),
true exit = slideOutHorizontally(
} targetOffsetX = { fullWidth -> fullWidth },
else -> { animationSpec = tween(
// Go back to chat durationMillis = 300,
selectedTab = 0 easing = FastOutSlowInEasing
true )
} ) + fadeOut(
} animationSpec = tween(
} durationMillis = 300,
easing = FastOutSlowInEasing
)
),
modifier = Modifier.fillMaxSize()
) {
WalletScreen(
walletViewModel = walletViewModel,
onBackToChat = { showWallet = false }
)
} }
} }
} }
@Composable
private fun AppBottomNavigation(
selectedTab: Int,
onTabSelected: (Int) -> Unit
) {
NavigationBar(
containerColor = Color(0xFF1A1A1A),
tonalElevation = 8.dp
) {
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Filled.Chat,
contentDescription = "Chat",
modifier = Modifier.size(20.dp)
)
},
label = {
Text(
text = "Chat",
fontFamily = FontFamily.Monospace,
fontSize = 12.sp
)
},
selected = selectedTab == 0,
onClick = { onTabSelected(0) },
colors = NavigationBarItemDefaults.colors(
selectedIconColor = Color(0xFF00C851),
selectedTextColor = Color(0xFF00C851),
unselectedIconColor = Color.Gray,
unselectedTextColor = Color.Gray,
indicatorColor = Color(0xFF00C851).copy(alpha = 0.2f)
)
)
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Filled.AccountBalanceWallet,
contentDescription = "Wallet",
modifier = Modifier.size(20.dp)
)
},
label = {
Text(
text = "Wallet",
fontFamily = FontFamily.Monospace,
fontSize = 12.sp
)
},
selected = selectedTab == 1,
onClick = { onTabSelected(1) },
colors = NavigationBarItemDefaults.colors(
selectedIconColor = Color(0xFF00C851),
selectedTextColor = Color(0xFF00C851),
unselectedIconColor = Color.Gray,
unselectedTextColor = Color.Gray,
indicatorColor = Color(0xFF00C851).copy(alpha = 0.2f)
)
)
}
}