Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
dc30964
feat: create global drawer state
jvsena42 Nov 26, 2025
59624a0
feat: create DrawerNavIcon
jvsena42 Nov 26, 2025
2555c83
chore: inject drawer state
jvsena42 Nov 26, 2025
5e3e70d
feat: elevate DrawerState to ContentView.kt
jvsena42 Nov 26, 2025
abb451c
feat: elevate DrawerState to ContentView.kt
jvsena42 Nov 26, 2025
928cc0e
feat: replace close button with drawer
jvsena42 Nov 26, 2025
9847059
chore: remove unused component
jvsena42 Nov 26, 2025
d9a7795
feat: move drawer up to ContentView.kt
jvsena42 Nov 26, 2025
379654c
chore: lint
jvsena42 Nov 26, 2025
ecfe28a
feat: drawer icon visibility
jvsena42 Nov 26, 2025
13df5e0
feat: drawer icon visibility
jvsena42 Nov 26, 2025
7bb4f3e
chore: clean imports
jvsena42 Nov 26, 2025
535ddd6
chore: preview visibility
jvsena42 Nov 26, 2025
f7f3bc1
chore: remove close action
jvsena42 Nov 26, 2025
7ecaf22
chore: remove close action
jvsena42 Nov 26, 2025
8737102
chore: remove close action
jvsena42 Nov 26, 2025
53bc55f
chore: remove close action
jvsena42 Nov 26, 2025
71b4d70
chore: remove close action
jvsena42 Nov 26, 2025
d64f43d
chore: remove close action
jvsena42 Nov 26, 2025
960c751
feat: wallet nav controller
jvsena42 Nov 26, 2025
b2d79bd
refactor: extract nav method
jvsena42 Nov 26, 2025
265ed4e
feat: activity screen nav drawer
jvsena42 Nov 26, 2025
bd4295c
fix: move AllActivities to top navigation graph
jvsena42 Nov 27, 2025
6d18ad5
fix: move TabBar to top layer
jvsena42 Nov 27, 2025
80cde89
chore: remove unused code
jvsena42 Nov 27, 2025
f214491
chore: remove unused code
jvsena42 Nov 27, 2025
b61dfed
chore: remove unused code
jvsena42 Nov 27, 2025
ed92a70
chore: return walletNavController to inner composable
jvsena42 Nov 27, 2025
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
201 changes: 115 additions & 86 deletions app/src/main/java/to/bitkit/ui/ContentView.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package to.bitkit.ui

