mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-25 04:25:22 +00:00
animate
This commit is contained in:
@@ -52,7 +52,7 @@ import java.util.*
|
||||
fun ChatScreen(
|
||||
viewModel: ChatViewModel,
|
||||
onWalletClick: () -> Unit = {},
|
||||
onWalletClickWithToken: ((String) -> Unit)? = null
|
||||
onWalletClickWithToken: ((com.bitchat.android.parsing.ParsedCashuToken) -> Unit)? = null
|
||||
) {
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
val messages by viewModel.messages.observeAsState(emptyList())
|
||||
@@ -112,7 +112,7 @@ fun ChatScreen(
|
||||
meshService = viewModel.meshService,
|
||||
onCashuPaymentClick = { parsedToken ->
|
||||
// Open wallet with the receive dialog pre-filled with this token
|
||||
onWalletClickWithToken?.invoke(parsedToken.originalString) ?: onWalletClick()
|
||||
onWalletClickWithToken?.invoke(parsedToken)
|
||||
},
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.bitchat.android.ui
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.core.*
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
@@ -50,21 +52,82 @@ fun MainAppScreen(
|
||||
}
|
||||
|
||||
Column(modifier = modifier.fillMaxSize()) {
|
||||
// Content based on selected tab
|
||||
when (selectedTab) {
|
||||
0 -> ChatScreen(
|
||||
viewModel = chatViewModel,
|
||||
onWalletClick = { selectedTab = 1 }, // Switch to wallet tab when header button is clicked
|
||||
onWalletClickWithToken = { token ->
|
||||
// Switch to wallet and open receive dialog with the token
|
||||
selectedTab = 1
|
||||
walletViewModel.openReceiveDialogWithToken(token)
|
||||
// Animated content with slide transitions
|
||||
AnimatedContent(
|
||||
targetState = selectedTab,
|
||||
transitionSpec = {
|
||||
// Slide in from right when going to wallet (0 -> 1)
|
||||
// Slide out to right when going back to chat (1 -> 0)
|
||||
if (targetState > initialState) {
|
||||
// Going forward (chat -> wallet)
|
||||
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
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
1 -> WalletScreen(
|
||||
walletViewModel = walletViewModel,
|
||||
onBackToChat = { selectedTab = 0 }
|
||||
)
|
||||
},
|
||||
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
|
||||
|
||||
@@ -976,6 +976,45 @@ class WalletViewModel(application: Application) : AndroidViewModel(application)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open receive dialog with pre-parsed Cashu token data (immediate display)
|
||||
*/
|
||||
fun openReceiveDialogWithParsedToken(parsedToken: com.bitchat.android.parsing.ParsedCashuToken) {
|
||||
try {
|
||||
// Clear any existing state first
|
||||
hideReceiveDialog()
|
||||
_tokenInput.value = ""
|
||||
_decodedToken.value = null
|
||||
|
||||
// Set the receive type to Cashu
|
||||
_receiveType.value = ReceiveType.CASHU
|
||||
|
||||
// Set the token input
|
||||
_tokenInput.value = parsedToken.originalString
|
||||
|
||||
// Create CashuToken from ParsedCashuToken immediately (no async needed)
|
||||
val cashuToken = com.bitchat.android.wallet.data.CashuToken(
|
||||
token = parsedToken.originalString,
|
||||
amount = java.math.BigDecimal(parsedToken.amount),
|
||||
unit = parsedToken.unit,
|
||||
mint = parsedToken.mintUrl,
|
||||
memo = parsedToken.memo
|
||||
)
|
||||
|
||||
// Set the decoded token immediately
|
||||
_decodedToken.value = cashuToken
|
||||
|
||||
// Show the receive dialog immediately
|
||||
_showReceiveDialog.value = true
|
||||
|
||||
Log.d(TAG, "Opened receive dialog with parsed token: ${parsedToken.amount} ${parsedToken.unit}")
|
||||
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error opening receive dialog with parsed token", e)
|
||||
_errorMessage.value = "Failed to process token: ${e.message}"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full transaction history (not just last 10)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user