mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-25 07:05:21 +00:00
ok
This commit is contained in:
@@ -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 }
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
// Wallet slides in from right when needed
|
||||||
// Set up back handler for wallet
|
AnimatedVisibility(
|
||||||
LaunchedEffect(selectedTab) {
|
visible = showWallet,
|
||||||
if (selectedTab == 1) {
|
enter = slideInHorizontally(
|
||||||
// When wallet is active, set up its back handler
|
initialOffsetX = { fullWidth -> fullWidth },
|
||||||
walletViewModel.setBackHandler {
|
animationSpec = tween(
|
||||||
// This will be called when back is pressed in wallet
|
durationMillis = 300,
|
||||||
// Return true if handled, false to pass to system
|
easing = FastOutSlowInEasing
|
||||||
when {
|
)
|
||||||
// Let wallet handle its internal navigation first
|
) + fadeIn(
|
||||||
walletViewModel.showSendDialog.value == true -> {
|
animationSpec = tween(
|
||||||
walletViewModel.hideSendDialog()
|
durationMillis = 300,
|
||||||
true
|
easing = FastOutSlowInEasing
|
||||||
}
|
)
|
||||||
walletViewModel.showReceiveDialog.value == true -> {
|
),
|
||||||
walletViewModel.hideReceiveDialog()
|
exit = slideOutHorizontally(
|
||||||
true
|
targetOffsetX = { fullWidth -> fullWidth },
|
||||||
}
|
animationSpec = tween(
|
||||||
else -> {
|
durationMillis = 300,
|
||||||
// Go back to chat
|
easing = FastOutSlowInEasing
|
||||||
selectedTab = 0
|
)
|
||||||
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)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user