flatten settigns navigation + move next mcu card behind preference

This commit is contained in:
Owen LeJeune
2023-07-09 15:37:26 -04:00
parent 080023c93e
commit f1471e280b
7 changed files with 605 additions and 501 deletions

View File

@@ -34,6 +34,7 @@ class AppPreferences(context: Context) {
private val ACCOUNT_TAB_POSITION = "account_tab_position"
private val SHOW_BTAB_LABELS = "show_btab_labels"
private val SHOW_POSTER_TITLE = "show_poster_titles"
private val SHOW_NEXT_MCU = "show_next_mcu"
}
private val preferences: SharedPreferences = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE)
@@ -128,6 +129,12 @@ class AppPreferences(context: Context) {
get() = preferences.getBoolean(SHOW_BACKDROP_GALLERY, showBackdropGalleryDefault)
set(value) { preferences.put(SHOW_BACKDROP_GALLERY, value) }
/******** Special Features Preferences ********/
val showNextMcuProductionDefault: Boolean = false
var showNextMcuProduction: Boolean
get() = preferences.getBoolean(SHOW_NEXT_MCU, showNextMcuProductionDefault)
set(value) { preferences.put(SHOW_NEXT_MCU, value) }
/********* Helpers ********/
private fun SharedPreferences.put(key: String, value: Any?) {
edit().apply {

View File

@@ -1,7 +1,5 @@
package com.owenlejeune.tvtime.ui.navigation
import android.os.Build
import android.util.Log
import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
@@ -93,18 +91,6 @@ fun AppNavigationHost(
}
}
}
composable(
AppNavItem.SettingsView.route.plus("/{${NavConstants.SETTINGS_KEY}}"),
arguments = listOf(
navArgument(NavConstants.SETTINGS_KEY) { type = NavType.StringType }
)
) {
val route = it.arguments?.getString(NavConstants.SETTINGS_KEY)
SettingsScreen(
appNavController = appNavController,
route = route
)
}
composable(AppNavItem.SettingsView.route) {
SettingsScreen(appNavController = appNavController)
}
@@ -237,9 +223,7 @@ sealed class AppNavItem(val route: String) {
object DetailView: AppNavItem("detail_route") {
fun withArgs(type: MediaViewType, id: Int) = route.plus("/${type}/${id}")
}
object SettingsView: AppNavItem("settings_route") {
fun withArgs(page: String) = route.plus("/$page")
}
object SettingsView: AppNavItem("settings_route")
object SearchView: AppNavItem("search_route") {
fun withArgs(searchType: MediaViewType, pageTitle: String) = route.plus("?searchType=$searchType&pageTitle=$pageTitle")
}

View File

@@ -0,0 +1,84 @@
package com.owenlejeune.tvtime.ui.navigation
import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.ui.res.stringResource
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.ui.screens.DarkModePreferences
import com.owenlejeune.tvtime.ui.screens.DesignPreferences
import com.owenlejeune.tvtime.ui.screens.DevPreferences
import com.owenlejeune.tvtime.ui.screens.HomeScreenPreferences
import com.owenlejeune.tvtime.ui.screens.SearchPreferences
import com.owenlejeune.tvtime.ui.screens.SettingsHome
import com.owenlejeune.tvtime.ui.screens.SpecialFeaturePreferences
@Composable
fun SettingsNavigationHost(
appNavController: NavController,
appBarTitle: MutableState<String>,
popBackAction: MutableState<() -> Unit>
) {
val settingsNavController = rememberNavController()
NavHost(
navController = settingsNavController,
startDestination = SettingsNavItem.Home.route,
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, tween(500)) },
popEnterTransition = { fadeIn(tween(500)) },
exitTransition = { fadeOut(tween(500)) },
popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End, tween(500)) }
) {
composable(SettingsNavItem.Home.route) {
appBarTitle.value = stringResource(id = R.string.nav_settings_title)
popBackAction.value = { appNavController.popBackStack() }
SettingsHome(settingsNavController = settingsNavController)
}
composable(SettingsNavItem.Search.route) {
appBarTitle.value = stringResource(id = R.string.preference_heading_search)
popBackAction.value = { settingsNavController.popBackStack() }
SearchPreferences()
}
composable(SettingsNavItem.Design.route) {
appBarTitle.value = stringResource(id = R.string.preference_heading_design)
popBackAction.value = { settingsNavController.popBackStack() }
DesignPreferences(settingsNavController = settingsNavController)
}
composable(SettingsNavItem.DarkMode.route) {
appBarTitle.value = stringResource(id = R.string.preference_heading_dark_mode)
popBackAction.value = { settingsNavController.popBackStack() }
DarkModePreferences()
}
composable(SettingsNavItem.HomeScreen.route) {
appBarTitle.value = stringResource(id = R.string.preference_heading_home_screen)
popBackAction.value = { settingsNavController.popBackStack() }
HomeScreenPreferences()
}
composable(SettingsNavItem.SpecialFeatures.route) {
appBarTitle.value = stringResource(id = R.string.preference_heading_special_features)
popBackAction.value = { settingsNavController.popBackStack() }
SpecialFeaturePreferences()
}
composable(SettingsNavItem.Developer.route) {
appBarTitle.value = stringResource(id = R.string.preferences_debug_title)
popBackAction.value = { settingsNavController.popBackStack() }
DevPreferences()
}
}
}
sealed class SettingsNavItem(val route: String) {
object Home: SettingsNavItem("settings_home")
object Search: SettingsNavItem("settings_search")
object Design: SettingsNavItem("settings_design")
object DarkMode: SettingsNavItem("settings_dark_mode")
object HomeScreen: SettingsNavItem("settings_home_screen")
object SpecialFeatures: SettingsNavItem("settings_special_feature")
object Developer: SettingsNavItem("settings_developer")
}

