diff --git a/app/src/main/java/com/henryhiles/qweather/domain/manager/BasePreferenceManager.kt b/app/src/main/java/com/henryhiles/qweather/domain/manager/BasePreferenceManager.kt index 2f3a8de..43ea37e 100644 --- a/app/src/main/java/com/henryhiles/qweather/domain/manager/BasePreferenceManager.kt +++ b/app/src/main/java/com/henryhiles/qweather/domain/manager/BasePreferenceManager.kt @@ -6,6 +6,9 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.graphics.Color import androidx.core.content.edit +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import kotlin.reflect.KProperty abstract class BasePreferenceManager( @@ -18,13 +21,16 @@ abstract class BasePreferenceManager( 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()) + val color = prefs.getString(key, null) + return if (color == null) defaultValue else Color(color.toULong()) } protected inline fun > getEnum(key: String, defaultValue: E) = enumValueOf(getString(key, defaultValue.name)) + protected inline fun getJson(key: String, defaultValue: T) = + Json.decodeFromString(getString(key, null)) ?: defaultValue + 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) } @@ -35,6 +41,9 @@ abstract class BasePreferenceManager( protected inline fun > putEnum(key: String, value: E) = putString(key, value.name) + protected inline fun putJson(key: String, value: T) = + putString(key, Json.encodeToString(value)) + protected class Preference( private val key: String, defaultValue: T, @@ -109,4 +118,14 @@ abstract class BasePreferenceManager( getter = ::getEnum, setter = ::putEnum ) + + protected inline fun jsonPreference( + key: String, + defaultValue: T + ) = Preference( + key = key, + defaultValue = defaultValue, + getter = ::getJson, + setter = ::putJson + ) } \ No newline at end of file diff --git a/app/src/main/java/com/henryhiles/qweather/presentation/QWeatherActivity.kt b/app/src/main/java/com/henryhiles/qweather/presentation/QWeatherActivity.kt index 3ee1759..ccb6db9 100644 --- a/app/src/main/java/com/henryhiles/qweather/presentation/QWeatherActivity.kt +++ b/app/src/main/java/com/henryhiles/qweather/presentation/QWeatherActivity.kt @@ -31,7 +31,8 @@ class QWeatherActivity : ComponentActivity() { Theme.LIGHT -> false Theme.DARK -> true } - val isLocationSet = location.getLocations().isNotEmpty() + val locations = location.locations + val isLocationSet = locations.isNotEmpty() WeatherAppTheme(darkTheme = isDark, monet = prefs.monet) { Surface(modifier = Modifier.fillMaxSize()) { diff --git a/app/src/main/java/com/henryhiles/qweather/presentation/components/location/LocationsDrawer.kt b/app/src/main/java/com/henryhiles/qweather/presentation/components/location/LocationsDrawer.kt index b1caecc..a606d2f 100644 --- a/app/src/main/java/com/henryhiles/qweather/presentation/components/location/LocationsDrawer.kt +++ b/app/src/main/java/com/henryhiles/qweather/presentation/components/location/LocationsDrawer.kt @@ -26,7 +26,7 @@ fun LocationsDrawer(drawerState: DrawerState, children: @Composable () -> Unit) ModalNavigationDrawer(drawerContent = { ModalDrawerSheet { Column(modifier = Modifier.padding(16.dp)) { - val locations = location.getLocations() + val locations = location.locations Text( text = stringResource(id = R.string.locations), @@ -36,10 +36,10 @@ fun LocationsDrawer(drawerState: DrawerState, children: @Composable () -> Unit) locations.forEachIndexed { index, data -> NavigationDrawerItem( label = { Text(text = data.location) }, - selected = index == location.selectedLocation, - onClick = { location.selectedLocation = index }, + selected = index == location.selectedIndex, + onClick = { location.selectedIndex = index }, badge = { - IconButton(onClick = { location.removeLocation(data) }) { + IconButton(onClick = { location.locations -= data }) { Icon( imageVector = Icons.Default.Delete, contentDescription = stringResource( diff --git a/app/src/main/java/com/henryhiles/qweather/presentation/screen/LocationPickerScreen.kt b/app/src/main/java/com/henryhiles/qweather/presentation/screen/LocationPickerScreen.kt index 08ace3c..c95776c 100644 --- a/app/src/main/java/com/henryhiles/qweather/presentation/screen/LocationPickerScreen.kt +++ b/app/src/main/java/com/henryhiles/qweather/presentation/screen/LocationPickerScreen.kt @@ -43,7 +43,7 @@ class LocationPickerScreen : Screen { floatingActionButton = { FloatingActionButton(onClick = { location?.let { - screenModel.prefs.addLocation(it) + screenModel.prefs.locations += it navigator?.push(MainScreen()) } ?: kotlin.run { isAboutOpen = true } }) { diff --git a/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/DailyWeatherScreenModel.kt b/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/DailyWeatherScreenModel.kt index fddf9c2..45c97c5 100644 --- a/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/DailyWeatherScreenModel.kt +++ b/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/DailyWeatherScreenModel.kt @@ -23,7 +23,7 @@ class DailyWeatherScreenModel( ) : ScreenModel { var state by mutableStateOf(DailyWeatherState()) private set - val location = locationPreferenceManager.getSelectedLocation() + val location = locationPreferenceManager.locations[locationPreferenceManager.selectedIndex] fun loadWeatherInfo(cache: Boolean = true) { coroutineScope.launch { diff --git a/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/HourlyWeatherScreenModel.kt b/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/HourlyWeatherScreenModel.kt index a04c7d4..39b3609 100644 --- a/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/HourlyWeatherScreenModel.kt +++ b/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/HourlyWeatherScreenModel.kt @@ -24,7 +24,7 @@ class HourlyWeatherScreenModel( var state by mutableStateOf(HourlyWeatherState()) private set - val location = locationPreferenceManager.getSelectedLocation() + val location = locationPreferenceManager.locations[locationPreferenceManager.selectedIndex] fun loadWeatherInfo(cache: Boolean = true) { coroutineScope.launch { diff --git a/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/LocationPickerScreenModel.kt b/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/LocationPickerScreenModel.kt index 5d00302..d67c5e5 100644 --- a/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/LocationPickerScreenModel.kt +++ b/app/src/main/java/com/henryhiles/qweather/presentation/screenmodel/LocationPickerScreenModel.kt @@ -11,9 +11,6 @@ import com.henryhiles.qweather.domain.manager.BasePreferenceManager import com.henryhiles.qweather.domain.repository.GeocodingRepository import com.henryhiles.qweather.domain.util.Resource import kotlinx.coroutines.launch -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json data class LocationPickerState( val locations: List? = null, @@ -23,29 +20,11 @@ data class LocationPickerState( class LocationPreferenceManager(context: Context) : BasePreferenceManager(context.getSharedPreferences("location", Context.MODE_PRIVATE)) { - private var locations by stringPreference( + var locations by jsonPreference>( "locations", - Json.encodeToString(value = listOf()) + listOf() ) - var selectedLocation by intPreference("selected_location", 0) - - fun getSelectedLocation(): GeocodingData { - return getLocations()[selectedLocation] - } - - fun getLocations(): List { - return Json.decodeFromString(string = locations) - } - - fun addLocation(location: GeocodingData) { - val currentLocations = getLocations() - locations = Json.encodeToString(value = currentLocations + location) - } - - fun removeLocation(location: GeocodingData) { - val currentLocations = getLocations() - locations = Json.encodeToString(value = currentLocations - location) - } + var selectedIndex by intPreference("selected_location", 0) } class LocationPickerScreenModel(