diff --git a/app/src/main/java/to/bitkit/ui/ContentView.kt b/app/src/main/java/to/bitkit/ui/ContentView.kt index ada75237f..280eb6630 100644 --- a/app/src/main/java/to/bitkit/ui/ContentView.kt +++ b/app/src/main/java/to/bitkit/ui/ContentView.kt @@ -1,8 +1,5 @@ package to.bitkit.ui -import androidx.compose.animation.core.tween -import androidx.compose.animation.slideInHorizontally -import androidx.compose.animation.slideOutHorizontally import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect @@ -69,6 +66,10 @@ import to.bitkit.ui.settings.OrderDetailScreen import to.bitkit.ui.settings.SettingsScreen import to.bitkit.ui.settings.backups.BackupWalletScreen import to.bitkit.ui.settings.backups.RestoreWalletScreen +import to.bitkit.ui.utils.screenScaleIn +import to.bitkit.ui.utils.screenScaleOut +import to.bitkit.ui.utils.screenSlideIn +import to.bitkit.ui.utils.screenSlideOut import to.bitkit.utils.Logger import to.bitkit.viewmodels.ActivityListViewModel import to.bitkit.viewmodels.AppViewModel @@ -323,7 +324,7 @@ fun ContentView( } else { navController.navigateToTransferSpendingAmount() } - }, + }, onFund = { scope.launch { // TODO show receive sheet -> ReceiveAmount @@ -367,7 +368,7 @@ private fun NavGraphBuilder.home( HomeScreen( walletViewModel = viewModel, appViewModel = appViewModel, - rootNavController = navController + rootNavController = navController, ) } } @@ -376,7 +377,12 @@ private fun NavGraphBuilder.settings( viewModel: WalletViewModel, navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { SettingsScreen(viewModel, navController) } } @@ -385,13 +391,21 @@ private fun NavGraphBuilder.nodeState( viewModel: WalletViewModel, navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenSlideOut }, + ) { NodeStateScreen(viewModel, navController) } } private fun NavGraphBuilder.generalSettings(navController: NavHostController) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { GeneralSettingsScreen(navController) } } @@ -400,7 +414,12 @@ private fun NavGraphBuilder.defaultUnitSettings( currencyViewModel: CurrencyViewModel, navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { DefaultUnitSettingsScreen(currencyViewModel, navController) } } @@ -409,7 +428,12 @@ private fun NavGraphBuilder.localCurrencySettings( currencyViewModel: CurrencyViewModel, navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { LocalCurrencySettingsScreen(currencyViewModel, navController) } } @@ -417,7 +441,12 @@ private fun NavGraphBuilder.localCurrencySettings( private fun NavGraphBuilder.backupSettings( navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { BackupSettingsScreen(navController) } } @@ -425,7 +454,12 @@ private fun NavGraphBuilder.backupSettings( private fun NavGraphBuilder.backupWalletSettings( navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { BackupWalletScreen(navController) } } @@ -433,7 +467,12 @@ private fun NavGraphBuilder.backupWalletSettings( private fun NavGraphBuilder.restoreWalletSettings( navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { RestoreWalletScreen(navController) } } @@ -441,7 +480,12 @@ private fun NavGraphBuilder.restoreWalletSettings( private fun NavGraphBuilder.channelOrdersSettings( navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { ChannelOrdersScreen( onBackClick = { navController.popBackStack() }, onOrderItemClick = { navController.navigateToOrderDetail(it) }, @@ -453,7 +497,12 @@ private fun NavGraphBuilder.channelOrdersSettings( private fun NavGraphBuilder.orderDetailSettings( navController: NavHostController, ) { - composable { navBackEntry -> + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { navBackEntry -> OrderDetailScreen( orderItem = navBackEntry.toRoute(), onBackClick = { navController.popBackStack() }, @@ -464,7 +513,12 @@ private fun NavGraphBuilder.orderDetailSettings( private fun NavGraphBuilder.cjitDetailSettings( navController: NavHostController, ) { - composable { navBackEntry -> + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { navBackEntry -> CJitDetailScreen( cjitItem = navBackEntry.toRoute(), onBackClick = { navController.popBackStack() }, @@ -476,7 +530,12 @@ private fun NavGraphBuilder.lightning( viewModel: WalletViewModel, navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { LightningSettingsScreen(viewModel, navController) } } @@ -485,7 +544,12 @@ private fun NavGraphBuilder.devSettings( viewModel: WalletViewModel, navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { DevSettingsScreen(viewModel, navController) } } @@ -493,7 +557,12 @@ private fun NavGraphBuilder.devSettings( private fun NavGraphBuilder.regtestSettings( navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { val viewModel = hiltViewModel() BlocktankRegtestScreen(viewModel, navController) } @@ -503,7 +572,12 @@ private fun NavGraphBuilder.allActivity( viewModel: ActivityListViewModel, navController: NavHostController, ) { - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { AllActivityScreen( viewModel = viewModel, onBackCLick = { navController.popBackStack() }, @@ -516,7 +590,12 @@ private fun NavGraphBuilder.activityItem( viewModel: ActivityListViewModel, navController: NavHostController, ) { - composable { navBackEntry -> + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { navBackEntry -> ActivityItemScreen( viewModel = viewModel, activityItem = navBackEntry.toRoute(), @@ -530,18 +609,8 @@ private fun NavGraphBuilder.qrScanner( navController: NavHostController, ) { composable( - enterTransition = { - slideInHorizontally( - initialOffsetX = { it }, - animationSpec = tween(durationMillis = 300) - ) - }, - exitTransition = { - slideOutHorizontally( - targetOffsetX = { it }, - animationSpec = tween(durationMillis = 300) - ) - }, + enterTransition = { screenSlideIn }, + exitTransition = { screenSlideOut }, ) { QrScanningScreen(navController = navController) { qrCode -> navController.popBackStack() diff --git a/app/src/main/java/to/bitkit/ui/MainActivity.kt b/app/src/main/java/to/bitkit/ui/MainActivity.kt index 948fe2e87..a517ad320 100644 --- a/app/src/main/java/to/bitkit/ui/MainActivity.kt +++ b/app/src/main/java/to/bitkit/ui/MainActivity.kt @@ -23,6 +23,10 @@ import to.bitkit.ui.screens.SplashScreen import to.bitkit.ui.screens.wallets.sheets.NewTransactionSheet import to.bitkit.ui.theme.AppThemeSurface import to.bitkit.ui.utils.enableAppEdgeToEdge +import to.bitkit.ui.utils.screenScaleIn +import to.bitkit.ui.utils.screenScaleOut +import to.bitkit.ui.utils.screenSlideIn +import to.bitkit.ui.utils.screenSlideOut import to.bitkit.viewmodels.ActivityListViewModel import to.bitkit.viewmodels.AppViewModel import to.bitkit.viewmodels.BlocktankViewModel @@ -61,7 +65,12 @@ class MainActivity : ComponentActivity() { } ) } - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { IntroScreen( onStartClick = { startupNavController.navigate(StartupRoutes.Slides()) @@ -71,7 +80,12 @@ class MainActivity : ComponentActivity() { }, ) } - composable { navBackEntry -> + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { navBackEntry -> val route = navBackEntry.toRoute() OnboardingSlidesScreen( currentTab = route.tab, @@ -91,7 +105,12 @@ class MainActivity : ComponentActivity() { onRestoreClick = { startupNavController.navigate(StartupRoutes.Restore) }, ) } - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { RestoreWalletView( onBackClick = { startupNavController.popBackStack() }, onRestoreClick = { mnemonic, passphrase -> @@ -109,7 +128,12 @@ class MainActivity : ComponentActivity() { } ) } - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenScaleOut }, + popEnterTransition = { screenScaleIn }, + popExitTransition = { screenSlideOut }, + ) { CreateWalletWithPassphraseScreen( onBackClick = { startupNavController.popBackStack() }, onCreateClick = { passphrase -> diff --git a/app/src/main/java/to/bitkit/ui/onboarding/CreateWalletScreen.kt b/app/src/main/java/to/bitkit/ui/onboarding/CreateWalletScreen.kt index 84fb3453e..440afb67a 100644 --- a/app/src/main/java/to/bitkit/ui/onboarding/CreateWalletScreen.kt +++ b/app/src/main/java/to/bitkit/ui/onboarding/CreateWalletScreen.kt @@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -51,7 +50,7 @@ fun CreateWalletScreen( Column( modifier = Modifier .fillMaxWidth() - .height(250.dp) + .height(264.dp) .align(Alignment.BottomCenter), ) { Display(text = stringResource(R.string.onboarding__slide4_header).withAccent()) @@ -79,6 +78,7 @@ fun CreateWalletScreen( modifier = Modifier.weight(1f) ) } + Spacer(modifier = Modifier.height(16.dp)) } } } diff --git a/app/src/main/java/to/bitkit/ui/onboarding/OnboardingSlidesScreen.kt b/app/src/main/java/to/bitkit/ui/onboarding/OnboardingSlidesScreen.kt index 9f67e3b40..f138c8f67 100644 --- a/app/src/main/java/to/bitkit/ui/onboarding/OnboardingSlidesScreen.kt +++ b/app/src/main/java/to/bitkit/ui/onboarding/OnboardingSlidesScreen.kt @@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -22,7 +21,6 @@ import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -203,7 +201,7 @@ fun OnboardingTab( Column( modifier = Modifier .fillMaxWidth() - .height(250.dp) + .height(264.dp) .align(Alignment.BottomCenter), ) { Display(text = title.withAccent(accentColor = titleAccentColor)) diff --git a/app/src/main/java/to/bitkit/ui/scaffold/ScreenColumn.kt b/app/src/main/java/to/bitkit/ui/scaffold/ScreenColumn.kt index eb9de08b4..e37970c01 100644 --- a/app/src/main/java/to/bitkit/ui/scaffold/ScreenColumn.kt +++ b/app/src/main/java/to/bitkit/ui/scaffold/ScreenColumn.kt @@ -1,15 +1,18 @@ package to.bitkit.ui.scaffold +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import to.bitkit.ui.theme.Colors @Composable fun ScreenColumn( modifier: Modifier = Modifier, + noBackground: Boolean = false, content: @Composable ColumnScope.() -> Unit, ) { Column( @@ -17,6 +20,7 @@ fun ScreenColumn( modifier = Modifier .systemBarsPadding() .fillMaxSize() + .then(if (noBackground) Modifier else Modifier.background(Colors.Black)) .then(modifier) ) } diff --git a/app/src/main/java/to/bitkit/ui/screens/SplashScreen.kt b/app/src/main/java/to/bitkit/ui/screens/SplashScreen.kt index ef32c4039..0025825b0 100644 --- a/app/src/main/java/to/bitkit/ui/screens/SplashScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/SplashScreen.kt @@ -7,7 +7,9 @@ import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -22,10 +24,11 @@ fun SplashScreen(isVisible: Boolean = true) { AnimatedVisibility( visible = isVisible, enter = fadeIn(), - exit = fadeOut(animationSpec = tween( - durationMillis = 300, - easing = EaseOut, - ) + exit = fadeOut( + animationSpec = tween( + durationMillis = 300, + easing = EaseOut, + ) ) ) { Box( diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/HomeScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/HomeScreen.kt index 58aa2c81a..f1f396433 100644 --- a/app/src/main/java/to/bitkit/ui/screens/wallets/HomeScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/wallets/HomeScreen.kt @@ -61,6 +61,8 @@ import to.bitkit.ui.screens.wallets.send.SendOptionsView import to.bitkit.ui.shared.TabBar import to.bitkit.ui.theme.AppThemeSurface import to.bitkit.ui.theme.Colors +import to.bitkit.ui.utils.screenSlideIn +import to.bitkit.ui.utils.screenSlideOut import to.bitkit.ui.utils.withAccent import to.bitkit.viewmodels.AppViewModel import to.bitkit.viewmodels.WalletViewModel @@ -110,7 +112,10 @@ fun HomeScreen( onRefresh = walletViewModel::refreshState, ) } - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenSlideOut }, + ) { val hasSeenSpendingIntro by appViewModel.hasSeenSpendingIntro.collectAsState() SavingsWalletScreen( onAllActivityButtonClick = { rootNavController.navigateToAllActivity() }, @@ -125,7 +130,10 @@ fun HomeScreen( onBackClick = { walletNavController.popBackStack() }, ) } - composable { + composable( + enterTransition = { screenSlideIn }, + exitTransition = { screenSlideOut }, + ) { val hasSeenSavingsIntro by appViewModel.hasSeenSavingsIntro.collectAsState() SpendingWalletScreen( onAllActivityButtonClick = { rootNavController.navigateToAllActivity() }, diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/SavingsWalletScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/SavingsWalletScreen.kt index 1a0efe6b9..4a9affd5c 100644 --- a/app/src/main/java/to/bitkit/ui/screens/wallets/SavingsWalletScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/wallets/SavingsWalletScreen.kt @@ -1,6 +1,7 @@ package to.bitkit.ui.screens.wallets import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -34,6 +35,7 @@ import to.bitkit.ui.scaffold.AppTopBar import to.bitkit.ui.scaffold.ScreenColumn import to.bitkit.ui.screens.wallets.activity.ActivityListWithHeaders import to.bitkit.ui.theme.AppThemeSurface +import to.bitkit.ui.theme.Colors import to.bitkit.ui.utils.withAccent @Composable @@ -47,7 +49,12 @@ fun SavingsWalletScreen( val showEmptyState by remember(balances.totalOnchainSats) { mutableStateOf(balances.totalOnchainSats == 0uL) // TODO use && hasOnchainActivity } - Box(modifier = Modifier.fillMaxSize()) { + + Box( + modifier = Modifier + .fillMaxSize() + .background(Colors.Black) + ) { Image( painter = painterResource(id = R.drawable.piggybank), contentDescription = null, @@ -57,7 +64,7 @@ fun SavingsWalletScreen( .offset(x = (120).dp) .size(268.dp) ) - ScreenColumn { + ScreenColumn(noBackground = true) { AppTopBar( titleText = stringResource(R.string.wallet__savings__title), icon = painterResource(R.drawable.ic_btc_circle), diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/SpendingWalletScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/SpendingWalletScreen.kt index cd83c950d..68321e44c 100644 --- a/app/src/main/java/to/bitkit/ui/screens/wallets/SpendingWalletScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/wallets/SpendingWalletScreen.kt @@ -1,6 +1,7 @@ package to.bitkit.ui.screens.wallets import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -53,7 +54,11 @@ fun SpendingWalletScreen( mutableStateOf(balances.totalLightningSats > 0uL) } - Box(modifier = Modifier.fillMaxSize()) { + Box( + modifier = Modifier + .fillMaxSize() + .background(Colors.Black) + ) { Image( painter = painterResource(id = R.drawable.coin_stack_x_2), contentDescription = null, @@ -63,7 +68,7 @@ fun SpendingWalletScreen( .offset(x = (155).dp, y = (-35).dp) .size(330.dp) ) - ScreenColumn { + ScreenColumn(noBackground = true) { AppTopBar( titleText = stringResource(R.string.wallet__spending__title), icon = painterResource(R.drawable.ic_ln_circle), diff --git a/app/src/main/java/to/bitkit/ui/utils/Nav.kt b/app/src/main/java/to/bitkit/ui/utils/Nav.kt index 11858b88f..a2ae88f37 100644 --- a/app/src/main/java/to/bitkit/ui/utils/Nav.kt +++ b/app/src/main/java/to/bitkit/ui/utils/Nav.kt @@ -1,5 +1,28 @@ package to.bitkit.ui.utils +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.scaleIn +import androidx.compose.animation.scaleOut +import androidx.compose.animation.slideInHorizontally +import androidx.compose.animation.slideOutHorizontally import androidx.navigation.NavOptionsBuilder fun NavOptionsBuilder.clearBackStack() = popUpTo(id = 0) + +// region transitions + +/** enterTransition */ +val screenSlideIn = slideInHorizontally(animationSpec = tween(), initialOffsetX = { it }) + +/** exitTransition */ +val screenSlideOut = slideOutHorizontally(animationSpec = tween(), targetOffsetX = { it }) + +/** popEnterTransition */ +val screenScaleIn = scaleIn(animationSpec = tween(), initialScale = 0.95f) + fadeIn() + +/** popExitTransition */ +val screenScaleOut = scaleOut(animationSpec = tween(), targetScale = 0.95f) + fadeOut() + +// endregion