refactor: improve preference bounds #115
2 changed files with 35 additions and 45 deletions
|
@ -6,7 +6,6 @@ import android.os.Build
|
|||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.widget.Toast
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.CheckBoxPreference
|
||||
import androidx.preference.Preference
|
||||
|
@ -14,7 +13,6 @@ import androidx.preference.PreferenceCategory
|
|||
import androidx.preference.PreferenceFragmentCompat
|
||||
import im.angry.openeuicc.common.R
|
||||
import im.angry.openeuicc.util.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -60,25 +58,25 @@ open class SettingsFragment: PreferenceFragmentCompat() {
|
|||
}
|
||||
|
||||
findPreference<CheckBoxPreference>("pref_notifications_download")
|
||||
?.bindBooleanFlow(preferenceRepository.notificationDownloadFlow, PreferenceKeys.NOTIFICATION_DOWNLOAD)
|
||||
?.bindBooleanFlow(preferenceRepository.notificationDownloadFlow)
|
||||
|
||||
findPreference<CheckBoxPreference>("pref_notifications_delete")
|
||||
?.bindBooleanFlow(preferenceRepository.notificationDeleteFlow, PreferenceKeys.NOTIFICATION_DELETE)
|
||||
?.bindBooleanFlow(preferenceRepository.notificationDeleteFlow)
|
||||
|
||||
findPreference<CheckBoxPreference>("pref_notifications_switch")
|
||||
?.bindBooleanFlow(preferenceRepository.notificationSwitchFlow, PreferenceKeys.NOTIFICATION_SWITCH)
|
||||
?.bindBooleanFlow(preferenceRepository.notificationSwitchFlow)
|
||||
|
||||
findPreference<CheckBoxPreference>("pref_advanced_disable_safeguard_removable_esim")
|
||||
?.bindBooleanFlow(preferenceRepository.disableSafeguardFlow, PreferenceKeys.DISABLE_SAFEGUARD_REMOVABLE_ESIM)
|
||||
?.bindBooleanFlow(preferenceRepository.disableSafeguardFlow)
|
||||
|
||||
findPreference<CheckBoxPreference>("pref_advanced_verbose_logging")
|
||||
?.bindBooleanFlow(preferenceRepository.verboseLoggingFlow, PreferenceKeys.VERBOSE_LOGGING)
|
||||
?.bindBooleanFlow(preferenceRepository.verboseLoggingFlow)
|
||||
|
||||
findPreference<CheckBoxPreference>("pref_developer_unfiltered_profile_list")
|
||||
?.bindBooleanFlow(preferenceRepository.unfilteredProfileListFlow, PreferenceKeys.UNFILTERED_PROFILE_LIST)
|
||||
?.bindBooleanFlow(preferenceRepository.unfilteredProfileListFlow)
|
||||
|
||||
findPreference<CheckBoxPreference>("pref_ignore_tls_certificate")
|
||||
?.bindBooleanFlow(preferenceRepository.ignoreTLSCertificateFlow, PreferenceKeys.IGNORE_TLS_CERTIFICATE)
|
||||
?.bindBooleanFlow(preferenceRepository.ignoreTLSCertificateFlow)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
@ -99,10 +97,7 @@ open class SettingsFragment: PreferenceFragmentCompat() {
|
|||
|
||||
if (numClicks == 7) {
|
||||
lifecycleScope.launch {
|
||||
preferenceRepository.updatePreference(
|
||||
PreferenceKeys.DEVELOPER_OPTIONS_ENABLED,
|
||||
true
|
||||
)
|
||||
preferenceRepository.developerOptionsEnabledFlow.emit(true)
|
||||
|
||||
lastToast?.cancel()
|
||||
Toast.makeText(
|
||||
|
@ -124,15 +119,13 @@ open class SettingsFragment: PreferenceFragmentCompat() {
|
|||
return true
|
||||
}
|
||||
|
||||
private fun CheckBoxPreference.bindBooleanFlow(flow: Flow<Boolean>, key: Preferences.Key<Boolean>) {
|
||||
private fun CheckBoxPreference.bindBooleanFlow(flow: BoundPreference<Boolean>) {
|
||||
lifecycleScope.launch {
|
||||
flow.collect { isChecked = it }
|
||||
}
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
runBlocking {
|
||||
preferenceRepository.updatePreference(key, newValue as Boolean)
|
||||
}
|
||||
runBlocking { flow.emit(newValue as Boolean) }
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import androidx.datastore.preferences.preferencesDataStore
|
|||
import androidx.fragment.app.Fragment
|
||||
import im.angry.openeuicc.OpenEuiccApplication
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.FlowCollector
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "prefs")
|
||||
|
@ -19,41 +20,37 @@ val Context.preferenceRepository: PreferenceRepository
|
|||
val Fragment.preferenceRepository: PreferenceRepository
|
||||
get() = requireContext().preferenceRepository
|
||||
|
||||
object PreferenceKeys {
|
||||
// ---- Profile Notifications ----
|
||||
val NOTIFICATION_DOWNLOAD = booleanPreferencesKey("notification_download")
|
||||
val NOTIFICATION_DELETE = booleanPreferencesKey("notification_delete")
|
||||
val NOTIFICATION_SWITCH = booleanPreferencesKey("notification_switch")
|
||||
|
||||
// ---- Advanced ----
|
||||
val DISABLE_SAFEGUARD_REMOVABLE_ESIM = booleanPreferencesKey("disable_safeguard_removable_esim")
|
||||
val VERBOSE_LOGGING = booleanPreferencesKey("verbose_logging")
|
||||
|
||||
// ---- Developer Options ----
|
||||
val DEVELOPER_OPTIONS_ENABLED = booleanPreferencesKey("developer_options_enabled")
|
||||
val UNFILTERED_PROFILE_LIST = booleanPreferencesKey("unfiltered_profile_list")
|
||||
val IGNORE_TLS_CERTIFICATE = booleanPreferencesKey("ignore_tls_certificate")
|
||||
}
|
||||
|
||||
class PreferenceRepository(private val context: Context) {
|
||||
// Expose flows so that we can also handle default values
|
||||
// ---- Profile Notifications ----
|
||||
val notificationDownloadFlow = bindFlow(PreferenceKeys.NOTIFICATION_DOWNLOAD, true)
|
||||
val notificationDeleteFlow = bindFlow(PreferenceKeys.NOTIFICATION_DELETE, true)
|
||||
val notificationSwitchFlow = bindFlow(PreferenceKeys.NOTIFICATION_SWITCH, false)
|
||||
val notificationDownloadFlow = bindFlow("notification_download", true)
|
||||
val notificationDeleteFlow = bindFlow("notification_delete", true)
|
||||
val notificationSwitchFlow = bindFlow("notification_switch", false)
|
||||
|
||||
// ---- Advanced ----
|
||||
val disableSafeguardFlow = bindFlow(PreferenceKeys.DISABLE_SAFEGUARD_REMOVABLE_ESIM, false)
|
||||
val verboseLoggingFlow = bindFlow(PreferenceKeys.VERBOSE_LOGGING, false)
|
||||
val disableSafeguardFlow = bindFlow("disable_safeguard_removable_esim", false)
|
||||
val verboseLoggingFlow = bindFlow("verbose_logging", false)
|
||||
|
||||
// ---- Developer Options ----
|
||||
val developerOptionsEnabledFlow = bindFlow(PreferenceKeys.DEVELOPER_OPTIONS_ENABLED, false)
|
||||
val unfilteredProfileListFlow = bindFlow(PreferenceKeys.UNFILTERED_PROFILE_LIST, false)
|
||||
val ignoreTLSCertificateFlow = bindFlow(PreferenceKeys.IGNORE_TLS_CERTIFICATE, false)
|
||||
val developerOptionsEnabledFlow = bindFlow("developer_options_enabled", false)
|
||||
val unfilteredProfileListFlow = bindFlow("unfiltered_profile_list", false)
|
||||
val ignoreTLSCertificateFlow = bindFlow("ignore_tls_certificate", false)
|
||||
|
||||
private fun <T> bindFlow(key: Preferences.Key<T>, defaultValue: T): Flow<T> =
|
||||
context.dataStore.data.map { it[key] ?: defaultValue }
|
||||
private fun bindFlow(name: String, defaultValue: Boolean) =
|
||||
bindFlow(booleanPreferencesKey(name), defaultValue)
|
||||
|
||||
suspend fun <T> updatePreference(key: Preferences.Key<T>, value: T) =
|
||||
context.dataStore.edit { it[key] = value }
|
||||
private fun <T> bindFlow(key: Preferences.Key<T>, defaultValue: T) =
|
||||
BoundPreference(context.dataStore, key, defaultValue)
|
||||
}
|
||||
|
||||
class BoundPreference<T>(
|
||||
private val store: DataStore<Preferences>,
|
||||
private val key: Preferences.Key<T>,
|
||||
defaultValue: T
|
||||
) : Flow<T> {
|
||||
private val flow = store.data.map { it[key] ?: defaultValue }
|
||||
|
||||
suspend fun emit(value: T) = store.edit { it[key] = value }
|
||||
|
||||
override suspend fun collect(collector: FlowCollector<T>) = flow.collect(collector)
|
||||
}
|
Loading…
Add table
Reference in a new issue