refactor settings behaviours

This commit is contained in:
Owen LeJeune
2023-06-12 11:27:38 -04:00
parent f36dc741e9
commit f66770ec2e
13 changed files with 347 additions and 120 deletions

View File

@@ -37,7 +37,7 @@ android {
targetCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
} }
kotlinOptions { kotlinOptions {
jvmTarget = '1.8' jvmTarget = '11'
useIR = true useIR = true
} }
buildFeatures { buildFeatures {

View File

@@ -65,9 +65,9 @@ class AppPreferences(context: Context) {
get() = preferences.getBoolean(USE_SYSTEM_COLORS, useSystemColorsDefault) get() = preferences.getBoolean(USE_SYSTEM_COLORS, useSystemColorsDefault)
set(value) { preferences.put(USE_SYSTEM_COLORS, value) } set(value) { preferences.put(USE_SYSTEM_COLORS, value) }
val chromeMultiplyerDefault: Double = MonetCompat.chromaMultiplier.toFloat().toDouble() val chromaMultiplierDefault: Double = MonetCompat.chromaMultiplier.toFloat().toDouble()
var chromaMultiplier: Double var chromaMultiplier: Double
get() = preferences.getFloat(CHROMA_MULTIPLIER, chromeMultiplyerDefault.toFloat()).toDouble() get() = preferences.getFloat(CHROMA_MULTIPLIER, chromaMultiplierDefault.toFloat()).toDouble()
set(value) { preferences.put(CHROMA_MULTIPLIER, value) } set(value) { preferences.put(CHROMA_MULTIPLIER, value) }
val selectedColorDefault: Int = Int.MAX_VALUE val selectedColorDefault: Int = Int.MAX_VALUE

View File

@@ -29,7 +29,7 @@ fun PreferenceHeading(
@Composable @Composable
fun SwitchPreference( fun SwitchPreference(
titleText: String, titleText: String,
checkState: Boolean, checkState: State<Boolean>,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
subtitleText: String = "", subtitleText: String = "",
onCheckedChange: (Boolean) -> Unit = {}, onCheckedChange: (Boolean) -> Unit = {},
@@ -59,6 +59,52 @@ fun SwitchPreference(
Spacer(modifier = Modifier.width(32.dp)) Spacer(modifier = Modifier.width(32.dp))
CustomSwitch(
modifier = Modifier
.align(Alignment.CenterVertically),
checked = checkState.value,
onCheckedChange = onCheckedChange,
width = 30.dp,
height = 15.dp,
colors = CustomSwitchColors.standardColors(),
enabled = enabled
)
}
}
@Composable
fun SwitchPreference(
titleText: String,
checkState: Boolean,
modifier: Modifier = Modifier,
subtitleText: String = "",
onCheckedChange: (Boolean) -> Unit = {},
titleTextColor: Color = MaterialTheme.colorScheme.onBackground,
subtitleTextColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
disabledTextColor: Color = MaterialTheme.colorScheme.outline,
enabled: Boolean = true
) {
Row(
modifier = modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(all = 8.dp)
) {
Column(
modifier = Modifier
.align(Alignment.CenterVertically)
.weight(1f)
) {
val titleColor = if (enabled) titleTextColor else disabledTextColor
val subtitleColor = if (enabled) subtitleTextColor else disabledTextColor
Text(text = titleText, style = MaterialTheme.typography.titleLarge, color = titleColor, fontSize = 20.sp)
if (subtitleText.isNotEmpty()) {
Text(text = subtitleText, style = MaterialTheme.typography.bodyMedium, color = subtitleColor)
}
}
Spacer(modifier = Modifier.width(32.dp))
CustomSwitch( CustomSwitch(
modifier = Modifier modifier = Modifier
.align(Alignment.CenterVertically), .align(Alignment.CenterVertically),
@@ -76,8 +122,8 @@ fun SwitchPreference(
fun SliderPreference( fun SliderPreference(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
titleText: String, titleText: String,
value: Float, value: State<Double>,
onValueChangeFinished: (Float) -> Unit , onValueChangeFinished: (Double) -> Unit ,
titleTextColor: Color = MaterialTheme.colorScheme.onBackground, titleTextColor: Color = MaterialTheme.colorScheme.onBackground,
disabledTextColor: Color = MaterialTheme.colorScheme.outline, disabledTextColor: Color = MaterialTheme.colorScheme.outline,
enabled: Boolean = true enabled: Boolean = true
@@ -90,14 +136,14 @@ fun SliderPreference(
val titleColor = if (enabled) titleTextColor else disabledTextColor val titleColor = if (enabled) titleTextColor else disabledTextColor
Text(text = titleText, style = MaterialTheme.typography.titleLarge, color = titleColor, fontSize = 20.sp) Text(text = titleText, style = MaterialTheme.typography.titleLarge, color = titleColor, fontSize = 20.sp)
var sliderValue by remember { mutableStateOf(value) } var sliderValue by remember { mutableStateOf(value.value) }
Slider( Slider(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(start = 8.dp), .padding(start = 8.dp),
value = sliderValue, value = sliderValue.toFloat(),
onValueChange = { sliderValue = it }, onValueChange = { sliderValue = it.toDouble() },
enabled = enabled, enabled = enabled,
valueRange = 0f..100f, valueRange = 0f..100f,
onValueChangeFinished = { onValueChangeFinished = {

View File

@@ -6,7 +6,7 @@ import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.HomePageService import com.owenlejeune.tvtime.api.tmdb.api.v3.HomePageService
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.HomePageResponse import com.owenlejeune.tvtime.api.tmdb.api.v3.model.HomePageResponse
import com.owenlejeune.tvtime.utils.types.MediaViewType import com.owenlejeune.tvtime.utils.types.MediaViewType
import com.owenlejeune.tvtime.api.tmdb.viewmodel.MediaTabViewModel import com.owenlejeune.tvtime.ui.viewmodel.MediaTabViewModel
import com.owenlejeune.tvtime.ui.screens.tabs.MediaTabContent import com.owenlejeune.tvtime.ui.screens.tabs.MediaTabContent
import com.owenlejeune.tvtime.utils.ResourceUtils import com.owenlejeune.tvtime.utils.ResourceUtils
import com.owenlejeune.tvtime.utils.types.TabNavItem import com.owenlejeune.tvtime.utils.types.TabNavItem

View File

@@ -30,7 +30,7 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.owenlejeune.tvtime.R import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.* import com.owenlejeune.tvtime.api.tmdb.api.v3.model.*
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AccountList import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AccountList
import com.owenlejeune.tvtime.api.tmdb.viewmodel.RecommendedMediaViewModel import com.owenlejeune.tvtime.ui.viewmodel.RecommendedMediaViewModel
import com.owenlejeune.tvtime.extensions.unlessEmpty import com.owenlejeune.tvtime.extensions.unlessEmpty
import com.owenlejeune.tvtime.ui.components.AccountIcon import com.owenlejeune.tvtime.ui.components.AccountIcon
import com.owenlejeune.tvtime.ui.components.PagingPosterGrid import com.owenlejeune.tvtime.ui.components.PagingPosterGrid

View File

@@ -26,6 +26,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@@ -38,6 +39,7 @@ import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.preferences.AppPreferences import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.ui.components.* import com.owenlejeune.tvtime.ui.components.*
import com.owenlejeune.tvtime.ui.navigation.AppNavItem import com.owenlejeune.tvtime.ui.navigation.AppNavItem
import com.owenlejeune.tvtime.ui.viewmodel.SettingsViewModel
import com.owenlejeune.tvtime.ui.views.HomeTabRecyclerAdapter import com.owenlejeune.tvtime.ui.views.HomeTabRecyclerAdapter
import com.owenlejeune.tvtime.ui.views.ItemMoveCallback import com.owenlejeune.tvtime.ui.views.ItemMoveCallback
import com.owenlejeune.tvtime.utils.ResourceUtils import com.owenlejeune.tvtime.utils.ResourceUtils
@@ -66,7 +68,11 @@ fun SettingsScreen(
val appBarTitle = remember { mutableStateOf("") } val appBarTitle = remember { mutableStateOf("") }
val defaultRestoreAction = ::resetAllPreferences val defaultRestoreAction = ::resetAllPreferences
val restoreAction = remember { mutableStateOf<(AppPreferences) -> Unit>(defaultRestoreAction) } val restoreAction = remember { mutableStateOf<SettingsResetHandler>(defaultRestoreAction) }
val settingsViewModel = viewModel<SettingsViewModel>()
val activity = LocalContext.current as AppCompatActivity
Scaffold( Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
@@ -89,9 +95,11 @@ fun SettingsScreen(
} }
}, },
actions = { actions = {
IconButton(onClick = { IconButton(
restoreAction.value(preferences) onClick = {
}) { restoreAction.value(preferences, settingsViewModel, activity)
}
) {
Icon( Icon(
imageVector = Icons.Filled.SettingsBackupRestore, imageVector = Icons.Filled.SettingsBackupRestore,
contentDescription = stringResource(R.string.preferences_restore_content_description) contentDescription = stringResource(R.string.preferences_restore_content_description)
@@ -109,11 +117,10 @@ fun SettingsScreen(
.padding(all = 24.dp), .padding(all = 24.dp),
verticalArrangement = Arrangement.spacedBy(18.dp) verticalArrangement = Arrangement.spacedBy(18.dp)
) { ) {
val activity = LocalContext.current as AppCompatActivity
SettingsPage.getByRoute(route).apply { SettingsPage.getByRoute(route).apply {
appBarTitle.value = name appBarTitle.value = name
restoreAction.value = resetPreferencesHandler restoreAction.value = resetPreferencesHandler
settingsPageRenderer(appNavController, activity, preferences) settingsPageRenderer(appNavController, activity)
} }
} }
} else { } else {
@@ -216,28 +223,24 @@ private fun TopLevelSettingsCard(
} }
@Composable @Composable
private fun SearchPreferences( private fun SearchPreferences() {
preferences: AppPreferences = get(AppPreferences::class.java) val settingsViewModel = viewModel<SettingsViewModel>()
) {
val persistentSearch = remember { mutableStateOf(preferences.showSearchBar) }
SwitchPreference( SwitchPreference(
titleText = stringResource(R.string.preferences_persistent_search_title), titleText = stringResource(R.string.preferences_persistent_search_title),
subtitleText = stringResource(R.string.preferences_persistent_search_subtitle), subtitleText = stringResource(R.string.preferences_persistent_search_subtitle),
checkState = persistentSearch.value, checkState = settingsViewModel.showSearchBar.collectAsState(),
onCheckedChange = { isChecked -> onCheckedChange = {
persistentSearch.value = isChecked settingsViewModel.toggleShowSearchBar()
preferences.showSearchBar = isChecked
} }
) )
val multiSearch = remember { mutableStateOf(preferences.multiSearch) }
SwitchPreference( SwitchPreference(
titleText = stringResource(R.string.preference_multi_search_title), titleText = stringResource(R.string.preference_multi_search_title),
subtitleText = stringResource(R.string.preference_multi_search_subtitle), subtitleText = stringResource(R.string.preference_multi_search_subtitle),
checkState = multiSearch.value, checkState = settingsViewModel.useMultiSearch.collectAsState(),
onCheckedChange = { isChecked -> onCheckedChange = {
multiSearch.value = isChecked settingsViewModel.toggleMultiSearch()
preferences.multiSearch = isChecked
} }
) )
} }
@@ -245,9 +248,10 @@ private fun SearchPreferences(
@Composable @Composable
private fun DesignPreferences( private fun DesignPreferences(
appNavController: NavController, appNavController: NavController,
activity: AppCompatActivity, activity: AppCompatActivity
preferences: AppPreferences = get(AppPreferences::class.java)
) { ) {
val settingsViewModel = viewModel<SettingsViewModel>()
TopLevelSettingsCard( TopLevelSettingsCard(
title = stringResource(id = R.string.preference_heading_dark_mode), title = stringResource(id = R.string.preference_heading_dark_mode),
subtitle = stringResource(R.string.preference_subtitle_dark_mode), subtitle = stringResource(R.string.preference_subtitle_dark_mode),
@@ -256,53 +260,48 @@ private fun DesignPreferences(
appNavController = appNavController appNavController = appNavController
) )
val useWallpaperColors = remember { mutableStateOf(preferences.useWallpaperColors) }
SwitchPreference( SwitchPreference(
titleText = stringResource(R.string.preferences_use_wallpaper_colors_title), titleText = stringResource(R.string.preferences_use_wallpaper_colors_title),
subtitleText = stringResource(R.string.preferences_use_wallpaper_colors_subtitle), subtitleText = stringResource(R.string.preferences_use_wallpaper_colors_subtitle),
checkState = useWallpaperColors.value, checkState = settingsViewModel.useWallpaperColors.collectAsState(),
onCheckedChange = { isChecked -> onCheckedChange = {
useWallpaperColors.value = isChecked settingsViewModel.toggleUseWallpaperColors()
preferences.useWallpaperColors = isChecked
activity.recreate() 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) }
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), subtitleText = stringResource(R.string.preference_system_colors_subtitle),
checkState = useSystemColors.value, checkState = settingsViewModel.useSystemColors.collectAsState(),
onCheckedChange = { isChecked -> onCheckedChange = { isChecked ->
useSystemColors.value = isChecked settingsViewModel.toggleUseSystemColors()
preferences.useSystemColors = isChecked
MonetCompat.useSystemColorsOnAndroid12 = isChecked MonetCompat.useSystemColorsOnAndroid12 = isChecked
MonetCompat.getInstance().updateMonetColors() MonetCompat.getInstance().updateMonetColors()
}, },
enabled = useWallpaperColors.value enabled = settingsViewModel.useSystemColors.collectAsState().value
) )
} }
SliderPreference( SliderPreference(
titleText = stringResource(id = R.string.preference_chroma_factor_heading), titleText = stringResource(id = R.string.preference_chroma_factor_heading),
value = preferences.chromaMultiplier.toFloat() * 50f, value = settingsViewModel.chromaMultiplier.collectAsState(),
onValueChangeFinished = { value -> onValueChangeFinished = { value ->
with((value / 50f).toDouble()) { with((value / 50f)) {
preferences.chromaMultiplier = this settingsViewModel.setChromaMultiplier(value)
MonetCompat.chromaMultiplier = this MonetCompat.chromaMultiplier = this
} }
MonetCompat.getInstance().updateMonetColors() MonetCompat.getInstance().updateMonetColors()
}, },
enabled = (if (isSystemColorsSupported) !preferences.useSystemColors else true).and( enabled = (if (isSystemColorsSupported) !settingsViewModel.useSystemColors.collectAsState().value else true)
useWallpaperColors.value .and(settingsViewModel.useWallpaperColors.collectAsState().value)
)
) )
val showWallpaperPicker = remember { mutableStateOf(false) } val showWallpaperPicker = remember { mutableStateOf(false) }
val wallpaperPickerModifier = val wallpaperPickerModifier =
if (isSystemColorsSupported && preferences.useSystemColors && useWallpaperColors.value) { if (isSystemColorsSupported && settingsViewModel.useSystemColors.collectAsState().value && settingsViewModel.useWallpaperColors.collectAsState().value) {
Modifier Modifier
} else { } else {
Modifier.clickable { showWallpaperPicker.value = true } Modifier.clickable { showWallpaperPicker.value = true }
@@ -311,7 +310,7 @@ private fun DesignPreferences(
text = stringResource(id = R.string.preference_wallpaper_color_heading), text = stringResource(id = R.string.preference_wallpaper_color_heading),
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
fontSize = 20.sp, fontSize = 20.sp,
color = if (isSystemColorsSupported && preferences.useSystemColors) { color = if (isSystemColorsSupported && settingsViewModel.useSystemColors.collectAsState().value) {//preferences.useSystemColors) {
MaterialTheme.colorScheme.outline MaterialTheme.colorScheme.outline
} else { } else {
MaterialTheme.colorScheme.onBackground MaterialTheme.colorScheme.onBackground
@@ -326,15 +325,13 @@ private fun DesignPreferences(
@Composable @Composable
private fun DarkModePreferences( private fun DarkModePreferences(
activity: AppCompatActivity, activity: AppCompatActivity
preferences: AppPreferences = get(AppPreferences::class.java)
) { ) {
val selectedValue = remember { mutableStateOf(preferences.darkTheme) } val settingsViewModel = viewModel<SettingsViewModel>()
val isSelected: (Int) -> Boolean = { selectedValue.value == it } val isSelected: (Int) -> Boolean = { settingsViewModel.darkTheme.value == it }
val onChangeState: (Int) -> Unit = { val onChangeState: (Int) -> Unit = {
selectedValue.value = it settingsViewModel.setDarkMode(it)
preferences.darkTheme = it
activity.recreate() activity.recreate()
} }
@@ -368,30 +365,26 @@ private fun DarkModePreferences(
} }
@Composable @Composable
private fun HomeScreenPreferences( private fun HomeScreenPreferences() {
preferences: AppPreferences = get(AppPreferences::class.java) val settingsViewModel = viewModel<SettingsViewModel>()
) {
PreferenceHeading(text = stringResource(R.string.preference_look_and_feel_heading)) PreferenceHeading(text = stringResource(R.string.preference_look_and_feel_heading))
val showTabLabels = remember { mutableStateOf(preferences.showBottomTabLabels) }
SwitchPreference( SwitchPreference(
titleText = stringResource(R.string.preference_show_text_labels_title), titleText = stringResource(R.string.preference_show_text_labels_title),
subtitleText = stringResource(R.string.preference_show_text_labels_subtitle), subtitleText = stringResource(R.string.preference_show_text_labels_subtitle),
checkState = showTabLabels.value, checkState = settingsViewModel.showBottomTabLabels.collectAsState(),
onCheckedChange = { isChecked -> onCheckedChange = {
showTabLabels.value = isChecked settingsViewModel.toggleShowBottomTabLabels()
preferences.showBottomTabLabels = isChecked
} }
) )
val showPosterTitles = remember { mutableStateOf(preferences.showPosterTitles) }
SwitchPreference( SwitchPreference(
titleText = stringResource(R.string.preference_show_poster_titles_title), titleText = stringResource(R.string.preference_show_poster_titles_title),
subtitleText = stringResource(R.string.preference_show_poster_titles_subtitle), subtitleText = stringResource(R.string.preference_show_poster_titles_subtitle),
checkState = showPosterTitles.value, checkState = settingsViewModel.showPosterTitles.collectAsState(),
onCheckedChange = { isChecked -> onCheckedChange = {
showPosterTitles.value = isChecked settingsViewModel.toggleShowPosterTitles()
preferences.showPosterTitles = isChecked
} }
) )
@@ -423,32 +416,28 @@ private fun HomeScreenPreferences(
} }
@Composable @Composable
private fun DevPreferences( private fun DevPreferences() {
preferences: AppPreferences = get(AppPreferences::class.java)
) {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
val settingsViewModel = viewModel<SettingsViewModel>()
val context = LocalContext.current val context = LocalContext.current
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
val showBackdropGallery = remember { mutableStateOf(preferences.showBackdropGallery) }
SwitchPreference( SwitchPreference(
titleText = "Show backdrop gallery", titleText = "Show backdrop gallery",
subtitleText = "Show galleries for movies/tv backdrops", subtitleText = "Show galleries for movies/tv backdrops",
checkState = showBackdropGallery.value, checkState = settingsViewModel.showBackdropGallery.collectAsState(),
onCheckedChange = { isChecked -> onCheckedChange = {
showBackdropGallery.value = isChecked settingsViewModel.toggleShowBackdropGallery()
preferences.showBackdropGallery = isChecked
} }
) )
val firstLaunchTesting = remember { mutableStateOf(preferences.firstLaunchTesting) }
SwitchPreference( SwitchPreference(
titleText = "Always show onboarding flow", titleText = "Always show onboarding flow",
subtitleText = "Show onboarding flow on each launch", subtitleText = "Show onboarding flow on each launch",
checkState = firstLaunchTesting.value, checkState = settingsViewModel.firstLaunchTesting.collectAsState(),
onCheckedChange = { isChecked -> onCheckedChange = {
firstLaunchTesting.value = isChecked settingsViewModel.toggleFirstLaunchTesting()
preferences.firstLaunchTesting = isChecked
} }
) )
Text( Text(
@@ -506,11 +495,12 @@ private fun DevPreferences(
@Composable @Composable
private fun WallpaperPicker( private fun WallpaperPicker(
showPopup: MutableState<Boolean>, showPopup: MutableState<Boolean>
preference: AppPreferences = get(AppPreferences::class.java)
) { ) {
val context = LocalContext.current val context = LocalContext.current
val settingsViewModel = viewModel<SettingsViewModel>()
val wallpaperColors = remember { mutableStateOf<List<Int>>(emptyList()) } val wallpaperColors = remember { mutableStateOf<List<Int>>(emptyList()) }
val selectedWallpaperColor = remember { mutableStateOf(0) } val selectedWallpaperColor = remember { mutableStateOf(0) }
LaunchedEffect(true) { LaunchedEffect(true) {
@@ -546,7 +536,7 @@ private fun WallpaperPicker(
showIcon = it == selectedWallpaperColor.value, showIcon = it == selectedWallpaperColor.value,
onClick = { onClick = {
if (it != selectedWallpaperColor.value) { if (it != selectedWallpaperColor.value) {
preference.selectedColor = it settingsViewModel.setSelectedColor(it)
MonetCompat MonetCompat
.getInstance() .getInstance()
.updateMonetColors() .updateMonetColors()
@@ -562,8 +552,8 @@ private fun WallpaperPicker(
icon = Icons.Filled.RestartAlt, icon = Icons.Filled.RestartAlt,
contentDescription = null, contentDescription = null,
onClick = { onClick = {
if (preference.selectedColor != Int.MAX_VALUE) { if (settingsViewModel.selectedColor.value != Int.MAX_VALUE) {
preference.selectedColor = Int.MAX_VALUE settingsViewModel.setSelectedColor(Int.MAX_VALUE)
MonetCompat.getInstance().updateMonetColors() MonetCompat.getInstance().updateMonetColors()
} else { } else {
Toast.makeText(context, context.getString(R.string.preference_wallpaper_color_default_selected), Toast.LENGTH_SHORT).show() Toast.makeText(context, context.getString(R.string.preference_wallpaper_color_default_selected), Toast.LENGTH_SHORT).show()
@@ -583,50 +573,99 @@ private fun WallpaperPicker(
} }
} }
private fun resetAllPreferences(preferences: AppPreferences) { private fun resetAllPreferences(
resetSearchPreferences(preferences = preferences) preferences: AppPreferences,
resetDesignPreferences(preferences = preferences) settingsViewModel: SettingsViewModel,
resetHomeScreenPreferences(preferences = preferences) activity: AppCompatActivity
resetDevModePreference(preferences = preferences) ) {
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) { private fun resetSearchPreferences(
preferences.showSearchBar = preferences.showSearchBarDefault preferences: AppPreferences,
preferences.multiSearch = preferences.multiSearchDefault settingsViewModel: SettingsViewModel,
activity: AppCompatActivity,
skipRecreate: Boolean = false
) {
settingsViewModel.setShowSearchBar(preferences.showSearchBarDefault)
settingsViewModel.setMultiSearch(preferences.multiSearchDefault)
if (!skipRecreate) {
activity.recreate()
}
} }
private fun resetDesignPreferences(preferences: AppPreferences) { private fun resetDesignPreferences(
preferences.useWallpaperColors = preferences.useWallpaperColorsDefault preferences: AppPreferences,
preferences.useSystemColors = preferences.useSystemColorsDefault settingsViewModel: SettingsViewModel,
preferences.chromaMultiplier = preferences.chromeMultiplyerDefault activity: AppCompatActivity,
preferences.selectedColor = preferences.selectedColorDefault skipRecreate: Boolean = false
resetDarkModePreferences(preferences = preferences) ) {
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) { private fun resetDarkModePreferences(
preferences.darkTheme = preferences.darkThemeDefault preferences: AppPreferences,
settingsViewModel: SettingsViewModel,
activity: AppCompatActivity,
skipRecreate: Boolean = false
) {
settingsViewModel.setDarkMode(preferences.darkThemeDefault)
if (!skipRecreate) {
activity.recreate()
}
} }
private fun resetDevModePreference(preferences: AppPreferences) { private fun resetDevModePreference(
preferences.firstLaunchTesting = preferences.firstLaunchTestingDefault preferences: AppPreferences,
preferences.showBackdropGallery = preferences.showBackdropGalleryDefault settingsViewModel: SettingsViewModel,
activity: AppCompatActivity,
skipRecreate: Boolean = false
) {
settingsViewModel.setFirstLaunchTesting(preferences.firstLaunchTestingDefault)
settingsViewModel.setShowBackdropGallery(preferences.showBackdropGalleryDefault)
if (!skipRecreate) {
activity.recreate()
}
} }
private fun resetHomeScreenPreferences(preferences: AppPreferences) { 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.moviesTabPosition = preferences.moviesTabPositionDefault
preferences.tvTabPosition = preferences.tvTabPositionDefault preferences.tvTabPosition = preferences.tvTabPositionDefault
preferences.peopleTabPosition = preferences.peopleTabPositionDefault preferences.peopleTabPosition = preferences.peopleTabPositionDefault
preferences.accountTabPosition = preferences.accountTabPositionDefault preferences.accountTabPosition = preferences.accountTabPositionDefault
preferences.showBottomTabLabels = preferences.showBottomTabLabelsDefault preferences.showBottomTabLabels = preferences.showBottomTabLabelsDefault
if (!skipRecreate) {
activity.recreate()
}
} }
private typealias SettingsPageRenderer = @Composable (NavController, AppCompatActivity, AppPreferences) -> Unit private typealias SettingsResetHandler = (AppPreferences, SettingsViewModel, AppCompatActivity) -> Unit
private typealias SettingsPageRenderer = @Composable (NavController, AppCompatActivity) -> Unit
private sealed class SettingsPage( private sealed class SettingsPage(
stringRes: Int, stringRes: Int,
val route: String, val route: String,
val settingsPageRenderer: SettingsPageRenderer, val settingsPageRenderer: SettingsPageRenderer,
val resetPreferencesHandler: (AppPreferences) -> Unit val resetPreferencesHandler: SettingsResetHandler
): KoinComponent { ): KoinComponent {
private val resources: ResourceUtils by inject() private val resources: ResourceUtils by inject()
@@ -654,31 +693,31 @@ private sealed class SettingsPage(
object SearchSettings: SettingsPage( object SearchSettings: SettingsPage(
R.string.preference_heading_search, R.string.preference_heading_search,
"search", "search",
@Composable { _, _, p -> SearchPreferences(p) }, @Composable { _, _ -> SearchPreferences() },
::resetSearchPreferences ::resetSearchPreferences
) )
object DesignSettings: SettingsPage( object DesignSettings: SettingsPage(
R.string.preference_heading_design, R.string.preference_heading_design,
"design", "design",
@Composable { n, a, p -> DesignPreferences(n, a, p) }, @Composable { n, a -> DesignPreferences(n, a) },
::resetDesignPreferences ::resetDesignPreferences
) )
object HomeScreenSettings: SettingsPage( object HomeScreenSettings: SettingsPage(
R.string.preference_heading_home_screen, R.string.preference_heading_home_screen,
"home", "home",
@Composable { _, _, p -> HomeScreenPreferences(p) }, @Composable { _, _ -> HomeScreenPreferences() },
::resetHomeScreenPreferences ::resetHomeScreenPreferences
) )
object DeveloperSettings: SettingsPage( object DeveloperSettings: SettingsPage(
R.string.preferences_debug_title, R.string.preferences_debug_title,
"dev", "dev",
@Composable { _, _, p -> DevPreferences(p) }, @Composable { _, _ -> DevPreferences() },
::resetDevModePreference ::resetDevModePreference
) )
object DarkModeSettings: SettingsPage( object DarkModeSettings: SettingsPage(
R.string.preference_heading_dark_mode, R.string.preference_heading_dark_mode,
"darkmode", "darkmode",
@Composable { _, a, p -> DarkModePreferences(a, p) }, @Composable { _, a -> DarkModePreferences(a) },
::resetDarkModePreferences ::resetDarkModePreferences
) )
} }

View File

@@ -18,7 +18,7 @@ import com.owenlejeune.tvtime.ui.components.SearchView
import com.owenlejeune.tvtime.ui.navigation.AppNavItem import com.owenlejeune.tvtime.ui.navigation.AppNavItem
import com.owenlejeune.tvtime.ui.navigation.MediaTabNavItem import com.owenlejeune.tvtime.ui.navigation.MediaTabNavItem
import com.owenlejeune.tvtime.ui.components.Tabs import com.owenlejeune.tvtime.ui.components.Tabs
import com.owenlejeune.tvtime.api.tmdb.viewmodel.MediaTabViewModel import com.owenlejeune.tvtime.ui.viewmodel.MediaTabViewModel
import com.owenlejeune.tvtime.utils.types.MediaViewType import com.owenlejeune.tvtime.utils.types.MediaViewType
@OptIn(ExperimentalPagerApi::class) @OptIn(ExperimentalPagerApi::class)

View File

@@ -11,7 +11,7 @@ import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.ui.components.PagingPeoplePosterGrid import com.owenlejeune.tvtime.ui.components.PagingPeoplePosterGrid
import com.owenlejeune.tvtime.ui.components.SearchView import com.owenlejeune.tvtime.ui.components.SearchView
import com.owenlejeune.tvtime.ui.navigation.AppNavItem import com.owenlejeune.tvtime.ui.navigation.AppNavItem
import com.owenlejeune.tvtime.api.tmdb.viewmodel.PeopleTabViewModel import com.owenlejeune.tvtime.ui.viewmodel.PeopleTabViewModel
import com.owenlejeune.tvtime.utils.types.MediaViewType import com.owenlejeune.tvtime.utils.types.MediaViewType
@Composable @Composable

View File

@@ -1,4 +1,4 @@
package com.owenlejeune.tvtime.api.tmdb.viewmodel package com.owenlejeune.tvtime.ui.viewmodel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope

View File

@@ -1,4 +1,4 @@
package com.owenlejeune.tvtime.api.tmdb.viewmodel package com.owenlejeune.tvtime.ui.viewmodel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope

View File

@@ -1,4 +1,4 @@
package com.owenlejeune.tvtime.api.tmdb.viewmodel package com.owenlejeune.tvtime.ui.viewmodel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope

View File

@@ -0,0 +1,142 @@
package com.owenlejeune.tvtime.ui.viewmodel
import androidx.lifecycle.ViewModel
import com.owenlejeune.tvtime.preferences.AppPreferences
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class SettingsViewModel: ViewModel(), KoinComponent {
private val preferences: AppPreferences by inject()
private val _showSearchBar = MutableStateFlow(preferences.showSearchBar)
val showSearchBar = _showSearchBar.asStateFlow()
private val _useMultiSearch = MutableStateFlow(preferences.multiSearch)
val useMultiSearch = _useMultiSearch.asStateFlow()
private val _useWallpaperColor = MutableStateFlow(preferences.useWallpaperColors)
val useWallpaperColors = _useWallpaperColor.asStateFlow()
private val _darkTheme = MutableStateFlow(preferences.darkTheme)
val darkTheme = _darkTheme.asStateFlow()
private val _useSystemColors = MutableStateFlow(preferences.useSystemColors)
val useSystemColors = _useSystemColors.asStateFlow()
private val _chromaMultiplier = MutableStateFlow(preferences.chromaMultiplier)
val chromaMultiplier = _chromaMultiplier.asStateFlow()
private val _selectedColor = MutableStateFlow(preferences.selectedColor)
val selectedColor = _selectedColor.asStateFlow()
private val _showBottomTabLabels = MutableStateFlow(preferences.showBottomTabLabels)
val showBottomTabLabels = _showBottomTabLabels.asStateFlow()
private val _showPosterTitles = MutableStateFlow(preferences.showPosterTitles)
val showPosterTitles = _showPosterTitles.asStateFlow()
private val _firstLaunchTesting = MutableStateFlow(preferences.firstLaunchTesting)
val firstLaunchTesting = _firstLaunchTesting.asStateFlow()
private val _showBackdropGallery = MutableStateFlow(preferences.showBackdropGallery)
val showBackdropGallery = _showBackdropGallery.asStateFlow()
fun toggleShowSearchBar() {
_showSearchBar.value = _showSearchBar.value.not()
preferences.showSearchBar = _showSearchBar.value
}
fun setShowSearchBar(value: Boolean) {
_showSearchBar.value = value
preferences.showSearchBar = value
}
fun toggleMultiSearch() {
_useMultiSearch.value = _useMultiSearch.value.not()
preferences.multiSearch = _useMultiSearch.value
}
fun setMultiSearch(value: Boolean) {
_useMultiSearch.value = value
preferences.multiSearch = value
}
fun toggleUseWallpaperColors() {
_useWallpaperColor.value = _useWallpaperColor.value.not()
preferences.useWallpaperColors = _useWallpaperColor.value
}
fun setUseWallpaperColors(value: Boolean) {
_useWallpaperColor.value = value
preferences.useWallpaperColors = value
}
fun setDarkMode(darkMode: Int) {
_darkTheme.value = darkMode
preferences.darkTheme = _darkTheme.value
}
fun toggleUseSystemColors() {
_useSystemColors.value = _useSystemColors.value.not()
preferences.useSystemColors = _useSystemColors.value
}
fun setUseSystemColors(value: Boolean) {
_useSystemColors.value = value
preferences.useSystemColors = value
}
fun setChromaMultiplier(multiplier: Double) {
_chromaMultiplier.value = multiplier
preferences.chromaMultiplier = _chromaMultiplier.value
}
fun setSelectedColor(selectedColor: Int) {
_selectedColor.value = selectedColor
preferences.selectedColor = _selectedColor.value
}
fun toggleShowBottomTabLabels() {
_showBottomTabLabels.value = _showBottomTabLabels.value.not()
preferences.showBottomTabLabels = _showBottomTabLabels.value
}
fun setShowBottomTabLabels(value: Boolean) {
_showBottomTabLabels.value = value
preferences.showBottomTabLabels = value
}
fun toggleShowPosterTitles() {
_showPosterTitles.value = _showPosterTitles.value.not()
preferences.showPosterTitles = _showPosterTitles.value
}
fun setShowPosterTitles(value: Boolean) {
_showPosterTitles.value = value
preferences.showPosterTitles = value
}
fun toggleFirstLaunchTesting() {
_firstLaunchTesting.value = _firstLaunchTesting.value.not()
preferences.firstLaunchTesting = _firstLaunchTesting.value
}
fun setFirstLaunchTesting(value: Boolean) {
_firstLaunchTesting.value = value
preferences.firstLaunchTesting = value
}
fun toggleShowBackdropGallery() {
_showBackdropGallery.value = _showBackdropGallery.value.not()
preferences.showBackdropGallery = _showBackdropGallery.value
}
fun setShowBackdropGallery(value: Boolean) {
_showBackdropGallery.value = value
preferences.showBackdropGallery = value
}
}

View File

@@ -1,4 +1,4 @@
package com.owenlejeune.tvtime.api.tmdb.viewmodel package com.owenlejeune.tvtime.ui.viewmodel
object ViewModelConstants { object ViewModelConstants {