From 4cd014957feb13483601029495e7a2e7ccd9d9ec Mon Sep 17 00:00:00 2001 From: jonasgaudian <43753916+jonasgaudian@users.noreply.github.com> Date: Wed, 18 Feb 2026 00:32:22 +0100 Subject: [PATCH] Refactor BottomNavBar visibility and add Daily Review feature --- .../gaudian/translator/view/MainActivity.kt | 16 +++++++----- .../eu/gaudian/translator/view/Navigation.kt | 26 ++++++++++++++----- .../translator/view/home/HomeScreen.kt | 10 +++---- app/src/main/res/values/strings.xml | 3 +++ 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/eu/gaudian/translator/view/MainActivity.kt b/app/src/main/java/eu/gaudian/translator/view/MainActivity.kt index 0e3e5c8..15d9b8f 100644 --- a/app/src/main/java/eu/gaudian/translator/view/MainActivity.kt +++ b/app/src/main/java/eu/gaudian/translator/view/MainActivity.kt @@ -253,19 +253,23 @@ fun TranslatorApp( val currentDestination = navBackStackEntry?.destination val selectedScreen = Screen.fromDestination(currentDestination) - @Suppress("HardCodedStringLiteral") val isBottomBarHidden = currentDestination?.hierarchy?.any { destination -> + @Suppress("HardCodedStringLiteral") + val currentRoute = currentDestination?.route + val isHiddenByHierarchy = currentDestination?.hierarchy?.any { destination -> destination.route in setOf( Screen.Translation.route, Screen.Dictionary.route, Screen.Exercises.route, Screen.Settings.route ) - } == true || currentDestination?.route in setOf( - "start_exercise", + } == true + val isBottomBarHidden = isHiddenByHierarchy || currentRoute in setOf( "new_word", "new_word_review", - "vocabulary_detail/{itemId}" - ) + "vocabulary_detail/{itemId}", + "daily_review" + ) || currentRoute?.startsWith("start_exercise") == true + || currentRoute?.startsWith("vocabulary_exercise") == true val showBottomNavLabels by settingsViewModel.showBottomNavLabels.collectAsStateWithLifecycle(initialValue = false) BottomNavigationBar( @@ -440,4 +444,4 @@ private fun AppTheme( } -} \ No newline at end of file +} diff --git a/app/src/main/java/eu/gaudian/translator/view/Navigation.kt b/app/src/main/java/eu/gaudian/translator/view/Navigation.kt index 36e11a5..aa2c7b8 100644 --- a/app/src/main/java/eu/gaudian/translator/view/Navigation.kt +++ b/app/src/main/java/eu/gaudian/translator/view/Navigation.kt @@ -29,10 +29,10 @@ import eu.gaudian.translator.view.exercises.MainExerciseScreen import eu.gaudian.translator.view.exercises.StartExerciseScreen import eu.gaudian.translator.view.exercises.YouTubeBrowserScreen import eu.gaudian.translator.view.exercises.YouTubeExerciseScreen +import eu.gaudian.translator.view.home.DailyReviewScreen import eu.gaudian.translator.view.home.HomeScreen import eu.gaudian.translator.view.library.LibraryScreen import eu.gaudian.translator.view.settings.DictionaryOptionsScreen -import eu.gaudian.translator.view.settings.SettingsRoutes import eu.gaudian.translator.view.settings.TranslationSettingsScreen import eu.gaudian.translator.view.settings.settingsGraph import eu.gaudian.translator.view.stats.StatsScreen @@ -53,6 +53,7 @@ import eu.gaudian.translator.view.vocabulary.VocabularySortingScreen private const val TRANSITION_DURATION = 300 object NavigationRoutes { + const val DAILY_REVIEW = "daily_review" const val NEW_WORD = "new_word" const val NEW_WORD_REVIEW = "new_word_review" const val VOCABULARY_DETAIL = "vocabulary_detail" @@ -68,6 +69,7 @@ object NavigationRoutes { const val STATS_VOCABULARY_LIST = "stats/vocabulary_list" } +@OptIn(androidx.compose.animation.ExperimentalAnimationApi::class) @Composable fun AppNavHost( navController: NavHostController, @@ -81,15 +83,23 @@ fun AppNavHost( Screen.Home.route, Screen.Library.route, Screen.Stats.route, - Screen.Translation.route, - Screen.Dictionary.route, - Screen.Exercises.route, - SettingsRoutes.LIST + ) // Helper to check if a route is a top-level tab + // Note: Routes can be "main_home", "main_library" etc. but mainTabRoutes contains parent routes fun isTabTransition(initial: String?, target: String?): Boolean { - return mainTabRoutes.contains(initial) && mainTabRoutes.contains(target) + if (initial == null || target == null) return false + // Check if either the direct route OR a "main_*" variant is in mainTabRoutes + val initialIsTab = mainTabRoutes.contains(initial) || + mainTabRoutes.any { route -> + initial == "main_${route}" || initial.startsWith("${route}_") + } + val targetIsTab = mainTabRoutes.contains(target) || + mainTabRoutes.any { route -> + target == "main_${route}" || target.startsWith("${route}_") + } + return initialIsTab && targetIsTab } NavHost( @@ -146,6 +156,10 @@ fun AppNavHost( HomeScreen(navController = navController) } + composable(NavigationRoutes.DAILY_REVIEW) { + DailyReviewScreen(navController = navController) + } + composable(NavigationRoutes.NEW_WORD) { NewWordScreen(navController = navController) } diff --git a/app/src/main/java/eu/gaudian/translator/view/home/HomeScreen.kt b/app/src/main/java/eu/gaudian/translator/view/home/HomeScreen.kt index eedb427..8b5db85 100644 --- a/app/src/main/java/eu/gaudian/translator/view/home/HomeScreen.kt +++ b/app/src/main/java/eu/gaudian/translator/view/home/HomeScreen.kt @@ -62,6 +62,7 @@ fun HomeScreen( val streak by viewModel.streak.collectAsState() val dailyGoal by viewModel.dailyGoal.collectAsState() val todayCompletedCount by viewModel.todayCompletedCount.collectAsState() + val dueTodayCount by viewModel.dueTodayCount.collectAsState() // Calculate daily goal progress val progress = if (dailyGoal > 0) { @@ -95,13 +96,12 @@ fun HomeScreen( ) } item { - //TODO replace with actual implementation - @Suppress("HardCodedStringLiteral") ActionCard( - title = "Daily Review", - subtitle = "42 words need attention", + title = stringResource(R.string.label_daily_review), + subtitle = stringResource(R.string.desc_daily_review_due, dueTodayCount), icon = Icons.Default.Psychology, - contentColor = MaterialTheme.colorScheme.onPrimary + contentColor = MaterialTheme.colorScheme.onPrimary, + onClick = { navController.navigate(NavigationRoutes.DAILY_REVIEW) } ) } item { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 847ed7b..46ea281 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1088,6 +1088,9 @@ %1$d Days Current Streak Daily Goal + Daily Review + %1$d words need attention + Daily review screen - implementation pending No activity data available See History Weekly Progress