mirror of
https://github.com/owenlejeune/TVTime.git
synced 2026-02-17 18:36:51 -05:00
add preference to use system colors or not
This commit is contained in:
@@ -352,6 +352,7 @@ class MainActivity : MonetCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MainNavGraph(
|
MainNavGraph(
|
||||||
|
activity = this@MainActivity,
|
||||||
appNavController = appNavController,
|
appNavController = appNavController,
|
||||||
navController = navController,
|
navController = navController,
|
||||||
appBarTitle = appBarTitle,
|
appBarTitle = appBarTitle,
|
||||||
|
|||||||
@@ -26,10 +26,12 @@ class AppPreferences(context: Context) {
|
|||||||
private val SELECTED_COLOR = "selected_color"
|
private val SELECTED_COLOR = "selected_color"
|
||||||
private val USE_V4_API = "use_v4_api"
|
private val USE_V4_API = "use_v4_api"
|
||||||
private val SHOW_BACKDROP_GALLERY = "show_backdrop_gallery"
|
private val SHOW_BACKDROP_GALLERY = "show_backdrop_gallery"
|
||||||
|
private val USE_WALLPAPER_COLORS = "use_wallpaper_colors"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val preferences: SharedPreferences = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE)
|
private val preferences: SharedPreferences = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE)
|
||||||
|
|
||||||
|
/******** Search Preferences ********/
|
||||||
var persistentSearch: Boolean
|
var persistentSearch: Boolean
|
||||||
get() = preferences.getBoolean(PERSISTENT_SEARCH, true)
|
get() = preferences.getBoolean(PERSISTENT_SEARCH, true)
|
||||||
set(value) { preferences.put(PERSISTENT_SEARCH, value) }
|
set(value) { preferences.put(PERSISTENT_SEARCH, value) }
|
||||||
@@ -38,6 +40,25 @@ class AppPreferences(context: Context) {
|
|||||||
get() = preferences.getBoolean(HIDE_TITLE, false)
|
get() = preferences.getBoolean(HIDE_TITLE, false)
|
||||||
set(value) { preferences.put(HIDE_TITLE, value) }
|
set(value) { preferences.put(HIDE_TITLE, value) }
|
||||||
|
|
||||||
|
var useWallpaperColors: Boolean
|
||||||
|
get() = preferences.getBoolean(USE_WALLPAPER_COLORS, true)
|
||||||
|
set(value) { preferences.put(USE_WALLPAPER_COLORS, value) }
|
||||||
|
|
||||||
|
|
||||||
|
/******* Design Preferences ********/
|
||||||
|
var useSystemColors: Boolean
|
||||||
|
get() = preferences.getBoolean(USE_SYSTEM_COLORS, true)
|
||||||
|
set(value) { preferences.put(USE_SYSTEM_COLORS, value) }
|
||||||
|
|
||||||
|
var chromaMultiplier: Double
|
||||||
|
get() = preferences.getFloat(CHROMA_MULTIPLIER, MonetCompat.chromaMultiplier.toFloat()).toDouble()
|
||||||
|
set(value) { preferences.put(CHROMA_MULTIPLIER, value) }
|
||||||
|
|
||||||
|
var selectedColor: Int
|
||||||
|
get() = preferences.getInt(SELECTED_COLOR, Int.MAX_VALUE)
|
||||||
|
set(value) { preferences.put(SELECTED_COLOR, value) }
|
||||||
|
|
||||||
|
/******* Session Tokens ********/
|
||||||
var guestSessionId: String
|
var guestSessionId: String
|
||||||
get() = preferences.getString(GUEST_SESSION, "") ?: ""
|
get() = preferences.getString(GUEST_SESSION, "") ?: ""
|
||||||
set(value) { preferences.put(GUEST_SESSION, value) }
|
set(value) { preferences.put(GUEST_SESSION, value) }
|
||||||
@@ -51,11 +72,8 @@ class AppPreferences(context: Context) {
|
|||||||
var authorizedSessionId: String
|
var authorizedSessionId: String
|
||||||
get() = preferences.getString(AUTHORIZED_SESSION, "") ?: ""
|
get() = preferences.getString(AUTHORIZED_SESSION, "") ?: ""
|
||||||
set(value) { preferences.put(AUTHORIZED_SESSION, value) }
|
set(value) { preferences.put(AUTHORIZED_SESSION, value) }
|
||||||
// val usePreferences: MutableState<Boolean>
|
|
||||||
// var usePreferences: Boolean
|
|
||||||
// get() = preferences.getBoolean(USE_PREFERENCES, false)
|
|
||||||
// set(value) { preferences.put(USE_PREFERENCES, value) }
|
|
||||||
|
|
||||||
|
/******** Dev Preferences ********/
|
||||||
var firstLaunchTesting: Boolean
|
var firstLaunchTesting: Boolean
|
||||||
get() = preferences.getBoolean(FIRST_LAUNCH_TESTING, false)
|
get() = preferences.getBoolean(FIRST_LAUNCH_TESTING, false)
|
||||||
set(value) { preferences.put(FIRST_LAUNCH_TESTING, value) }
|
set(value) { preferences.put(FIRST_LAUNCH_TESTING, value) }
|
||||||
@@ -64,18 +82,6 @@ class AppPreferences(context: Context) {
|
|||||||
get() = if (BuildConfig.DEBUG) firstLaunchTesting else preferences.getBoolean(FIRST_LAUNCH, true)
|
get() = if (BuildConfig.DEBUG) firstLaunchTesting else preferences.getBoolean(FIRST_LAUNCH, true)
|
||||||
set(value) { preferences.put(FIRST_LAUNCH, value) }
|
set(value) { preferences.put(FIRST_LAUNCH, value) }
|
||||||
|
|
||||||
var useSystemColors: Boolean
|
|
||||||
get() = preferences.getBoolean(USE_SYSTEM_COLORS, true)
|
|
||||||
set(value) { preferences.put(USE_SYSTEM_COLORS, value) }
|
|
||||||
|
|
||||||
var chromaMultiplier: Double
|
|
||||||
get() = preferences.getFloat(CHROMA_MULTIPLIER, MonetCompat.chromaMultiplier.toFloat()).toDouble()
|
|
||||||
set(value) { preferences.put(CHROMA_MULTIPLIER, value) }
|
|
||||||
|
|
||||||
var selectedColor: Int
|
|
||||||
get() = preferences.getInt(SELECTED_COLOR, Int.MAX_VALUE)
|
|
||||||
set(value) { preferences.put(SELECTED_COLOR, value) }
|
|
||||||
|
|
||||||
var useV4Api: Boolean
|
var useV4Api: Boolean
|
||||||
get() = preferences.getBoolean(USE_V4_API, true)
|
get() = preferences.getBoolean(USE_V4_API, true)
|
||||||
set(value) { preferences.put(USE_V4_API, value) }
|
set(value) { preferences.put(USE_V4_API, value) }
|
||||||
|
|||||||
@@ -71,12 +71,6 @@ fun SwitchPreference(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
private fun SwitchPreferencePreview() {
|
|
||||||
SwitchPreference("Title", true, subtitleText = "Subtitle")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SliderPreference(
|
fun SliderPreference(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|||||||
@@ -196,16 +196,6 @@ fun CustomSwitch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview(name = "TopLevelSwitch", showBackground = true)
|
|
||||||
@Preview(name = "Dark TopLevelSwitch", showBackground = true, uiMode = UI_MODE_NIGHT_YES)
|
|
||||||
@Composable
|
|
||||||
fun TopLevelSwitchPreview() {
|
|
||||||
val context = LocalContext.current
|
|
||||||
TopLevelSwitch("This is a switch") { isChecked ->
|
|
||||||
Toast.makeText(context, "Switch changed to $isChecked", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SearchFab(
|
fun SearchFab(
|
||||||
focusSearchBar: MutableState<Boolean> = mutableStateOf(false),
|
focusSearchBar: MutableState<Boolean> = mutableStateOf(false),
|
||||||
@@ -221,12 +211,6 @@ fun SearchFab(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun SearchFabPreview() {
|
|
||||||
SearchFab()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MinLinesText(
|
fun MinLinesText(
|
||||||
text: String,
|
text: String,
|
||||||
@@ -438,12 +422,6 @@ fun ChipGroup(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun ChipPreview() {
|
|
||||||
BoxyChip("Test Chip")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param progress The progress of the ring as a value between 0 and 1
|
* @param progress The progress of the ring as a value between 0 and 1
|
||||||
*/
|
*/
|
||||||
@@ -566,28 +544,6 @@ fun RoundedTextField(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview(widthDp = 300, heightDp = 40)
|
|
||||||
@Composable
|
|
||||||
private fun RoundedEditTextPreview() {
|
|
||||||
RoundedTextField(
|
|
||||||
value = "this is my value",
|
|
||||||
onValueChange = {},
|
|
||||||
placeHolder = "this is my placeholder",
|
|
||||||
trailingIcon = {
|
|
||||||
Image(
|
|
||||||
painter = painterResource(id = R.drawable.ic_search),
|
|
||||||
contentDescription = ""
|
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingIcon = {
|
|
||||||
Image(
|
|
||||||
painter = painterResource(id = R.drawable.ic_search),
|
|
||||||
contentDescription = ""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun FullScreenThumbnailVideoPlayer(
|
fun FullScreenThumbnailVideoPlayer(
|
||||||
@@ -689,18 +645,6 @@ fun CircleBackgroundColorImage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
@Preview
|
|
||||||
private fun CircleBackgroundColorImagePreview() {
|
|
||||||
CircleBackgroundColorImage(
|
|
||||||
size = 100.dp,
|
|
||||||
backgroundColor = MaterialTheme.colorScheme.inverseSurface,
|
|
||||||
painter = painterResource(id = R.drawable.ic_rating_star),
|
|
||||||
colorFilter = ColorFilter.tint(color = RatingSelected),
|
|
||||||
imageSize = DpSize(width = 70.dp, height = 70.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CircleBackgroundColorImage(
|
fun CircleBackgroundColorImage(
|
||||||
size: Dp,
|
size: Dp,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.owenlejeune.tvtime.ui.navigation
|
package com.owenlejeune.tvtime.ui.navigation
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
@@ -18,42 +19,9 @@ object NavConstants {
|
|||||||
const val TYPE_KEY = "type_key"
|
const val TYPE_KEY = "type_key"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun MainNavigationRoutes(
|
|
||||||
navController: NavHostController,
|
|
||||||
startDestination: String = MainNavItem.MainView.route
|
|
||||||
) {
|
|
||||||
NavHost(navController = navController, startDestination = startDestination) {
|
|
||||||
composable(MainNavItem.MainView.route) {
|
|
||||||
MainAppView(appNavController = navController)
|
|
||||||
}
|
|
||||||
composable(
|
|
||||||
MainNavItem.DetailView.route.plus("/{${NavConstants.TYPE_KEY}}/{${NavConstants.ID_KEY}}"),
|
|
||||||
arguments = listOf(
|
|
||||||
navArgument(NavConstants.ID_KEY) { type = NavType.IntType },
|
|
||||||
navArgument(NavConstants.TYPE_KEY) { type = NavType.EnumType(MediaViewType::class.java) }
|
|
||||||
)
|
|
||||||
) { navBackStackEntry ->
|
|
||||||
val args = navBackStackEntry.arguments
|
|
||||||
val mediaType = args?.getSerializable(NavConstants.TYPE_KEY) as MediaViewType
|
|
||||||
if (mediaType != MediaViewType.PERSON) {
|
|
||||||
MediaDetailView(
|
|
||||||
appNavController = navController,
|
|
||||||
itemId = args.getInt(NavConstants.ID_KEY),
|
|
||||||
type = mediaType
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
PersonDetailView(
|
|
||||||
appNavController = navController,
|
|
||||||
personId = args.getInt(NavConstants.ID_KEY)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainNavGraph(
|
fun MainNavGraph(
|
||||||
|
activity: AppCompatActivity,
|
||||||
appNavController: NavHostController,
|
appNavController: NavHostController,
|
||||||
navController: NavHostController,
|
navController: NavHostController,
|
||||||
appBarTitle: MutableState<String>,
|
appBarTitle: MutableState<String>,
|
||||||
@@ -82,7 +50,7 @@ fun MainNavGraph(
|
|||||||
// }
|
// }
|
||||||
composable(BottomNavItem.Settings.route) {
|
composable(BottomNavItem.Settings.route) {
|
||||||
appBarActions.value = {}
|
appBarActions.value = {}
|
||||||
SettingsTab(appBarTitle = appBarTitle)
|
SettingsTab(appBarTitle = appBarTitle, activity = activity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
package com.owenlejeune.tvtime.ui.screens.main
|
|
||||||
|
|
||||||
import androidx.compose.animation.rememberSplineBasedDecay
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.material.Scaffold
|
|
||||||
import androidx.compose.material3.*
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import androidx.navigation.NavHostController
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
|
||||||
import com.owenlejeune.tvtime.R
|
|
||||||
import com.owenlejeune.tvtime.preferences.AppPreferences
|
|
||||||
import com.owenlejeune.tvtime.ui.components.RoundedTextField
|
|
||||||
import com.owenlejeune.tvtime.ui.components.SearchFab
|
|
||||||
import com.owenlejeune.tvtime.ui.navigation.BottomNavItem
|
|
||||||
import com.owenlejeune.tvtime.ui.navigation.MainNavGraph
|
|
||||||
import com.owenlejeune.tvtime.utils.KeyboardManager
|
|
||||||
import org.koin.java.KoinJavaComponent.get
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalPagerApi::class)
|
|
||||||
@Composable
|
|
||||||
fun MainAppView(appNavController: NavHostController, preferences: AppPreferences = get(AppPreferences::class.java)) {
|
|
||||||
val navController = rememberNavController()
|
|
||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
|
||||||
val currentRoute = navBackStackEntry?.destination?.route
|
|
||||||
|
|
||||||
val appBarTitle = rememberSaveable { mutableStateOf(BottomNavItem.getByRoute(currentRoute)?.name ?: BottomNavItem.Items[0].name) }
|
|
||||||
val decayAnimationSpec = rememberSplineBasedDecay<Float>()
|
|
||||||
val topAppBarScrollState = rememberTopAppBarScrollState()
|
|
||||||
val scrollBehavior = remember(decayAnimationSpec) {
|
|
||||||
TopAppBarDefaults.exitUntilCollapsedScrollBehavior(decayAnimationSpec, topAppBarScrollState)
|
|
||||||
}
|
|
||||||
|
|
||||||
val focusRequester = remember { FocusRequester() }
|
|
||||||
val focusSearchBar = rememberSaveable { mutableStateOf(false) }
|
|
||||||
val searchableScreens = listOf(BottomNavItem.Movies.route, BottomNavItem.TV.route, BottomNavItem.People.route)
|
|
||||||
|
|
||||||
val appBarActions = remember { mutableStateOf<@Composable RowScope.() -> Unit>( {} ) }
|
|
||||||
|
|
||||||
// todo - scroll state not remember when returing from detail screen
|
|
||||||
|
|
||||||
Scaffold(
|
|
||||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
|
||||||
backgroundColor = MaterialTheme.colorScheme.background,
|
|
||||||
bottomBar = {
|
|
||||||
BottomNavBar(
|
|
||||||
navController = navController,
|
|
||||||
appBarTitle = appBarTitle
|
|
||||||
)
|
|
||||||
},
|
|
||||||
topBar = {
|
|
||||||
if (currentRoute in searchableScreens) {
|
|
||||||
SearchTopBar(
|
|
||||||
title = appBarTitle,
|
|
||||||
scrollBehavior = scrollBehavior,
|
|
||||||
requestSearchFocus = focusSearchBar,
|
|
||||||
focusRequester = focusRequester
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TopBar(
|
|
||||||
title = appBarTitle,
|
|
||||||
scrollBehavior = scrollBehavior,
|
|
||||||
appBarActions = appBarActions
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
floatingActionButton = {
|
|
||||||
if (currentRoute in searchableScreens && !preferences.persistentSearch && !focusSearchBar.value) {
|
|
||||||
SearchFab(
|
|
||||||
focusSearchBar = focusSearchBar,
|
|
||||||
focusRequester = focusRequester
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) { innerPadding ->
|
|
||||||
Box(modifier = Modifier.padding(innerPadding)) {
|
|
||||||
MainNavGraph(appNavController = appNavController, navController = navController, appBarTitle = appBarTitle, appBarActions = appBarActions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TopBar(
|
|
||||||
title: MutableState<String>,
|
|
||||||
scrollBehavior: TopAppBarScrollBehavior,
|
|
||||||
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({})
|
|
||||||
) {
|
|
||||||
LargeTopAppBar(
|
|
||||||
title = { Text(text = title.value) },
|
|
||||||
scrollBehavior = scrollBehavior,
|
|
||||||
colors = TopAppBarDefaults
|
|
||||||
.largeTopAppBarColors(
|
|
||||||
scrolledContainerColor = MaterialTheme.colorScheme.background,
|
|
||||||
titleContentColor = MaterialTheme.colorScheme.primary
|
|
||||||
),
|
|
||||||
actions = appBarActions.value
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun SearchTopBar(
|
|
||||||
title: MutableState<String>,
|
|
||||||
scrollBehavior: TopAppBarScrollBehavior,
|
|
||||||
requestSearchFocus: MutableState<Boolean> = remember { mutableStateOf(false) },
|
|
||||||
focusRequester: FocusRequester = remember { FocusRequester() },
|
|
||||||
preferences: AppPreferences = get(AppPreferences::class.java)
|
|
||||||
) {
|
|
||||||
SmallTopAppBar(
|
|
||||||
title = {
|
|
||||||
Row(
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
val hasSearchFocus = rememberSaveable { mutableStateOf(requestSearchFocus.value) }
|
|
||||||
if (!requestSearchFocus.value && !hasSearchFocus.value && !(preferences.persistentSearch && preferences.hideTitle)) {
|
|
||||||
Text(text = title.value)
|
|
||||||
}
|
|
||||||
if (requestSearchFocus.value || preferences.persistentSearch) {
|
|
||||||
var textState by remember { mutableStateOf("") }
|
|
||||||
val basePadding = 8.dp
|
|
||||||
RoundedTextField(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(
|
|
||||||
end = if (hasSearchFocus.value || preferences.hideTitle) (basePadding * 3) else basePadding,
|
|
||||||
start = if (hasSearchFocus.value || preferences.hideTitle) 0.dp else basePadding
|
|
||||||
)
|
|
||||||
.height(35.dp)
|
|
||||||
.onFocusChanged { focusState ->
|
|
||||||
hasSearchFocus.value = focusState.isFocused
|
|
||||||
},
|
|
||||||
requestFocus = requestSearchFocus.value,
|
|
||||||
focusRequester = focusRequester,
|
|
||||||
value = textState,
|
|
||||||
onValueChange = { textState = it },
|
|
||||||
placeHolder = stringResource(id = R.string.search_placeholder, title.value),
|
|
||||||
trailingIcon = {
|
|
||||||
Image(
|
|
||||||
painter = painterResource(id = R.drawable.ic_search),
|
|
||||||
contentDescription = stringResource(R.string.search_icon_content_descriptor),
|
|
||||||
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.primary)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scrollBehavior = scrollBehavior,
|
|
||||||
colors = TopAppBarDefaults
|
|
||||||
.largeTopAppBarColors(
|
|
||||||
scrolledContainerColor = MaterialTheme.colorScheme.background,
|
|
||||||
titleContentColor = MaterialTheme.colorScheme.primary
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
val context = LocalContext.current
|
|
||||||
val keyboardManager = KeyboardManager.getInstance(context)
|
|
||||||
keyboardManager.attachKeyboardDismissListener {
|
|
||||||
requestSearchFocus.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun BottomNavBar(navController: NavController, appBarTitle: MutableState<String>) {
|
|
||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
|
||||||
val currentRoute = navBackStackEntry?.destination?.route
|
|
||||||
|
|
||||||
NavigationBar {
|
|
||||||
BottomNavItem.Items.forEach { item ->
|
|
||||||
NavigationBarItem(
|
|
||||||
icon = { Icon(painter = painterResource(id = item.icon), contentDescription = null) },
|
|
||||||
label = { Text(item.name) },
|
|
||||||
selected = currentRoute == item.route,
|
|
||||||
onClick = {
|
|
||||||
onBottomAppBarItemClicked(
|
|
||||||
navController = navController,
|
|
||||||
appBarTitle = appBarTitle,
|
|
||||||
item = item
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onBottomAppBarItemClicked(
|
|
||||||
navController: NavController,
|
|
||||||
appBarTitle: MutableState<String>,
|
|
||||||
item: BottomNavItem
|
|
||||||
) {
|
|
||||||
appBarTitle.value = item.name
|
|
||||||
navController.navigate(item.route) {
|
|
||||||
navController.graph.startDestinationRoute?.let { screenRoute ->
|
|
||||||
popUpTo(screenRoute) {
|
|
||||||
saveState = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
launchSingleTop = true
|
|
||||||
restoreState = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -88,13 +88,4 @@ fun MediaTabs(
|
|||||||
HorizontalPager(count = tabs.size, state = pagerState) { page ->
|
HorizontalPager(count = tabs.size, state = pagerState) { page ->
|
||||||
tabs[page].screen(appNavController, mediaViewType, tabs[page])
|
tabs[page].screen(appNavController, mediaViewType, tabs[page])
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalPagerApi::class)
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Composable
|
|
||||||
fun MediaTabsPreview() {
|
|
||||||
val tabs = MediaTabNavItem.MovieItems
|
|
||||||
val pagerState = rememberPagerState()
|
|
||||||
MediaTabs(tabs = tabs, pagerState = pagerState, MediaViewType.MOVIE)
|
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.owenlejeune.tvtime.ui.screens.main
|
|||||||
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
@@ -42,6 +43,7 @@ import org.koin.java.KoinJavaComponent.get
|
|||||||
@Composable
|
@Composable
|
||||||
fun SettingsTab(
|
fun SettingsTab(
|
||||||
appBarTitle: MutableState<String>,
|
appBarTitle: MutableState<String>,
|
||||||
|
activity: AppCompatActivity,
|
||||||
preferences: AppPreferences = get(AppPreferences::class.java)
|
preferences: AppPreferences = get(AppPreferences::class.java)
|
||||||
) {
|
) {
|
||||||
appBarTitle.value = stringResource(id = R.string.nav_settings_title)
|
appBarTitle.value = stringResource(id = R.string.nav_settings_title)
|
||||||
@@ -54,23 +56,7 @@ fun SettingsTab(
|
|||||||
.padding(start = 8.dp, top = 8.dp, bottom = 8.dp, end = 24.dp)
|
.padding(start = 8.dp, top = 8.dp, bottom = 8.dp, end = 24.dp)
|
||||||
.verticalScroll(scrollState)
|
.verticalScroll(scrollState)
|
||||||
) {
|
) {
|
||||||
// val usePreferences = remember { mutableStateOf(preferences.usePreferences) }
|
/******* Search Preferences ********/
|
||||||
// TopLevelSwitch(
|
|
||||||
// text = "Enable Preferences",
|
|
||||||
// checkedState = usePreferences,
|
|
||||||
// onCheckChanged = { isChecked ->
|
|
||||||
// usePreferences.value = isChecked
|
|
||||||
// preferences.usePreferences = isChecked
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// Column(
|
|
||||||
// modifier = Modifier
|
|
||||||
// .fillMaxWidth()
|
|
||||||
// .wrapContentHeight()
|
|
||||||
// .padding(start = 8.dp, top = 8.dp, bottom = 8.dp, end = 24.dp)
|
|
||||||
// .verticalScroll()
|
|
||||||
// ) {
|
|
||||||
PreferenceHeading(text = stringResource(R.string.preference_heading_search))
|
PreferenceHeading(text = stringResource(R.string.preference_heading_search))
|
||||||
|
|
||||||
val persistentSearch = remember { mutableStateOf(preferences.persistentSearch) }
|
val persistentSearch = remember { mutableStateOf(preferences.persistentSearch) }
|
||||||
@@ -96,20 +82,35 @@ fun SettingsTab(
|
|||||||
enabled = persistentSearch.value
|
enabled = persistentSearch.value
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/******* Design Preferences ********/
|
||||||
PreferenceHeading(text = stringResource(id = R.string.preference_heading_design))
|
PreferenceHeading(text = stringResource(id = R.string.preference_heading_design))
|
||||||
|
|
||||||
|
val useWallpaperColors = remember { mutableStateOf(preferences.useWallpaperColors) }
|
||||||
|
SwitchPreference(
|
||||||
|
titleText = stringResource(R.string.preferences_use_wallpaper_colors_title),
|
||||||
|
subtitleText = stringResource(R.string.preferences_use_wallpaper_colors_subtitle),
|
||||||
|
checkState = useWallpaperColors.value,
|
||||||
|
onCheckedChange = { isChecked ->
|
||||||
|
useWallpaperColors.value = isChecked
|
||||||
|
preferences.useWallpaperColors = isChecked
|
||||||
|
activity.recreate()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
val isSystemColorsSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
val isSystemColorsSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||||
if (isSystemColorsSupported) {
|
if (isSystemColorsSupported) {
|
||||||
val useSystemColors = remember { mutableStateOf(preferences.useSystemColors) }
|
val useSystemColors = remember { mutableStateOf(preferences.useSystemColors) }
|
||||||
SwitchPreference(
|
SwitchPreference(
|
||||||
titleText = stringResource(id = R.string.preference_system_colors_heading),
|
titleText = stringResource(id = R.string.preference_system_colors_heading),
|
||||||
|
subtitleText = stringResource(R.string.preference_system_colors_subtitle),
|
||||||
checkState = useSystemColors.value,
|
checkState = useSystemColors.value,
|
||||||
onCheckedChange = { isChecked ->
|
onCheckedChange = { isChecked ->
|
||||||
useSystemColors.value = isChecked
|
useSystemColors.value = isChecked
|
||||||
preferences.useSystemColors = isChecked
|
preferences.useSystemColors = isChecked
|
||||||
MonetCompat.useSystemColorsOnAndroid12 = isChecked
|
MonetCompat.useSystemColorsOnAndroid12 = isChecked
|
||||||
MonetCompat.getInstance().updateMonetColors()
|
MonetCompat.getInstance().updateMonetColors()
|
||||||
}
|
},
|
||||||
|
enabled = useWallpaperColors.value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,11 +124,11 @@ fun SettingsTab(
|
|||||||
}
|
}
|
||||||
MonetCompat.getInstance().updateMonetColors()
|
MonetCompat.getInstance().updateMonetColors()
|
||||||
},
|
},
|
||||||
enabled = if (isSystemColorsSupported) !preferences.useSystemColors else true
|
enabled = (if (isSystemColorsSupported) !preferences.useSystemColors else true).and(useWallpaperColors.value)
|
||||||
)
|
)
|
||||||
|
|
||||||
val showWallpaperPicker = remember { mutableStateOf(false) }
|
val showWallpaperPicker = remember { mutableStateOf(false) }
|
||||||
val wallpaperPickerModifier = if (isSystemColorsSupported && preferences.useSystemColors) {
|
val wallpaperPickerModifier = if (isSystemColorsSupported && preferences.useSystemColors && useWallpaperColors.value) {
|
||||||
Modifier
|
Modifier
|
||||||
} else {
|
} else {
|
||||||
Modifier.clickable { showWallpaperPicker.value = true }
|
Modifier.clickable { showWallpaperPicker.value = true }
|
||||||
@@ -148,8 +149,9 @@ fun SettingsTab(
|
|||||||
WallpaperPicker(showPopup = showWallpaperPicker)
|
WallpaperPicker(showPopup = showWallpaperPicker)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******* Dev Preferences ********/
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
Divider(modifier = Modifier.padding(start = 8.dp, top = 20.dp))
|
Divider(modifier = Modifier.padding(start = 8.dp, top = 20.dp), color = MaterialTheme.colorScheme.primaryContainer)
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.padding(start = 8.dp, top = 20.dp),
|
modifier = Modifier.padding(start = 8.dp, top = 20.dp),
|
||||||
text = stringResource(R.string.preferences_debug_title),
|
text = stringResource(R.string.preferences_debug_title),
|
||||||
|
|||||||
@@ -137,12 +137,3 @@ private fun SmallTabIndicator(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalPagerApi::class)
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Composable
|
|
||||||
fun TabsPreview() {
|
|
||||||
val tabs = MediaTabNavItem.MovieItems
|
|
||||||
val pagerState = rememberPagerState()
|
|
||||||
Tabs(tabs = tabs, pagerState = pagerState)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import androidx.compose.material3.lightColorScheme
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.kieronquinn.monetcompat.core.MonetCompat
|
import com.kieronquinn.monetcompat.core.MonetCompat
|
||||||
|
import com.owenlejeune.tvtime.preferences.AppPreferences
|
||||||
|
import org.koin.java.KoinJavaComponent.get
|
||||||
|
|
||||||
private val DarkColorPalette = darkColorScheme(
|
private val DarkColorPalette = darkColorScheme(
|
||||||
primary = A1_200,
|
primary = A1_200,
|
||||||
@@ -97,14 +99,22 @@ private val LightColorPalette = lightColorScheme(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TVTimeTheme(
|
fun TVTimeTheme(
|
||||||
|
preferences: AppPreferences = get(AppPreferences::class.java),
|
||||||
isDarkTheme: Boolean = isSystemInDarkTheme(),
|
isDarkTheme: Boolean = isSystemInDarkTheme(),
|
||||||
monetCompat: MonetCompat,
|
monetCompat: MonetCompat,
|
||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val colors = if(isDarkTheme) {
|
// val colors = if(isDarkTheme) {
|
||||||
monetCompat.darkMonetCompatScheme()
|
// monetCompat.darkMonetCompatScheme()
|
||||||
} else {
|
// } else {
|
||||||
monetCompat.lightMonetCompatScheme()
|
// monetCompat.lightMonetCompatScheme()
|
||||||
|
// }
|
||||||
|
val colors = when {
|
||||||
|
isDarkTheme && preferences.useWallpaperColors -> monetCompat.darkMonetCompatScheme()
|
||||||
|
isDarkTheme && !preferences.useWallpaperColors -> DarkColorPalette
|
||||||
|
!isDarkTheme && preferences.useWallpaperColors -> monetCompat.lightMonetCompatScheme()
|
||||||
|
!isDarkTheme && !preferences.useWallpaperColors -> LightColorPalette
|
||||||
|
else -> throw Exception("Error getting theme colors, should never happen")
|
||||||
}
|
}
|
||||||
|
|
||||||
androidx.compose.material3.MaterialTheme(
|
androidx.compose.material3.MaterialTheme(
|
||||||
|
|||||||
@@ -114,4 +114,7 @@
|
|||||||
<!-- onboarding -->
|
<!-- onboarding -->
|
||||||
<string name="get_started">Get started</string>
|
<string name="get_started">Get started</string>
|
||||||
<string name="example_page_desc">This is an example</string>
|
<string name="example_page_desc">This is an example</string>
|
||||||
|
<string name="preferences_use_wallpaper_colors_title">Use wallpaper colors</string>
|
||||||
|
<string name="preferences_use_wallpaper_colors_subtitle">Use theme colors pulled from your device\'s wallpaper</string>
|
||||||
|
<string name="preference_system_colors_subtitle">Use wallpaper colors chosen by your device</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user