From 614ce5511c3930143eff2ca6b9d5dc11bca0637d Mon Sep 17 00:00:00 2001 From: F0x1d Date: Sun, 30 Jun 2024 02:57:37 +0300 Subject: [PATCH] [fix]: using flows in preferences --- .../kotlin/AndroidFeatureConventionPlugin.kt | 1 + core/core-preferences/build.gradle.kts | 1 + .../preferences/shared/AppPreferences.kt | 38 +++++++++++++++++- .../shared/base/BasePreferences.kt | 23 +++-------- .../shared/base/SharedPreferenceLiveData.kt | 28 ------------- .../com/f0x1d/logfox/ui/view/PreferenceExt.kt | 29 -------------- .../feature/logging/service/LoggingService.kt | 32 +++++++++------ .../logging/ui/fragment/LogsFragment.kt | 39 +++++++------------ .../logging/viewmodel/LogsViewModel.kt | 3 +- .../f0x1d/feature/logging/viewmodel/UriExt.kt | 4 +- .../ui/fragment/SettingsServiceFragment.kt | 9 ++--- .../ui/fragment/SettingsUIFragment.kt | 36 +++++++---------- .../fragment/base/BasePreferenceFragment.kt | 15 +++++++ gradle/libs.versions.toml | 2 + 14 files changed, 116 insertions(+), 144 deletions(-) delete mode 100644 core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/base/SharedPreferenceLiveData.kt diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt index 5e64f62d..55ab7435 100644 --- a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt @@ -37,6 +37,7 @@ class AndroidFeatureConventionPlugin : Plugin { ksp(library("androidx-room-compiler")) implementation(library("insetter")) + implementation(library("flow-preferences")) } } } diff --git a/core/core-preferences/build.gradle.kts b/core/core-preferences/build.gradle.kts index 8beae328..4b7a01f7 100644 --- a/core/core-preferences/build.gradle.kts +++ b/core/core-preferences/build.gradle.kts @@ -11,4 +11,5 @@ dependencies { implementation(project(":core:core-database")) implementation(libs.bundles.androidx) + implementation(libs.flow.preferences) } diff --git a/core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/AppPreferences.kt b/core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/AppPreferences.kt index f91a868b..a55ad651 100644 --- a/core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/AppPreferences.kt +++ b/core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/AppPreferences.kt @@ -7,7 +7,11 @@ import com.f0x1d.logfox.database.entity.CrashType import com.f0x1d.logfox.model.logline.LogLine import com.f0x1d.logfox.model.preferences.ShowLogValues import com.f0x1d.logfox.preferences.shared.base.BasePreferences +import com.fredporciuncula.flow.preferences.keyFlow import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onStart import java.util.Date import javax.inject.Inject import javax.inject.Singleton @@ -21,29 +25,50 @@ class AppPreferences @Inject constructor( const val DATE_FORMAT_DEFAULT = "dd.MM" const val TIME_FORMAT_DEFAULT = "HH:mm:ss.SSS" + const val LOGS_EXPANDED_DEFAULT = false const val LOGS_UPDATE_INTERVAL_DEFAULT = 300L const val LOGS_TEXT_SIZE_DEFAULT = 14 const val LOGS_DISPLAY_LIMIT_DEFAULT = 10000 + + const val TERMINAL_INDEX_DEFAULT = 0 } var dateFormat get() = getNullable("pref_date_format", DATE_FORMAT_DEFAULT) set(value) { put("pref_date_format", value) } + val dateFormatFlow get() = flowSharedPreferences.getString("pref_date_format", DATE_FORMAT_DEFAULT).asFlow() + var timeFormat get() = getNullable("pref_time_format", TIME_FORMAT_DEFAULT) set(value) { put("pref_time_format", value) } + val timeFormatFlow get() = flowSharedPreferences.getString("pref_time_format", TIME_FORMAT_DEFAULT).asFlow() + var logsUpdateInterval get() = get("pref_logs_update_interval", LOGS_UPDATE_INTERVAL_DEFAULT) set(value) { put("pref_logs_update_interval", value) } + val logsUpdateIntervalFlow get() = flowSharedPreferences.getLong( + key = "pref_logs_update_interval", + defaultValue = LOGS_UPDATE_INTERVAL_DEFAULT, + ).asFlow() + var logsTextSize get() = get("pref_logs_text_size", LOGS_TEXT_SIZE_DEFAULT) set(value) { put("pref_logs_text_size", value) } + val logsTextSizeFlow get() = flowSharedPreferences.getInt("pref_logs_text_size", LOGS_TEXT_SIZE_DEFAULT).asFlow() + var logsDisplayLimit get() = get("pref_logs_display_limit", LOGS_DISPLAY_LIMIT_DEFAULT) set(value) { put("pref_logs_display_limit", value) } + val logsDisplayLimitFlow get() = flowSharedPreferences.getInt( + key = "pref_logs_display_limit", + defaultValue = LOGS_DISPLAY_LIMIT_DEFAULT, + ).asFlow() + var logsExpanded - get() = get("pref_logs_expanded", false) + get() = get("pref_logs_expanded", LOGS_EXPANDED_DEFAULT) set(value) { put("pref_logs_expanded", value) } + val logsExpandedFlow get() = flowSharedPreferences.getBoolean("pref_logs_expanded", LOGS_EXPANDED_DEFAULT).asFlow() + var resumeLoggingWithBottomTouch get() = get("pref_resume_logs_with_touch", true) set(value) { put("pref_resume_logs_with_touch", value) } @@ -76,9 +101,18 @@ class AppPreferences @Inject constructor( get() = get("pref_show_log_content", true) set(value) { put("pref_show_log_content", value) } + val showLogValuesFlow get() = sharedPreferences.keyFlow.filter { key -> + key?.startsWith("pref_show_log") == true + }.onStart { emit("initial") }.map { showLogValues } + var selectedTerminalIndex - get() = get("pref_selected_terminal_index", 0) + get() = get("pref_selected_terminal_index", TERMINAL_INDEX_DEFAULT) set(value) { put("pref_selected_terminal_index", value) } + val selectedTerminalIndexFlow get() = flowSharedPreferences.getInt( + key = "pref_selected_terminal_index", + defaultValue = TERMINAL_INDEX_DEFAULT, + ).asFlow() + var fallbackToDefaultTerminal get() = get("pref_fallback_to_default_terminal", true) set(value) { put("pref_fallback_to_default_terminal", value) } diff --git a/core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/base/BasePreferences.kt b/core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/base/BasePreferences.kt index 1afcef0a..e5b503a8 100644 --- a/core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/base/BasePreferences.kt +++ b/core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/base/BasePreferences.kt @@ -3,23 +3,17 @@ package com.f0x1d.logfox.preferences.shared.base import android.content.Context import android.content.SharedPreferences import androidx.core.content.edit +import com.fredporciuncula.flow.preferences.FlowSharedPreferences abstract class BasePreferences(context: Context) { - val sharedPreferences by lazy { providePreferences(context) } + protected val sharedPreferences by lazy { providePreferences(context) } + protected val flowSharedPreferences by lazy { FlowSharedPreferences(sharedPreferences) } abstract fun providePreferences(context: Context): SharedPreferences - inline fun asLiveData(key: String, defValue: T?) = object : SharedPreferenceLiveData(sharedPreferences, key, defValue) { - override fun fromPreferences(key: String, defValue: T?) = try { - get(key, defValue) - } catch (e: RuntimeException) { - getNullable(key, defValue) - } - } - @Suppress("UNCHECKED_CAST") - inline fun put(key: String, value: T?) = sharedPreferences.edit { + protected inline fun put(key: String, value: T?) = sharedPreferences.edit { when (value) { null -> putString(key, null) @@ -32,7 +26,7 @@ abstract class BasePreferences(context: Context) { } } - inline fun get(key: String, defaultValue: T): T = when (defaultValue) { + protected inline fun get(key: String, defaultValue: T): T = when (defaultValue) { is Boolean -> sharedPreferences.getBoolean(key, defaultValue) as T is Int -> sharedPreferences.getInt(key, defaultValue) as T is Long -> sharedPreferences.getLong(key, defaultValue) as T @@ -42,7 +36,7 @@ abstract class BasePreferences(context: Context) { } @Suppress("UNCHECKED_CAST") - inline fun getNullable(key: String, defaultValue: T?): T? = when (defaultValue) { + protected inline fun getNullable(key: String, defaultValue: T?): T? = when (defaultValue) { null -> sharedPreferences.getString(key, defaultValue) as T? is String -> sharedPreferences.getString(key, defaultValue) as T? @@ -50,9 +44,4 @@ abstract class BasePreferences(context: Context) { else -> error("Type of $defaultValue is not supported") } - - fun registerListener(listener: SharedPreferences.OnSharedPreferenceChangeListener) = - sharedPreferences.registerOnSharedPreferenceChangeListener(listener) - fun unregisterListener(listener: SharedPreferences.OnSharedPreferenceChangeListener) = - sharedPreferences.unregisterOnSharedPreferenceChangeListener(listener) } diff --git a/core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/base/SharedPreferenceLiveData.kt b/core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/base/SharedPreferenceLiveData.kt deleted file mode 100644 index 10e6f27b..00000000 --- a/core/core-preferences/src/main/kotlin/com/f0x1d/logfox/preferences/shared/base/SharedPreferenceLiveData.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.f0x1d.logfox.preferences.shared.base - -import android.content.SharedPreferences -import androidx.lifecycle.LiveData - -abstract class SharedPreferenceLiveData( - private val sharedPreferences: SharedPreferences, - private val key: String, - private val defValue: T, -): LiveData(), SharedPreferences.OnSharedPreferenceChangeListener { - - abstract fun fromPreferences(key: String, defValue: T): T - - override fun onActive() { - value = fromPreferences(key, defValue) - sharedPreferences.registerOnSharedPreferenceChangeListener(this) - } - - override fun onInactive() { - sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) - } - - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { - if (key == this.key) { - value = fromPreferences(key, defValue) - } - } -} diff --git a/core/core-ui/src/main/kotlin/com/f0x1d/logfox/ui/view/PreferenceExt.kt b/core/core-ui/src/main/kotlin/com/f0x1d/logfox/ui/view/PreferenceExt.kt index dccc39eb..0ec077d9 100644 --- a/core/core-ui/src/main/kotlin/com/f0x1d/logfox/ui/view/PreferenceExt.kt +++ b/core/core-ui/src/main/kotlin/com/f0x1d/logfox/ui/view/PreferenceExt.kt @@ -2,10 +2,8 @@ package com.f0x1d.logfox.ui.view import android.view.LayoutInflater import android.view.inputmethod.InputMethodManager -import androidx.lifecycle.LifecycleOwner import androidx.preference.Preference import com.f0x1d.logfox.context.inputMethodManager -import com.f0x1d.logfox.preferences.shared.appPreferences import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.databinding.DialogTextBinding import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -66,30 +64,3 @@ fun Preference.setupAsListPreference( .show() return@setOnPreferenceClickListener true } - -fun Preference.observeAndUpdateSummaryForList( - observer: LifecycleOwner, - defValue: Int, - items: Array -) = observeAndUpdateSummary(observer, defValue) { - summary = items[it] -} - -inline fun Preference.observeAndUpdateSummary( - observer: LifecycleOwner, - defValue: T -) { - observeAndUpdateSummary(observer, defValue) { - summary = it.toString() - } -} - -inline fun Preference.observeAndUpdateSummary( - observer: LifecycleOwner, - defValue: T, - crossinline block: (T) -> Unit -) { - context.appPreferences.asLiveData(key, defValue).observe(observer) { - block(it ?: return@observe) - } -} diff --git a/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/service/LoggingService.kt b/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/service/LoggingService.kt index 26fea15b..20ad300e 100644 --- a/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/service/LoggingService.kt +++ b/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/service/LoggingService.kt @@ -4,11 +4,11 @@ import android.content.Intent import android.content.SharedPreferences import android.os.Binder import android.os.IBinder -import android.util.Log import androidx.core.app.NotificationCompat import androidx.core.app.ServiceCompat import androidx.lifecycle.LifecycleService import androidx.lifecycle.lifecycleScope +import com.f0x1d.logfox.arch.di.MainDispatcher import com.f0x1d.logfox.context.LOGGING_STATUS_CHANNEL_ID import com.f0x1d.logfox.context.activityManager import com.f0x1d.logfox.context.toast @@ -26,12 +26,14 @@ import com.f0x1d.logfox.terminals.DefaultTerminal import com.f0x1d.logfox.terminals.base.Terminal import com.f0x1d.logfox.ui.Icons import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Job import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.delay import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock @@ -69,6 +71,10 @@ class LoggingService : LifecycleService(), SharedPreferences.OnSharedPreferenceC @Inject lateinit var terminals: Array + @MainDispatcher + @Inject + lateinit var mainDispatcher: CoroutineDispatcher + private val logs = LinkedList() private val logsMutex = Mutex() private var loggingJob: Job? = null @@ -87,7 +93,6 @@ class LoggingService : LifecycleService(), SharedPreferences.OnSharedPreferenceC override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) - Log.e("f0x1d", "got intent ${intent?.action}") when (intent?.action) { ACTION_RESTART_LOGGING -> restartLogging() @@ -102,11 +107,19 @@ class LoggingService : LifecycleService(), SharedPreferences.OnSharedPreferenceC private fun startLogging() { if (loggingJob?.isActive == true) return - var loggingTerminal = terminals[appPreferences.selectedTerminalIndex] - loggingInterval = appPreferences.logsUpdateInterval - logsDisplayLimit = appPreferences.logsDisplayLimit + lifecycleScope.launch { + appPreferences.logsUpdateIntervalFlow + .onEach { loggingInterval = it } + .launchIn(this) + + appPreferences.logsDisplayLimitFlow + .onEach { logsDisplayLimit = it } + .launchIn(this) + } - appPreferences.registerListener(this) + var loggingTerminal = terminals[appPreferences.selectedTerminalIndex] + //loggingInterval = appPreferences.logsUpdateInterval + //logsDisplayLimit = appPreferences.logsDisplayLimit loggingJob = lifecycleScope.launch { try { @@ -116,7 +129,7 @@ class LoggingService : LifecycleService(), SharedPreferences.OnSharedPreferenceC startingId = idsCounter, ).catch { throwable -> if (throwable is TerminalNotSupportedException) { - if (appPreferences.fallbackToDefaultTerminal) withContext(Dispatchers.Main) { + if (appPreferences.fallbackToDefaultTerminal) withContext(mainDispatcher) { toast(Strings.terminal_unavailable_falling_back) loggingTerminal.exit() @@ -129,8 +142,6 @@ class LoggingService : LifecycleService(), SharedPreferences.OnSharedPreferenceC } }.collect { logLine -> logsMutex.withLock { - - logs.add(logLine) while (logs.size > logsDisplayLimit) @@ -149,7 +160,6 @@ class LoggingService : LifecycleService(), SharedPreferences.OnSharedPreferenceC withContext(NonCancellable) { recordingController.loggingStopped() clearLogs().join() - appPreferences.unregisterListener(this@LoggingService) loggingTerminal.exit() } diff --git a/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/ui/fragment/LogsFragment.kt b/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/ui/fragment/LogsFragment.kt index 11de16d9..e3ca6eb8 100644 --- a/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/ui/fragment/LogsFragment.kt +++ b/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/ui/fragment/LogsFragment.kt @@ -1,6 +1,5 @@ package com.f0x1d.feature.logging.ui.fragment -import android.content.SharedPreferences import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -35,7 +34,7 @@ import dev.chrisbanes.insetter.applyInsetter import kotlinx.coroutines.flow.update @AndroidEntryPoint -class LogsFragment: BaseViewModelFragment(), SharedPreferences.OnSharedPreferenceChangeListener { +class LogsFragment: BaseViewModelFragment() { override val viewModel by hiltNavGraphViewModels(Directions.logsFragment) @@ -77,8 +76,6 @@ class LogsFragment: BaseViewModelFragment(), ) = FragmentLogsBinding.inflate(inflater, container, false) override fun FragmentLogsBinding.onViewCreated(view: View, savedInstanceState: Bundle?) { - viewModel.appPreferences.registerListener(this@LogsFragment) - requireContext().isHorizontalOrientation.also { horizontalOrientation -> logsRecycler.applyInsetter { type(navigationBars = true) { @@ -216,6 +213,19 @@ class LogsFragment: BaseViewModelFragment(), changingState = false } + viewModel.apply { + appPreferences.logsTextSizeFlow.collectWithLifecycle { + adapter.textSize = it.toFloat() + } + appPreferences.logsExpandedFlow.collectWithLifecycle { + adapter.logsExpanded = it + } + + appPreferences.showLogValuesFlow.collectWithLifecycle { + adapter.logsFormat = it + } + } + requireActivity().onBackPressedDispatcher.apply { addCallback(viewLifecycleOwner, clearSelectionOnBackPressedCallback) } @@ -281,25 +291,4 @@ class LogsFragment: BaseViewModelFragment(), logsRecycler.stopScroll() logsRecycler.scrollToPosition(adapter.itemCount - 1) } - - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { - viewModel.appPreferences.apply { - when (key) { - "pref_logs_text_size" -> adapter.textSize = logsTextSize.toFloat() - "pref_logs_expanded" -> adapter.logsExpanded = logsExpanded - - "pref_date_format", "pref_time_format" -> adapter.notifyItemRangeChanged( - 0, - adapter.itemCount - ) - } - - if (key?.startsWith("pref_show_log") == true) adapter.logsFormat = showLogValues - } - } - - override fun onDestroy() { - super.onDestroy() - viewModel.appPreferences.unregisterListener(this) - } } diff --git a/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/LogsViewModel.kt b/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/LogsViewModel.kt index 00ad8a50..e9a6bc71 100644 --- a/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/LogsViewModel.kt +++ b/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/LogsViewModel.kt @@ -17,7 +17,6 @@ import com.f0x1d.logfox.model.logline.LogLine import com.f0x1d.logfox.preferences.shared.AppPreferences import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine @@ -94,7 +93,7 @@ class LogsViewModel @Inject constructor( logs.filterAndSearch(filters, query) } }.flowOn( - Dispatchers.IO + ioDispatcher, ).stateIn( scope = viewModelScope, started = SharingStarted.Eagerly, diff --git a/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/UriExt.kt b/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/UriExt.kt index ee89bb05..e770ac14 100644 --- a/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/UriExt.kt +++ b/feature/feature-logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/UriExt.kt @@ -4,10 +4,8 @@ import android.content.Context import android.net.Uri import androidx.documentfile.provider.DocumentFile import com.f0x1d.logfox.model.logline.LogLine -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.flowOn import java.util.LinkedList internal fun Uri?.readFileContentsAsFlow( @@ -46,6 +44,6 @@ internal fun Uri?.readFileContentsAsFlow( }.catch { it.printStackTrace() emit(emptyList()) -}.flowOn(Dispatchers.IO) +} internal fun Uri.readFileName(context: Context) = DocumentFile.fromSingleUri(context, this)?.name diff --git a/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsServiceFragment.kt b/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsServiceFragment.kt index 3e2696f1..7bdf49ad 100644 --- a/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsServiceFragment.kt +++ b/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsServiceFragment.kt @@ -14,7 +14,6 @@ import com.f0x1d.logfox.preferences.shared.AppPreferences import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.terminals.base.Terminal import com.f0x1d.logfox.ui.Icons -import com.f0x1d.logfox.ui.view.observeAndUpdateSummaryForList import com.f0x1d.logfox.ui.view.setupAsListPreference import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint @@ -67,11 +66,9 @@ class SettingsServiceFragment: BasePreferenceFragment() { } ) - observeAndUpdateSummaryForList( - observer = this@SettingsServiceFragment, - defValue = 0, - items = filledTerminalSettings - ) + appPreferences.selectedTerminalIndexFlow.collectWithLifecycle { + summary = filledTerminalSettings[it] + } } findPreference("pref_start_on_boot")?.apply { diff --git a/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsUIFragment.kt b/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsUIFragment.kt index 40ae2291..21f5b711 100644 --- a/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsUIFragment.kt +++ b/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsUIFragment.kt @@ -10,7 +10,6 @@ import com.f0x1d.logfox.feature.settings.ui.fragment.base.BasePreferenceFragment import com.f0x1d.logfox.preferences.shared.AppPreferences import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.Icons -import com.f0x1d.logfox.ui.view.observeAndUpdateSummary import com.f0x1d.logfox.ui.view.setupAsEditTextPreference import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint @@ -38,10 +37,9 @@ class SettingsUIFragment: BasePreferenceFragment() { } ) - observeAndUpdateSummary( - observer = this@SettingsUIFragment, - defValue = AppPreferences.DATE_FORMAT_DEFAULT - ) + appPreferences.dateFormatFlow.collectWithLifecycle { + summary = it + } } findPreference("pref_time_format")?.apply { @@ -54,10 +52,9 @@ class SettingsUIFragment: BasePreferenceFragment() { } ) - observeAndUpdateSummary( - observer = this@SettingsUIFragment, - defValue = AppPreferences.TIME_FORMAT_DEFAULT - ) + appPreferences.timeFormatFlow.collectWithLifecycle { + summary = it + } } findPreference("pref_logs_format")?.setOnPreferenceClickListener { @@ -108,10 +105,9 @@ class SettingsUIFragment: BasePreferenceFragment() { } ) - observeAndUpdateSummary( - observer = this@SettingsUIFragment, - defValue = AppPreferences.LOGS_UPDATE_INTERVAL_DEFAULT - ) + appPreferences.logsUpdateIntervalFlow.collectWithLifecycle { + summary = it.toString() + } } findPreference("pref_logs_text_size")?.apply { @@ -126,10 +122,9 @@ class SettingsUIFragment: BasePreferenceFragment() { } ) - observeAndUpdateSummary( - observer = this@SettingsUIFragment, - defValue = AppPreferences.LOGS_TEXT_SIZE_DEFAULT - ) + appPreferences.logsTextSizeFlow.collectWithLifecycle { + summary = it.toString() + } } findPreference("pref_logs_display_limit")?.apply { @@ -150,10 +145,9 @@ class SettingsUIFragment: BasePreferenceFragment() { } ) - observeAndUpdateSummary( - observer = this@SettingsUIFragment, - defValue = AppPreferences.LOGS_DISPLAY_LIMIT_DEFAULT - ) + appPreferences.logsDisplayLimitFlow.collectWithLifecycle { + summary = it.toString() + } } } } diff --git a/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/base/BasePreferenceFragment.kt b/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/base/BasePreferenceFragment.kt index c134650d..612d8aad 100644 --- a/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/base/BasePreferenceFragment.kt +++ b/feature/feature-settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/base/BasePreferenceFragment.kt @@ -2,6 +2,9 @@ package com.f0x1d.logfox.feature.settings.ui.fragment.base import android.os.Bundle import android.view.View +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.preference.PreferenceFragmentCompat import com.f0x1d.logfox.context.isHorizontalOrientation import com.f0x1d.logfox.feature.settings.R @@ -9,6 +12,9 @@ import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.view.setupBackButtonForNavController import com.google.android.material.appbar.MaterialToolbar import dev.chrisbanes.insetter.applyInsetter +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.FlowCollector +import kotlinx.coroutines.launch abstract class BasePreferenceFragment: PreferenceFragmentCompat() { @@ -34,4 +40,13 @@ abstract class BasePreferenceFragment: PreferenceFragmentCompat() { } } } + + protected fun Flow.collectWithLifecycle( + state: Lifecycle.State = Lifecycle.State.RESUMED, + collector: FlowCollector, + ) = lifecycleScope.launch { + repeatOnLifecycle(state) { + collect(collector) + } + } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0aee39f8..b56d6141 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,6 +25,7 @@ viewpump = "2.1.1" material = "1.12.0" glide = "4.16.0" gson = "2.10.1" +flow-preferences = "1.9.1" timber = "5.0.1" junit = "4.13.2" androidx-test-ext-junit = "1.2.0" @@ -60,6 +61,7 @@ hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hil glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" } glide-compiler = { module = "com.github.bumptech.glide:ksp", version.ref = "glide" } gson = { module = "com.google.code.gson:gson", version.ref = "gson" } +flow-preferences = { module = "com.fredporciuncula:flow-preferences", version.ref = "flow-preferences" } timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" } junit = { module = "junit:junit", version.ref = "junit" } androidx-test-ext-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-test-ext-junit" }