import android.content.Intent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
Expand All @@ -12,6 +17,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.core.net.toUri
import androidx.hilt.navigation.compose.hiltViewModel
Expand All @@ -38,6 +45,7 @@ import to.bitkit.models.Toast
import to.bitkit.models.WidgetType
import to.bitkit.ui.Routes.ExternalConnection
import to.bitkit.ui.components.AuthCheckScreen
import to.bitkit.ui.components.DrawerMenu
import to.bitkit.ui.components.Sheet
import to.bitkit.ui.components.SheetHost
import to.bitkit.ui.components.TimedSheetType
Expand Down Expand Up @@ -183,6 +191,7 @@ fun ContentView(
backupsViewModel: BackupsViewModel,
) {
val navController = rememberNavController()
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val context = LocalContext.current
val lifecycle = LocalLifecycleOwner.current.lifecycle

Expand Down Expand Up @@ -337,99 +346,118 @@ fun ContentView(
LocalTransferViewModel provides transferViewModel,
LocalSettingsViewModel provides settingsViewModel,
LocalBackupsViewModel provides backupsViewModel,
LocalDrawerState provides drawerState,
LocalBalances provides balance,
LocalCurrencies provides currencies,
) {
AutoReadClipboardHandler()

val currentSheet by appViewModel.currentSheet.collectAsStateWithLifecycle()
SheetHost(
shouldExpand = currentSheet != null,
onDismiss = { appViewModel.hideSheet() },
sheets = {
when (val sheet = currentSheet) {
null -> Unit
is Sheet.Send -> {
SendSheet(
appViewModel = appViewModel,
walletViewModel = walletViewModel,
startDestination = sheet.route,
)
}

is Sheet.Receive -> {
val walletUiState by walletViewModel.uiState.collectAsState()
ReceiveSheet(
walletState = walletUiState,
navigateToExternalConnection = {
navController.navigate(ExternalConnection())
appViewModel.hideSheet()
}
)
}
val hasSeenWidgetsIntro by settingsViewModel.hasSeenWidgetsIntro.collectAsStateWithLifecycle()
val hasSeenShopIntro by settingsViewModel.hasSeenShopIntro.collectAsStateWithLifecycle()

is Sheet.ActivityDateRangeSelector -> DateRangeSelectorSheet()
is Sheet.ActivityTagSelector -> TagSelectorSheet()
is Sheet.Pin -> PinSheet(sheet, appViewModel)
is Sheet.Backup -> BackupSheet(sheet, onDismiss = { appViewModel.hideSheet() })
is Sheet.LnurlAuth -> LnurlAuthSheet(sheet, appViewModel)
Sheet.ForceTransfer -> ForceTransferSheet(appViewModel, transferViewModel)
is Sheet.Gift -> GiftSheet(sheet, appViewModel)
is Sheet.TimedSheet -> {
when (sheet.type) {
TimedSheetType.APP_UPDATE -> {
UpdateSheet(onCancel = { appViewModel.dismissTimedSheet() })
}

TimedSheetType.BACKUP -> {
BackupSheet(
sheet = Sheet.Backup(BackupRoute.Intro),
onDismiss = { appViewModel.dismissTimedSheet() }
)
}

TimedSheetType.NOTIFICATIONS -> {
BackgroundPaymentsIntroSheet(
onContinue = {
appViewModel.dismissTimedSheet(skipQueue = true)
navController.navigate(Routes.BackgroundPaymentsSettings)
settingsViewModel.setBgPaymentsIntroSeen(true)
},
)
}
val currentSheet by appViewModel.currentSheet.collectAsStateWithLifecycle()
Box(
modifier = Modifier.fillMaxSize()
) {
SheetHost(
shouldExpand = currentSheet != null,
onDismiss = { appViewModel.hideSheet() },
sheets = {
when (val sheet = currentSheet) {
null -> Unit
is Sheet.Send -> {
SendSheet(
appViewModel = appViewModel,
walletViewModel = walletViewModel,
startDestination = sheet.route,
)
}

TimedSheetType.QUICK_PAY -> {
QuickPayIntroSheet(
onContinue = {
appViewModel.dismissTimedSheet(skipQueue = true)
navController.navigate(Routes.QuickPaySettings)
},
)
}
is Sheet.Receive -> {
val walletUiState by walletViewModel.uiState.collectAsState()
ReceiveSheet(
walletState = walletUiState,
navigateToExternalConnection = {
navController.navigate(ExternalConnection())
appViewModel.hideSheet()
}
)
}

TimedSheetType.HIGH_BALANCE -> {
HighBalanceWarningSheet(
understoodClick = { appViewModel.dismissTimedSheet() },
learnMoreClick = {
val intent = Intent(Intent.ACTION_VIEW, Env.STORING_BITCOINS_URL.toUri())
context.startActivity(intent)
appViewModel.dismissTimedSheet(skipQueue = true)
}
)
is Sheet.ActivityDateRangeSelector -> DateRangeSelectorSheet()
is Sheet.ActivityTagSelector -> TagSelectorSheet()
is Sheet.Pin -> PinSheet(sheet, appViewModel)
is Sheet.Backup -> BackupSheet(sheet, onDismiss = { appViewModel.hideSheet() })
is Sheet.LnurlAuth -> LnurlAuthSheet(sheet, appViewModel)
Sheet.ForceTransfer -> ForceTransferSheet(appViewModel, transferViewModel)
is Sheet.Gift -> GiftSheet(sheet, appViewModel)
is Sheet.TimedSheet -> {
when (sheet.type) {
TimedSheetType.APP_UPDATE -> {
UpdateSheet(onCancel = { appViewModel.dismissTimedSheet() })
}

TimedSheetType.BACKUP -> {
BackupSheet(
sheet = Sheet.Backup(BackupRoute.Intro),
onDismiss = { appViewModel.dismissTimedSheet() }
)
}

TimedSheetType.NOTIFICATIONS -> {
BackgroundPaymentsIntroSheet(
onContinue = {
appViewModel.dismissTimedSheet(skipQueue = true)
navController.navigate(Routes.BackgroundPaymentsSettings)
settingsViewModel.setBgPaymentsIntroSeen(true)
},
)
}

TimedSheetType.QUICK_PAY -> {
QuickPayIntroSheet(
onContinue = {
appViewModel.dismissTimedSheet(skipQueue = true)
navController.navigate(Routes.QuickPaySettings)
},
)
}

TimedSheetType.HIGH_BALANCE -> {
HighBalanceWarningSheet(
understoodClick = { appViewModel.dismissTimedSheet() },
learnMoreClick = {
val intent =
Intent(Intent.ACTION_VIEW, Env.STORING_BITCOINS_URL.toUri())
context.startActivity(intent)
appViewModel.dismissTimedSheet(skipQueue = true)
}
)
}
}
}
}
}
) {
RootNavHost(
navController = navController,
drawerState = drawerState,
walletViewModel = walletViewModel,
appViewModel = appViewModel,
activityListViewModel = activityListViewModel,
settingsViewModel = settingsViewModel,
currencyViewModel = currencyViewModel,
transferViewModel = transferViewModel,
)
}
) {
RootNavHost(
navController = navController,
walletViewModel = walletViewModel,
appViewModel = appViewModel,
activityListViewModel = activityListViewModel,
settingsViewModel = settingsViewModel,
currencyViewModel = currencyViewModel,
transferViewModel = transferViewModel,

DrawerMenu(
drawerState = drawerState,
walletNavController = null,
rootNavController = navController,
hasSeenWidgetsIntro = hasSeenWidgetsIntro,
hasSeenShopIntro = hasSeenShopIntro,
modifier = Modifier.align(Alignment.TopEnd),
)
}
}
Expand All @@ -439,6 +467,7 @@ fun ContentView(
@Composable
private fun RootNavHost(
navController: NavHostController,
drawerState: DrawerState,
walletViewModel: WalletViewModel,
appViewModel: AppViewModel,
activityListViewModel: ActivityListViewModel,
Expand All @@ -449,7 +478,7 @@ private fun RootNavHost(
val scope = rememberCoroutineScope()

NavHost(navController, startDestination = Routes.Home) {
home(walletViewModel, appViewModel, activityListViewModel, settingsViewModel, navController)
home(walletViewModel, appViewModel, activityListViewModel, settingsViewModel, navController, drawerState)
settings(navController, settingsViewModel)
profile(navController, settingsViewModel)
shop(navController, settingsViewModel, appViewModel)
Expand Down Expand Up @@ -589,7 +618,6 @@ private fun RootNavHost(
composableWithDefaultTransitions<Routes.SettingUp> {
SettingUpScreen(
viewModel = transferViewModel,
onCloseClick = { navController.popBackStack<Routes.TransferRoot>(inclusive = true) },
onContinueClick = { navController.popBackStack<Routes.TransferRoot>(inclusive = true) },
)
}
Expand Down Expand Up @@ -628,11 +656,11 @@ private fun RootNavHost(
)
}
navigationWithDefaultTransitions<Routes.ExternalNav>(
startDestination = Routes.ExternalConnection(),
startDestination = ExternalConnection(),
) {
composableWithDefaultTransitions<Routes.ExternalConnection> {
composableWithDefaultTransitions<ExternalConnection> {
val parentEntry = remember(it) { navController.getBackStackEntry(Routes.ExternalNav) }
val route = it.toRoute<Routes.ExternalConnection>()
val route = it.toRoute<ExternalConnection>()
val viewModel = hiltViewModel<ExternalNodeViewModel>(parentEntry)

ExternalConnectionScreen(
Expand Down Expand Up @@ -707,6 +735,7 @@ private fun NavGraphBuilder.home(
activityListViewModel: ActivityListViewModel,
settingsViewModel: SettingsViewModel,
navController: NavHostController,
drawerState: DrawerState,
) {
composable<Routes.Home> {
HomeNav(
Expand All @@ -715,6 +744,7 @@ private fun NavGraphBuilder.home(
activityListViewModel = activityListViewModel,
settingsViewModel = settingsViewModel,
rootNavController = navController,
drawerState = drawerState,
)
}
}
Expand Down Expand Up @@ -788,7 +818,6 @@ private fun NavGraphBuilder.shop(
) {
composableWithDefaultTransitions<Routes.ShopIntro> {
ShopIntroScreen(
onClose = { navController.navigateToHome() },
onContinue = {
settingsViewModel.setHasSeenShopIntro(true)
navController.navigate(Routes.ShopDiscover)
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/to/bitkit/ui/Locals.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package to.bitkit.ui

import androidx.compose.material3.DrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.staticCompositionLocalOf
Expand All @@ -19,6 +20,7 @@
val LocalCurrencies = compositionLocalOf { CurrencyState() }

// Statics
val LocalDrawerState = staticCompositionLocalOf<DrawerState?> { null }
val LocalAppViewModel = staticCompositionLocalOf<AppViewModel?> { null }
val LocalWalletViewModel = staticCompositionLocalOf<WalletViewModel?> { null }
val LocalBlocktankViewModel = staticCompositionLocalOf<BlocktankViewModel?> { null }
Expand Down Expand Up @@ -51,3 +53,6 @@

val backupsViewModel: BackupsViewModel?
@Composable get() = LocalBackupsViewModel.current

val drawerState: DrawerState?
@Composable get() = LocalDrawerState.current
6 changes: 2 additions & 4 deletions app/src/main/java/to/bitkit/ui/NodeInfoScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import to.bitkit.ui.components.rememberMoneyText
import to.bitkit.ui.components.settings.SectionHeader
import to.bitkit.ui.components.settings.SettingsTextButtonRow
import to.bitkit.ui.scaffold.AppTopBar
import to.bitkit.ui.scaffold.CloseNavIcon
import to.bitkit.ui.scaffold.DrawerNavIcon
import to.bitkit.ui.scaffold.ScreenColumn
import to.bitkit.ui.shared.util.clickableAlpha
import to.bitkit.ui.theme.AppThemeSurface
Expand Down Expand Up @@ -88,7 +88,6 @@ fun NodeInfoScreen(
isDevModeEnabled = isDevModeEnabled,
balanceDetails = lightningState.balances,
onBack = { navController.popBackStack() },
onClose = { navController.navigateToHome() },
onRefresh = { wallet.onPullToRefresh() },
onDisconnectPeer = { wallet.disconnectPeer(it) },
onCopy = { text ->
Expand All @@ -108,7 +107,6 @@ private fun Content(
isDevModeEnabled: Boolean,
balanceDetails: BalanceDetails? = null,
onBack: () -> Unit = {},
onClose: () -> Unit = {},
onRefresh: () -> Unit = {},
onDisconnectPeer: (PeerDetails) -> Unit = {},
onCopy: (String) -> Unit = {},
Expand All @@ -117,7 +115,7 @@ private fun Content(
AppTopBar(
titleText = stringResource(R.string.lightning__node_info),
onBackClick = onBack,
actions = { CloseNavIcon(onClose) },
actions = { DrawerNavIcon() },
)
PullToRefreshBox(
isRefreshing = uiState.isRefreshing,
Expand Down
11 changes: 8 additions & 3 deletions app/src/main/java/to/bitkit/ui/components/DrawerMenu.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ private val drawerWidth = 200.dp
@Composable
fun DrawerMenu(
drawerState: DrawerState,
walletNavController: NavController,
walletNavController: NavController?,
rootNavController: NavController,
hasSeenWidgetsIntro: Boolean,
hasSeenShopIntro: Boolean,
Expand Down Expand Up @@ -119,7 +119,7 @@ fun DrawerMenu(

@Composable
private fun Menu(
walletNavController: NavController,
walletNavController: NavController?,
rootNavController: NavController,
drawerState: DrawerState,
onClickAddWidget: () -> Unit,
Expand All @@ -140,6 +140,7 @@ private fun Menu(
label = stringResource(R.string.wallet__drawer__wallet),
iconRes = R.drawable.ic_coins,
onClick = {
rootNavController.navigate(Routes.Home)
scope.launch { drawerState.close() }
},
modifier = Modifier.testTag("DrawerWallet")
Expand All @@ -149,7 +150,11 @@ private fun Menu(
label = stringResource(R.string.wallet__drawer__activity),
iconRes = R.drawable.ic_heartbeat,
onClick = {
walletNavController.navigate(HomeRoutes.AllActivity)
if (walletNavController != null) {
walletNavController.navigate(HomeRoutes.AllActivity)
} else {
rootNavController.navigate(Routes.Home)
}
scope.launch { drawerState.close() }
},
modifier = Modifier.testTag("DrawerActivity")
Expand Down
Loading
Loading