extensions: Strip out logic for shared pref callback into extension

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2025-12-15 12:44:37 +08:00
parent a68acce413
commit b308535a8c
2 changed files with 48 additions and 22 deletions

View File

@@ -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 <T> SharedPreferences.observeAsStateFlow(
key: String,
scope: CoroutineScope,
started: SharingStarted = SharingStarted.Eagerly,
initial: T,
valueProvider: () -> T
): StateFlow<T> =
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)

View File

@@ -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<Set<String>>
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 {