Skip to content

Commit

Permalink
refactor: implement PreferenceDelegate to simplify AppPrefs
Browse files Browse the repository at this point in the history
Say goodbye to dizzy getters and setters. Also add support of Float, Set<String> and Enum<*> type.
  • Loading branch information
WhiredPlanck committed Jun 17, 2024
1 parent d0f1787 commit 310449e
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 269 deletions.
322 changes: 76 additions & 246 deletions app/src/main/java/com/osfans/trime/data/AppPrefs.kt

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions app/src/main/java/com/osfans/trime/data/db/ClipboardHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,12 @@ object ClipboardHelper :
}

private val limit get() = AppPrefs.defaultInstance().clipboard.clipboardLimit
private val compare get() = AppPrefs.defaultInstance().clipboard.clipboardCompareRules
private val output get() = AppPrefs.defaultInstance().clipboard.clipboardOutputRules
private val compare get() =
AppPrefs.defaultInstance().clipboard.clipboardCompareRules
.trim().split('\n')
private val output get() =
AppPrefs.defaultInstance().clipboard.clipboardOutputRules
.trim().split('\n')

var lastBean: DatabaseBean? = null

Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/com/osfans/trime/data/db/DraftHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ object DraftHelper : CoroutineScope by CoroutineScope(SupervisorJob() + Dispatch
}

private val limit get() = AppPrefs.defaultInstance().clipboard.draftLimit
private val output get() = AppPrefs.defaultInstance().clipboard.draftOutputRules
private val output get() =
AppPrefs.defaultInstance().clipboard.draftOutputRules
.trim().split('n')

var lastBean: DatabaseBean? = null

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.osfans.trime.data.prefs

import android.content.SharedPreferences
import androidx.core.content.edit
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

open class PreferenceDelegate<T : Any>(
val sharedPreferences: SharedPreferences,
val key: String,
val defaultValue: T,
) : ReadWriteProperty<Any?, T> {
@Suppress("IMPLICIT_CAST_TO_ANY", "UNCHECKED_CAST")
open fun getValue(fallbackKey: String): T {
val finalKey = key.ifEmpty { fallbackKey }
return try {
when (defaultValue) {
is Int -> sharedPreferences.getInt(finalKey, defaultValue)
is Long -> sharedPreferences.getLong(finalKey, defaultValue)
is Float -> sharedPreferences.getFloat(finalKey, defaultValue)
is Boolean -> sharedPreferences.getBoolean(finalKey, defaultValue)
is String -> sharedPreferences.getString(finalKey, defaultValue) ?: defaultValue
is Set<*> -> sharedPreferences.getStringSet(finalKey, defaultValue as? Set<String>)
else -> null
} as T
} catch (e: Exception) {
setValue(fallbackKey, defaultValue)
defaultValue
}
}

open fun setValue(
fallbackKey: String,
value: T,
) {
val finalKey = key.ifEmpty { fallbackKey }
sharedPreferences.edit {
when (value) {
is Int -> putInt(finalKey, value)
is Long -> putLong(finalKey, value)
is Float -> putFloat(finalKey, value)
is Boolean -> putBoolean(finalKey, value)
is String -> putString(finalKey, value)
is Set<*> -> putStringSet(finalKey, value.map { it.toString() }.toHashSet())
}
}
}

override fun getValue(
thisRef: Any?,
property: KProperty<*>,
): T = getValue(property.name)

override fun setValue(
thisRef: Any?,
property: KProperty<*>,
value: T,
) = setValue(property.name, value)

interface Serializer<T : Any> {
fun serialize(t: T): String

fun deserialize(raw: String): T?
}

class SerializableDelegate<T : Any>(
sharedPreferences: SharedPreferences,
key: String,
defaultValue: T,
private val serializer: Serializer<T>,
) : PreferenceDelegate<T>(sharedPreferences, key, defaultValue) {
override fun setValue(
fallbackKey: String,
value: T,
) {
val finalKey = key.ifEmpty { fallbackKey }
sharedPreferences.edit { putString(finalKey, serializer.serialize(value)) }
}

override fun getValue(fallbackKey: String): T {
val finalKey = key.ifEmpty { fallbackKey }
return try {
sharedPreferences.getString(finalKey, null)?.let {
serializer.deserialize(it)
} ?: defaultValue
} catch (e: Exception) {
setValue(fallbackKey, defaultValue)
defaultValue
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.osfans.trime.data.prefs

import android.content.SharedPreferences

abstract class PreferenceDelegateOwner(
protected val sharedPreferences: SharedPreferences,
) {
protected fun int(
key: String,
defaultValue: Int,
) = PreferenceDelegate(sharedPreferences, key, defaultValue)

protected fun long(
key: String,
defaultValue: Long,
) = PreferenceDelegate(sharedPreferences, key, defaultValue)

protected fun float(
key: String,
defaultValue: Float,
) = PreferenceDelegate(sharedPreferences, key, defaultValue)

protected fun bool(
key: String,
defaultValue: Boolean,
): PreferenceDelegate<Boolean> {
return PreferenceDelegate(sharedPreferences, key, defaultValue)
}

protected fun string(
key: String,
defaultValue: String,
): PreferenceDelegate<String> {
return PreferenceDelegate(sharedPreferences, key, defaultValue)
}

protected fun stringSet(
key: String,
defaultValue: Set<String>,
) = PreferenceDelegate(sharedPreferences, key, defaultValue)

protected fun <T : Any> serializable(
key: String,
defaultValue: T,
serializer: PreferenceDelegate.Serializer<T>,
) = PreferenceDelegate.SerializableDelegate(sharedPreferences, key, defaultValue, serializer)

protected inline fun <reified T : Enum<T>> enum(
key: String,
defaultValue: T,
) = serializable(
key,
defaultValue,
object : PreferenceDelegate.Serializer<T> {
override fun serialize(t: T) = t.name

override fun deserialize(raw: String) = enumValueOf<T>(raw.uppercase())
},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
} else if (attribute.packageName == BuildConfig.APPLICATION_ID ||
prefs
.clipboard
.draftExcludeApp
.draftExcludeApp.trim().split('\n')
.contains(attribute.packageName)
) {
normalTextEditor = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,4 @@ enum class FullscreenMode {
AUTO_SHOW,
ALWAYS_SHOW,
NEVER_SHOW,
;

companion object {
fun fromString(mode: String): FullscreenMode {
return runCatching {
valueOf(mode.uppercase())
}.getOrDefault(AUTO_SHOW)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,4 @@ enum class InlinePreeditMode {
PREVIEW,
COMPOSITION,
INPUT,
;

companion object {
fun fromString(string: String): InlinePreeditMode {
return runCatching {
InlinePreeditMode.valueOf(string.uppercase())
}.getOrDefault(NONE)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class KeyboardFragment :
TrimeInputMethodService.getServiceOrNull()?.recreateInputView()
}
"keyboard__candidate_page_size" -> {
val pageSize = AppPrefs.defaultInstance().keyboard.candidatePageSize
val pageSize = AppPrefs.defaultInstance().keyboard.candidatePageSize.toInt()
if (pageSize <= 0) return
lifecycleScope.launch {
withContext(Dispatchers.IO) {
Expand Down

0 comments on commit 310449e

Please sign in to comment.