diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt index c2cbee3..65e6fde 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt @@ -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("pref_notifications_download") - ?.bindBooleanFlow(preferenceRepository.notificationDownloadFlow, PreferenceKeys.NOTIFICATION_DOWNLOAD) + ?.bindBooleanFlow(preferenceRepository.notificationDownloadFlow) findPreference("pref_notifications_delete") - ?.bindBooleanFlow(preferenceRepository.notificationDeleteFlow, PreferenceKeys.NOTIFICATION_DELETE) + ?.bindBooleanFlow(preferenceRepository.notificationDeleteFlow) findPreference("pref_notifications_switch") - ?.bindBooleanFlow(preferenceRepository.notificationSwitchFlow, PreferenceKeys.NOTIFICATION_SWITCH) + ?.bindBooleanFlow(preferenceRepository.notificationSwitchFlow) findPreference("pref_advanced_disable_safeguard_removable_esim") - ?.bindBooleanFlow(preferenceRepository.disableSafeguardFlow, PreferenceKeys.DISABLE_SAFEGUARD_REMOVABLE_ESIM) + ?.bindBooleanFlow(preferenceRepository.disableSafeguardFlow) findPreference("pref_advanced_verbose_logging") - ?.bindBooleanFlow(preferenceRepository.verboseLoggingFlow, PreferenceKeys.VERBOSE_LOGGING) + ?.bindBooleanFlow(preferenceRepository.verboseLoggingFlow) findPreference("pref_developer_unfiltered_profile_list") - ?.bindBooleanFlow(preferenceRepository.unfilteredProfileListFlow, PreferenceKeys.UNFILTERED_PROFILE_LIST) + ?.bindBooleanFlow(preferenceRepository.unfilteredProfileListFlow) findPreference("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, key: Preferences.Key) { + private fun CheckBoxPreference.bindBooleanFlow(flow: BoundPreference) { lifecycleScope.launch { flow.collect { isChecked = it } } setOnPreferenceChangeListener { _, newValue -> - runBlocking { - preferenceRepository.updatePreference(key, newValue as Boolean) - } + runBlocking { flow.emit(newValue as Boolean) } true } } diff --git a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt index e768fa9..3f5525b 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt @@ -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 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 bindFlow(key: Preferences.Key, defaultValue: T): Flow = - context.dataStore.data.map { it[key] ?: defaultValue } + private fun bindFlow(name: String, defaultValue: Boolean) = + bindFlow(booleanPreferencesKey(name), defaultValue) - suspend fun updatePreference(key: Preferences.Key, value: T) = - context.dataStore.edit { it[key] = value } + private fun bindFlow(key: Preferences.Key, defaultValue: T) = + BoundPreference(context.dataStore, key, defaultValue) +} + +class BoundPreference( + private val store: DataStore, + private val key: Preferences.Key, + defaultValue: T +) : Flow { + 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) = flow.collect(collector) } \ No newline at end of file