nordiccalendar

A simple Material 3 native calendar app fitting my personal requirements
git clone git://archive.git.mtrnord.blog/MTRNord/nordiccalendar.git
Log | Files | Refs | README | LICENSE

commit 16accc5671a67263571d33fc3b5fe1d3228a6051
parent d17bbae470335241b63bdf1a7392ae9f9322aa23
Author: MTRNord <MTRNord@users.noreply.github.com>
Date:   Tue, 29 Jul 2025 19:09:26 +0200

Switch to proper preferences lib

Diffstat:
Mapp/build.gradle.kts | 1+
Mapp/src/main/java/space/midnightthoughts/nordiccalendar/screens/SettingsView.kt | 70++++++++++++++++++----------------------------------------------------
Mapp/src/main/java/space/midnightthoughts/nordiccalendar/viewmodels/SettingsViewModel.kt | 15---------------
Mgradle/libs.versions.toml | 4+++-
4 files changed, 22 insertions(+), 68 deletions(-)

diff --git a/app/build.gradle.kts b/app/build.gradle.kts @@ -77,6 +77,7 @@ dependencies { implementation(libs.ktor.serialization.kotlinx.json) implementation(libs.ktor.client.logging) implementation(libs.ktor.client.android) + implementation(libs.compose.preference) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/screens/SettingsView.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/screens/SettingsView.kt @@ -1,29 +1,18 @@ package space.midnightthoughts.nordiccalendar.screens -import android.util.Patterns import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material3.Button -import androidx.compose.material3.OutlinedTextField +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardCapitalization -import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController +import me.zhanghai.compose.preference.ProvidePreferenceLocals +import me.zhanghai.compose.preference.textFieldPreference import space.midnightthoughts.nordiccalendar.R import space.midnightthoughts.nordiccalendar.components.AppScaffold import space.midnightthoughts.nordiccalendar.viewmodels.SettingsViewModel @@ -31,50 +20,27 @@ import space.midnightthoughts.nordiccalendar.viewmodels.SettingsViewModel @Composable fun SettingsView(navController: NavHostController) { val viewModel: SettingsViewModel = hiltViewModel() - val nominatimUrl = remember(viewModel) { - viewModel.nominatimUrl - }.collectAsState() - val textFieldValue: MutableState<String> = remember { mutableStateOf(nominatimUrl.value) } - val isValidUrl = remember(textFieldValue) { - Patterns.WEB_URL.matcher(textFieldValue.value).matches() - } AppScaffold( title = stringResource(R.string.settings), selectedDestination = "settings", navController = navController, - - ) { innerPadding -> - Column( - modifier = innerPadding - .padding(16.dp) - .fillMaxSize(), - horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - OutlinedTextField( - value = textFieldValue.value, - onValueChange = { value: String -> - textFieldValue.value = value - }, - label = { Text(stringResource(R.string.nominatim_url_label)) }, - singleLine = true, - supportingText = { Text(stringResource(R.string.nominatim_url_hint)) }, - keyboardOptions = KeyboardOptions( - capitalization = KeyboardCapitalization.None, - autoCorrectEnabled = false, - keyboardType = KeyboardType.Uri, - imeAction = ImeAction.Done - ), - isError = !isValidUrl && textFieldValue.value.isNotBlank(), - modifier = Modifier.fillMaxWidth() - ) - Button( - onClick = { viewModel.setNominatimUrl(textFieldValue.value) }, - enabled = textFieldValue.value.isNotBlank() && textFieldValue != nominatimUrl && isValidUrl, - modifier = Modifier.align(Alignment.End) + ) { innerPadding -> + ProvidePreferenceLocals { + LazyColumn( + modifier = innerPadding + .padding(16.dp) + .fillMaxSize(), + horizontalAlignment = Alignment.Start, + verticalArrangement = Arrangement.spacedBy(8.dp) ) { - Text(stringResource(R.string.save)) + textFieldPreference( + key = "nominatim_url", + defaultValue = "https://nominatim.openstreetmap.org/search", + title = { Text(text = stringResource(R.string.nominatim_url_label)) }, + textToValue = { it }, + summary = { Text(text = stringResource(R.string.nominatim_url_hint)) }, + ) } } } diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/viewmodels/SettingsViewModel.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/viewmodels/SettingsViewModel.kt @@ -4,26 +4,11 @@ import android.content.Context import androidx.lifecycle.ViewModel import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow import javax.inject.Inject @HiltViewModel class SettingsViewModel @Inject constructor( @param:ApplicationContext private val context: Context ) : ViewModel() { - private val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE) - private val _nominatimUrl = MutableStateFlow( - prefs.getString( - "nominatim_url", - "https://nominatim.openstreetmap.org/search" - )!! - ) - val nominatimUrl: StateFlow<String> = _nominatimUrl.asStateFlow() - fun setNominatimUrl(url: String) { - prefs.edit().putString("nominatim_url", url).apply() - _nominatimUrl.value = url - } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml @@ -16,7 +16,8 @@ hilt = "2.57" ksp = "2.2.0-2.0.2" hiltNavigationCompose = "1.2.0" maplibreCompose = "0.10.4" -ktorVersion = "3.2.2" +ktorVersion = "3.2.3" +preferenceVersion = "2.1.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -46,6 +47,7 @@ ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-conte ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktorVersion" } ktor-client-logging = { group = "io.ktor", name = "ktor-client-logging", version.ref = "ktorVersion" } ktor-client-android = { group = "io.ktor", name = "ktor-client-android", version.ref = "ktorVersion" } +compose-preference = { group = "me.zhanghai.compose.preference", name = "preference", version.ref = "preferenceVersion" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" }