nordiccalendar

A simple Material 3 native calendar app fitting my personal requirements
git clone git://archive.git.mtrnord.blog/MTRNord/nordiccalendar.git
Log | Files | Refs | README | LICENSE

commit 900abe345637c11f288a83b84e956097dbea3d76
parent 7c7e06bc0a8b8b1e67925c084b99ccc9ceb766ac
Author: MTRNord <MTRNord@users.noreply.github.com>
Date:   Mon, 28 Jul 2025 18:26:13 +0200

Improve navigation in SidebarDrawer

Diffstat:
Mapp/src/main/java/space/midnightthoughts/nordiccalendar/MainActivity.kt | 26+++++++++-----------------
Mapp/src/main/java/space/midnightthoughts/nordiccalendar/components/AppScaffold.kt | 3++-
Mapp/src/main/java/space/midnightthoughts/nordiccalendar/components/SidebarDrawer.kt | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
3 files changed, 68 insertions(+), 43 deletions(-)

diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/MainActivity.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/MainActivity.kt @@ -117,14 +117,12 @@ class MainActivity : ComponentActivity() { } composable(Destinations.Settings.route) { backStackEntry -> SettingsView( - navController = navController, - backStackEntry = backStackEntry + navController = navController ) } composable(Destinations.About.route) { backStackEntry -> AboutView( - navController = navController, - backStackEntry = backStackEntry + navController = navController ) } } @@ -230,6 +228,8 @@ fun IntroScreen(navController: NavHostController, onFinish: (() -> Unit)? = null @Composable fun CalendarView(backStackEntry: NavBackStackEntry, navController: NavHostController) { val calendarViewModel: CalendarViewModel = viewModel() + + val selectedTab = remember(calendarViewModel) { calendarViewModel.selectedTab }.collectAsState(initial = 0) @@ -292,17 +292,13 @@ fun EventDetailsView( } @Composable -fun SettingsView(navController: NavHostController, backStackEntry: NavBackStackEntry) { - val parentEntry = remember(backStackEntry) { - navController.getBackStackEntry(Destinations.Calendar.route) - } - val calendarViewModel: CalendarViewModel = viewModel(parentEntry) +fun SettingsView(navController: NavHostController) { AppScaffold( title = stringResource(R.string.settings), selectedDestination = "settings", navController = navController, - calendarViewModel - ) { innerPadding -> + + ) { innerPadding -> Column( modifier = innerPadding .fillMaxSize() @@ -317,16 +313,12 @@ fun SettingsView(navController: NavHostController, backStackEntry: NavBackStackE } @Composable -fun AboutView(navController: NavHostController, backStackEntry: NavBackStackEntry) { - val parentEntry = remember(backStackEntry) { - navController.getBackStackEntry(Destinations.Calendar.route) - } - val calendarViewModel: CalendarViewModel = viewModel(parentEntry) +fun AboutView(navController: NavHostController) { + AppScaffold( title = stringResource(R.string.about) + " Nordic Calendar", selectedDestination = "about", navController = navController, - calendarViewModel ) { innerPadding -> Column( modifier = innerPadding diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/components/AppScaffold.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/components/AppScaffold.kt @@ -37,9 +37,10 @@ fun AppScaffold( ) { val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed) val scope = rememberCoroutineScope() + val isDrawerDestination = selectedDestination in listOf("calendar", "settings", "about") val isBackButtonVisible by remember { derivedStateOf { - navController.previousBackStackEntry != null + navController.previousBackStackEntry != null && !isDrawerDestination } } diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/components/SidebarDrawer.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/components/SidebarDrawer.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController +import androidx.navigation.NavGraph.Companion.findStartDestination import kotlinx.coroutines.launch import space.midnightthoughts.nordiccalendar.Destinations import space.midnightthoughts.nordiccalendar.R @@ -66,7 +67,17 @@ fun SidebarDrawer( scope.launch { drawerState.close() } - navController.navigate(Destinations.Calendar.route) + navController.navigate(Destinations.Calendar.route) { + popUpTo(navController.graph.findStartDestination().id) { + inclusive = true + saveState = true + } + // Avoid multiple copies of the same destination when + // reselecting the same item + launchSingleTop = true + // Restore state when reselecting a previously selected item + restoreState = true + } }, modifier = Modifier.fillMaxWidth(), colors = NavigationDrawerItemDefaults.colors() @@ -78,7 +89,17 @@ fun SidebarDrawer( scope.launch { drawerState.close() } - navController.navigate(Destinations.Settings.route) + navController.navigate(Destinations.Settings.route) { + popUpTo(navController.graph.findStartDestination().id) { + inclusive = true + saveState = true + } + // Avoid multiple copies of the same destination when + // reselecting the same item + launchSingleTop = true + // Restore state when reselecting a previously selected item + restoreState = true + } }, modifier = Modifier.fillMaxWidth(), colors = NavigationDrawerItemDefaults.colors() @@ -90,36 +111,47 @@ fun SidebarDrawer( scope.launch { drawerState.close() } - navController.navigate(Destinations.About.route) + navController.navigate(Destinations.About.route) { + popUpTo(navController.graph.findStartDestination().id) { + inclusive = true + saveState = true + } + // Avoid multiple copies of the same destination when + // reselecting the same item + launchSingleTop = true + // Restore state when reselecting a previously selected item + restoreState = true + } }, modifier = Modifier.fillMaxWidth(), colors = NavigationDrawerItemDefaults.colors() ) - Spacer(Modifier.height(16.dp)) - HorizontalDivider(Modifier, DividerDefaults.Thickness, DividerDefaults.color) - Spacer(Modifier.height(8.dp)) - Text( - stringResource(R.string.calendar_selection), - style = MaterialTheme.typography.titleMedium, - modifier = - Modifier.padding(start = 8.dp, bottom = 8.dp, end = 8.dp, top = 8.dp) - ) - Spacer(Modifier.height(8.dp)) - calendars?.value?.forEach { calendar -> - Row(verticalAlignment = androidx.compose.ui.Alignment.CenterVertically) { - Checkbox( - checked = selectedCalendars.value?.contains(calendar) == true, - onCheckedChange = { - scope.launch { - calendarViewModel?.toggleCalendar(calendar) + if (selectedCalendars.value !== null && !selectedCalendars.value!!.isEmpty()) { + Spacer(Modifier.height(16.dp)) + HorizontalDivider(Modifier, DividerDefaults.Thickness, DividerDefaults.color) + Spacer(Modifier.height(8.dp)) + Text( + stringResource(R.string.calendar_selection), + style = MaterialTheme.typography.titleMedium, + modifier = + Modifier.padding(start = 8.dp, bottom = 8.dp, end = 8.dp, top = 8.dp) + ) + Spacer(Modifier.height(8.dp)) + calendars?.value?.forEach { calendar -> + Row(verticalAlignment = androidx.compose.ui.Alignment.CenterVertically) { + Checkbox( + checked = selectedCalendars.value?.contains(calendar) == true, + onCheckedChange = { + scope.launch { + calendarViewModel?.toggleCalendar(calendar) + } } - } - ) - Text(calendar.name, modifier = Modifier.padding(start = 8.dp)) + ) + Text(calendar.name, modifier = Modifier.padding(start = 8.dp)) + } } - } - + } } } }