From 8abd40a0c21eeaf9e087ba05e272ae0c71007677 Mon Sep 17 00:00:00 2001 From: Owen LeJeune Date: Tue, 25 Jul 2023 20:46:17 -0400 Subject: [PATCH] add option for floating bottom bar design --- .../com/owenlejeune/tvtime/MainActivity.kt | 14 +++- .../tvtime/extensions/ComposeExtensions.kt | 18 ++++- .../tvtime/preferences/AppPreferences.kt | 8 +- .../owenlejeune/tvtime/ui/components/Menus.kt | 3 +- .../tvtime/ui/components/Widgets.kt | 4 +- .../tvtime/ui/navigation/AppNavigation.kt | 2 +- .../ui/navigation/HomeScreenNavigation.kt | 6 +- .../ui/navigation/SettingsNavigation.kt | 4 +- .../tvtime/ui/screens/HomeScreen.kt | 81 +++++++++++++++++-- .../tvtime/ui/screens/SettingsScreen.kt | 44 +++++++--- .../com/owenlejeune/tvtime/ui/theme/Theme.kt | 20 ++++- .../tvtime/ui/viewmodel/SettingsViewModel.kt | 12 +++ app/src/main/res/values/themes.xml | 1 + 13 files changed, 188 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt b/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt index 2983740..2f63994 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt @@ -1,6 +1,7 @@ package com.owenlejeune.tvtime import android.annotation.SuppressLint +import android.os.Build import android.os.Bundle import android.widget.Toast import androidx.activity.compose.setContent @@ -12,17 +13,23 @@ import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.unit.dp +import androidx.core.view.WindowCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.compose.rememberNavController import com.kieronquinn.monetcompat.app.MonetCompatActivity +import com.owenlejeune.tvtime.extensions.copy import com.owenlejeune.tvtime.extensions.rememberWindowSizeClass import com.owenlejeune.tvtime.ui.navigation.AppNavigationHost import com.owenlejeune.tvtime.ui.navigation.HomeScreenNavItem @@ -50,6 +57,9 @@ class MainActivity : MonetCompatActivity() { lifecycleScope.launch { lifecycle.repeatOnLifecycle(Lifecycle.State.CREATED) { monet.awaitMonetReady() + + WindowCompat.setDecorFitsSystemWindows(window, false) + setContent { AppKeyboardFocusManager() TVTimeTheme(monetCompat = monet) { @@ -83,10 +93,10 @@ class MainActivity : MonetCompatActivity() { Scaffold( snackbarHost = { SnackbarHost(hostState = snackbarHostState) } - ) { + ) { innerPadding -> val windowSize = rememberWindowSizeClass() val appNavController = rememberNavController() - Box(modifier = Modifier.padding(it)) { + Box(modifier = Modifier.padding(innerPadding.copy(bottom = 0.dp))) { AppNavigationHost( appNavController = appNavController, mainNavStartRoute = mainNavStartRoute, diff --git a/app/src/main/java/com/owenlejeune/tvtime/extensions/ComposeExtensions.kt b/app/src/main/java/com/owenlejeune/tvtime/extensions/ComposeExtensions.kt index bf29325..15daf47 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/extensions/ComposeExtensions.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/extensions/ComposeExtensions.kt @@ -1,13 +1,19 @@ package com.owenlejeune.tvtime.extensions import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.foundation.lazy.grid.LazyGridItemScope import androidx.compose.foundation.lazy.grid.LazyGridScope +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.compositeOver +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.LayoutDirection import androidx.paging.compose.LazyPagingItems fun LazyGridScope.lazyPagingItems( @@ -54,4 +60,14 @@ fun LazyListScope.lazyPagingItems( @Composable fun Color.unlessDarkMode(other: Color): Color { return if (isSystemInDarkTheme()) this else other -} \ No newline at end of file +} + +@Composable +fun ColorScheme.defaultNavBarColor(): Color = primary.copy(alpha = 0.08f).compositeOver(background = surface) + +fun PaddingValues.copy( + start: Dp = this.calculateLeftPadding(LayoutDirection.Ltr), + end: Dp = this.calculateRightPadding(LayoutDirection.Ltr), + top: Dp = this.calculateTopPadding(), + bottom: Dp = this.calculateBottomPadding() +) = PaddingValues(start = start, end = end, top = top, bottom = bottom) \ No newline at end of file diff --git a/app/src/main/java/com/owenlejeune/tvtime/preferences/AppPreferences.kt b/app/src/main/java/com/owenlejeune/tvtime/preferences/AppPreferences.kt index c0c8467..4aed1bf 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/preferences/AppPreferences.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/preferences/AppPreferences.kt @@ -36,6 +36,7 @@ class AppPreferences(context: Context) { private val SHOW_POSTER_TITLE = "show_poster_titles" private val SHOW_NEXT_MCU = "show_next_mcu" private val STORED_TEST_ROUTE = "stored_test_route" + private val FLOATING_BOTTOM_BAR = "floating_bottom_bar" } private val preferences: SharedPreferences = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE) @@ -105,7 +106,7 @@ class AppPreferences(context: Context) { get() = preferences.getInt(ACCOUNT_TAB_POSITION, accountTabPositionDefault) set(value) { preferences.put(ACCOUNT_TAB_POSITION, value) } - val showBottomTabLabelsDefault: Boolean = true + val showBottomTabLabelsDefault: Boolean = false var showBottomTabLabels: Boolean get() = preferences.getBoolean(SHOW_BTAB_LABELS, showBottomTabLabelsDefault) set(value) { preferences.put(SHOW_BTAB_LABELS, value) } @@ -115,6 +116,11 @@ class AppPreferences(context: Context) { get() = preferences.getBoolean(SHOW_POSTER_TITLE, showPosterTitlesDefault) set(value) { preferences.put(SHOW_POSTER_TITLE, value) } + val floatingBottomBarDefault: Boolean = false + var floatingBottomBar: Boolean + get() = preferences.getBoolean(FLOATING_BOTTOM_BAR, floatingBottomBarDefault) + set(value) { preferences.put(FLOATING_BOTTOM_BAR, value) } + /******** Dev Preferences ********/ val firstLaunchTestingDefault: Boolean = false var firstLaunchTesting: Boolean diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/components/Menus.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/components/Menus.kt index 176c195..59e46b4 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/components/Menus.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/components/Menus.kt @@ -55,7 +55,6 @@ import kotlinx.coroutines.launch private const val ALPHA = 0.7f -@OptIn(ExperimentalMaterial3Api::class) @Composable fun ProfileMenuOverlay( appNavController: NavController, @@ -73,7 +72,7 @@ fun ProfileMenuOverlay( Card( modifier = Modifier .align(Alignment.TopCenter) - .padding(vertical = 100.dp, horizontal = 12.dp) + .padding(vertical = 100.dp, horizontal = 24.dp) .fillMaxWidth() .wrapContentHeight(), colors = CardDefaults.cardColors( diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt index 0e7cb41..a870644 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt @@ -73,6 +73,7 @@ import com.owenlejeune.tvtime.extensions.toDp import com.owenlejeune.tvtime.extensions.unlessEmpty import com.owenlejeune.tvtime.preferences.AppPreferences import com.owenlejeune.tvtime.ui.navigation.AppNavItem +import com.owenlejeune.tvtime.ui.screens.HomeScreen import com.owenlejeune.tvtime.ui.viewmodel.HomeScreenViewModel import com.owenlejeune.tvtime.utils.SessionManager import com.owenlejeune.tvtime.utils.TmdbUtils @@ -229,7 +230,8 @@ fun SearchView( contentColor = MaterialTheme.colorScheme.tertiary, onClick = { appNavController.navigate(route) - } + }, + modifier = Modifier.offset(y = if (preferences.floatingBottomBar) -(HomeScreen.FLOATING_NAV_BAR_HEIGHT - HomeScreen.FLOATING_NAV_BAR_OFFSET) else 0.dp) ) { Icon(Icons.Filled.Search, stringResource(id = R.string.preference_heading_search)) } diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AppNavigation.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AppNavigation.kt index 7f6c22f..87c2360 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AppNavigation.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AppNavigation.kt @@ -235,7 +235,7 @@ fun AppNavigationHost( // Settings View composable(AppNavItem.SettingsView.route) { applicationViewModel.currentRoute.value = AppNavItem.SettingsView.route - SettingsScreen(appNavController = appNavController) + SettingsScreen(appNavController = appNavController, windowSizeClass = windowSize) } // Web Link View composable( diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/HomeScreenNavigation.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/HomeScreenNavigation.kt index 955aa4e..e9b4b73 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/HomeScreenNavigation.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/HomeScreenNavigation.kt @@ -1,5 +1,7 @@ package com.owenlejeune.tvtime.ui.navigation +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.material.icons.Icons @@ -35,8 +37,8 @@ fun HomeScreenNavHost( NavHost( navController = navController, startDestination = startDestination, - enterTransition = { fadeIn() }, - exitTransition = { fadeOut() } + enterTransition = { EnterTransition.None }, + exitTransition = { ExitTransition.None } ) { composable(HomeScreenNavItem.Movies.route) { homeScreenViewModel.appBarActions.value = {} diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/SettingsNavigation.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/SettingsNavigation.kt index 9f17b33..81a5cb7 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/SettingsNavigation.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/SettingsNavigation.kt @@ -12,6 +12,7 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.owenlejeune.tvtime.R +import com.owenlejeune.tvtime.extensions.WindowSizeClass import com.owenlejeune.tvtime.ui.screens.DarkModePreferences import com.owenlejeune.tvtime.ui.screens.DesignPreferences import com.owenlejeune.tvtime.ui.screens.DevPreferences @@ -23,6 +24,7 @@ import com.owenlejeune.tvtime.ui.screens.SpecialFeaturePreferences @Composable fun SettingsNavigationHost( appNavController: NavController, + windowSizeClass: WindowSizeClass, appBarTitle: MutableState, popBackAction: MutableState<() -> Unit> ) { @@ -58,7 +60,7 @@ fun SettingsNavigationHost( composable(SettingsNavItem.HomeScreen.route) { appBarTitle.value = stringResource(id = R.string.preference_heading_home_screen) popBackAction.value = { settingsNavController.popBackStack() } - HomeScreenPreferences() + HomeScreenPreferences(windowSizeClass = windowSizeClass) } composable(SettingsNavItem.SpecialFeatures.route) { appBarTitle.value = stringResource(id = R.string.preference_heading_special_features) diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/HomeScreen.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/HomeScreen.kt index 74753e0..3f602aa 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/HomeScreen.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/HomeScreen.kt @@ -2,13 +2,19 @@ package com.owenlejeune.tvtime.ui.screens import android.app.Activity import androidx.activity.compose.BackHandler +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement 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.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Scaffold import androidx.compose.material3.ExperimentalMaterial3Api @@ -28,6 +34,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.compositeOver @@ -40,6 +47,7 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.owenlejeune.tvtime.extensions.WindowSizeClass +import com.owenlejeune.tvtime.extensions.defaultNavBarColor import com.owenlejeune.tvtime.extensions.navigateInBottomBar import com.owenlejeune.tvtime.preferences.AppPreferences import com.owenlejeune.tvtime.ui.components.AccountIcon @@ -50,13 +58,20 @@ import com.owenlejeune.tvtime.ui.navigation.HomeScreenNavHost import com.owenlejeune.tvtime.ui.navigation.HomeScreenNavItem import com.owenlejeune.tvtime.ui.viewmodel.HomeScreenViewModel import org.koin.java.KoinJavaComponent +import org.koin.java.KoinJavaComponent.get + +object HomeScreen { + val FLOATING_NAV_BAR_HEIGHT = 80.dp + val FLOATING_NAV_BAR_OFFSET = (-24).dp +} @OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeScreen( appNavController: NavHostController, mainNavStartRoute: String = HomeScreenNavItem.SortedItems[0].route, - windowSize: WindowSizeClass + windowSize: WindowSizeClass, + preferences: AppPreferences = get(AppPreferences::class.java) ) { val navController = rememberNavController() @@ -74,13 +89,11 @@ fun HomeScreen( ) } - val defaultNavBarColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.08f).compositeOver(background = MaterialTheme.colorScheme.surface) - ProfileMenuContainer( appNavController = appNavController, visible = showProfileMenuOverlay.value, onDismissRequest = { showProfileMenuOverlay.value = false }, - colors = ProfileMenuDefaults.systemBarColors(navBarColor = defaultNavBarColor) + colors = ProfileMenuDefaults.systemBarColors(navBarColor = MaterialTheme.colorScheme.defaultNavBarColor()) ) { Scaffold( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), @@ -98,7 +111,7 @@ fun HomeScreen( fab.value() }, bottomBar = { - if (windowSize != WindowSizeClass.Expanded) { + if (windowSize != WindowSizeClass.Expanded && !preferences.floatingBottomBar) { BottomNavBar(navController = navController) } } @@ -112,6 +125,10 @@ fun HomeScreen( mainNavStartRoute = mainNavStartRoute, navigationIcon = navigationIcon ) + + if (windowSize != WindowSizeClass.Expanded && preferences.floatingBottomBar) { + FloatingBottomNavBar(navController = navController, modifier = Modifier.align(Alignment.BottomCenter)) + } } } } @@ -137,10 +154,60 @@ private fun TopBar( ) } +@Composable +private fun FloatingBottomNavBar( + navController: NavHostController, + modifier: Modifier = Modifier, + preferences: AppPreferences = get(AppPreferences::class.java) +) { + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentRoute = navBackStackEntry?.destination?.route + + Box( + modifier = modifier.then( + Modifier + .fillMaxWidth() + .height(HomeScreen.FLOATING_NAV_BAR_HEIGHT) + .padding(horizontal = 24.dp) + .offset(y = HomeScreen.FLOATING_NAV_BAR_OFFSET) + .clip(RoundedCornerShape(50)) + .background(MaterialTheme.colorScheme.defaultNavBarColor()) + ) + ) { + Row( + modifier = Modifier.align(Alignment.Center), + verticalAlignment = Alignment.CenterVertically + ) { + HomeScreenNavItem.SortedItems.forEach { item -> + val isSelected = currentRoute == item.route + NavigationBarItem( + modifier = Modifier.clip(RoundedCornerShape(25.dp)), + icon = { Icon(imageVector = item.icon, contentDescription = null) }, + label = { + if (preferences.showBottomTabLabels) { + Text(text = item.name) + } + }, + selected = isSelected, + onClick = { + if (!isSelected) { + navController.navigateInBottomBar(item.route) + } + }, + colors = NavigationBarItemDefaults.colors( + indicatorColor = MaterialTheme.colorScheme.secondary, + selectedIconColor = MaterialTheme.colorScheme.onSecondary + ) + ) + } + } + } +} + @Composable private fun BottomNavBar( navController: NavController, - preferences: AppPreferences = KoinJavaComponent.get(AppPreferences::class.java) + preferences: AppPreferences = get(AppPreferences::class.java) ) { val navBackStackEntry by navController.currentBackStackEntryAsState() val currentRoute = navBackStackEntry?.destination?.route @@ -220,7 +287,7 @@ private fun DualColumnMainContent( topBarScrollBehaviour: TopAppBarScrollBehavior, navigationIcon: @Composable () -> Unit = {}, mainNavStartRoute: String = HomeScreenNavItem.SortedItems[0].route, - preferences: AppPreferences = KoinJavaComponent.get(AppPreferences::class.java) + preferences: AppPreferences = get(AppPreferences::class.java) ) { val navBackStackEntry by navController.currentBackStackEntryAsState() val currentRoute = navBackStackEntry?.destination?.route diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/SettingsScreen.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/SettingsScreen.kt index 97d91ad..e7fd71a 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/SettingsScreen.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/SettingsScreen.kt @@ -16,7 +16,9 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll import androidx.compose.material.IconButton import androidx.compose.material.TextButton import androidx.compose.material.icons.Icons @@ -67,6 +69,7 @@ import com.kieronquinn.monetcompat.core.MonetCompat import com.owenlejeune.tvtime.BuildConfig import com.owenlejeune.tvtime.OnboardingActivity import com.owenlejeune.tvtime.R +import com.owenlejeune.tvtime.extensions.WindowSizeClass import com.owenlejeune.tvtime.extensions.unlessEmpty import com.owenlejeune.tvtime.preferences.AppPreferences import com.owenlejeune.tvtime.ui.components.CenteredIconCircle @@ -89,7 +92,8 @@ import org.koin.java.KoinJavaComponent.get @OptIn(ExperimentalMaterial3Api::class) @Composable fun SettingsScreen( - appNavController: NavController + appNavController: NavController, + windowSizeClass: WindowSizeClass ) { val applicationViewModel = viewModel() applicationViewModel.statusBarColor.value = MaterialTheme.colorScheme.background @@ -137,7 +141,8 @@ fun SettingsScreen( SettingsNavigationHost( appNavController = appNavController, appBarTitle = appBarTitle, - popBackAction = popBackAction + popBackAction = popBackAction, + windowSizeClass = windowSizeClass ) } } @@ -150,7 +155,8 @@ fun SettingsHome( Column( modifier = Modifier .fillMaxSize() - .padding(all = 24.dp), + .padding(horizontal = 24.dp) + .verticalScroll(state = rememberScrollState()), verticalArrangement = Arrangement.spacedBy(24.dp) ) { TopLevelSettingsCard( @@ -202,7 +208,8 @@ fun SearchPreferences() { Column( modifier = Modifier .fillMaxSize() - .padding(all = 24.dp), + .padding(horizontal = 24.dp) + .verticalScroll(state = rememberScrollState()), verticalArrangement = Arrangement.spacedBy(24.dp) ) { SwitchPreference( @@ -235,7 +242,8 @@ fun DesignPreferences( Column( modifier = Modifier .fillMaxSize() - .padding(all = 24.dp), + .padding(horizontal = 24.dp) + .verticalScroll(state = rememberScrollState()), verticalArrangement = Arrangement.spacedBy(24.dp) ) { TopLevelSettingsCard( @@ -325,7 +333,8 @@ fun DarkModePreferences() { Column( modifier = Modifier .fillMaxSize() - .padding(all = 24.dp), + .padding(horizontal = 24.dp) + .verticalScroll(state = rememberScrollState()), verticalArrangement = Arrangement.spacedBy(24.dp) ) { PreferenceHeading(text = stringResource(R.string.preference_dark_mode_automatic_heading)) @@ -359,13 +368,14 @@ fun DarkModePreferences() { } @Composable -fun HomeScreenPreferences() { +fun HomeScreenPreferences(windowSizeClass: WindowSizeClass) { val settingsViewModel = viewModel() Column( modifier = Modifier .fillMaxSize() - .padding(all = 24.dp), + .padding(horizontal = 24.dp) + .verticalScroll(state = rememberScrollState()), verticalArrangement = Arrangement.spacedBy(24.dp) ) { PreferenceHeading(text = stringResource(R.string.preference_look_and_feel_heading)) @@ -387,6 +397,17 @@ fun HomeScreenPreferences() { settingsViewModel.toggleShowPosterTitles() } ) + + if (windowSizeClass != WindowSizeClass.Expanded) { + SwitchPreference( + titleText = "Floating bottom navigation bar", + subtitleText = "Show the bottom navigation bar as a floating overlay", + checkState = settingsViewModel.showFloatingBottomBar.collectAsState(), + onCheckedChange = { + settingsViewModel.toggleShowFloatingBottomBar() + } + ) + } PreferenceHeading(text = stringResource(R.string.preference_home_tab_order_heading)) @@ -398,6 +419,7 @@ fun HomeScreenPreferences() { shape = RoundedCornerShape(10.dp) ) .padding(horizontal = 12.dp) + .wrapContentHeight() ) { AndroidView( modifier = Modifier.fillMaxWidth(), @@ -424,7 +446,8 @@ fun SpecialFeaturePreferences() { Column( modifier = Modifier .fillMaxSize() - .padding(all = 24.dp), + .padding(horizontal = 24.dp) + .verticalScroll(state = rememberScrollState()), verticalArrangement = Arrangement.spacedBy(24.dp) ) { SwitchPreference( @@ -449,7 +472,8 @@ fun DevPreferences(preferences: AppPreferences = get(AppPreferences::class.java) Column( modifier = Modifier .fillMaxSize() - .padding(all = 24.dp), + .padding(horizontal = 24.dp) + .verticalScroll(state = rememberScrollState()), verticalArrangement = Arrangement.spacedBy(24.dp) ) { SwitchPreference( diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/theme/Theme.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/theme/Theme.kt index 61c44eb..5bb5ca7 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/theme/Theme.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/theme/Theme.kt @@ -1,13 +1,20 @@ package com.owenlejeune.tvtime.ui.theme +import android.app.Activity +import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material.Colors import androidx.compose.material.MaterialTheme import androidx.compose.material3.darkColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.remember +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat import androidx.lifecycle.viewmodel.compose.viewModel import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.kieronquinn.monetcompat.core.MonetCompat @@ -124,7 +131,18 @@ fun TVTimeTheme( val systemUiController = rememberSystemUiController() systemUiController.setStatusBarColor(color = statusBarColor) - systemUiController.setNavigationBarColor(color = navigationBarColor) + systemUiController.setNavigationBarColor(color = Color.Transparent) +// systemUiController.setNavigationBarColor(color = navigationBarColor) + + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.navigationBarColor = Color.Transparent.toArgb() + + WindowCompat.getInsetsController(window, view).isAppearanceLightNavigationBars = isDarkTheme + } + } } ) } diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/viewmodel/SettingsViewModel.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/viewmodel/SettingsViewModel.kt index 72070c3..2137090 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/viewmodel/SettingsViewModel.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/viewmodel/SettingsViewModel.kt @@ -24,6 +24,7 @@ class SettingsViewModel: ViewModel() { private val _firstLaunchTesting = MutableStateFlow(preferences.firstLaunchTesting) private val _showBackdropGallery = MutableStateFlow(preferences.showBackdropGallery) private val _showNextMcuProduction = MutableStateFlow(preferences.showNextMcuProduction) + private val _showFloatingBottomBar = MutableStateFlow(preferences.floatingBottomBar) } val showSearchBar = _showSearchBar.asStateFlow() @@ -38,6 +39,7 @@ class SettingsViewModel: ViewModel() { val firstLaunchTesting = _firstLaunchTesting.asStateFlow() val showBackdropGallery = _showBackdropGallery.asStateFlow() val showNextMcuProduction = _showNextMcuProduction.asStateFlow() + val showFloatingBottomBar = _showFloatingBottomBar.asStateFlow() fun toggleShowSearchBar() { _showSearchBar.value = _showSearchBar.value.not() @@ -144,4 +146,14 @@ class SettingsViewModel: ViewModel() { preferences.showNextMcuProduction = value } + fun toggleShowFloatingBottomBar() { + _showFloatingBottomBar.value = _showFloatingBottomBar.value.not() + preferences.floatingBottomBar = _showFloatingBottomBar.value + } + + fun setShowFloatingBottomBar(value: Boolean) { + _showFloatingBottomBar.value = value + preferences.floatingBottomBar = value + } + } \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index f933468..0dd83e8 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -2,5 +2,6 @@ \ No newline at end of file