From d4798734325c78899e2ff8449e16eea2fd800f9c Mon Sep 17 00:00:00 2001 From: rumboalla Date: Wed, 9 Aug 2023 09:49:41 +0200 Subject: [PATCH] Add setting to select theme Fix dropdowns not saving value Add few string to romanian --- .../main/java/com/apkupdater/di/MainModule.kt | 4 +-- .../main/java/com/apkupdater/prefs/Prefs.kt | 1 + .../apkupdater/ui/activity/MainActivity.kt | 3 +-- .../com/apkupdater/ui/component/Settings.kt | 8 +++--- .../com/apkupdater/ui/screen/MainScreen.kt | 27 ++++++++++++------- .../apkupdater/ui/screen/SettingsScreen.kt | 11 ++++++++ .../java/com/apkupdater/ui/theme/Theme.kt | 11 ++++++-- .../java/com/apkupdater/util/Extensions.kt | 4 +++ .../com/apkupdater/viewmodel/MainViewModel.kt | 8 +++++- .../apkupdater/viewmodel/SettingsViewModel.kt | 8 ++++++ app/src/main/res/drawable/ic_theme.xml | 5 ++++ app/src/main/res/values-ro/strings.xml | 2 +- app/src/main/res/values/strings.xml | 4 +++ 13 files changed, 75 insertions(+), 21 deletions(-) create mode 100644 app/src/main/res/drawable/ic_theme.xml diff --git a/app/src/main/java/com/apkupdater/di/MainModule.kt b/app/src/main/java/com/apkupdater/di/MainModule.kt index a421ceb5..0c3ffd7b 100644 --- a/app/src/main/java/com/apkupdater/di/MainModule.kt +++ b/app/src/main/java/com/apkupdater/di/MainModule.kt @@ -136,11 +136,11 @@ val mainModule = module { viewModel { parameters -> AppsViewModel(parameters.get(), get(), get()) } - viewModel { MainViewModel() } + viewModel { MainViewModel(get()) } viewModel { parameters -> UpdatesViewModel(parameters.get(), get(), get(), get(), get()) } - viewModel { SettingsViewModel(get(), get(), WorkManager.getInstance(get())) } + viewModel { parameters -> SettingsViewModel(parameters.get(), get(), get(), WorkManager.getInstance(get())) } viewModel { parameters -> SearchViewModel(parameters.get(), get(), get(), get(), get()) } diff --git a/app/src/main/java/com/apkupdater/prefs/Prefs.kt b/app/src/main/java/com/apkupdater/prefs/Prefs.kt index d2bd4b0d..7f89637d 100644 --- a/app/src/main/java/com/apkupdater/prefs/Prefs.kt +++ b/app/src/main/java/com/apkupdater/prefs/Prefs.kt @@ -26,4 +26,5 @@ class Prefs( val alarmFrequency = int("alarmFrequency", 0, backed = true) val androidTvUi = boolean("androidTvUi", defValue = isAndroidTv, backed = true) val rootInstall = boolean("rootInstall", defValue = false, backed = true) + val theme = int("theme", defValue = 0, backed = true) } diff --git a/app/src/main/java/com/apkupdater/ui/activity/MainActivity.kt b/app/src/main/java/com/apkupdater/ui/activity/MainActivity.kt index 4aaf8895..9e92c296 100644 --- a/app/src/main/java/com/apkupdater/ui/activity/MainActivity.kt +++ b/app/src/main/java/com/apkupdater/ui/activity/MainActivity.kt @@ -4,12 +4,11 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import com.apkupdater.ui.screen.MainScreen -import com.apkupdater.ui.theme.AppTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContent { AppTheme { MainScreen() } } + setContent { MainScreen() } } } diff --git a/app/src/main/java/com/apkupdater/ui/component/Settings.kt b/app/src/main/java/com/apkupdater/ui/component/Settings.kt index ddc556f9..8601a249 100644 --- a/app/src/main/java/com/apkupdater/ui/component/Settings.kt +++ b/app/src/main/java/com/apkupdater/ui/component/Settings.kt @@ -121,8 +121,9 @@ fun DropDownSetting( @DrawableRes icon: Int ) = Box( Modifier - .padding(16.dp) - .fillMaxWidth()) { + .padding(top = 16.dp, start = 16.dp, end = 16.dp, bottom = 8.dp) + .fillMaxWidth() +) { var expanded by remember { mutableStateOf(false) } var selectedOptionText by remember { mutableStateOf(options[getValue()]) } @@ -155,12 +156,13 @@ fun DropDownSetting( expanded = expanded, onDismissRequest = { expanded = false } ) { - options.forEach { option -> + options.forEachIndexed { i, option -> DropdownMenuItem( text = { Text(text = option) }, onClick = { selectedOptionText = option expanded = false + setValue(i) } ) } diff --git a/app/src/main/java/com/apkupdater/ui/screen/MainScreen.kt b/app/src/main/java/com/apkupdater/ui/screen/MainScreen.kt index d443431b..6d75fd30 100644 --- a/app/src/main/java/com/apkupdater/ui/screen/MainScreen.kt +++ b/app/src/main/java/com/apkupdater/ui/screen/MainScreen.kt @@ -41,6 +41,7 @@ import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.apkupdater.data.ui.Screen import com.apkupdater.ui.component.BadgeText +import com.apkupdater.ui.theme.AppTheme import com.apkupdater.viewmodel.AppsViewModel import com.apkupdater.viewmodel.MainViewModel import com.apkupdater.viewmodel.SearchViewModel @@ -56,6 +57,7 @@ fun MainScreen(mainViewModel: MainViewModel = koinViewModel()) { val appsViewModel: AppsViewModel = koinViewModel(parameters = { parametersOf(mainViewModel) }) val updatesViewModel: UpdatesViewModel = koinViewModel(parameters = { parametersOf(mainViewModel) }) val searchViewModel: SearchViewModel = koinViewModel(parameters = { parametersOf(mainViewModel) }) + val settingsViewModel: SettingsViewModel = koinViewModel(parameters = { parametersOf(mainViewModel) }) // Navigation val navController = rememberNavController() @@ -80,15 +82,20 @@ fun MainScreen(mainViewModel: MainViewModel = koinViewModel()) { // Check notification intent when hot starting intentListener(mainViewModel, updatesViewModel, navController, launcher) - Scaffold(bottomBar = { BottomBar(mainViewModel, navController) }) { padding -> - Box(modifier = Modifier.pullRefresh(pullToRefresh)) { - NavHost(navController, padding, appsViewModel, updatesViewModel, searchViewModel) - PullRefreshIndicator( - refreshing = isRefreshing.value, - state = pullToRefresh, - modifier = Modifier.align(Alignment.TopCenter), - contentColor = MaterialTheme.colorScheme.primary - ) + // Theme + val theme = mainViewModel.theme.collectAsStateWithLifecycle().value + + AppTheme(theme) { + Scaffold(bottomBar = { BottomBar(mainViewModel, navController) }) { padding -> + Box(modifier = Modifier.pullRefresh(pullToRefresh)) { + NavHost(navController, padding, appsViewModel, updatesViewModel, searchViewModel, settingsViewModel) + PullRefreshIndicator( + refreshing = isRefreshing.value, + state = pullToRefresh, + modifier = Modifier.align(Alignment.TopCenter), + contentColor = MaterialTheme.colorScheme.primary + ) + } } } } @@ -167,7 +174,7 @@ fun NavHost( appsViewModel: AppsViewModel, updatesViewModel: UpdatesViewModel, searchViewModel: SearchViewModel, - settingsViewModel: SettingsViewModel = koinViewModel() + settingsViewModel: SettingsViewModel ) = NavHost( navController = navController, startDestination = Screen.Apps.route, diff --git a/app/src/main/java/com/apkupdater/ui/screen/SettingsScreen.kt b/app/src/main/java/com/apkupdater/ui/screen/SettingsScreen.kt index 61b7e8a7..00adaaf5 100644 --- a/app/src/main/java/com/apkupdater/ui/screen/SettingsScreen.kt +++ b/app/src/main/java/com/apkupdater/ui/screen/SettingsScreen.kt @@ -101,6 +101,17 @@ fun Settings(viewModel: SettingsViewModel) = LazyColumn { 6, R.drawable.ic_landscape ) + DropDownSetting( + stringResource(R.string.theme), + listOf( + stringResource(R.string.theme_system), + stringResource(R.string.theme_dark), + stringResource(R.string.theme_light) + ), + { viewModel.getTheme() }, + { viewModel.setTheme(it) }, + R.drawable.ic_theme + ) } item { diff --git a/app/src/main/java/com/apkupdater/ui/theme/Theme.kt b/app/src/main/java/com/apkupdater/ui/theme/Theme.kt index 0abfd0e6..8680f443 100644 --- a/app/src/main/java/com/apkupdater/ui/theme/Theme.kt +++ b/app/src/main/java/com/apkupdater/ui/theme/Theme.kt @@ -2,7 +2,6 @@ package com.apkupdater.ui.theme import android.app.Activity import android.os.Build -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.ColorScheme import androidx.compose.material3.MaterialTheme import androidx.compose.material3.darkColorScheme @@ -17,10 +16,12 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView import androidx.compose.ui.unit.dp import androidx.core.view.WindowCompat +import com.apkupdater.util.isDark + @Composable fun AppTheme( - darkTheme: Boolean = isSystemInDarkTheme(), + darkTheme: Boolean, dynamicColor: Boolean = true, content: @Composable () -> Unit ) { @@ -60,3 +61,9 @@ fun AppTheme( } fun ColorScheme.statusBarColor() = surfaceColorAtElevation(3.dp) + +fun isDarkTheme(theme: Int): Boolean { + if (theme == 1) return true + if (theme == 2) return false + return isDark() +} diff --git a/app/src/main/java/com/apkupdater/util/Extensions.kt b/app/src/main/java/com/apkupdater/util/Extensions.kt index e048caf6..c90cfb19 100644 --- a/app/src/main/java/com/apkupdater/util/Extensions.kt +++ b/app/src/main/java/com/apkupdater/util/Extensions.kt @@ -4,6 +4,8 @@ import android.content.Context import android.content.Intent import android.content.pm.PackageInfo import android.content.pm.PackageManager +import android.content.res.Configuration +import android.content.res.Resources import android.os.Build import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource @@ -93,3 +95,5 @@ fun PackageManager.isAndroidTv() = hasSystemFeature(PackageManager.FEATURE_LEANB fun Context.isAndroidTv() = packageManager.isAndroidTv() fun randomUUID() = UUID.randomUUID().toString() + +fun isDark() = Resources.getSystem().configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES diff --git a/app/src/main/java/com/apkupdater/viewmodel/MainViewModel.kt b/app/src/main/java/com/apkupdater/viewmodel/MainViewModel.kt index 2c6765af..b755796e 100644 --- a/app/src/main/java/com/apkupdater/viewmodel/MainViewModel.kt +++ b/app/src/main/java/com/apkupdater/viewmodel/MainViewModel.kt @@ -11,6 +11,8 @@ import androidx.navigation.NavController import androidx.navigation.NavGraph.Companion.findStartDestination import com.apkupdater.data.ui.AppInstallStatus import com.apkupdater.data.ui.Screen +import com.apkupdater.prefs.Prefs +import com.apkupdater.ui.theme.isDarkTheme import com.apkupdater.util.SessionInstaller import com.apkupdater.util.UpdatesNotification import com.apkupdater.util.getAppId @@ -22,10 +24,12 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch -class MainViewModel : ViewModel() { +class MainViewModel(prefs: Prefs) : ViewModel() { val screens = listOf(Screen.Apps, Screen.Search, Screen.Updates, Screen.Settings) + val theme = MutableStateFlow(isDarkTheme(prefs.theme.get())) + val badges = MutableStateFlow(mapOf( Screen.Apps.route to "", Screen.Search.route to "", @@ -48,6 +52,8 @@ class MainViewModel : ViewModel() { } } + fun setTheme(theme: Boolean) = this.theme.apply { value = theme } + fun changeSearchBadge(number: String) = changeBadge(Screen.Search.route, number) fun changeAppsBadge(number: String) = changeBadge(Screen.Apps.route, number) diff --git a/app/src/main/java/com/apkupdater/viewmodel/SettingsViewModel.kt b/app/src/main/java/com/apkupdater/viewmodel/SettingsViewModel.kt index ae0d16a3..0fa72e02 100644 --- a/app/src/main/java/com/apkupdater/viewmodel/SettingsViewModel.kt +++ b/app/src/main/java/com/apkupdater/viewmodel/SettingsViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModel import androidx.work.WorkManager import com.apkupdater.data.ui.SettingsUiState import com.apkupdater.prefs.Prefs +import com.apkupdater.ui.theme.isDarkTheme import com.apkupdater.util.UpdatesNotification import com.apkupdater.worker.UpdatesWorker import eu.chainfire.libsuperuser.Shell @@ -12,6 +13,7 @@ import kotlinx.coroutines.flow.MutableStateFlow class SettingsViewModel( + private val mainViewModel: MainViewModel, private val prefs: Prefs, private val notification: UpdatesNotification, private val workManager: WorkManager @@ -41,6 +43,12 @@ class SettingsViewModel( fun getRootInstall() = prefs.rootInstall.get() fun getAlarmHour() = prefs.alarmHour.get() fun getAlarmFrequency() = prefs.alarmFrequency.get() + fun getTheme() = prefs.theme.get() + + fun setTheme(theme: Int) { + prefs.theme.put(theme) + mainViewModel.setTheme(isDarkTheme(theme)) + } fun setRootInstall(b: Boolean) { if (b && Shell.SU.available()) { diff --git a/app/src/main/res/drawable/ic_theme.xml b/app/src/main/res/drawable/ic_theme.xml new file mode 100644 index 00000000..cac8de55 --- /dev/null +++ b/app/src/main/res/drawable/ic_theme.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 9983e2e4..2c2b3a73 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -46,7 +46,7 @@ updateChannel Actualizări - TODO + Au fost găsite %1$d actualizări. Nicio actualizare găsită. A fost găsită %1$d actualizare. Au fost găsite %1$d actualizări. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0d75ead1..8e7cff56 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -39,6 +39,10 @@ GitHub About Frequency + Theme + System + Dark + Light // Notifications Updates