From 211421b3e1b0ee5641c2fc4f7038aa06844cf3e4 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 31 Mar 2023 10:21:14 -0400 Subject: [PATCH] some initial testing, still doesnt work --- .../com/henryhiles/qweather/di/AppModule.kt | 4 + .../screen/AppearanceSettingsScreen.kt | 5 +- .../AppearanceSettingsScreenModel.kt | 130 ++++++++++++++++-- 3 files changed, 126 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/henryhiles/qweather/di/AppModule.kt b/app/src/main/java/com/henryhiles/qweather/di/AppModule.kt index 4c2e87f..421e0a6 100644 --- a/app/src/main/java/com/henryhiles/qweather/di/AppModule.kt +++ b/app/src/main/java/com/henryhiles/qweather/di/AppModule.kt @@ -1,6 +1,8 @@ package com.henryhiles.qweather.di import com.henryhiles.qweather.data.remote.WeatherApi +import com.henryhiles.qweather.presentation.screenmodel.AppearanceSettingsScreenModel +import com.henryhiles.qweather.presentation.screenmodel.PreferenceManager import com.henryhiles.qweather.presentation.screenmodel.WeatherScreenModel import org.koin.core.module.dsl.factoryOf import org.koin.core.module.dsl.singleOf @@ -33,6 +35,8 @@ val appModule = module { } singleOf(::provideWeatherApi) + singleOf(::PreferenceManager) + factoryOf(::AppearanceSettingsScreenModel) // single { // LocationServices.getFusedLocationProviderClient(get()) // } diff --git a/app/src/main/java/com/henryhiles/qweather/presentation/screen/AppearanceSettingsScreen.kt b/app/src/main/java/com/henryhiles/qweather/presentation/screen/AppearanceSettingsScreen.kt index 48c079e..c8e397a 100644 --- a/app/src/main/java/com/henryhiles/qweather/presentation/screen/AppearanceSettingsScreen.kt +++ b/app/src/main/java/com/henryhiles/qweather/presentation/screen/AppearanceSettingsScreen.kt @@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -30,10 +29,10 @@ class AppearanceSettingsScreen : Screen { ) { val ctx = LocalContext.current - Scaffold(topBar = { Toolbar() }) { pv -> + Scaffold(topBar = { Toolbar() }) { padding -> Column( modifier = Modifier - .padding(pv) + .padding(padding) .verticalScroll(rememberScrollState()) ) { diff --git a/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/AppearanceSettingsScreenModel.kt b/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/AppearanceSettingsScreenModel.kt index 7a12166..c7d2ef8 100644 --- a/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/AppearanceSettingsScreenModel.kt +++ b/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/AppearanceSettingsScreenModel.kt @@ -1,20 +1,130 @@ package com.henryhiles.qweather.presentation.screenmodel import android.content.Context +import android.content.SharedPreferences +import android.content.res.Resources import android.os.Build -import androidx.annotation.StringRes +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.graphics.Color +import androidx.core.content.edit import cafe.adriel.voyager.core.model.ScreenModel -import com.henryhiles.qweather.R +import kotlin.reflect.KProperty -class AppearanceSettingsScreenModel(context: Context) : ScreenModel { +abstract class BasePreferenceManager( + private val prefs: SharedPreferences +) { + protected fun getString(key: String, defaultValue: String?) = + prefs.getString(key, defaultValue)!! - var theme by enumPreference("theme", Theme.SYSTEM) - var monet by booleanPreference("monet", Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) + private fun getBoolean(key: String, defaultValue: Boolean) = prefs.getBoolean(key, defaultValue) + private fun getInt(key: String, defaultValue: Int) = prefs.getInt(key, defaultValue) + private fun getFloat(key: String, defaultValue: Float) = prefs.getFloat(key, defaultValue) + private fun getColor(key: String, defaultValue: Color): Color { + val c = prefs.getString(key, null) + return if (c == null) defaultValue else Color(c.toULong()) + } + protected inline fun > getEnum(key: String, defaultValue: E) = + enumValueOf(getString(key, defaultValue.name)) + + protected fun putString(key: String, value: String?) = prefs.edit { putString(key, value) } + private fun putBoolean(key: String, value: Boolean) = prefs.edit { putBoolean(key, value) } + private fun putInt(key: String, value: Int) = prefs.edit { putInt(key, value) } + private fun putFloat(key: String, value: Float) = prefs.edit { putFloat(key, value) } + private fun putColor(key: String, value: Color) = + prefs.edit { putString(key, value.value.toString()) } + + protected inline fun > putEnum(key: String, value: E) = + putString(key, value.name) + + protected class Preference( + private val key: String, + defaultValue: T, + getter: (key: String, defaultValue: T) -> T, + private val setter: (key: String, newValue: T) -> Unit + ) { + @Suppress("RedundantSetter") + var value by mutableStateOf(getter(key, defaultValue)) + private set + + operator fun getValue(thisRef: Any?, property: KProperty<*>) = value + operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: T) { + value = newValue + setter(key, newValue) + } + } + + protected fun stringPreference( + key: String, + defaultValue: String = "" + ) = Preference( + key = key, + defaultValue = defaultValue, + getter = ::getString, + setter = ::putString + ) + + protected fun booleanPreference( + key: String, + defaultValue: Boolean + ) = Preference( + key = key, + defaultValue = defaultValue, + getter = ::getBoolean, + setter = ::putBoolean + ) + + protected fun intPreference( + key: String, + defaultValue: Int + ) = Preference( + key = key, + defaultValue = defaultValue, + getter = ::getInt, + setter = ::putInt + ) + + protected fun floatPreference( + key: String, + defaultValue: Float + ) = Preference( + key = key, + defaultValue = defaultValue, + getter = ::getFloat, + setter = ::putFloat + ) + + protected fun colorPreference( + key: String, + defaultValue: Color + ) = Preference( + key = key, + defaultValue = defaultValue, + getter = ::getColor, + setter = ::putColor + ) + + + protected inline fun > enumPreference( + key: String, + defaultValue: E + ) = Preference( + key = key, + defaultValue = defaultValue, + getter = ::getEnum, + setter = ::putEnum + ) } -enum class Theme(@StringRes val label: Int) { - SYSTEM(R.string.theme_system), - LIGHT(R.string.theme_light), - DARK(R.string.theme_dark); -} \ No newline at end of file +class PreferenceManager(context: Context) : + BasePreferenceManager(context.getSharedPreferences("prefs", Context.MODE_PRIVATE)) { + + var theme by enumPreference("theme", Resources.Theme.SYSTEM) + var monet by booleanPreference("monet", Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) +} + +class AppearanceSettingsScreenModel( + val prefs: PreferenceManager +) : ScreenModel \ No newline at end of file