mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-08 04:32:43 -05:00
add option for floating bottom bar design
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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 <T: Any> LazyGridScope.lazyPagingItems(
|
||||
@@ -54,4 +60,14 @@ fun <T: Any> LazyListScope.lazyPagingItems(
|
||||
@Composable
|
||||
fun Color.unlessDarkMode(other: Color): Color {
|
||||
return if (isSystemInDarkTheme()) this else other
|
||||
}
|
||||
}
|
||||
|
||||
@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)
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 = {}
|
||||
|
||||
@@ -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<String>,
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>()
|
||||
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<SettingsViewModel>()
|
||||
|
||||
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(
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,5 +2,6 @@
|
||||
<resources>
|
||||
|
||||
<style name="Theme.TVTime" parent="Theme.AppCompat.NoActionBar">
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
</style>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user