Repo created
This commit is contained in:
parent
75dc487a7a
commit
39c29d175b
6317 changed files with 388324 additions and 2 deletions
10
core/preference/api/build.gradle.kts
Normal file
10
core/preference/api/build.gradle.kts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
plugins {
|
||||
id(ThunderbirdPlugins.Library.kmp)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "net.thunderbird.core.preference"
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package net.thunderbird.core.preference.debugging
|
||||
|
||||
import net.thunderbird.core.preference.BuildConfig
|
||||
|
||||
actual val isDebug: Boolean = BuildConfig.DEBUG
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package net.thunderbird.core.preference
|
||||
|
||||
import net.thunderbird.core.preference.debugging.DebuggingSettings
|
||||
import net.thunderbird.core.preference.display.DisplaySettings
|
||||
import net.thunderbird.core.preference.network.NetworkSettings
|
||||
import net.thunderbird.core.preference.notification.NotificationPreference
|
||||
import net.thunderbird.core.preference.privacy.PrivacySettings
|
||||
|
||||
/**
|
||||
* Stores a snapshot of the app's general settings.
|
||||
*
|
||||
* When adding a setting here, make sure to also add it in these places:
|
||||
* - [GeneralSettingsManager] (write function)
|
||||
* - [GeneralSettingsDescriptions]
|
||||
*/
|
||||
// TODO: Move over settings from K9
|
||||
data class GeneralSettings(
|
||||
val network: NetworkSettings = NetworkSettings(),
|
||||
val notification: NotificationPreference = NotificationPreference(),
|
||||
val display: DisplaySettings = DisplaySettings(),
|
||||
val privacy: PrivacySettings = PrivacySettings(),
|
||||
val debugging: DebuggingSettings = DebuggingSettings(),
|
||||
)
|
||||
|
||||
enum class BackgroundSync {
|
||||
ALWAYS,
|
||||
NEVER,
|
||||
FOLLOW_SYSTEM_AUTO_SYNC,
|
||||
}
|
||||
|
||||
enum class AppTheme {
|
||||
LIGHT,
|
||||
DARK,
|
||||
FOLLOW_SYSTEM,
|
||||
}
|
||||
|
||||
enum class SubTheme {
|
||||
LIGHT,
|
||||
DARK,
|
||||
USE_GLOBAL,
|
||||
}
|
||||
|
||||
enum class BackgroundOps {
|
||||
ALWAYS,
|
||||
NEVER,
|
||||
WHEN_CHECKED_AUTO_SYNC,
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls when to use the message list split view.
|
||||
*/
|
||||
enum class SplitViewMode {
|
||||
ALWAYS,
|
||||
NEVER,
|
||||
WHEN_IN_LANDSCAPE,
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.thunderbird.core.preference
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Retrieve and modify general settings.
|
||||
*
|
||||
*/
|
||||
interface GeneralSettingsManager : PreferenceManager<GeneralSettings> {
|
||||
@Deprecated(
|
||||
message = "Use PreferenceManager<GeneralSettings>.getConfig() instead",
|
||||
replaceWith = ReplaceWith(
|
||||
expression = "getConfig()",
|
||||
),
|
||||
)
|
||||
fun getSettings(): GeneralSettings
|
||||
|
||||
@Deprecated(
|
||||
message = "Use PreferenceManager<GeneralSettings>.getConfigFlow() instead",
|
||||
replaceWith = ReplaceWith(
|
||||
expression = "getConfigFlow()",
|
||||
),
|
||||
)
|
||||
fun getSettingsFlow(): Flow<GeneralSettings>
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package net.thunderbird.core.preference
|
||||
|
||||
/**
|
||||
* Broker to manage subscribers and notify them about changes in the preferences, when the
|
||||
* [PreferenceChangePublisher] publishes a change.
|
||||
*/
|
||||
interface PreferenceChangeBroker {
|
||||
|
||||
/**
|
||||
* Subscribe to preference changes.
|
||||
*
|
||||
* @param subscriber The subscriber to be notified about preference changes.
|
||||
*/
|
||||
fun subscribe(subscriber: PreferenceChangeSubscriber)
|
||||
|
||||
/**
|
||||
* Unsubscribe from preference changes.
|
||||
*
|
||||
* @param subscriber The subscriber that no longer wants to be notified about preference changes.
|
||||
*/
|
||||
fun unsubscribe(subscriber: PreferenceChangeSubscriber)
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package net.thunderbird.core.preference
|
||||
|
||||
/**
|
||||
* Publishes changes of preferences to all subscribers.
|
||||
*/
|
||||
interface PreferenceChangePublisher {
|
||||
|
||||
/**
|
||||
* Publish a change in the preferences.
|
||||
*/
|
||||
fun publish()
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package net.thunderbird.core.preference
|
||||
|
||||
/**
|
||||
* Subscribe to be notified about changes in the preferences.
|
||||
*/
|
||||
fun interface PreferenceChangeSubscriber {
|
||||
|
||||
/**
|
||||
* Called when preferences change.
|
||||
*/
|
||||
fun receive()
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package net.thunderbird.core.preference
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Interface for managing preferences of a specific type.
|
||||
*
|
||||
* This interface provides methods to save, retrieve, and observe changes to a configuration object.
|
||||
*
|
||||
* @param T The type of the configuration object being managed.
|
||||
*/
|
||||
interface PreferenceManager<T> {
|
||||
/**
|
||||
* Saves the given configuration.
|
||||
*
|
||||
* @param config The configuration of type [T] to be saved.
|
||||
*/
|
||||
fun save(config: T)
|
||||
|
||||
/**
|
||||
* Retrieves a snapshot of the current configuration.
|
||||
*
|
||||
* **Note:** This function provides a one-time snapshot of the configuration.
|
||||
* For observing configuration changes reactively, it is recommended to use [getConfigFlow] instead.
|
||||
*
|
||||
* @return The current configuration of type [T].
|
||||
*/
|
||||
fun getConfig(): T
|
||||
|
||||
/**
|
||||
* Returns a [Flow] that emits the configuration whenever it changes.
|
||||
*
|
||||
* This allows observing changes to the configuration in a reactive way.
|
||||
*
|
||||
* @return A [Flow] of [T] representing the configuration.
|
||||
*/
|
||||
fun getConfigFlow(): Flow<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the configuration by applying the given [updater] function to the current configuration.
|
||||
*
|
||||
* This function is an inline extension function for [PreferenceManager].
|
||||
* It retrieves the current configuration, applies the [updater] function to it,
|
||||
* and then saves the updated configuration.
|
||||
*
|
||||
* @param T The type of the configuration.
|
||||
* @param updater A lambda function that takes the current configuration of type [T]
|
||||
* and returns the updated configuration of type [T].
|
||||
*/
|
||||
inline fun <reified T> PreferenceManager<T>.update(updater: (T) -> T) {
|
||||
val config = getConfig()
|
||||
save(updater(config))
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package net.thunderbird.core.preference.debugging
|
||||
|
||||
expect val isDebug: Boolean
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package net.thunderbird.core.preference.debugging
|
||||
|
||||
const val DEBUGGING_SETTINGS_DEFAULT_IS_SYNC_LOGGING_ENABLED = false
|
||||
val DEBUGGING_SETTINGS_DEFAULT_IS_DEBUGGING_LOGGING_ENABLED = isDebug
|
||||
|
||||
data class DebuggingSettings(
|
||||
val isDebugLoggingEnabled: Boolean = DEBUGGING_SETTINGS_DEFAULT_IS_DEBUGGING_LOGGING_ENABLED,
|
||||
val isSyncLoggingEnabled: Boolean = DEBUGGING_SETTINGS_DEFAULT_IS_SYNC_LOGGING_ENABLED,
|
||||
)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
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"
|
||||
|
||||
interface DebuggingSettingsPreferenceManager : PreferenceManager<DebuggingSettings>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package net.thunderbird.core.preference.display
|
||||
|
||||
import net.thunderbird.core.preference.display.coreSettings.DisplayCoreSettings
|
||||
import net.thunderbird.core.preference.display.inboxSettings.DisplayInboxSettings
|
||||
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_SHOW_ANIMATION = true
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_SHOW_CORRESPONDENT_NAMES = true
|
||||
const val DISPLAY_SETTINGS_DEFAULT_SHOW_RECENT_CHANGES = true
|
||||
const val DISPLAY_SETTINGS_DEFAULT_SHOULD_SHOW_SETUP_ARCHIVE_FOLDER_DIALOG = true
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_SHOW_CONTACT_NAME = false
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_SHOW_CONTACT_PICTURE = true
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_CHANGE_CONTACT_NAME_COLOR = true
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_COLORIZE_MISSING_CONTACT_PICTURE = false
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_USE_BACKGROUND_AS_INDICATOR = false
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_USE_MESSAGE_VIEW_FIXED_WIDTH_FONT = false
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_AUTO_FIT_WIDTH = true
|
||||
|
||||
data class DisplaySettings(
|
||||
val coreSettings: DisplayCoreSettings = DisplayCoreSettings(),
|
||||
val inboxSettings: DisplayInboxSettings = DisplayInboxSettings(),
|
||||
val isShowAnimations: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_SHOW_ANIMATION,
|
||||
val isShowCorrespondentNames: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_SHOW_CORRESPONDENT_NAMES,
|
||||
val showRecentChanges: Boolean = DISPLAY_SETTINGS_DEFAULT_SHOW_RECENT_CHANGES,
|
||||
val shouldShowSetupArchiveFolderDialog: Boolean = DISPLAY_SETTINGS_DEFAULT_SHOULD_SHOW_SETUP_ARCHIVE_FOLDER_DIALOG,
|
||||
val isShowContactName: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_SHOW_CONTACT_NAME,
|
||||
val isShowContactPicture: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_SHOW_CONTACT_PICTURE,
|
||||
val isChangeContactNameColor: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_CHANGE_CONTACT_NAME_COLOR,
|
||||
val isColorizeMissingContactPictures: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_COLORIZE_MISSING_CONTACT_PICTURE,
|
||||
val isUseBackgroundAsUnreadIndicator: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_USE_BACKGROUND_AS_INDICATOR,
|
||||
val isUseMessageViewFixedWidthFont: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_USE_MESSAGE_VIEW_FIXED_WIDTH_FONT,
|
||||
val isAutoFitWidth: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_AUTO_FIT_WIDTH,
|
||||
)
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package net.thunderbird.core.preference.display
|
||||
|
||||
import net.thunderbird.core.preference.PreferenceManager
|
||||
|
||||
const val KEY_SHOW_CONTACT_NAME = "showContactName"
|
||||
const val KEY_SHOW_CORRESPONDENT_NAMES = "showCorrespondentNames"
|
||||
const val KEY_SHOW_RECENT_CHANGES = "showRecentChanges"
|
||||
const val KEY_THEME = "theme"
|
||||
const val KEY_ANIMATION = "animations"
|
||||
const val KEY_SHOULD_SHOW_SETUP_ARCHIVE_FOLDER_DIALOG = "shouldShowSetupArchiveFolderDialog"
|
||||
const val KEY_CHANGE_REGISTERED_NAME_COLOR = "changeRegisteredNameColor"
|
||||
const val KEY_COLORIZE_MISSING_CONTACT_PICTURE = "colorizeMissingContactPictures"
|
||||
const val KEY_USE_BACKGROUND_AS_UNREAD_INDICATOR = "isUseBackgroundAsUnreadIndicator"
|
||||
const val KEY_MESSAGE_VIEW_FIXED_WIDTH_FONT = "messageViewFixedWidthFont"
|
||||
const val KEY_AUTO_FIT_WIDTH = "autofitWidth"
|
||||
const val KEY_SHOW_CONTACT_PICTURE = "showContactPicture"
|
||||
|
||||
interface DisplaySettingsPreferenceManager : PreferenceManager<DisplaySettings>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package net.thunderbird.core.preference.display.coreSettings
|
||||
|
||||
import net.thunderbird.core.preference.AppTheme
|
||||
import net.thunderbird.core.preference.SplitViewMode
|
||||
import net.thunderbird.core.preference.SubTheme
|
||||
|
||||
const val DISPLAY_SETTINGS_DEFAULT_APP_LANGUAGE = ""
|
||||
const val DISPLAY_SETTINGS_DEFAULT_FIXED_MESSAGE_VIEW_THEME = true
|
||||
val DISPLAY_SETTINGS_DEFAULT_APP_THEME = AppTheme.FOLLOW_SYSTEM
|
||||
val DISPLAY_SETTINGS_DEFAULT_MESSAGE_COMPOSE_THEME = SubTheme.USE_GLOBAL
|
||||
val DISPLAY_SETTINGS_DEFAULT_SPLIT_VIEW_MODE = SplitViewMode.NEVER
|
||||
val DISPLAY_SETTINGS_DEFAULT_MESSAGE_VIEW_THEME = SubTheme.USE_GLOBAL
|
||||
data class DisplayCoreSettings(
|
||||
val fixedMessageViewTheme: Boolean = DISPLAY_SETTINGS_DEFAULT_FIXED_MESSAGE_VIEW_THEME,
|
||||
val appTheme: AppTheme = DISPLAY_SETTINGS_DEFAULT_APP_THEME,
|
||||
val messageViewTheme: SubTheme = DISPLAY_SETTINGS_DEFAULT_MESSAGE_VIEW_THEME,
|
||||
val messageComposeTheme: SubTheme = DISPLAY_SETTINGS_DEFAULT_MESSAGE_COMPOSE_THEME,
|
||||
val appLanguage: String = DISPLAY_SETTINGS_DEFAULT_APP_LANGUAGE,
|
||||
val splitViewMode: SplitViewMode = DISPLAY_SETTINGS_DEFAULT_SPLIT_VIEW_MODE,
|
||||
)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
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"
|
||||
|
||||
interface DisplayCoreSettingsPreferenceManager : PreferenceManager<DisplayCoreSettings>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package net.thunderbird.core.preference.display.inboxSettings
|
||||
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_SHOW_UNIFIED_INBOX = false
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_SHOW_STAR_COUNT = false
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_SHOW_MESSAGE_LIST_STAR = true
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_MESSAGE_LIST_SENDER_ABOVE_SUBJECT = false
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_SHOW_COMPOSE_BUTTON_ON_MESSAGE_LIST = true
|
||||
const val DISPLAY_SETTINGS_DEFAULT_IS_THREAD_VIEW_ENABLED = true
|
||||
|
||||
data class DisplayInboxSettings(
|
||||
val isShowUnifiedInbox: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_SHOW_UNIFIED_INBOX,
|
||||
val isShowStarredCount: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_SHOW_STAR_COUNT,
|
||||
val isShowMessageListStars: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_SHOW_MESSAGE_LIST_STAR,
|
||||
val isMessageListSenderAboveSubject: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_MESSAGE_LIST_SENDER_ABOVE_SUBJECT,
|
||||
val isShowComposeButtonOnMessageList: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_SHOW_COMPOSE_BUTTON_ON_MESSAGE_LIST,
|
||||
val isThreadedViewEnabled: Boolean = DISPLAY_SETTINGS_DEFAULT_IS_THREAD_VIEW_ENABLED,
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
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"
|
||||
|
||||
interface DisplayInboxSettingsPreferenceManager : PreferenceManager<DisplayInboxSettings>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package net.thunderbird.core.preference.network
|
||||
|
||||
import net.thunderbird.core.preference.BackgroundOps
|
||||
|
||||
val NETWORK_SETTINGS_DEFAULT_BACKGROUND_OPS = BackgroundOps.ALWAYS
|
||||
|
||||
data class NetworkSettings(
|
||||
val backgroundOps: BackgroundOps = NETWORK_SETTINGS_DEFAULT_BACKGROUND_OPS,
|
||||
)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package net.thunderbird.core.preference.network
|
||||
|
||||
import net.thunderbird.core.preference.PreferenceManager
|
||||
|
||||
const val KEY_BG_OPS = "backgroundOperations"
|
||||
|
||||
interface NetworkSettingsPreferenceManager : PreferenceManager<NetworkSettings>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package net.thunderbird.core.preference.notification
|
||||
|
||||
const val NOTIFICATION_PREFERENCE_DEFAULT_IS_QUIET_TIME_ENABLED = false
|
||||
const val NOTIFICATION_PREFERENCE_DEFAULT_QUIET_TIME_STARTS = "21:00"
|
||||
const val NOTIFICATION_PREFERENCE_DEFAULT_QUIET_TIME_END = "7:00"
|
||||
|
||||
data class NotificationPreference(
|
||||
val isQuietTimeEnabled: Boolean = NOTIFICATION_PREFERENCE_DEFAULT_IS_QUIET_TIME_ENABLED,
|
||||
val quietTimeStarts: String = NOTIFICATION_PREFERENCE_DEFAULT_QUIET_TIME_STARTS,
|
||||
val quietTimeEnds: String = NOTIFICATION_PREFERENCE_DEFAULT_QUIET_TIME_END,
|
||||
)
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
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"
|
||||
|
||||
interface NotificationPreferenceManager : PreferenceManager<NotificationPreference>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package net.thunderbird.core.preference.privacy
|
||||
|
||||
const val PRIVACY_SETTINGS_DEFAULT_HIDE_TIME_ZONE = false
|
||||
const val PRIVACY_SETTINGS_DEFAULT_HIDE_USER_AGENT = false
|
||||
|
||||
data class PrivacySettings(
|
||||
val isHideTimeZone: Boolean = PRIVACY_SETTINGS_DEFAULT_HIDE_TIME_ZONE,
|
||||
val isHideUserAgent: Boolean = PRIVACY_SETTINGS_DEFAULT_HIDE_USER_AGENT,
|
||||
)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
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"
|
||||
|
||||
interface PrivacySettingsPreferenceManager : PreferenceManager<PrivacySettings>
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
package net.thunderbird.core.preference.storage
|
||||
|
||||
interface Storage {
|
||||
/**
|
||||
* Checks if the storage is empty.
|
||||
*
|
||||
* @return true if the storage is empty, false otherwise.
|
||||
*/
|
||||
fun isEmpty(): Boolean
|
||||
|
||||
/**
|
||||
* Checks if the storage contains a value for the given key.
|
||||
*
|
||||
* @param key The key to check.
|
||||
* @return true if the storage contains a value for the given key, false otherwise.
|
||||
*/
|
||||
fun contains(key: String): Boolean
|
||||
|
||||
/**
|
||||
* Returns a map of all key-value pairs in the storage.
|
||||
*
|
||||
* @return A map of all key-value pairs.
|
||||
*/
|
||||
fun getAll(): Map<String, String>
|
||||
|
||||
/**
|
||||
* Returns the boolean value for the given key.
|
||||
*
|
||||
* @param key The key to look up.
|
||||
* @param defValue The default value to return if the key is not found.
|
||||
* @return The boolean value for the given key, or the default value if the key is not found.
|
||||
*/
|
||||
fun getBoolean(key: String, defValue: Boolean): Boolean
|
||||
|
||||
/**
|
||||
* Returns the integer value for the given key.
|
||||
*
|
||||
* @param key The key to look up.
|
||||
* @param defValue The default value to return if the key is not found.
|
||||
* @return The integer value for the given key, or the default value if the key is not found.
|
||||
*/
|
||||
fun getInt(key: String, defValue: Int): Int
|
||||
|
||||
/**
|
||||
* Returns the long value for the given key.
|
||||
*
|
||||
* @param key The key to look up.
|
||||
* @param defValue The default value to return if the key is not found.
|
||||
* @return The long value for the given key, or the default value if the key is not found.
|
||||
*/
|
||||
fun getLong(key: String, defValue: Long): Long
|
||||
|
||||
/**
|
||||
* Returns the string value for the given key.
|
||||
*
|
||||
* @param key The key to look up.
|
||||
* @return The string value for the given key.
|
||||
* @throws NoSuchElementException if the key is not found.
|
||||
*/
|
||||
@Throws(NoSuchElementException::class)
|
||||
fun getString(key: String): String
|
||||
|
||||
/**
|
||||
* Returns the string value for the given key.
|
||||
*
|
||||
* @param key The key to look up.
|
||||
* @param defValue The default value to return if the key is not found.
|
||||
* @return The string value for the given key, or the default value if the key is not found.
|
||||
*/
|
||||
fun getStringOrDefault(key: String, defValue: String): String
|
||||
|
||||
/**
|
||||
* Returns the string value for the given key, or null if the key is not found.
|
||||
*
|
||||
* @param key The key to look up.
|
||||
* @return The string value for the given key, or null if the key is not found.
|
||||
*/
|
||||
fun getStringOrNull(key: String): String?
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the enum value for the given key, or the default value if the key is not found or the stored value
|
||||
* is not a valid enum constant.
|
||||
*
|
||||
* @param T The enum type.
|
||||
* @param key The key to look up.
|
||||
* @param default The default enum value to return if the key is not found or the value is invalid.
|
||||
* @return The enum value for the given key, or the default value.
|
||||
* @throws IllegalArgumentException if the stored string value does not match any of the enum constants.
|
||||
*/
|
||||
@Throws(IllegalArgumentException::class)
|
||||
inline fun <reified T : Enum<T>> Storage.getEnumOrDefault(key: String, default: T): T =
|
||||
getStringOrNull(key)
|
||||
?.let { value ->
|
||||
try {
|
||||
enumValueOf<T>(value)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
throw IllegalArgumentException(
|
||||
buildString {
|
||||
append("Unable to convert stored key [$key] value [$value] ")
|
||||
appendLine("to enum of type ${T::class.qualifiedName}.")
|
||||
append("Valid values: ${enumValues<T>().joinToString()}")
|
||||
},
|
||||
e,
|
||||
)
|
||||
}
|
||||
}
|
||||
?: default
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package net.thunderbird.core.preference.storage
|
||||
|
||||
/**
|
||||
* Interface for editing the storage.
|
||||
*
|
||||
* This interface provides methods to put various types of values into the storage,
|
||||
* remove values, and commit the changes.
|
||||
*/
|
||||
interface StorageEditor {
|
||||
|
||||
/**
|
||||
* Puts a boolean value into the storage.
|
||||
*
|
||||
* @param key The key for the value.
|
||||
* @param value The boolean value to put.
|
||||
* @return The StorageEditor instance for chaining.
|
||||
*/
|
||||
fun putBoolean(key: String, value: Boolean): StorageEditor
|
||||
|
||||
/**
|
||||
* Puts an integer value into the storage.
|
||||
*
|
||||
* @param key The key for the value.
|
||||
* @param value The integer value to put.
|
||||
* @return The StorageEditor instance for chaining.
|
||||
*/
|
||||
fun putInt(key: String, value: Int): StorageEditor
|
||||
|
||||
/**
|
||||
* Puts a long value into the storage.
|
||||
*
|
||||
* @param key The key for the value.
|
||||
* @param value The long value to put.
|
||||
* @return The StorageEditor instance for chaining.
|
||||
*/
|
||||
fun putLong(key: String, value: Long): StorageEditor
|
||||
|
||||
/**
|
||||
* Puts a string value into the storage.
|
||||
*
|
||||
* @param key The key for the value.
|
||||
* @param value The string value to put. If null, the key will be removed.
|
||||
* @return The StorageEditor instance for chaining.
|
||||
*/
|
||||
fun putString(key: String, value: String?): StorageEditor
|
||||
|
||||
/**
|
||||
* Removes a value from the storage.
|
||||
*
|
||||
* @param key The key for the value to remove.
|
||||
* @return The StorageEditor instance for chaining.
|
||||
*/
|
||||
fun remove(key: String): StorageEditor
|
||||
|
||||
/**
|
||||
* Commits the changes made to the storage.
|
||||
*
|
||||
* @return true if the commit was successful, false otherwise.
|
||||
*/
|
||||
fun commit(): Boolean
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package net.thunderbird.core.preference.storage
|
||||
|
||||
/**
|
||||
* Extension functions for the [StorageEditor] interface to simplify putting enum values.
|
||||
*
|
||||
* @param T The type of the enum.
|
||||
* @param key The key under which the enum value will be stored.
|
||||
* @param value The enum value to be stored.
|
||||
*/
|
||||
inline fun <reified T : Enum<T>> StorageEditor.putEnum(key: String, value: T) {
|
||||
putString(key, value.name)
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package net.thunderbird.core.preference.storage
|
||||
|
||||
/**
|
||||
* Represents a mechanism for persisting storage data.
|
||||
*
|
||||
* This interface provides methods to:
|
||||
* - Load the current storage values.
|
||||
* - Create a storage editor for applying updates to the storage.
|
||||
*/
|
||||
interface StoragePersister {
|
||||
|
||||
/**
|
||||
* Loads the storage values.
|
||||
*
|
||||
* @return The loaded storage.
|
||||
*/
|
||||
fun loadValues(): Storage
|
||||
|
||||
/**
|
||||
* Creates a storage editor for updating the storage.
|
||||
*
|
||||
* @param storageUpdater The updater to apply changes to the storage.
|
||||
* @return A new instance of [StorageEditor].
|
||||
*/
|
||||
fun createStorageEditor(storageUpdater: StorageUpdater): StorageEditor
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package net.thunderbird.core.preference.storage
|
||||
|
||||
/**
|
||||
* Interface for updating the storage.
|
||||
*/
|
||||
fun interface StorageUpdater {
|
||||
|
||||
/**
|
||||
* Updates the storage using the provided updater function.
|
||||
*
|
||||
* @param updater A function that takes the current storage and returns the updated storage.
|
||||
*/
|
||||
fun updateStorage(updater: (currentStorage: Storage) -> Storage)
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package net.thunderbird.core.preference.debugging
|
||||
|
||||
actual val isDebug: Boolean = false
|
||||
Loading…
Add table
Add a link
Reference in a new issue