diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceChangePublisher.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceChangePublisher.kt index 66061e49f84..44949cc1d2b 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceChangePublisher.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceChangePublisher.kt @@ -2,11 +2,15 @@ package net.thunderbird.core.preference /** * Publishes changes of preferences to all subscribers. + * The change can be scoped to a specific category of preferences or applied globally. + * @see PreferenceScope for available scopes of preference changes. */ interface PreferenceChangePublisher { /** * Publish a change in the preferences. + * @param scope Defines which category of preferences has changed. + * By default, [PreferenceScope.ALL] is used, indicating a global change affecting all preferences. */ - fun publish() + fun publish(scope: PreferenceScope = PreferenceScope.ALL) } diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceChangeSubscriber.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceChangeSubscriber.kt index bd7feb17ccd..6fd11347de2 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceChangeSubscriber.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceChangeSubscriber.kt @@ -6,7 +6,9 @@ package net.thunderbird.core.preference fun interface PreferenceChangeSubscriber { /** - * Called when preferences change. + * Called when preferences within a given scope have changed. + * @param scope The [PreferenceScope] indicating which category of preferences + * has been updated. */ - fun receive() + fun receive(scope: PreferenceScope) } diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceScope.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceScope.kt new file mode 100644 index 00000000000..b820e89289d --- /dev/null +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceScope.kt @@ -0,0 +1,15 @@ +package net.thunderbird.core.preference + +enum class PreferenceScope { + ALL, + DEBUGGING, + DISPLAY_CORE, + DISPLAY_INBOX, + DISPLAY_MISC, + DISPLAY_VISUAL, + DISPLAY_VISUAL_MESSAGE_LIST, + INTERACTION, + NETWORK, + NOTIFICATION, + PRIVACY, +} diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceScopeRegistry.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceScopeRegistry.kt new file mode 100644 index 00000000000..e26e1c21592 --- /dev/null +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/PreferenceScopeRegistry.kt @@ -0,0 +1,51 @@ +package net.thunderbird.core.preference + +import net.thunderbird.core.preference.debugging.DebugSettingKey +import net.thunderbird.core.preference.display.coreSettings.DisplayCoreSettingKey +import net.thunderbird.core.preference.display.inboxSettings.DisplayInboxSettingKey +import net.thunderbird.core.preference.display.miscSettings.DisplayMiscSettingKey +import net.thunderbird.core.preference.display.visualSettings.DisplayVisualSettingKey +import net.thunderbird.core.preference.display.visualSettings.message.list.DisplayMessageListSettingKey +import net.thunderbird.core.preference.interaction.InteractionSettingKey +import net.thunderbird.core.preference.network.NetworkSettingKey +import net.thunderbird.core.preference.notification.NotificationSettingKey +import net.thunderbird.core.preference.privacy.PrivacySettingKey + +object PreferenceScopeRegistry { + + private val map: Map = buildMap { + + DebugSettingKey.entries.forEach { put(it.value, PreferenceScope.DEBUGGING) } + InteractionSettingKey.entries.forEach { put(it.value, PreferenceScope.INTERACTION) } + NetworkSettingKey.entries.forEach { put(it.value, PreferenceScope.NETWORK) } + NotificationSettingKey.entries.forEach { put(it.value, PreferenceScope.NOTIFICATION) } + PrivacySettingKey.entries.forEach { put(it.value, PreferenceScope.PRIVACY) } + + DisplayCoreSettingKey.entries.forEach { + put(it.value, PreferenceScope.DISPLAY_CORE) + } + + DisplayInboxSettingKey.entries.forEach { + put(it.value, PreferenceScope.DISPLAY_INBOX) + } + + DisplayMiscSettingKey.entries.forEach { + put(it.value, PreferenceScope.DISPLAY_MISC) + } + + DisplayVisualSettingKey.entries.forEach { + put(it.value, PreferenceScope.DISPLAY_VISUAL) + } + + DisplayMessageListSettingKey.entries.forEach { + put(it.value, PreferenceScope.DISPLAY_VISUAL_MESSAGE_LIST) + } + } + + fun getScope(key: String): PreferenceScope = + map[key] ?: PreferenceScope.ALL +} + +fun getPreferenceScope(changedKey: String): PreferenceScope { + return PreferenceScopeRegistry.getScope(changedKey) +} diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/debugging/DebuggingSettingsPreferenceManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/debugging/DebuggingSettingsPreferenceManager.kt index d149fec3de0..644f4850db4 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/debugging/DebuggingSettingsPreferenceManager.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/debugging/DebuggingSettingsPreferenceManager.kt @@ -2,8 +2,11 @@ package net.thunderbird.core.preference.debugging import net.thunderbird.core.preference.PreferenceManager -const val KEY_ENABLE_DEBUG_LOGGING = "enableDebugLogging" -const val KEY_ENABLE_SYNC_DEBUG_LOGGING = "enableSyncDebugLogging" -const val KEY_ENABLE_SENSITIVE_LOGGING = "enableSensitiveLogging" +enum class DebugSettingKey(val value: String) { + + EnableDebugLogging("enableDebugLogging"), + EnableSyncDebugLogging("enableSyncDebugLogging"), + EnableSensitiveLogging("enableSensitiveLogging"), +} interface DebuggingSettingsPreferenceManager : PreferenceManager diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/coreSettings/DisplayCoreSettingsPreferenceManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/coreSettings/DisplayCoreSettingsPreferenceManager.kt index 968d6a5420a..f8f49653142 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/coreSettings/DisplayCoreSettingsPreferenceManager.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/coreSettings/DisplayCoreSettingsPreferenceManager.kt @@ -2,11 +2,14 @@ package net.thunderbird.core.preference.display.coreSettings import net.thunderbird.core.preference.PreferenceManager -const val KEY_FIXED_MESSAGE_VIEW_THEME = "fixedMessageViewTheme" -const val KEY_MESSAGE_VIEW_THEME = "messageViewTheme" -const val KEY_MESSAGE_COMPOSE_THEME = "messageComposeTheme" -const val KEY_APP_LANGUAGE = "language" -const val KEY_SPLIT_VIEW_MODE = "splitViewMode" -const val KEY_THEME = "theme" +enum class DisplayCoreSettingKey(val value: String) { + + FixedMessageViewTheme("fixedMessageViewTheme"), + MessageViewTheme("messageViewTheme"), + MessageComposeTheme("messageComposeTheme"), + AppLanguage("language"), + SplitViewMode("splitViewMode"), + Theme("theme"), +} interface DisplayCoreSettingsPreferenceManager : PreferenceManager diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/inboxSettings/DisplayInboxSettingsPreferenceManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/inboxSettings/DisplayInboxSettingsPreferenceManager.kt index e38647f74a5..0c5b8479033 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/inboxSettings/DisplayInboxSettingsPreferenceManager.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/inboxSettings/DisplayInboxSettingsPreferenceManager.kt @@ -2,11 +2,14 @@ package net.thunderbird.core.preference.display.inboxSettings import net.thunderbird.core.preference.PreferenceManager -const val KEY_MESSAGE_LIST_SENDER_ABOVE_SUBJECT = "messageListSenderAboveSubject" -const val KEY_SHOW_COMPOSE_BUTTON_ON_MESSAGE_LIST = "showComposeButtonOnMessageList" -const val KEY_SHOW_MESSAGE_LIST_STARS = "messageListStars" -const val KEY_SHOW_STAR_COUNT = "showStarredCount" -const val KEY_SHOW_UNIFIED_INBOX = "showUnifiedInbox" -const val KEY_THREAD_VIEW_ENABLED = "isThreadedViewEnabled" +enum class DisplayInboxSettingKey(val value: String) { + + MessageListSenderAboveSubject("messageListSenderAboveSubject"), + ShowComposeButtonOnMessageList("showComposeButtonOnMessageList"), + ShowMessageListStars("messageListStars"), + ShowStarCount("showStarredCount"), + ShowUnifiedInbox("showUnifiedInbox"), + ThreadViewEnabled("isThreadedViewEnabled"), +} interface DisplayInboxSettingsPreferenceManager : PreferenceManager diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/miscSettings/DisplayMiscSettingsPreferenceManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/miscSettings/DisplayMiscSettingsPreferenceManager.kt index 7e35af6dc41..7c76709fcff 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/miscSettings/DisplayMiscSettingsPreferenceManager.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/miscSettings/DisplayMiscSettingsPreferenceManager.kt @@ -2,7 +2,10 @@ package net.thunderbird.core.preference.display.miscSettings import net.thunderbird.core.preference.PreferenceManager -const val KEY_SHOW_RECENT_CHANGES = "showRecentChanges" -const val KEY_SHOULD_SHOW_SETUP_ARCHIVE_FOLDER_DIALOG = "shouldShowSetupArchiveFolderDialog" +enum class DisplayMiscSettingKey(val value: String) { + + ShowRecentChanges("showRecentChanges"), + ShouldShowSetupArchiveFolderDialog("shouldShowSetupArchiveFolderDialog"), +} interface DisplayMiscSettingsPreferenceManager : PreferenceManager diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/DisplayVisualSettingsPreferenceManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/DisplayVisualSettingsPreferenceManager.kt index 210d1f9063b..7940863a1a7 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/DisplayVisualSettingsPreferenceManager.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/DisplayVisualSettingsPreferenceManager.kt @@ -2,15 +2,18 @@ package net.thunderbird.core.preference.display.visualSettings import net.thunderbird.core.preference.PreferenceManager -const val KEY_ANIMATION = "animations" -const val KEY_MESSAGE_VIEW_FIXED_WIDTH_FONT = "messageViewFixedWidthFont" -const val KEY_AUTO_FIT_WIDTH = "autofitWidth" -const val KEY_MESSAGE_VIEW_BODY_CONTENT_TYPE = "messageViewBodyContentType" -const val KEY_DRAWER_EXPAND_ALL_FOLDER = "drawerExpandAllFolder" -const val KEY_MESSAGE_VIEW_ARCHIVE_ACTION_VISIBLE = "messageViewArchiveActionVisible" -const val KEY_MESSAGE_VIEW_DELETE_ACTION_VISIBLE = "messageViewDeleteActionVisible" -const val KEY_MESSAGE_VIEW_MOVE_ACTION_VISIBLE = "messageViewMoveActionVisible" -const val KEY_MESSAGE_VIEW_COPY_ACTION_VISIBLE = "messageViewCopyActionVisible" -const val KEY_MESSAGE_VIEW_SPAM_ACTION_VISIBLE = "messageViewSpamActionVisible" +enum class DisplayVisualSettingKey(val value: String) { + + Animation("animations"), + MessageViewFixedWidthFont("messageViewFixedWidthFont"), + AutoFitWidth("autofitWidth"), + MessageViewBodyContentType("messageViewBodyContentType"), + DrawerExpandAllFolder("drawerExpandAllFolder"), + MessageViewArchiveActionVisible("messageViewArchiveActionVisible"), + MessageViewDeleteActionVisible("messageViewDeleteActionVisible"), + MessageViewMoveActionVisible("messageViewMoveActionVisible"), + MessageViewCopyActionVisible("messageViewCopyActionVisible"), + MessageViewSpamActionVisible("messageViewSpamActionVisible"), +} interface DisplayVisualSettingsPreferenceManager : PreferenceManager diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/message/list/MessageListPreferencesManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/message/list/MessageListPreferencesManager.kt index 7544915552b..eadae66c9a5 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/message/list/MessageListPreferencesManager.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/message/list/MessageListPreferencesManager.kt @@ -2,15 +2,18 @@ package net.thunderbird.core.preference.display.visualSettings.message.list import net.thunderbird.core.preference.PreferenceManager -const val KEY_COLORIZE_MISSING_CONTACT_PICTURE = "colorizeMissingContactPictures" -const val KEY_CHANGE_REGISTERED_NAME_COLOR = "changeRegisteredNameColor" -const val KEY_USE_BACKGROUND_AS_UNREAD_INDICATOR = "isUseBackgroundAsUnreadIndicator" -const val KEY_SHOW_CORRESPONDENT_NAMES = "showCorrespondentNames" -const val KEY_SHOW_CONTACT_NAME = "showContactName" -const val KEY_SHOW_CONTACT_PICTURE = "showContactPicture" -const val KEY_MESSAGE_LIST_VIEW_PREVIEW_LINES = "messageListPreviewLines" -const val KEY_MESSAGE_LIST_VIEW_DENSITY = "messageListDensity" -const val KEY_REGISTERED_NAME_COLOR = "registeredNameColor" -const val KEY_MESSAGE_LIST_DATE_TIME_FORMAT = "messageListDateTimeFormat" +enum class DisplayMessageListSettingKey(val value: String) { + + ColorizeMissingContactPicture("colorizeMissingContactPictures"), + ChangeRegisteredNameColor("changeRegisteredNameColor"), + UseBackgroundAsUnreadIndicator("isUseBackgroundAsUnreadIndicator"), + ShowCorrespondentNames("showCorrespondentNames"), + ShowContactName("showContactName"), + ShowContactPicture("showContactPicture"), + MessageListPreviewLines("messageListPreviewLines"), + MessageListDensity("messageListDensity"), + RegisteredNameColor("registeredNameColor"), + MessageListDateTimeFormat("messageListDateTimeFormat"), +} interface MessageListPreferencesManager : PreferenceManager diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/interaction/InteractionSettingsPreferenceManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/interaction/InteractionSettingsPreferenceManager.kt index 818df9ce425..01ff41669d0 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/interaction/InteractionSettingsPreferenceManager.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/interaction/InteractionSettingsPreferenceManager.kt @@ -2,16 +2,19 @@ package net.thunderbird.core.preference.interaction import net.thunderbird.core.preference.PreferenceManager -const val KEY_USE_VOLUME_KEYS_FOR_NAVIGATION = "useVolumeKeysForNavigation" -const val KEY_MESSAGE_VIEW_POST_DELETE_ACTION = "messageViewPostDeleteAction" -const val KEY_MESSAGE_VIEW_POST_MARK_AS_UNREAD_ACTION = "messageViewPostMarkAsReadAction" -const val KEY_SWIPE_ACTION_LEFT = "swipeLeftAction" -const val KEY_SWIPE_ACTION_RIGHT = "swipeRightAction" -const val KEY_CONFIRM_DELETE = "confirmDelete" -const val KEY_CONFIRM_DISCARD_MESSAGE = "confirmDiscardMessage" -const val KEY_CONFIRM_DELETE_STARRED = "confirmDeleteStarred" -const val KEY_CONFIRM_SPAM = "confirmSpam" -const val KEY_CONFIRM_DELETE_FROM_NOTIFICATION = "confirmDeleteFromNotification" -const val KEY_CONFIRM_MARK_ALL_READ = "confirmMarkAllRead" +enum class InteractionSettingKey(val value: String) { + + UseVolumeKeysForNavigation("useVolumeKeysForNavigation"), + MessageViewPostDeleteAction("messageViewPostDeleteAction"), + SwipeActionLeft("swipeLeftAction"), + SwipeActionRight("swipeRightAction"), + ConfirmDelete("confirmDelete"), + ConfirmDiscardMessage("confirmDiscardMessage"), + ConfirmDeleteStarred("confirmDeleteStarred"), + ConfirmSpam("confirmSpam"), + ConfirmDeleteFromNotification("confirmDeleteFromNotification"), + ConfirmMarkAllRead("confirmMarkAllRead"), + MessageViewPostMarkAsRead("messageViewPostMarkAsReadAction"), +} interface InteractionSettingsPreferenceManager : PreferenceManager diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/network/NetworkSettingsPreferenceManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/network/NetworkSettingsPreferenceManager.kt index bd97a95a932..50c90d0594d 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/network/NetworkSettingsPreferenceManager.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/network/NetworkSettingsPreferenceManager.kt @@ -2,6 +2,8 @@ package net.thunderbird.core.preference.network import net.thunderbird.core.preference.PreferenceManager -const val KEY_BG_OPS = "backgroundOperations" +enum class NetworkSettingKey(val value: String) { + BackgroundOperations("backgroundOperations"), +} interface NetworkSettingsPreferenceManager : PreferenceManager diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/notification/NotificationPreferenceManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/notification/NotificationPreferenceManager.kt index e25be0dce7d..ca6fff5ba3e 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/notification/NotificationPreferenceManager.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/notification/NotificationPreferenceManager.kt @@ -2,15 +2,16 @@ package net.thunderbird.core.preference.notification import net.thunderbird.core.preference.PreferenceManager -const val KEY_QUIET_TIME_ENDS = "quietTimeEnds" -const val KEY_QUIET_TIME_STARTS = "quietTimeStarts" -const val KEY_QUIET_TIME_ENABLED = "quietTimeEnabled" -const val KEY_NOTIFICATION_DURING_QUIET_TIME_ENABLED = "notificationDuringQuietTimeEnabled" -const val KEY_MESSAGE_ACTIONS_ORDER = "messageActionsOrder" -const val KEY_MESSAGE_ACTIONS_CUTOFF = "messageActionsCutoff" -const val KEY_IS_SUMMARY_DELETE_ACTION_ENABLED = "isSummaryDeleteActionEnabled" - -const val KEY_NOTIFICATION_QUICK_DELETE_BEHAVIOUR = "notificationQuickDelete" -const val KEY_LOCK_SCREEN_NOTIFICATION_VISIBILITY = "lockScreenNotificationVisibility" +enum class NotificationSettingKey(val value: String) { + QuietTimeEnds("quietTimeEnds"), + QuietTimeStarts("quietTimeStarts"), + QuietTimeEnabled("quietTimeEnabled"), + NotificationDuringQuietTimeEnabled("notificationDuringQuietTimeEnabled"), + MessageActionsOrder("messageActionsOrder"), + MessageActionsCutoff("messageActionsCutoff"), + IsSummaryDeleteActionEnabled("isSummaryDeleteActionEnabled"), + NotificationQuickDeleteBehaviour("notificationQuickDelete"), + LockScreenNotificationVisibility("lockScreenNotificationVisibility"), +} interface NotificationPreferenceManager : PreferenceManager diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettingsPreferenceManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettingsPreferenceManager.kt index 60e3fafe561..0d1c58816a6 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettingsPreferenceManager.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettingsPreferenceManager.kt @@ -2,7 +2,10 @@ package net.thunderbird.core.preference.privacy import net.thunderbird.core.preference.PreferenceManager -const val KEY_HIDE_TIME_ZONE = "hideTimeZone" -const val KEY_HIDE_USER_AGENT = "hideUserAgent" +enum class PrivacySettingKey(val value: String) { + + HideTimeZone("hideTimeZone"), + HideUserAgent("hideUserAgent"), +} interface PrivacySettingsPreferenceManager : PreferenceManager diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/DefaultPreferenceChangeBroker.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/DefaultPreferenceChangeBroker.kt index 75ddb974993..aba0979e215 100644 --- a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/DefaultPreferenceChangeBroker.kt +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/DefaultPreferenceChangeBroker.kt @@ -18,11 +18,11 @@ class DefaultPreferenceChangeBroker( } } - override fun publish() { + override fun publish(scope: PreferenceScope) { val currentSubscribers = synchronized(lock) { HashSet(subscribers) } for (subscriber in currentSubscribers) { - subscriber.receive() + subscriber.receive(scope) } } } diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/debugging/DefaultDebuggingSettingsPreferenceManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/debugging/DefaultDebuggingSettingsPreferenceManager.kt index 258a5ef6ab4..ba22abf2590 100644 --- a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/debugging/DefaultDebuggingSettingsPreferenceManager.kt +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/debugging/DefaultDebuggingSettingsPreferenceManager.kt @@ -14,6 +14,9 @@ import net.thunderbird.core.common.appConfig.PlatformConfigProvider import net.thunderbird.core.logging.LogLevel import net.thunderbird.core.logging.LogLevelManager import net.thunderbird.core.logging.Logger +import net.thunderbird.core.preference.PreferenceChangeBroker +import net.thunderbird.core.preference.PreferenceChangeSubscriber +import net.thunderbird.core.preference.PreferenceScope import net.thunderbird.core.preference.storage.Storage import net.thunderbird.core.preference.storage.StorageEditor import net.thunderbird.core.preference.storage.StoragePersister @@ -28,7 +31,12 @@ class DefaultDebuggingSettingsPreferenceManager( private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, private var scope: CoroutineScope = CoroutineScope(SupervisorJob()), private val platformConfigProvider: PlatformConfigProvider, -) : DebuggingSettingsPreferenceManager { + preferenceChangeBroker: PreferenceChangeBroker, +) : DebuggingSettingsPreferenceManager, PreferenceChangeSubscriber { + + init { + preferenceChangeBroker.subscribe(this) + } private val configState: MutableStateFlow = MutableStateFlow(value = loadConfig()) private val mutex = Mutex() private val storage: Storage @@ -45,15 +53,15 @@ class DefaultDebuggingSettingsPreferenceManager( private fun loadConfig(): DebuggingSettings = DebuggingSettings( isDebugLoggingEnabled = storage.getBoolean( - KEY_ENABLE_DEBUG_LOGGING, + DebugSettingKey.EnableDebugLogging.value, platformConfigProvider.isDebug, ), isSyncLoggingEnabled = storage.getBoolean( - KEY_ENABLE_SYNC_DEBUG_LOGGING, + DebugSettingKey.EnableSyncDebugLogging.value, DEBUGGING_SETTINGS_DEFAULT_IS_SYNC_LOGGING_ENABLED, ), isSensitiveLoggingEnabled = storage.getBoolean( - key = KEY_ENABLE_SENSITIVE_LOGGING, + key = DebugSettingKey.EnableSensitiveLogging.value, defValue = DEBUGGING_SETTINGS_DEFAULT_SENSITIVE_LOGGING_ENABLED, ), ).also(::updateDebugLogLevel) @@ -62,9 +70,9 @@ class DefaultDebuggingSettingsPreferenceManager( logger.debug(TAG) { "writeConfig() called with: config = $config" } scope.launch(ioDispatcher) { mutex.withLock { - storageEditor.putBoolean(KEY_ENABLE_DEBUG_LOGGING, config.isDebugLoggingEnabled) - storageEditor.putBoolean(KEY_ENABLE_SYNC_DEBUG_LOGGING, config.isSyncLoggingEnabled) - storageEditor.putBoolean(KEY_ENABLE_SENSITIVE_LOGGING, config.isSensitiveLoggingEnabled) + storageEditor.putBoolean(DebugSettingKey.EnableDebugLogging.value, config.isDebugLoggingEnabled) + storageEditor.putBoolean(DebugSettingKey.EnableSyncDebugLogging.value, config.isSyncLoggingEnabled) + storageEditor.putBoolean(DebugSettingKey.EnableSensitiveLogging.value, config.isSensitiveLoggingEnabled) storageEditor.commit().also { commited -> logger.verbose(TAG) { "writeConfig: storageEditor.commit() resulted in: $commited" } } @@ -79,4 +87,10 @@ class DefaultDebuggingSettingsPreferenceManager( logLevelManager.restoreDefault() } } + + override fun receive(scope: PreferenceScope) { + if (scope == PreferenceScope.ALL || scope == PreferenceScope.DEBUGGING) { + configState.update { loadConfig() } + } + } } diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/coreSettings/DefaultDisplayCoreSettingsPreferenceManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/coreSettings/DefaultDisplayCoreSettingsPreferenceManager.kt index a8bcda29690..47843bfcc7f 100644 --- a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/coreSettings/DefaultDisplayCoreSettingsPreferenceManager.kt +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/coreSettings/DefaultDisplayCoreSettingsPreferenceManager.kt @@ -11,6 +11,9 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import net.thunderbird.core.logging.Logger +import net.thunderbird.core.preference.PreferenceChangeBroker +import net.thunderbird.core.preference.PreferenceChangeSubscriber +import net.thunderbird.core.preference.PreferenceScope import net.thunderbird.core.preference.storage.Storage import net.thunderbird.core.preference.storage.StorageEditor import net.thunderbird.core.preference.storage.StoragePersister @@ -25,8 +28,12 @@ class DefaultDisplayCoreSettingsPreferenceManager( private val storageEditor: StorageEditor, private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, private var scope: CoroutineScope = CoroutineScope(SupervisorJob()), -) : DisplayCoreSettingsPreferenceManager { + preferenceChangeBroker: PreferenceChangeBroker, +) : DisplayCoreSettingsPreferenceManager, PreferenceChangeSubscriber { + init { + preferenceChangeBroker.subscribe(this) + } private val configState: MutableStateFlow = MutableStateFlow(value = loadConfig()) private val mutex = Mutex() private val storage: Storage @@ -44,24 +51,24 @@ class DefaultDisplayCoreSettingsPreferenceManager( private fun loadConfig(): DisplayCoreSettings = DisplayCoreSettings( fixedMessageViewTheme = storage.getBoolean( - KEY_FIXED_MESSAGE_VIEW_THEME, + DisplayCoreSettingKey.FixedMessageViewTheme.value, DISPLAY_SETTINGS_DEFAULT_FIXED_MESSAGE_VIEW_THEME, ), - appTheme = storage.getEnumOrDefault(KEY_THEME, DISPLAY_SETTINGS_DEFAULT_APP_THEME), + appTheme = storage.getEnumOrDefault(DisplayCoreSettingKey.Theme.value, DISPLAY_SETTINGS_DEFAULT_APP_THEME), messageViewTheme = storage.getEnumOrDefault( - KEY_MESSAGE_VIEW_THEME, + DisplayCoreSettingKey.MessageViewTheme.value, DISPLAY_SETTINGS_DEFAULT_MESSAGE_VIEW_THEME, ), messageComposeTheme = storage.getEnumOrDefault( - KEY_MESSAGE_COMPOSE_THEME, + DisplayCoreSettingKey.MessageComposeTheme.value, DISPLAY_SETTINGS_DEFAULT_MESSAGE_COMPOSE_THEME, ), appLanguage = storage.getStringOrDefault( - KEY_APP_LANGUAGE, + DisplayCoreSettingKey.AppLanguage.value, DISPLAY_SETTINGS_DEFAULT_APP_LANGUAGE, ), splitViewMode = storage.getEnumOrDefault( - KEY_SPLIT_VIEW_MODE, + DisplayCoreSettingKey.SplitViewMode.value, DISPLAY_SETTINGS_DEFAULT_SPLIT_VIEW_MODE, ), ) @@ -70,22 +77,28 @@ class DefaultDisplayCoreSettingsPreferenceManager( logger.debug(TAG) { "writeConfig() called with: config = $config" } scope.launch(ioDispatcher) { mutex.withLock { - storageEditor.putEnum(KEY_THEME, config.appTheme) - storageEditor.putEnum(KEY_MESSAGE_VIEW_THEME, config.messageViewTheme) + storageEditor.putEnum(DisplayCoreSettingKey.Theme.value, config.appTheme) + storageEditor.putEnum(DisplayCoreSettingKey.MessageViewTheme.value, config.messageViewTheme) storageEditor.putEnum( - KEY_MESSAGE_COMPOSE_THEME, + DisplayCoreSettingKey.MessageComposeTheme.value, config.messageComposeTheme, ) storageEditor.putBoolean( - KEY_FIXED_MESSAGE_VIEW_THEME, + DisplayCoreSettingKey.FixedMessageViewTheme.value, config.fixedMessageViewTheme, ) - storageEditor.putString(KEY_APP_LANGUAGE, config.appLanguage) - storageEditor.putEnum(KEY_SPLIT_VIEW_MODE, config.splitViewMode) + storageEditor.putString(DisplayCoreSettingKey.AppLanguage.value, config.appLanguage) + storageEditor.putEnum(DisplayCoreSettingKey.SplitViewMode.value, config.splitViewMode) storageEditor.commit().also { commited -> logger.verbose(TAG) { "writeConfig: storageEditor.commit() resulted in: $commited" } } } } } + + override fun receive(scope: PreferenceScope) { + if (scope == PreferenceScope.ALL || scope == PreferenceScope.DISPLAY_CORE) { + configState.update { loadConfig() } + } + } } diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/inboxSettings/DefaultDisplayInboxSettingsPreferenceManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/inboxSettings/DefaultDisplayInboxSettingsPreferenceManager.kt index 62ac95ceb8e..4c76ecedc11 100644 --- a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/inboxSettings/DefaultDisplayInboxSettingsPreferenceManager.kt +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/inboxSettings/DefaultDisplayInboxSettingsPreferenceManager.kt @@ -11,6 +11,9 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import net.thunderbird.core.logging.Logger +import net.thunderbird.core.preference.PreferenceChangeBroker +import net.thunderbird.core.preference.PreferenceChangeSubscriber +import net.thunderbird.core.preference.PreferenceScope import net.thunderbird.core.preference.storage.Storage import net.thunderbird.core.preference.storage.StorageEditor import net.thunderbird.core.preference.storage.StoragePersister @@ -23,8 +26,12 @@ class DefaultDisplayInboxSettingsPreferenceManager( private val storageEditor: StorageEditor, private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, private var scope: CoroutineScope = CoroutineScope(SupervisorJob()), -) : DisplayInboxSettingsPreferenceManager { + preferenceChangeBroker: PreferenceChangeBroker, +) : DisplayInboxSettingsPreferenceManager, PreferenceChangeSubscriber { + init { + preferenceChangeBroker.subscribe(this) + } private val configState: MutableStateFlow = MutableStateFlow(value = loadConfig()) private val mutex = Mutex() private val storage: Storage @@ -42,27 +49,27 @@ class DefaultDisplayInboxSettingsPreferenceManager( private fun loadConfig(): DisplayInboxSettings = DisplayInboxSettings( isShowUnifiedInbox = storage.getBoolean( - KEY_SHOW_UNIFIED_INBOX, + DisplayInboxSettingKey.ShowUnifiedInbox.value, DISPLAY_SETTINGS_DEFAULT_IS_SHOW_UNIFIED_INBOX, ), isShowComposeButtonOnMessageList = storage.getBoolean( - KEY_SHOW_COMPOSE_BUTTON_ON_MESSAGE_LIST, + DisplayInboxSettingKey.ShowComposeButtonOnMessageList.value, DISPLAY_SETTINGS_DEFAULT_IS_SHOW_COMPOSE_BUTTON_ON_MESSAGE_LIST, ), isThreadedViewEnabled = storage.getBoolean( - KEY_THREAD_VIEW_ENABLED, + DisplayInboxSettingKey.ThreadViewEnabled.value, DISPLAY_SETTINGS_DEFAULT_IS_THREAD_VIEW_ENABLED, ), isShowStarredCount = storage.getBoolean( - KEY_SHOW_STAR_COUNT, + DisplayInboxSettingKey.ShowStarCount.value, DISPLAY_SETTINGS_DEFAULT_IS_SHOW_STAR_COUNT, ), isShowMessageListStars = storage.getBoolean( - KEY_SHOW_MESSAGE_LIST_STARS, + DisplayInboxSettingKey.ShowMessageListStars.value, DISPLAY_SETTINGS_DEFAULT_IS_SHOW_MESSAGE_LIST_STAR, ), isMessageListSenderAboveSubject = storage.getBoolean( - KEY_MESSAGE_LIST_SENDER_ABOVE_SUBJECT, + DisplayInboxSettingKey.MessageListSenderAboveSubject.value, DISPLAY_SETTINGS_DEFAULT_IS_MESSAGE_LIST_SENDER_ABOVE_SUBJECT, ), ) @@ -72,27 +79,33 @@ class DefaultDisplayInboxSettingsPreferenceManager( scope.launch(ioDispatcher) { mutex.withLock { storageEditor.putBoolean( - KEY_MESSAGE_LIST_SENDER_ABOVE_SUBJECT, + DisplayInboxSettingKey.MessageListSenderAboveSubject.value, config.isMessageListSenderAboveSubject, ) storageEditor.putBoolean( - KEY_SHOW_MESSAGE_LIST_STARS, + DisplayInboxSettingKey.ShowMessageListStars.value, config.isShowMessageListStars, ) storageEditor.putBoolean( - KEY_SHOW_COMPOSE_BUTTON_ON_MESSAGE_LIST, + DisplayInboxSettingKey.ShowComposeButtonOnMessageList.value, config.isShowComposeButtonOnMessageList, ) storageEditor.putBoolean( - KEY_THREAD_VIEW_ENABLED, + DisplayInboxSettingKey.ThreadViewEnabled.value, config.isThreadedViewEnabled, ) - storageEditor.putBoolean(KEY_SHOW_UNIFIED_INBOX, config.isShowUnifiedInbox) - storageEditor.putBoolean(KEY_SHOW_STAR_COUNT, config.isShowStarredCount) + storageEditor.putBoolean(DisplayInboxSettingKey.ShowUnifiedInbox.value, config.isShowUnifiedInbox) + storageEditor.putBoolean(DisplayInboxSettingKey.ShowStarCount.value, config.isShowStarredCount) storageEditor.commit().also { commited -> logger.verbose(TAG) { "writeConfig: storageEditor.commit() resulted in: $commited" } } } } } + + override fun receive(scope: PreferenceScope) { + if (scope == PreferenceScope.ALL || scope == PreferenceScope.DISPLAY_INBOX) { + configState.update { loadConfig() } + } + } } diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/miscSettings/DefaultDisplayMiscSettingsPreferenceManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/miscSettings/DefaultDisplayMiscSettingsPreferenceManager.kt index 052d8e0b4a4..cb2a42a3a1f 100644 --- a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/miscSettings/DefaultDisplayMiscSettingsPreferenceManager.kt +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/miscSettings/DefaultDisplayMiscSettingsPreferenceManager.kt @@ -11,6 +11,9 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import net.thunderbird.core.logging.Logger +import net.thunderbird.core.preference.PreferenceChangeBroker +import net.thunderbird.core.preference.PreferenceChangeSubscriber +import net.thunderbird.core.preference.PreferenceScope import net.thunderbird.core.preference.storage.Storage import net.thunderbird.core.preference.storage.StorageEditor import net.thunderbird.core.preference.storage.StoragePersister @@ -23,7 +26,12 @@ class DefaultDisplayMiscSettingsPreferenceManager( private val storageEditor: StorageEditor, private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, private var scope: CoroutineScope = CoroutineScope(SupervisorJob()), -) : DisplayMiscSettingsPreferenceManager { + preferenceChangeBroker: PreferenceChangeBroker, +) : DisplayMiscSettingsPreferenceManager, PreferenceChangeSubscriber { + + init { + preferenceChangeBroker.subscribe(this) + } private val configState: MutableStateFlow = MutableStateFlow(value = loadConfig()) private val mutex = Mutex() private val storage: Storage @@ -40,11 +48,11 @@ class DefaultDisplayMiscSettingsPreferenceManager( private fun loadConfig(): DisplayMiscSettings = DisplayMiscSettings( showRecentChanges = storage.getBoolean( - KEY_SHOW_RECENT_CHANGES, + DisplayMiscSettingKey.ShowRecentChanges.value, DISPLAY_SETTINGS_DEFAULT_SHOW_RECENT_CHANGES, ), shouldShowSetupArchiveFolderDialog = storage.getBoolean( - KEY_SHOULD_SHOW_SETUP_ARCHIVE_FOLDER_DIALOG, + DisplayMiscSettingKey.ShouldShowSetupArchiveFolderDialog.value, DISPLAY_SETTINGS_DEFAULT_SHOULD_SHOW_SETUP_ARCHIVE_FOLDER_DIALOG, ), ) @@ -54,14 +62,20 @@ class DefaultDisplayMiscSettingsPreferenceManager( scope.launch(ioDispatcher) { mutex.withLock { storageEditor.putBoolean( - KEY_SHOULD_SHOW_SETUP_ARCHIVE_FOLDER_DIALOG, + DisplayMiscSettingKey.ShouldShowSetupArchiveFolderDialog.value, config.shouldShowSetupArchiveFolderDialog, ) - storageEditor.putBoolean(KEY_SHOW_RECENT_CHANGES, config.showRecentChanges) + storageEditor.putBoolean(DisplayMiscSettingKey.ShowRecentChanges.value, config.showRecentChanges) storageEditor.commit().also { commited -> logger.verbose(TAG) { "writeConfig: storageEditor.commit() resulted in: $commited" } } } } } + + override fun receive(scope: PreferenceScope) { + if (scope == PreferenceScope.ALL || scope == PreferenceScope.DISPLAY_MISC) { + configState.update { loadConfig() } + } + } } diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/DefaultDisplayVisualSettingsPreferenceManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/DefaultDisplayVisualSettingsPreferenceManager.kt index 594129673bb..6b361a63994 100644 --- a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/DefaultDisplayVisualSettingsPreferenceManager.kt +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/DefaultDisplayVisualSettingsPreferenceManager.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.sync.withLock import net.thunderbird.core.logging.Logger import net.thunderbird.core.preference.PreferenceChangeBroker import net.thunderbird.core.preference.PreferenceChangeSubscriber +import net.thunderbird.core.preference.PreferenceScope import net.thunderbird.core.preference.display.visualSettings.message.list.MessageListPreferencesManager import net.thunderbird.core.preference.storage.Storage import net.thunderbird.core.preference.storage.StorageEditor @@ -30,15 +31,16 @@ class DefaultDisplayVisualSettingsPreferenceManager( private val logger: Logger, private val storagePersister: StoragePersister, private val storageEditor: StorageEditor, - preferenceChangeBroker: PreferenceChangeBroker, private val messageListPreferences: MessageListPreferencesManager, private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, private val scope: CoroutineScope = CoroutineScope(SupervisorJob()), + preferenceChangeBroker: PreferenceChangeBroker, ) : DisplayVisualSettingsPreferenceManager, PreferenceChangeSubscriber { init { preferenceChangeBroker.subscribe(this) } + private val internalConfigState = MutableStateFlow(value = loadConfig()) private val configState: StateFlow = combine( internalConfigState, @@ -58,43 +60,43 @@ class DefaultDisplayVisualSettingsPreferenceManager( private fun loadConfig(): DisplayVisualSettings = DisplayVisualSettings( isUseMessageViewFixedWidthFont = storage.getBoolean( - KEY_MESSAGE_VIEW_FIXED_WIDTH_FONT, + DisplayVisualSettingKey.MessageViewFixedWidthFont.value, DISPLAY_SETTINGS_DEFAULT_IS_USE_MESSAGE_VIEW_FIXED_WIDTH_FONT, ), isAutoFitWidth = storage.getBoolean( - KEY_AUTO_FIT_WIDTH, + DisplayVisualSettingKey.AutoFitWidth.value, DISPLAY_SETTINGS_DEFAULT_IS_AUTO_FIT_WIDTH, ), isShowAnimations = storage.getBoolean( - KEY_ANIMATION, + DisplayVisualSettingKey.Animation.value, DISPLAY_SETTINGS_DEFAULT_IS_SHOW_ANIMATION, ), bodyContentType = storage.getEnumOrDefault( - KEY_MESSAGE_VIEW_BODY_CONTENT_TYPE, + DisplayVisualSettingKey.MessageViewBodyContentType.value, DISPLAY_SETTINGS_DEFAULT_BODY_CONTENT_TYPE, ), drawerExpandAllFolder = storage.getBoolean( - KEY_DRAWER_EXPAND_ALL_FOLDER, + DisplayVisualSettingKey.DrawerExpandAllFolder.value, DISPLAY_SETTINGS_DEFAULT_DRAWER_EXPAND_ALL_FOLDER, ), isMessageViewArchiveActionVisible = storage.getBoolean( - KEY_MESSAGE_VIEW_ARCHIVE_ACTION_VISIBLE, + DisplayVisualSettingKey.MessageViewArchiveActionVisible.value, DISPLAY_SETTINGS_DEFAULT_MESSAGE_VIEW_ARCHIVE_ACTION_VISIBLE, ), isMessageViewDeleteActionVisible = storage.getBoolean( - KEY_MESSAGE_VIEW_DELETE_ACTION_VISIBLE, + DisplayVisualSettingKey.MessageViewDeleteActionVisible.value, DISPLAY_SETTINGS_DEFAULT_MESSAGE_VIEW_DELETE_ACTION_VISIBLE, ), isMessageViewMoveActionVisible = storage.getBoolean( - KEY_MESSAGE_VIEW_MOVE_ACTION_VISIBLE, + DisplayVisualSettingKey.MessageViewMoveActionVisible.value, DISPLAY_SETTINGS_DEFAULT_MESSAGE_VIEW_MOVE_ACTION_VISIBLE, ), isMessageViewCopyActionVisible = storage.getBoolean( - KEY_MESSAGE_VIEW_COPY_ACTION_VISIBLE, + DisplayVisualSettingKey.MessageViewCopyActionVisible.value, DISPLAY_SETTINGS_DEFAULT_MESSAGE_VIEW_COPY_ACTION_VISIBLE, ), isMessageViewSpamActionVisible = storage.getBoolean( - KEY_MESSAGE_VIEW_SPAM_ACTION_VISIBLE, + DisplayVisualSettingKey.MessageViewSpamActionVisible.value, DISPLAY_SETTINGS_DEFAULT_MESSAGE_VIEW_SPAM_ACTION_VISIBLE, ), ) @@ -103,33 +105,36 @@ class DefaultDisplayVisualSettingsPreferenceManager( logger.debug(TAG) { "writeConfig() called with: config = $config" } scope.launch(ioDispatcher) { mutex.withLock { - storageEditor.putBoolean(KEY_ANIMATION, config.isShowAnimations) + storageEditor.putBoolean(DisplayVisualSettingKey.Animation.value, config.isShowAnimations) storageEditor.putBoolean( - KEY_MESSAGE_VIEW_FIXED_WIDTH_FONT, + DisplayVisualSettingKey.MessageViewFixedWidthFont.value, config.isUseMessageViewFixedWidthFont, ) - storageEditor.putBoolean(KEY_AUTO_FIT_WIDTH, config.isAutoFitWidth) - storageEditor.putEnum(KEY_MESSAGE_VIEW_BODY_CONTENT_TYPE, config.bodyContentType) - storageEditor.putBoolean(KEY_DRAWER_EXPAND_ALL_FOLDER, config.drawerExpandAllFolder) + storageEditor.putBoolean(DisplayVisualSettingKey.AutoFitWidth.value, config.isAutoFitWidth) + storageEditor.putEnum(DisplayVisualSettingKey.MessageViewBodyContentType.value, config.bodyContentType) + storageEditor.putBoolean( + DisplayVisualSettingKey.DrawerExpandAllFolder.value, + config.drawerExpandAllFolder, + ) messageListPreferences.save(config.messageListSettings) storageEditor.putBoolean( - KEY_MESSAGE_VIEW_ARCHIVE_ACTION_VISIBLE, + DisplayVisualSettingKey.MessageViewArchiveActionVisible.value, config.isMessageViewArchiveActionVisible, ) storageEditor.putBoolean( - KEY_MESSAGE_VIEW_DELETE_ACTION_VISIBLE, + DisplayVisualSettingKey.MessageViewDeleteActionVisible.value, config.isMessageViewDeleteActionVisible, ) storageEditor.putBoolean( - KEY_MESSAGE_VIEW_MOVE_ACTION_VISIBLE, + DisplayVisualSettingKey.MessageViewMoveActionVisible.value, config.isMessageViewMoveActionVisible, ) storageEditor.putBoolean( - KEY_MESSAGE_VIEW_COPY_ACTION_VISIBLE, + DisplayVisualSettingKey.MessageViewCopyActionVisible.value, config.isMessageViewCopyActionVisible, ) storageEditor.putBoolean( - KEY_MESSAGE_VIEW_SPAM_ACTION_VISIBLE, + DisplayVisualSettingKey.MessageViewSpamActionVisible.value, config.isMessageViewSpamActionVisible, ) storageEditor.commit().also { commited -> @@ -143,7 +148,9 @@ class DefaultDisplayVisualSettingsPreferenceManager( override fun getConfigFlow(): Flow = configState - override fun receive() { - internalConfigState.update { loadConfig() } + override fun receive(scope: PreferenceScope) { + if (scope == PreferenceScope.ALL || scope == PreferenceScope.DISPLAY_VISUAL) { + internalConfigState.update { loadConfig() } + } } } diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/message/list/DefaultMessageListPreferencesManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/message/list/DefaultMessageListPreferencesManager.kt index d4f0b897ecb..e554a704903 100644 --- a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/message/list/DefaultMessageListPreferencesManager.kt +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/display/visualSettings/message/list/DefaultMessageListPreferencesManager.kt @@ -4,6 +4,9 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update import net.thunderbird.core.logging.Logger +import net.thunderbird.core.preference.PreferenceChangeBroker +import net.thunderbird.core.preference.PreferenceChangeSubscriber +import net.thunderbird.core.preference.PreferenceScope import net.thunderbird.core.preference.storage.Storage import net.thunderbird.core.preference.storage.StorageEditor import net.thunderbird.core.preference.storage.getEnumOrDefault @@ -15,7 +18,12 @@ class DefaultMessageListPreferencesManager( private val logger: Logger, private val storage: Storage, private val storageEditor: StorageEditor, -) : MessageListPreferencesManager { + preferenceChangeBroker: PreferenceChangeBroker, +) : MessageListPreferencesManager, PreferenceChangeSubscriber { + + init { + preferenceChangeBroker.subscribe(this) + } private val preferences = MutableStateFlow(value = loadPreferences()) override fun save(config: DisplayMessageListSettings) { logger.debug(TAG) { "save() called with: config = $config" } @@ -25,58 +33,73 @@ class DefaultMessageListPreferencesManager( private fun loadPreferences(): DisplayMessageListSettings = DisplayMessageListSettings( isColorizeMissingContactPictures = storage.getBoolean( - KEY_COLORIZE_MISSING_CONTACT_PICTURE, + DisplayMessageListSettingKey.ColorizeMissingContactPicture.value, MESSAGE_LIST_SETTINGS_DEFAULT_IS_COLORIZE_MISSING_CONTACT_PICTURE, ), isChangeContactNameColor = storage.getBoolean( - KEY_CHANGE_REGISTERED_NAME_COLOR, + DisplayMessageListSettingKey.ChangeRegisteredNameColor.value, MESSAGE_LIST_SETTINGS_DEFAULT_IS_CHANGE_CONTACT_NAME_COLOR, ), isUseBackgroundAsUnreadIndicator = storage.getBoolean( - KEY_USE_BACKGROUND_AS_UNREAD_INDICATOR, + DisplayMessageListSettingKey.UseBackgroundAsUnreadIndicator.value, MESSAGE_LIST_SETTINGS_DEFAULT_IS_USE_BACKGROUND_AS_INDICATOR, ), isShowCorrespondentNames = storage.getBoolean( - KEY_SHOW_CORRESPONDENT_NAMES, + DisplayMessageListSettingKey.ShowCorrespondentNames.value, MESSAGE_LIST_SETTINGS_DEFAULT_IS_SHOW_CORRESPONDENT_NAMES, ), isShowContactName = storage.getBoolean( - KEY_SHOW_CONTACT_NAME, + DisplayMessageListSettingKey.ShowContactName.value, MESSAGE_LIST_SETTINGS_DEFAULT_IS_SHOW_CONTACT_NAME, ), isShowContactPicture = storage.getBoolean( - KEY_SHOW_CONTACT_PICTURE, + DisplayMessageListSettingKey.ShowContactPicture.value, MESSAGE_LIST_SETTINGS_DEFAULT_IS_SHOW_CONTACT_PICTURE, ), previewLines = storage.getInt( - KEY_MESSAGE_LIST_VIEW_PREVIEW_LINES, + DisplayMessageListSettingKey.MessageListPreviewLines.value, MESSAGE_LIST_SETTINGS_DEFAULT_PREVIEW_LINES, ), uiDensity = storage.getEnumOrDefault( - KEY_MESSAGE_LIST_VIEW_DENSITY, + DisplayMessageListSettingKey.MessageListDensity.value, MESSAGE_LIST_SETTINGS_DEFAULT_UI_DENSITY, ), contactNameColor = storage.getInt( - KEY_REGISTERED_NAME_COLOR, + DisplayMessageListSettingKey.RegisteredNameColor.value, DISPLAY_SETTINGS_DEFAULT_CONTACT_NAME_COLOR, ), dateTimeFormat = storage.getEnumOrDefault( - KEY_MESSAGE_LIST_DATE_TIME_FORMAT, + DisplayMessageListSettingKey.MessageListDateTimeFormat.value, MESSAGE_LIST_SETTINGS_DEFAULT_DATE_TIME_FORMAT, ), ) private fun write(preferences: DisplayMessageListSettings) { - storageEditor.putBoolean(KEY_CHANGE_REGISTERED_NAME_COLOR, preferences.isChangeContactNameColor) - storageEditor.putBoolean(KEY_COLORIZE_MISSING_CONTACT_PICTURE, preferences.isColorizeMissingContactPictures) - storageEditor.putBoolean(KEY_SHOW_CONTACT_PICTURE, preferences.isShowContactPicture) - storageEditor.putBoolean(KEY_USE_BACKGROUND_AS_UNREAD_INDICATOR, preferences.isUseBackgroundAsUnreadIndicator) - storageEditor.putBoolean(KEY_SHOW_CONTACT_NAME, preferences.isShowContactName) - storageEditor.putBoolean(KEY_SHOW_CORRESPONDENT_NAMES, preferences.isShowCorrespondentNames) - storageEditor.putInt(KEY_MESSAGE_LIST_VIEW_PREVIEW_LINES, preferences.previewLines) - storageEditor.putInt(KEY_REGISTERED_NAME_COLOR, preferences.contactNameColor) - storageEditor.putEnum(KEY_MESSAGE_LIST_VIEW_DENSITY, preferences.uiDensity) - storageEditor.putEnum(KEY_MESSAGE_LIST_DATE_TIME_FORMAT, preferences.dateTimeFormat) + storageEditor.putBoolean( + DisplayMessageListSettingKey.ChangeRegisteredNameColor.value, + preferences.isChangeContactNameColor, + ) + storageEditor.putBoolean( + DisplayMessageListSettingKey.ColorizeMissingContactPicture.value, + preferences.isColorizeMissingContactPictures, + ) + storageEditor.putBoolean( + DisplayMessageListSettingKey.ShowContactPicture.value, + preferences.isShowContactPicture, + ) + storageEditor.putBoolean( + DisplayMessageListSettingKey.UseBackgroundAsUnreadIndicator.value, + preferences.isUseBackgroundAsUnreadIndicator, + ) + storageEditor.putBoolean(DisplayMessageListSettingKey.ShowContactName.value, preferences.isShowContactName) + storageEditor.putBoolean( + DisplayMessageListSettingKey.ShowCorrespondentNames.value, + preferences.isShowCorrespondentNames, + ) + storageEditor.putInt(DisplayMessageListSettingKey.MessageListPreviewLines.value, preferences.previewLines) + storageEditor.putInt(DisplayMessageListSettingKey.RegisteredNameColor.value, preferences.contactNameColor) + storageEditor.putEnum(DisplayMessageListSettingKey.MessageListDensity.value, preferences.uiDensity) + storageEditor.putEnum(DisplayMessageListSettingKey.MessageListDateTimeFormat.value, preferences.dateTimeFormat) storageEditor.commit().also { commited -> logger.verbose(TAG) { "writeConfig: storageEditor.commit() resulted in: $commited" } } @@ -84,4 +107,10 @@ class DefaultMessageListPreferencesManager( override fun getConfig(): DisplayMessageListSettings = preferences.value override fun getConfigFlow(): Flow = preferences + + override fun receive(scope: PreferenceScope) { + if (scope == PreferenceScope.ALL || scope == PreferenceScope.DISPLAY_VISUAL_MESSAGE_LIST) { + preferences.update { loadPreferences() } + } + } } diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/interaction/DefaultInteractionSettingsPreferenceManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/interaction/DefaultInteractionSettingsPreferenceManager.kt index 4688fd8a3ca..2c4c60510e4 100644 --- a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/interaction/DefaultInteractionSettingsPreferenceManager.kt +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/interaction/DefaultInteractionSettingsPreferenceManager.kt @@ -12,6 +12,9 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import net.thunderbird.core.common.action.SwipeActions import net.thunderbird.core.logging.Logger +import net.thunderbird.core.preference.PreferenceChangeBroker +import net.thunderbird.core.preference.PreferenceChangeSubscriber +import net.thunderbird.core.preference.PreferenceScope import net.thunderbird.core.preference.storage.Storage import net.thunderbird.core.preference.storage.StorageEditor import net.thunderbird.core.preference.storage.StoragePersister @@ -26,7 +29,12 @@ class DefaultInteractionSettingsPreferenceManager( private val storageEditor: StorageEditor, private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, private var scope: CoroutineScope = CoroutineScope(SupervisorJob()), -) : InteractionSettingsPreferenceManager { + preferenceChangeBroker: PreferenceChangeBroker, +) : InteractionSettingsPreferenceManager, PreferenceChangeSubscriber { + + init { + preferenceChangeBroker.subscribe(this) + } private val configState: MutableStateFlow = MutableStateFlow(value = loadConfig()) private val mutex = Mutex() @@ -44,43 +52,49 @@ class DefaultInteractionSettingsPreferenceManager( private fun loadConfig(): InteractionSettings = InteractionSettings( useVolumeKeysForNavigation = storage.getBoolean( - KEY_USE_VOLUME_KEYS_FOR_NAVIGATION, + InteractionSettingKey.UseVolumeKeysForNavigation.value, INTERACTION_SETTINGS_DEFAULT_USE_VOLUME_KEYS_NAVIGATION, ), messageViewPostRemoveNavigation = storage.getStringOrDefault( - KEY_MESSAGE_VIEW_POST_DELETE_ACTION, + InteractionSettingKey.MessageViewPostDeleteAction.value, INTERACTION_SETTINGS_DEFAULT_MESSAGE_VIEW_POST_REMOVE_NAVIGATION, ), messageViewPostMarkAsUnreadNavigation = storage.getEnumOrDefault( - KEY_MESSAGE_VIEW_POST_MARK_AS_UNREAD_ACTION, + InteractionSettingKey.MessageViewPostMarkAsRead.value, INTERACTION_SETTINGS_DEFAULT_MESSAGE_VIEW_POST_MARK_AS_UNREAD_NAVIGATION, ), swipeActions = SwipeActions( leftAction = storage.getEnumOrDefault( - key = KEY_SWIPE_ACTION_LEFT, + key = InteractionSettingKey.SwipeActionLeft.value, default = INTERACTION_SETTINGS_DEFAULT_SWIPE_ACTION.leftAction, ), rightAction = storage.getEnumOrDefault( - key = KEY_SWIPE_ACTION_RIGHT, + key = InteractionSettingKey.SwipeActionRight.value, default = INTERACTION_SETTINGS_DEFAULT_SWIPE_ACTION.rightAction, ), ), - isConfirmDelete = storage.getBoolean(KEY_CONFIRM_DELETE, INTERACTION_SETTINGS_DEFAULT_CONFIRM_DELETE), + isConfirmDelete = storage.getBoolean( + InteractionSettingKey.ConfirmDelete.value, + INTERACTION_SETTINGS_DEFAULT_CONFIRM_DELETE, + ), isConfirmDeleteStarred = storage.getBoolean( - KEY_CONFIRM_DELETE_STARRED, + InteractionSettingKey.ConfirmDeleteStarred.value, INTERACTION_SETTINGS_DEFAULT_CONFIRM_DELETE_STARRED, ), isConfirmDeleteFromNotification = storage.getBoolean( - KEY_CONFIRM_DELETE_FROM_NOTIFICATION, + InteractionSettingKey.ConfirmDeleteFromNotification.value, INTERACTION_SETTINGS_DEFAULT_CONFIRM_DELETE_FROM_NOTIFICATION, ), - isConfirmSpam = storage.getBoolean(KEY_CONFIRM_SPAM, INTERACTION_SETTINGS_DEFAULT_CONFIRM_SPAM), + isConfirmSpam = storage.getBoolean( + InteractionSettingKey.ConfirmSpam.value, + INTERACTION_SETTINGS_DEFAULT_CONFIRM_SPAM, + ), isConfirmDiscardMessage = storage.getBoolean( - KEY_CONFIRM_DISCARD_MESSAGE, + InteractionSettingKey.ConfirmDiscardMessage.value, INTERACTION_SETTINGS_DEFAULT_CONFIRM_DISCARD_MESSAGE, ), isConfirmMarkAllRead = storage.getBoolean( - KEY_CONFIRM_MARK_ALL_READ, + InteractionSettingKey.ConfirmMarkAllRead.value, INTERACTION_SETTINGS_DEFAULT_CONFIRM_MARK_ALL_READ, ), ) @@ -89,24 +103,45 @@ class DefaultInteractionSettingsPreferenceManager( logger.debug(TAG) { "writeConfig() called with: config = $config" } scope.launch(ioDispatcher) { mutex.withLock { - storageEditor.putBoolean(KEY_USE_VOLUME_KEYS_FOR_NAVIGATION, config.useVolumeKeysForNavigation) - storageEditor.putString(KEY_MESSAGE_VIEW_POST_DELETE_ACTION, config.messageViewPostRemoveNavigation) + storageEditor.putBoolean( + InteractionSettingKey.UseVolumeKeysForNavigation.value, + config.useVolumeKeysForNavigation, + ) + storageEditor.putString( + InteractionSettingKey.MessageViewPostDeleteAction.value, + config.messageViewPostRemoveNavigation, + ) storageEditor.putEnum( - KEY_MESSAGE_VIEW_POST_MARK_AS_UNREAD_ACTION, + InteractionSettingKey.MessageViewPostMarkAsRead.value, config.messageViewPostMarkAsUnreadNavigation, ) - storageEditor.putEnum(KEY_SWIPE_ACTION_LEFT, config.swipeActions.leftAction) - storageEditor.putEnum(KEY_SWIPE_ACTION_RIGHT, config.swipeActions.rightAction) - storageEditor.putBoolean(KEY_CONFIRM_DELETE, config.isConfirmDelete) - storageEditor.putBoolean(KEY_CONFIRM_DISCARD_MESSAGE, config.isConfirmDiscardMessage) - storageEditor.putBoolean(KEY_CONFIRM_DELETE_STARRED, config.isConfirmDeleteStarred) - storageEditor.putBoolean(KEY_CONFIRM_SPAM, config.isConfirmSpam) - storageEditor.putBoolean(KEY_CONFIRM_DELETE_FROM_NOTIFICATION, config.isConfirmDeleteFromNotification) - storageEditor.putBoolean(KEY_CONFIRM_MARK_ALL_READ, config.isConfirmMarkAllRead) + storageEditor.putEnum(InteractionSettingKey.SwipeActionLeft.value, config.swipeActions.leftAction) + storageEditor.putEnum(InteractionSettingKey.SwipeActionRight.value, config.swipeActions.rightAction) + storageEditor.putBoolean(InteractionSettingKey.ConfirmDelete.value, config.isConfirmDelete) + storageEditor.putBoolean( + InteractionSettingKey.ConfirmDiscardMessage.value, + config.isConfirmDiscardMessage, + ) + storageEditor.putBoolean( + InteractionSettingKey.ConfirmDeleteStarred.value, + config.isConfirmDeleteStarred, + ) + storageEditor.putBoolean(InteractionSettingKey.ConfirmSpam.value, config.isConfirmSpam) + storageEditor.putBoolean( + InteractionSettingKey.ConfirmDeleteFromNotification.value, + config.isConfirmDeleteFromNotification, + ) + storageEditor.putBoolean(InteractionSettingKey.ConfirmMarkAllRead.value, config.isConfirmMarkAllRead) storageEditor.commit().also { commited -> logger.verbose(TAG) { "writeConfig: storageEditor.commit() resulted in: $commited" } } } } } + + override fun receive(scope: PreferenceScope) { + if (scope == PreferenceScope.ALL || scope == PreferenceScope.INTERACTION) { + configState.update { loadConfig() } + } + } } diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/network/DefaultNetworkSettingsPreferenceManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/network/DefaultNetworkSettingsPreferenceManager.kt index 2f47d06de08..473797f54ff 100644 --- a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/network/DefaultNetworkSettingsPreferenceManager.kt +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/network/DefaultNetworkSettingsPreferenceManager.kt @@ -11,6 +11,9 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import net.thunderbird.core.logging.Logger +import net.thunderbird.core.preference.PreferenceChangeBroker +import net.thunderbird.core.preference.PreferenceChangeSubscriber +import net.thunderbird.core.preference.PreferenceScope import net.thunderbird.core.preference.storage.Storage import net.thunderbird.core.preference.storage.StorageEditor import net.thunderbird.core.preference.storage.StoragePersister @@ -25,7 +28,12 @@ class DefaultNetworkSettingsPreferenceManager( private val storageEditor: StorageEditor, private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, private var scope: CoroutineScope = CoroutineScope(SupervisorJob()), -) : NetworkSettingsPreferenceManager { + preferenceChangeBroker: PreferenceChangeBroker, +) : NetworkSettingsPreferenceManager, PreferenceChangeSubscriber { + + init { + preferenceChangeBroker.subscribe(this) + } private val configState: MutableStateFlow = MutableStateFlow(value = loadConfig()) private val mutex = Mutex() private val storage: Storage @@ -41,18 +49,27 @@ class DefaultNetworkSettingsPreferenceManager( } private fun loadConfig(): NetworkSettings = NetworkSettings( - backgroundOps = storage.getEnumOrDefault(KEY_BG_OPS, NETWORK_SETTINGS_DEFAULT_BACKGROUND_OPS), + backgroundOps = storage.getEnumOrDefault( + NetworkSettingKey.BackgroundOperations.value, + NETWORK_SETTINGS_DEFAULT_BACKGROUND_OPS, + ), ) private fun writeConfig(config: NetworkSettings) { logger.debug(TAG) { "writeConfig() called with: config = $config" } scope.launch(ioDispatcher) { mutex.withLock { - storageEditor.putEnum(KEY_BG_OPS, config.backgroundOps) + storageEditor.putEnum(NetworkSettingKey.BackgroundOperations.value, config.backgroundOps) storageEditor.commit().also { commited -> logger.verbose(TAG) { "writeConfig: storageEditor.commit() resulted in: $commited" } } } } } + + override fun receive(scope: PreferenceScope) { + if (scope == PreferenceScope.ALL || scope == PreferenceScope.NETWORK) { + configState.update { loadConfig() } + } + } } diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/notification/DefaultNotificationPreferenceManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/notification/DefaultNotificationPreferenceManager.kt index 1d3d4201e20..c34d7bab422 100644 --- a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/notification/DefaultNotificationPreferenceManager.kt +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/notification/DefaultNotificationPreferenceManager.kt @@ -13,6 +13,9 @@ import kotlinx.coroutines.sync.withLock import net.thunderbird.core.common.notification.NotificationActionTokens import net.thunderbird.core.logging.Logger import net.thunderbird.core.preference.NotificationQuickDelete +import net.thunderbird.core.preference.PreferenceChangeBroker +import net.thunderbird.core.preference.PreferenceChangeSubscriber +import net.thunderbird.core.preference.PreferenceScope import net.thunderbird.core.preference.storage.Storage import net.thunderbird.core.preference.storage.StorageEditor import net.thunderbird.core.preference.storage.StoragePersister @@ -27,7 +30,12 @@ class DefaultNotificationPreferenceManager( private val storageEditor: StorageEditor, private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, private var scope: CoroutineScope = CoroutineScope(SupervisorJob()), -) : NotificationPreferenceManager { + preferenceChangeBroker: PreferenceChangeBroker, +) : NotificationPreferenceManager, PreferenceChangeSubscriber { + + init { + preferenceChangeBroker.subscribe(this) + } private val mutex = Mutex() private val storage: Storage get() = storagePersister.loadValues() @@ -39,7 +47,7 @@ class DefaultNotificationPreferenceManager( private fun getConfigFromStorage(storage: Storage): NotificationPreference { val notificationQuickDeleteBehaviour = storage.getEnumOrDefault( - key = KEY_NOTIFICATION_QUICK_DELETE_BEHAVIOUR, + key = NotificationSettingKey.NotificationQuickDeleteBehaviour.value, default = NOTIFICATION_PREFERENCE_DEFAULT_QUICK_DELETE_BEHAVIOUR, ) val isSummaryDeleteActionEnabled = resolveSummaryDeleteActionEnabled( @@ -49,37 +57,37 @@ class DefaultNotificationPreferenceManager( return NotificationPreference( isQuietTimeEnabled = storage.getBoolean( - key = KEY_QUIET_TIME_ENABLED, + key = NotificationSettingKey.QuietTimeEnabled.value, defValue = NOTIFICATION_PREFERENCE_DEFAULT_IS_QUIET_TIME_ENABLED, ), quietTimeStarts = storage.getStringOrDefault( - key = KEY_QUIET_TIME_STARTS, + key = NotificationSettingKey.QuietTimeStarts.value, defValue = NOTIFICATION_PREFERENCE_DEFAULT_QUIET_TIME_STARTS, ), quietTimeEnds = storage.getStringOrDefault( - key = KEY_QUIET_TIME_ENDS, + key = NotificationSettingKey.QuietTimeEnds.value, defValue = NOTIFICATION_PREFERENCE_DEFAULT_QUIET_TIME_END, ), isNotificationDuringQuietTimeEnabled = storage.getBoolean( - key = KEY_NOTIFICATION_DURING_QUIET_TIME_ENABLED, + key = NotificationSettingKey.NotificationDuringQuietTimeEnabled.value, defValue = NOTIFICATION_PREFERENCE_DEFAULT_IS_NOTIFICATION_DURING_QUIET_TIME_ENABLED, ), messageActionsOrder = NotificationActionTokens.parseOrder( storage.getStringOrDefault( - key = KEY_MESSAGE_ACTIONS_ORDER, + key = NotificationSettingKey.MessageActionsOrder.value, defValue = NotificationActionTokens.serializeOrder( NOTIFICATION_PREFERENCE_DEFAULT_MESSAGE_ACTIONS_ORDER, ), ), ), messageActionsCutoff = storage.getInt( - key = KEY_MESSAGE_ACTIONS_CUTOFF, + key = NotificationSettingKey.MessageActionsCutoff.value, defValue = NOTIFICATION_PREFERENCE_DEFAULT_MESSAGE_ACTIONS_CUTOFF, ), isSummaryDeleteActionEnabled = isSummaryDeleteActionEnabled, notificationQuickDeleteBehaviour = notificationQuickDeleteBehaviour, lockScreenNotificationVisibility = storage.getEnumOrDefault( - key = KEY_LOCK_SCREEN_NOTIFICATION_VISIBILITY, + key = NotificationSettingKey.LockScreenNotificationVisibility.value, default = NOTIFICATION_PREFERENCE_DEFAULT_LOCK_SCREEN_NOTIFICATION_VISIBILITY, ), ) @@ -89,14 +97,14 @@ class DefaultNotificationPreferenceManager( storage: Storage, quickDeleteBehaviour: NotificationQuickDelete, ): Boolean { - return if (storage.contains(KEY_IS_SUMMARY_DELETE_ACTION_ENABLED)) { + return if (storage.contains(NotificationSettingKey.IsSummaryDeleteActionEnabled.value)) { storage.getBoolean( - key = KEY_IS_SUMMARY_DELETE_ACTION_ENABLED, + key = NotificationSettingKey.IsSummaryDeleteActionEnabled.value, defValue = NOTIFICATION_PREFERENCE_DEFAULT_IS_SUMMARY_DELETE_ACTION_ENABLED, ) } else { val derivedValue = quickDeleteBehaviour == NotificationQuickDelete.ALWAYS - storageEditor.putBoolean(KEY_IS_SUMMARY_DELETE_ACTION_ENABLED, derivedValue) + storageEditor.putBoolean(NotificationSettingKey.IsSummaryDeleteActionEnabled.value, derivedValue) storageEditor.commit() derivedValue } @@ -109,28 +117,31 @@ class DefaultNotificationPreferenceManager( logger.debug(TAG) { "writeConfig() called with: config = $config" } scope.launch(ioDispatcher) { mutex.withLock { - storageEditor.putString(KEY_QUIET_TIME_ENDS, config.quietTimeEnds) - storageEditor.putString(KEY_QUIET_TIME_STARTS, config.quietTimeStarts) + storageEditor.putString(NotificationSettingKey.QuietTimeEnds.value, config.quietTimeEnds) + storageEditor.putString(NotificationSettingKey.QuietTimeStarts.value, config.quietTimeStarts) storageEditor.putBoolean( - KEY_QUIET_TIME_ENABLED, + NotificationSettingKey.QuietTimeEnabled.value, config.isQuietTimeEnabled, ) storageEditor.putBoolean( - KEY_NOTIFICATION_DURING_QUIET_TIME_ENABLED, + NotificationSettingKey.NotificationDuringQuietTimeEnabled.value, config.isNotificationDuringQuietTimeEnabled, ) storageEditor.putString( - KEY_MESSAGE_ACTIONS_ORDER, + NotificationSettingKey.MessageActionsOrder.value, NotificationActionTokens.serializeOrder(config.messageActionsOrder), ) - storageEditor.putInt(KEY_MESSAGE_ACTIONS_CUTOFF, config.messageActionsCutoff) - storageEditor.putBoolean(KEY_IS_SUMMARY_DELETE_ACTION_ENABLED, config.isSummaryDeleteActionEnabled) + storageEditor.putInt(NotificationSettingKey.MessageActionsCutoff.value, config.messageActionsCutoff) + storageEditor.putBoolean( + NotificationSettingKey.IsSummaryDeleteActionEnabled.value, + config.isSummaryDeleteActionEnabled, + ) storageEditor.putEnum( - KEY_NOTIFICATION_QUICK_DELETE_BEHAVIOUR, + NotificationSettingKey.NotificationQuickDeleteBehaviour.value, config.notificationQuickDeleteBehaviour, ) storageEditor.putEnum( - KEY_LOCK_SCREEN_NOTIFICATION_VISIBILITY, + NotificationSettingKey.LockScreenNotificationVisibility.value, config.lockScreenNotificationVisibility, ) storageEditor.commit().also { commited -> @@ -140,4 +151,10 @@ class DefaultNotificationPreferenceManager( configState.update { config } } } + + override fun receive(scope: PreferenceScope) { + if (scope == PreferenceScope.ALL || scope == PreferenceScope.NOTIFICATION) { + configState.update { getConfigFromStorage(storage) } + } + } } diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/DefaultPrivacySettingsPreferenceManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/DefaultPrivacySettingsPreferenceManager.kt index 51bbcd0c568..9dd126d910f 100644 --- a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/DefaultPrivacySettingsPreferenceManager.kt +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/DefaultPrivacySettingsPreferenceManager.kt @@ -11,6 +11,9 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import net.thunderbird.core.logging.Logger +import net.thunderbird.core.preference.PreferenceChangeBroker +import net.thunderbird.core.preference.PreferenceChangeSubscriber +import net.thunderbird.core.preference.PreferenceScope import net.thunderbird.core.preference.storage.Storage import net.thunderbird.core.preference.storage.StorageEditor import net.thunderbird.core.preference.storage.StoragePersister @@ -23,7 +26,12 @@ class DefaultPrivacySettingsPreferenceManager( private val storageEditor: StorageEditor, private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, private var scope: CoroutineScope = CoroutineScope(SupervisorJob()), -) : PrivacySettingsPreferenceManager { + preferenceChangeBroker: PreferenceChangeBroker, +) : PrivacySettingsPreferenceManager, PreferenceChangeSubscriber { + + init { + preferenceChangeBroker.subscribe(this) + } private val configState: MutableStateFlow = MutableStateFlow(value = loadConfig()) private val mutex = Mutex() private val storage: Storage @@ -40,11 +48,11 @@ class DefaultPrivacySettingsPreferenceManager( private fun loadConfig(): PrivacySettings = PrivacySettings( isHideTimeZone = storage.getBoolean( - key = KEY_HIDE_TIME_ZONE, + key = PrivacySettingKey.HideTimeZone.value, defValue = PRIVACY_SETTINGS_DEFAULT_HIDE_TIME_ZONE, ), isHideUserAgent = storage.getBoolean( - key = KEY_HIDE_USER_AGENT, + key = PrivacySettingKey.HideUserAgent.value, defValue = PRIVACY_SETTINGS_DEFAULT_HIDE_USER_AGENT, ), ) @@ -53,12 +61,18 @@ class DefaultPrivacySettingsPreferenceManager( logger.debug(TAG) { "writeConfig() called with: config = $config" } scope.launch(ioDispatcher) { mutex.withLock { - storageEditor.putBoolean(KEY_HIDE_TIME_ZONE, config.isHideTimeZone) - storageEditor.putBoolean(KEY_HIDE_USER_AGENT, config.isHideUserAgent) + storageEditor.putBoolean(PrivacySettingKey.HideTimeZone.value, config.isHideTimeZone) + storageEditor.putBoolean(PrivacySettingKey.HideUserAgent.value, config.isHideUserAgent) storageEditor.commit().also { commited -> logger.verbose(TAG) { "writeConfig: storageEditor.commit() resulted in: $commited" } } } } } + + override fun receive(scope: PreferenceScope) { + if (scope == PreferenceScope.ALL || scope == PreferenceScope.PRIVACY) { + configState.update { loadConfig() } + } + } } diff --git a/core/preference/impl/src/commonTest/kotlin/net/thunderbird/core/preference/DefaultPreferenceChangeBrokerTest.kt b/core/preference/impl/src/commonTest/kotlin/net/thunderbird/core/preference/DefaultPreferenceChangeBrokerTest.kt index e75a1568e15..6884141005d 100644 --- a/core/preference/impl/src/commonTest/kotlin/net/thunderbird/core/preference/DefaultPreferenceChangeBrokerTest.kt +++ b/core/preference/impl/src/commonTest/kotlin/net/thunderbird/core/preference/DefaultPreferenceChangeBrokerTest.kt @@ -46,4 +46,59 @@ class DefaultPreferenceChangeBrokerTest { assertThat(received).isEqualTo(true) assertThat(receivedOther).isEqualTo(true) } + + @Test + fun `publish should notify subscribers with correct scope`() { + var receivedScope: PreferenceScope? = null + + val subscriber = PreferenceChangeSubscriber { scope -> + receivedScope = scope + } + + val broker = DefaultPreferenceChangeBroker(mutableSetOf(subscriber)) + + broker.publish(PreferenceScope.NOTIFICATION) + + assertThat(receivedScope).isEqualTo(PreferenceScope.NOTIFICATION) + } + + @Test + fun `subscribe should not duplicate subscriber`() { + val subscriber = PreferenceChangeSubscriber { } + val subscribers = mutableSetOf() + val broker = DefaultPreferenceChangeBroker(subscribers) + + broker.subscribe(subscriber) + broker.subscribe(subscriber) + + assertThat(subscribers.size).isEqualTo(1) + } + + @Test + fun `unsubscribe should not fail if subscriber not present`() { + val subscriber = PreferenceChangeSubscriber { } + val broker = DefaultPreferenceChangeBroker(mutableSetOf()) + + broker.unsubscribe(subscriber) + + assertThat(true).isEqualTo(true) + } + + @Test + fun `publish should handle subscriber removal during iteration`() { + val subscribers = mutableSetOf() + + lateinit var subscriber: PreferenceChangeSubscriber + subscriber = PreferenceChangeSubscriber { + subscribers.remove(subscriber) + } + + subscribers.add(subscriber) + + val broker = DefaultPreferenceChangeBroker(subscribers) + + broker.publish() + + assertThat(true).isEqualTo(true) + } } diff --git a/feature/mail/message/list/internal/src/test/kotlin/net/thunderbird/feature/mail/message/list/internal/domain/usecase/BuildSwipeActionsTest.kt b/feature/mail/message/list/internal/src/test/kotlin/net/thunderbird/feature/mail/message/list/internal/domain/usecase/BuildSwipeActionsTest.kt index f490dd0c09d..e3024a88a8e 100644 --- a/feature/mail/message/list/internal/src/test/kotlin/net/thunderbird/feature/mail/message/list/internal/domain/usecase/BuildSwipeActionsTest.kt +++ b/feature/mail/message/list/internal/src/test/kotlin/net/thunderbird/feature/mail/message/list/internal/domain/usecase/BuildSwipeActionsTest.kt @@ -21,8 +21,7 @@ import net.thunderbird.core.common.mail.Protocols import net.thunderbird.core.preference.GeneralSettings import net.thunderbird.core.preference.GeneralSettingsManager import net.thunderbird.core.preference.display.DisplaySettings -import net.thunderbird.core.preference.interaction.KEY_SWIPE_ACTION_LEFT -import net.thunderbird.core.preference.interaction.KEY_SWIPE_ACTION_RIGHT +import net.thunderbird.core.preference.interaction.InteractionSettingKey import net.thunderbird.core.preference.network.NetworkSettings import net.thunderbird.core.preference.notification.NotificationPreference import net.thunderbird.core.preference.privacy.PrivacySettings @@ -120,7 +119,7 @@ class BuildSwipeActionsTest { val testSubject = createTestSubject( accountsIds = ids, storageValues = mapOf( - KEY_SWIPE_ACTION_LEFT to SwipeAction.None, + InteractionSettingKey.SwipeActionLeft.value to SwipeAction.None, ), ) @@ -150,7 +149,7 @@ class BuildSwipeActionsTest { val testSubject = createTestSubject( accountsIds = ids, storageValues = mapOf( - KEY_SWIPE_ACTION_RIGHT to SwipeAction.Delete, + InteractionSettingKey.SwipeActionRight.value to SwipeAction.Delete, ), ) @@ -179,8 +178,8 @@ class BuildSwipeActionsTest { val testSubject = createTestSubject( accounts = listOf(FakeLegacyAccount(id = id, archiveFolderId = 123)), storageValues = mapOf( - KEY_SWIPE_ACTION_LEFT to SwipeAction.Archive, - KEY_SWIPE_ACTION_RIGHT to SwipeAction.Archive, + InteractionSettingKey.SwipeActionLeft.value to SwipeAction.Archive, + InteractionSettingKey.SwipeActionRight.value to SwipeAction.Archive, ), ) @@ -209,8 +208,8 @@ class BuildSwipeActionsTest { val testSubject = createTestSubject( accounts = listOf(FakeLegacyAccount(id = id, incomingServerType = Protocols.POP3)), storageValues = mapOf( - KEY_SWIPE_ACTION_LEFT to SwipeAction.Archive, - KEY_SWIPE_ACTION_RIGHT to SwipeAction.Archive, + InteractionSettingKey.SwipeActionLeft.value to SwipeAction.Archive, + InteractionSettingKey.SwipeActionRight.value to SwipeAction.Archive, ), ) @@ -247,8 +246,8 @@ class BuildSwipeActionsTest { ), accountsIds = ids, storageValues = mapOf( - KEY_SWIPE_ACTION_LEFT to SwipeAction.Archive, - KEY_SWIPE_ACTION_RIGHT to SwipeAction.Archive, + InteractionSettingKey.SwipeActionLeft.value to SwipeAction.Archive, + InteractionSettingKey.SwipeActionRight.value to SwipeAction.Archive, ), ) @@ -290,8 +289,8 @@ class BuildSwipeActionsTest { ), accounts = accounts, storageValues = mapOf( - KEY_SWIPE_ACTION_LEFT to SwipeAction.Archive, - KEY_SWIPE_ACTION_RIGHT to SwipeAction.Archive, + InteractionSettingKey.SwipeActionLeft.value to SwipeAction.Archive, + InteractionSettingKey.SwipeActionRight.value to SwipeAction.Archive, ), ) @@ -342,14 +341,19 @@ class BuildSwipeActionsTest { generalSettingsManager = FakeGeneralSettingsManager( initialGeneralSettings.let { settings -> if (storageValues.isNotEmpty() && - (KEY_SWIPE_ACTION_LEFT in storageValues || KEY_SWIPE_ACTION_RIGHT in storageValues) + ( + InteractionSettingKey.SwipeActionLeft.value in storageValues || + InteractionSettingKey.SwipeActionRight.value in storageValues + ) ) { val swipeActions = settings.interaction.swipeActions settings.copy( interaction = settings.interaction.copy( swipeActions = swipeActions.copy( - leftAction = storageValues[KEY_SWIPE_ACTION_LEFT] ?: swipeActions.leftAction, - rightAction = storageValues[KEY_SWIPE_ACTION_RIGHT] ?: swipeActions.rightAction, + leftAction = storageValues[InteractionSettingKey.SwipeActionLeft.value] + ?: swipeActions.leftAction, + rightAction = storageValues[InteractionSettingKey.SwipeActionRight.value] + ?: swipeActions.rightAction, ), ), ) diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsWriter.kt b/legacy/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsWriter.kt index 233aed69f4a..2251ea7d334 100644 --- a/legacy/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsWriter.kt +++ b/legacy/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsWriter.kt @@ -2,12 +2,15 @@ package com.fsck.k9.preferences import com.fsck.k9.Preferences import net.thunderbird.core.logging.legacy.Log +import net.thunderbird.core.preference.PreferenceChangePublisher +import net.thunderbird.core.preference.getPreferenceScope import net.thunderbird.core.preference.storage.StorageEditor import net.thunderbird.feature.account.storage.legacy.LegacyAccountStorageHandler internal class GeneralSettingsWriter( private val preferences: Preferences, private val generalSettingsManager: DefaultGeneralSettingsManager, + private val changePublisher: PreferenceChangePublisher, ) { fun write(settings: InternalSettingsMap): Boolean { // Convert general settings to the string representation used in preference storage @@ -32,6 +35,10 @@ internal class GeneralSettingsWriter( Log.v("Committed general settings to the preference storage.") generalSettingsManager.loadSettings() + mergedSettings.keys.forEach { + val preferenceScope = getPreferenceScope(it) + changePublisher.publish(scope = preferenceScope) + } true } else { diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt b/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt index 98f93394e8d..a7ae38c22f9 100644 --- a/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt +++ b/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt @@ -54,6 +54,7 @@ val preferencesModule = module { logger = get(), storagePersister = get(), storageEditor = get().createStorageEditor(), + preferenceChangeBroker = get(), ) } single { @@ -61,6 +62,7 @@ val preferencesModule = module { logger = get(), storagePersister = get(), storageEditor = get().createStorageEditor(), + preferenceChangeBroker = get(), ) } single { @@ -68,6 +70,7 @@ val preferencesModule = module { logger = get(), storagePersister = get(), storageEditor = get().createStorageEditor(), + preferenceChangeBroker = get(), ) } single { @@ -75,6 +78,7 @@ val preferencesModule = module { logger = get(), storagePersister = get(), storageEditor = get().createStorageEditor(), + preferenceChangeBroker = get(), ) } single { @@ -91,6 +95,7 @@ val preferencesModule = module { logger = get(), storagePersister = get(), storageEditor = get().createStorageEditor(), + preferenceChangeBroker = get(), ) } single { @@ -98,6 +103,7 @@ val preferencesModule = module { logger = get(), storagePersister = get(), storageEditor = get().createStorageEditor(), + preferenceChangeBroker = get(), ) } single { @@ -114,6 +120,7 @@ val preferencesModule = module { logger = get(), storage = get(), storageEditor = get(), + preferenceChangeBroker = get(), ) } single { @@ -121,6 +128,7 @@ val preferencesModule = module { logger = get(), storagePersister = get(), storageEditor = get().createStorageEditor(), + preferenceChangeBroker = get(), ) } single { @@ -130,6 +138,7 @@ val preferencesModule = module { storageEditor = get().createStorageEditor(), logLevelManager = get(), platformConfigProvider = get(), + preferenceChangeBroker = get(), ) } single { @@ -175,7 +184,13 @@ val preferencesModule = module { factory { GeneralSettingsValidator() } factory { GeneralSettingsUpgrader() } - factory { GeneralSettingsWriter(preferences = get(), generalSettingsManager = get()) } + factory { + GeneralSettingsWriter( + preferences = get(), + generalSettingsManager = get(), + changePublisher = get(), + ) + } factory { AccountSettingsValidator() }