diff --git a/app/src/main/java/com/aurora/extensions/SharedPreferences.kt b/app/src/main/java/com/aurora/extensions/SharedPreferences.kt new file mode 100644 index 000000000..aac8fb849 --- /dev/null +++ b/app/src/main/java/com/aurora/extensions/SharedPreferences.kt @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2025 The Calyx Institute + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.aurora.extensions + +import android.content.SharedPreferences +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.stateIn + +/** + * Extension method to observe changes in shared preferences as a flow + */ +fun SharedPreferences.observeAsStateFlow( + key: String, + scope: CoroutineScope, + started: SharingStarted = SharingStarted.Eagerly, + initial: T, + valueProvider: () -> T +): StateFlow = + callbackFlow { + val listener = + SharedPreferences.OnSharedPreferenceChangeListener { _, changedKey -> + if (changedKey == key) { + trySend(valueProvider()) + } + } + + // Emit the initial value + trySend(valueProvider()) + + registerOnSharedPreferenceChangeListener(listener) + awaitClose { + unregisterOnSharedPreferenceChangeListener(listener) + } + }.stateIn(scope, started, initial) diff --git a/app/src/main/java/com/aurora/store/viewmodel/dispenser/DispenserViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/dispenser/DispenserViewModel.kt index 842528ffe..98fa057ff 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/dispenser/DispenserViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/dispenser/DispenserViewModel.kt @@ -6,21 +6,15 @@ package com.aurora.store.viewmodel.dispenser import android.content.Context -import android.content.SharedPreferences import androidx.core.content.edit import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.aurora.extensions.observeAsStateFlow import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences.PREFERENCE_DISPENSER_URLS import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.flow.stateIn import javax.inject.Inject -import kotlin.collections.toMutableSet @HiltViewModel class DispenserViewModel @Inject constructor( @@ -33,21 +27,12 @@ class DispenserViewModel @Inject constructor( set(value) = sharedPreferences.edit { putStringSet(PREFERENCE_DISPENSER_URLS, value) } get() = sharedPreferences.getStringSet(PREFERENCE_DISPENSER_URLS, emptySet()) ?: emptySet() - val dispensers: StateFlow> - get() { - return callbackFlow { - val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, changedKey -> - if (changedKey == PREFERENCE_DISPENSER_URLS) trySend(_dispensers) - } - - trySend(_dispensers) - - sharedPreferences.registerOnSharedPreferenceChangeListener(listener) - awaitClose { - sharedPreferences.unregisterOnSharedPreferenceChangeListener(listener) - } - }.stateIn(viewModelScope, SharingStarted.Eagerly, emptySet()) - } + val dispensers = sharedPreferences.observeAsStateFlow( + key = PREFERENCE_DISPENSER_URLS, + scope = viewModelScope, + initial = emptySet(), + valueProvider = { _dispensers } + ) fun addDispenser(url: String) { _dispensers = _dispensers.toMutableSet().apply {