View File

@@ -46,6 +46,7 @@ import com.owenlejeune.tvtime.extensions.format
import com.owenlejeune.tvtime.extensions.getCalendarYear
import com.owenlejeune.tvtime.extensions.lazyPagingItems
import com.owenlejeune.tvtime.extensions.listItems
import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.ui.components.*
import com.owenlejeune.tvtime.ui.navigation.AppNavItem
import com.owenlejeune.tvtime.ui.viewmodel.MainViewModel
@@ -54,6 +55,7 @@ import com.owenlejeune.tvtime.utils.SessionManager
import com.owenlejeune.tvtime.utils.TmdbUtils
import com.owenlejeune.tvtime.utils.types.MediaViewType
import kotlinx.coroutines.*
import org.koin.java.KoinJavaComponent.get
@OptIn(ExperimentalMaterial3Api::class, ExperimentalPagerApi::class)
@Composable
@@ -152,7 +154,8 @@ private fun MediaViewContent(
type: MediaViewType,
windowSize: WindowSizeClass,
showImageGallery: MutableState<Boolean>,
pagerState: PagerState
pagerState: PagerState,
preferences: AppPreferences = get(AppPreferences::class.java)
) {
LaunchedEffect(Unit) {
mainViewModel.getExternalIds(itemId, type)
@@ -249,7 +252,10 @@ private fun MediaViewContent(
WatchProvidersCard(itemId = itemId, type = type, mainViewModel = mainViewModel)
if (mediaItem?.productionCompanies?.firstOrNull { it.name == "Marvel Studios" } != null) {
if (
mediaItem?.productionCompanies?.firstOrNull { it.name == "Marvel Studios" } != null
&& preferences.showNextMcuProduction
) {
NextMcuProjectCard(appNavController = appNavController)
}
@@ -1078,7 +1084,7 @@ private fun NextMcuProjectCard(
Text(
text = nextMcuProject.value?.title ?: "",
style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.W700
fontWeight = FontWeight.W600
)
val releaseDate =

View File

@@ -1,20 +1,50 @@
package com.owenlejeune.tvtime.ui.screens
import android.app.Activity
import android.os.Build
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
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.fillMaxSize
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.shape.RoundedCornerShape
import androidx.compose.material.IconButton
import androidx.compose.material.TextButton
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Brightness6
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.DeveloperBoard
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Palette
import androidx.compose.material.icons.filled.RestartAlt
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.outlined.DarkMode
import androidx.compose.material.icons.outlined.Flare
import androidx.compose.material.icons.outlined.LightMode
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -36,25 +66,24 @@ import com.owenlejeune.tvtime.BuildConfig
import com.owenlejeune.tvtime.OnboardingActivity
import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.ui.components.*
import com.owenlejeune.tvtime.ui.navigation.AppNavItem
import com.owenlejeune.tvtime.ui.components.CenteredIconCircle
import com.owenlejeune.tvtime.ui.components.PaletteView
import com.owenlejeune.tvtime.ui.components.PreferenceHeading
import com.owenlejeune.tvtime.ui.components.RadioButtonPreference
import com.owenlejeune.tvtime.ui.components.SliderPreference
import com.owenlejeune.tvtime.ui.components.SwitchPreference
import com.owenlejeune.tvtime.ui.navigation.SettingsNavItem
import com.owenlejeune.tvtime.ui.navigation.SettingsNavigationHost
import com.owenlejeune.tvtime.ui.viewmodel.SettingsViewModel
import com.owenlejeune.tvtime.ui.views.HomeTabRecyclerAdapter
import com.owenlejeune.tvtime.ui.views.ItemMoveCallback
import com.owenlejeune.tvtime.utils.ResourceUtils
import com.owenlejeune.tvtime.utils.SessionManager
import kotlinx.coroutines.launch
import org.koin.androidx.compose.koinViewModel
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.koin.java.KoinJavaComponent.get
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(
appNavController: NavController,
route: String? = null,
preferences: AppPreferences = get(AppPreferences::class.java)
appNavController: NavController
) {
val systemUiController = rememberSystemUiController()
systemUiController.setStatusBarColor(color = MaterialTheme.colorScheme.background)
@@ -64,12 +93,7 @@ fun SettingsScreen(
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(topAppBarScrollState)
val appBarTitle = remember { mutableStateOf("") }
val defaultRestoreAction = ::resetAllPreferences
val restoreAction = remember { mutableStateOf<SettingsResetHandler>(defaultRestoreAction) }
val settingsViewModel = viewModel<SettingsViewModel>()
val activity = LocalContext.current as AppCompatActivity
val popBackAction = remember { mutableStateOf({}) }
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
@@ -83,7 +107,7 @@ fun SettingsScreen(
title = { Text(text = appBarTitle.value) },
navigationIcon = {
IconButton(
onClick = { appNavController.popBackStack() }
onClick = popBackAction.value
) {
Icon(
imageVector = Icons.Filled.ArrowBack,
@@ -91,53 +115,35 @@ fun SettingsScreen(
)
}
},
actions = {
IconButton(
onClick = {
restoreAction.value(preferences, settingsViewModel, activity)
}
) {
Icon(
imageVector = Icons.Filled.SettingsBackupRestore,
contentDescription = stringResource(R.string.preferences_restore_content_description)
)
}
}
// actions = {
// IconButton(
// onClick = {
// restoreAction.value(preferences, settingsViewModel, activity)
// }
// ) {
// Icon(
// imageVector = Icons.Filled.SettingsBackupRestore,
// contentDescription = stringResource(R.string.preferences_restore_content_description)
// )
// }
// }
)
}
) { innerPadding ->
Box(modifier = Modifier.padding(innerPadding)) {
if (route != null) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 24.dp),
verticalArrangement = Arrangement.spacedBy(18.dp)
) {
SettingsPage.getByRoute(route).apply {
appBarTitle.value = name
restoreAction.value = resetPreferencesHandler
settingsPageRenderer(appNavController, activity)
}
}
} else {
restoreAction.value = ::resetAllPreferences
SettingsTabView(
SettingsNavigationHost(
appNavController = appNavController,
appBarTitle = appBarTitle
appBarTitle = appBarTitle,
popBackAction = popBackAction
)
}
}
}
}
@Composable
private fun SettingsTabView(
appNavController: NavController,
appBarTitle: MutableState<String>
fun SettingsHome(
settingsNavController: NavController
) {
appBarTitle.value = stringResource(id = R.string.nav_settings_title)
Column(
modifier = Modifier
.fillMaxSize()
@@ -148,81 +154,54 @@ private fun SettingsTabView(
title = stringResource(id = R.string.preference_heading_search),
subtitle = stringResource(R.string.preference_subtitle_search),
icon = Icons.Filled.Search,
settingsView = SettingsPage.SearchSettings,
appNavController = appNavController
route = SettingsNavItem.Search.route,
settingsNavController = settingsNavController
)
TopLevelSettingsCard(
title = stringResource(id = R.string.preference_heading_design),
subtitle = stringResource(R.string.preference_subtitle_design),
icon = Icons.Filled.Palette,
settingsView = SettingsPage.DesignSettings,
appNavController = appNavController
route = SettingsNavItem.Design.route,
settingsNavController = settingsNavController
)
TopLevelSettingsCard(
title = stringResource(id = R.string.preference_heading_home_screen),
subtitle = stringResource(R.string.preference_subtitle_home_screen),
icon = Icons.Filled.Home,
settingsView = SettingsPage.HomeScreenSettings,
appNavController = appNavController
route = SettingsNavItem.HomeScreen.route,
settingsNavController = settingsNavController
)
TopLevelSettingsCard(
title = stringResource(id = R.string.preference_heading_special_features),
subtitle = stringResource(id = R.string.preference_subtitle_special_features),
icon = Icons.Outlined.Flare,
route = SettingsNavItem.SpecialFeatures.route,
settingsNavController = settingsNavController
)
TopLevelSettingsCard(
title = stringResource(id = R.string.preferences_debug_title),
subtitle = stringResource(R.string.preference_subtitle_debug),
icon = Icons.Filled.DeveloperBoard,
settingsView = SettingsPage.DeveloperSettings,
appNavController = appNavController
route = SettingsNavItem.Developer.route,
settingsNavController = settingsNavController
)
}
}
@Composable
private fun TopLevelSettingsCard(
title: String,
subtitle: String? = null,
icon: ImageVector,
settingsView: SettingsPage,
appNavController: NavController
) {
Row(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.clickable(
onClick = {
appNavController.navigate(AppNavItem.SettingsView.withArgs(settingsView.route))
}
)
) {
Icon(
imageVector = icon,
contentDescription = subtitle,
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(end = 16.dp),
tint = MaterialTheme.colorScheme.primary
)
fun SearchPreferences() {
val settingsViewModel = viewModel<SettingsViewModel>()
Column(
modifier = Modifier
.align(Alignment.CenterVertically)
.weight(1f)
.fillMaxSize()
.padding(all = 24.dp),
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
val titleColor = MaterialTheme.colorScheme.onBackground
val subtitleColor = MaterialTheme.colorScheme.onSurfaceVariant
Text(text = title, style = MaterialTheme.typography.titleLarge, color = titleColor, fontSize = 20.sp)
subtitle?.let {
Text(text = subtitle, style = MaterialTheme.typography.bodyMedium, color = subtitleColor)
}
}
}
}
@Composable
private fun SearchPreferences() {
val settingsViewModel = koinViewModel<SettingsViewModel>()
SwitchPreference(
titleText = stringResource(R.string.preferences_persistent_search_title),
subtitleText = stringResource(R.string.preferences_persistent_search_subtitle),
@@ -240,21 +219,28 @@ private fun SearchPreferences() {
settingsViewModel.toggleMultiSearch()
}
)
}
}
@Composable
private fun DesignPreferences(
appNavController: NavController,
activity: AppCompatActivity
fun DesignPreferences(
settingsNavController: NavController,
) {
val settingsViewModel = viewModel<SettingsViewModel>()
val activity = LocalContext.current as Activity
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 24.dp),
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
TopLevelSettingsCard(
title = stringResource(id = R.string.preference_heading_dark_mode),
subtitle = stringResource(R.string.preference_subtitle_dark_mode),
icon = Icons.Outlined.DarkMode,
settingsView = SettingsPage.DarkModeSettings,
appNavController = appNavController
route = SettingsNavItem.DarkMode.route,
settingsNavController = settingsNavController
)
SwitchPreference(
@@ -318,12 +304,13 @@ private fun DesignPreferences(
if (showWallpaperPicker.value) {
WallpaperPicker(showPopup = showWallpaperPicker)
}
}
}
@Composable
private fun DarkModePreferences(
activity: AppCompatActivity
) {
fun DarkModePreferences() {
val activity = LocalContext.current as Activity
val settingsViewModel = viewModel<SettingsViewModel>()
val isSelected: (Int) -> Boolean = { settingsViewModel.darkTheme.value == it }
@@ -332,6 +319,12 @@ private fun DarkModePreferences(
activity.recreate()
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 24.dp),
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
PreferenceHeading(text = stringResource(R.string.preference_dark_mode_automatic_heading))
RadioButtonPreference(
selected = isSelected(AppPreferences.DarkMode.Automatic.ordinal),
@@ -359,12 +352,19 @@ private fun DarkModePreferences(
onChangeState(AppPreferences.DarkMode.Dark.ordinal)
}
)
}
}
@Composable
private fun HomeScreenPreferences() {
fun HomeScreenPreferences() {
val settingsViewModel = viewModel<SettingsViewModel>()
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 24.dp),
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
PreferenceHeading(text = stringResource(R.string.preference_look_and_feel_heading))
SwitchPreference(
@@ -387,7 +387,8 @@ private fun HomeScreenPreferences() {
PreferenceHeading(text = stringResource(R.string.preference_home_tab_order_heading))
Box(modifier = Modifier
Box(
modifier = Modifier
.border(
width = 1.dp,
color = MaterialTheme.colorScheme.primary,
@@ -410,16 +411,44 @@ private fun HomeScreenPreferences() {
update = { }
)
}
}
}
@Composable
private fun DevPreferences() {
fun SpecialFeaturePreferences() {
val settingsViewModel = viewModel<SettingsViewModel>()
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 24.dp),
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
SwitchPreference(
titleText = stringResource(R.string.preferences_show_next_mcu_title),
subtitleText = stringResource(R.string.preferences_show_next_mcu_subtitle),
checkState = settingsViewModel.showNextMcuProduction.collectAsState(),
onCheckedChange = {
settingsViewModel.toggleShowNextMcuProduction()
}
)
}
}
@Composable
fun DevPreferences() {
if (BuildConfig.DEBUG) {
val settingsViewModel = viewModel<SettingsViewModel>()
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 24.dp),
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
SwitchPreference(
titleText = "Show backdrop gallery",
subtitleText = "Show galleries for movies/tv backdrops",
@@ -488,6 +517,7 @@ private fun DevPreferences() {
)
)
}
}
}
@Composable
@@ -570,151 +600,128 @@ private fun WallpaperPicker(
}
}
private fun resetAllPreferences(
preferences: AppPreferences,
settingsViewModel: SettingsViewModel,
activity: AppCompatActivity
@Composable
private fun TopLevelSettingsCard(
title: String,
subtitle: String? = null,
icon: ImageVector,
route: String,
settingsNavController: NavController
) {
resetSearchPreferences(preferences = preferences, settingsViewModel = settingsViewModel, activity = activity, skipRecreate = true)
resetDesignPreferences(preferences = preferences, settingsViewModel = settingsViewModel, activity = activity, skipRecreate = true)
resetHomeScreenPreferences(preferences = preferences, settingsViewModel = settingsViewModel, activity = activity, skipRecreate = true)
resetDevModePreference(preferences = preferences, settingsViewModel = settingsViewModel, activity = activity, skipRecreate = true)
activity.recreate()
Toast.makeText(activity, "All settings reset successfully", Toast.LENGTH_SHORT).show()
}
private fun resetSearchPreferences(
preferences: AppPreferences,
settingsViewModel: SettingsViewModel,
activity: AppCompatActivity,
skipRecreate: Boolean = false
) {
settingsViewModel.setShowSearchBar(preferences.showSearchBarDefault)
settingsViewModel.setMultiSearch(preferences.multiSearchDefault)
if (!skipRecreate) {
activity.recreate()
Row(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.clickable(
onClick = {
settingsNavController.navigate(route)
}
}
private fun resetDesignPreferences(
preferences: AppPreferences,
settingsViewModel: SettingsViewModel,
activity: AppCompatActivity,
skipRecreate: Boolean = false
) {
settingsViewModel.setUseSystemColors(preferences.useSystemColorsDefault)
settingsViewModel.setUseWallpaperColors(preferences.useWallpaperColorsDefault)
settingsViewModel.setChromaMultiplier(preferences.chromaMultiplierDefault)
settingsViewModel.setSelectedColor(preferences.selectedColorDefault)
resetDarkModePreferences(preferences = preferences, settingsViewModel = settingsViewModel, activity = activity, skipRecreate = true)
if (!skipRecreate) {
activity.recreate()
}
}
private fun resetDarkModePreferences(
preferences: AppPreferences,
settingsViewModel: SettingsViewModel,
activity: AppCompatActivity,
skipRecreate: Boolean = false
) {
settingsViewModel.setDarkMode(preferences.darkThemeDefault)
if (!skipRecreate) {
activity.recreate()
}
}
private fun resetDevModePreference(
preferences: AppPreferences,
settingsViewModel: SettingsViewModel,
activity: AppCompatActivity,
skipRecreate: Boolean = false
) {
settingsViewModel.setFirstLaunchTesting(preferences.firstLaunchTestingDefault)
settingsViewModel.setShowBackdropGallery(preferences.showBackdropGalleryDefault)
if (!skipRecreate) {
activity.recreate()
}
}
private fun resetHomeScreenPreferences(
preferences: AppPreferences,
settingsViewModel: SettingsViewModel,
activity: AppCompatActivity,
skipRecreate: Boolean = false
) {
settingsViewModel.setShowBottomTabLabels(preferences.showBottomTabLabelsDefault)
settingsViewModel.setShowPosterTitles(preferences.showPosterTitlesDefault)
preferences.moviesTabPosition = preferences.moviesTabPositionDefault
preferences.tvTabPosition = preferences.tvTabPositionDefault
preferences.peopleTabPosition = preferences.peopleTabPositionDefault
preferences.accountTabPosition = preferences.accountTabPositionDefault
preferences.showBottomTabLabels = preferences.showBottomTabLabelsDefault
if (!skipRecreate) {
activity.recreate()
}
}
private typealias SettingsResetHandler = (AppPreferences, SettingsViewModel, AppCompatActivity) -> Unit
private typealias SettingsPageRenderer = @Composable (NavController, AppCompatActivity) -> Unit
private sealed class SettingsPage(
stringRes: Int,
val route: String,
val settingsPageRenderer: SettingsPageRenderer,
val resetPreferencesHandler: SettingsResetHandler
): KoinComponent {
private val resources: ResourceUtils by inject()
val name = resources.getString(stringRes)
companion object {
val Pages by lazy {
listOf(
SearchSettings,
DesignSettings,
DeveloperSettings,
DarkModeSettings,
HomeScreenSettings
)
}
fun getByRoute(route: String): SettingsPage {
return Pages.map { it.route to it }
.find { it.first == route }
?.second
?: throw IllegalArgumentException("Invalid settings page route: $route")
) {
Icon(
imageVector = icon,
contentDescription = subtitle,
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(end = 16.dp),
tint = MaterialTheme.colorScheme.primary
)
Column(
modifier = Modifier
.align(Alignment.CenterVertically)
.weight(1f)
) {
val titleColor = MaterialTheme.colorScheme.onBackground
val subtitleColor = MaterialTheme.colorScheme.onSurfaceVariant
Text(text = title, style = MaterialTheme.typography.titleLarge, color = titleColor, fontSize = 20.sp)
subtitle?.let {
Text(text = subtitle, style = MaterialTheme.typography.bodyMedium, color = subtitleColor)
}
}
}
object SearchSettings: SettingsPage(
R.string.preference_heading_search,
"search",
@Composable { _, _ -> SearchPreferences() },
::resetSearchPreferences
)
object DesignSettings: SettingsPage(
R.string.preference_heading_design,
"design",
@Composable { n, a -> DesignPreferences(n, a) },
::resetDesignPreferences
)
object HomeScreenSettings: SettingsPage(
R.string.preference_heading_home_screen,
"home",
@Composable { _, _ -> HomeScreenPreferences() },
::resetHomeScreenPreferences
)
object DeveloperSettings: SettingsPage(
R.string.preferences_debug_title,
"dev",
@Composable { _, _ -> DevPreferences() },
::resetDevModePreference
)
object DarkModeSettings: SettingsPage(
R.string.preference_heading_dark_mode,
"darkmode",
@Composable { _, a -> DarkModePreferences(a) },
::resetDarkModePreferences
)
}
//private fun resetAllPreferences(
// preferences: AppPreferences,
// settingsViewModel: SettingsViewModel,
// activity: AppCompatActivity
//) {
// resetSearchPreferences(preferences = preferences, settingsViewModel = settingsViewModel, activity = activity, skipRecreate = true)
// resetDesignPreferences(preferences = preferences, settingsViewModel = settingsViewModel, activity = activity, skipRecreate = true)
// resetHomeScreenPreferences(preferences = preferences, settingsViewModel = settingsViewModel, activity = activity, skipRecreate = true)
// resetDevModePreference(preferences = preferences, settingsViewModel = settingsViewModel, activity = activity, skipRecreate = true)
// activity.recreate()
// Toast.makeText(activity, "All settings reset successfully", Toast.LENGTH_SHORT).show()
//}
//
//private fun resetSearchPreferences(
// preferences: AppPreferences,
// settingsViewModel: SettingsViewModel,
// activity: AppCompatActivity,
// skipRecreate: Boolean = false
//) {
// settingsViewModel.setShowSearchBar(preferences.showSearchBarDefault)
// settingsViewModel.setMultiSearch(preferences.multiSearchDefault)
// if (!skipRecreate) {
// activity.recreate()
// }
//}
//
//private fun resetDesignPreferences(
// preferences: AppPreferences,
// settingsViewModel: SettingsViewModel,
// activity: AppCompatActivity,
// skipRecreate: Boolean = false
//) {
// settingsViewModel.setUseSystemColors(preferences.useSystemColorsDefault)
// settingsViewModel.setUseWallpaperColors(preferences.useWallpaperColorsDefault)
// settingsViewModel.setChromaMultiplier(preferences.chromaMultiplierDefault)
// settingsViewModel.setSelectedColor(preferences.selectedColorDefault)
// resetDarkModePreferences(preferences = preferences, settingsViewModel = settingsViewModel, activity = activity, skipRecreate = true)
// if (!skipRecreate) {
// activity.recreate()
// }
//}
//
//private fun resetDarkModePreferences(
// preferences: AppPreferences,
// settingsViewModel: SettingsViewModel,
// activity: AppCompatActivity,
// skipRecreate: Boolean = false
//) {
// settingsViewModel.setDarkMode(preferences.darkThemeDefault)
// if (!skipRecreate) {
// activity.recreate()
// }
//}
//
//private fun resetDevModePreference(
// preferences: AppPreferences,
// settingsViewModel: SettingsViewModel,
// activity: AppCompatActivity,
// skipRecreate: Boolean = false
//) {
// settingsViewModel.setFirstLaunchTesting(preferences.firstLaunchTestingDefault)
// settingsViewModel.setShowBackdropGallery(preferences.showBackdropGalleryDefault)
// if (!skipRecreate) {
// activity.recreate()
// }
//}
//
//private fun resetHomeScreenPreferences(
// preferences: AppPreferences,
// settingsViewModel: SettingsViewModel,
// activity: AppCompatActivity,
// skipRecreate: Boolean = false
//) {
// settingsViewModel.setShowBottomTabLabels(preferences.showBottomTabLabelsDefault)
// settingsViewModel.setShowPosterTitles(preferences.showPosterTitlesDefault)
// preferences.moviesTabPosition = preferences.moviesTabPositionDefault
// preferences.tvTabPosition = preferences.tvTabPositionDefault
// preferences.peopleTabPosition = preferences.peopleTabPositionDefault
// preferences.accountTabPosition = preferences.accountTabPositionDefault
// preferences.showBottomTabLabels = preferences.showBottomTabLabelsDefault
// if (!skipRecreate) {
// activity.recreate()
// }
//}

View File

@@ -23,6 +23,7 @@ class SettingsViewModel: ViewModel() {
private val _showPosterTitles = MutableStateFlow(preferences.showPosterTitles)
private val _firstLaunchTesting = MutableStateFlow(preferences.firstLaunchTesting)
private val _showBackdropGallery = MutableStateFlow(preferences.showBackdropGallery)
private val _showNextMcuProduction = MutableStateFlow(preferences.showNextMcuProduction)
}
val showSearchBar = _showSearchBar.asStateFlow()
@@ -36,6 +37,7 @@ class SettingsViewModel: ViewModel() {
val showPosterTitles = _showPosterTitles.asStateFlow()
val firstLaunchTesting = _firstLaunchTesting.asStateFlow()
val showBackdropGallery = _showBackdropGallery.asStateFlow()
val showNextMcuProduction = _showNextMcuProduction.asStateFlow()
fun toggleShowSearchBar() {
_showSearchBar.value = _showSearchBar.value.not()
@@ -132,4 +134,14 @@ class SettingsViewModel: ViewModel() {
preferences.showBackdropGallery = value
}
fun toggleShowNextMcuProduction() {
_showNextMcuProduction.value = _showNextMcuProduction.value.not()
preferences.showNextMcuProduction = _showNextMcuProduction.value
}
fun setShowNextMcuProduction(value: Boolean) {
_showNextMcuProduction.value = value
preferences.showNextMcuProduction = value
}
}

View File

@@ -84,6 +84,10 @@
<string name="preference_show_text_labels_title">Show tab text labels</string>
<string name="preference_show_text_labels_subtitle">Show text labels for tab items in the bottom tab bar or navigation rail</string>
<string name="preference_home_tab_order_heading">Home Tab Order</string>
<string name="preference_heading_special_features">Special Features</string>
<string name="preference_subtitle_special_features">Extra features and hidden goodies</string>
<string name="preferences_show_next_mcu_title">Show Next MCU Production</string>
<string name="preferences_show_next_mcu_subtitle">Show a card with information on the next scheduled MCU production when viewing details for an MCU release</string>
<!-- video type -->
<string name="video_type_clip">Clips</string>