Skip to content

Commit d73cfec

Browse files
committed
refactor: type-safe IntPreference & Editable API
1 parent c435228 commit d73cfec

File tree

3 files changed

+20
-189
lines changed

3 files changed

+20
-189
lines changed

app/src/main/java/me/ash/reader/infrastructure/preference/DarkThemePreference.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,14 @@ import androidx.compose.runtime.Composable
66
import androidx.compose.runtime.ReadOnlyComposable
77
import androidx.compose.runtime.compositionLocalOf
88
import androidx.datastore.preferences.core.Preferences
9-
import androidx.datastore.preferences.core.edit
109
import me.ash.reader.R
1110
import me.ash.reader.ui.ext.PreferenceKey
12-
import me.ash.reader.ui.ext.dataStore
1311
import me.ash.reader.ui.ext.get
14-
import me.ash.reader.ui.ext.set
1512

1613
val LocalDarkTheme = compositionLocalOf<DarkThemePreference> { DarkThemePreference.default }
1714

1815
sealed class DarkThemePreference(override val value: Int) :
19-
AppPreference.IntPreference, AppPreference.Editable {
16+
AppPreference.IntPreference {
2017
override val key: PreferenceKey.IntKey = Companion.key
2118

2219
object UseDeviceTheme : DarkThemePreference(0)
@@ -25,10 +22,6 @@ sealed class DarkThemePreference(override val value: Int) :
2522

2623
object OFF : DarkThemePreference(2)
2724

28-
override suspend fun put(context: Context) {
29-
context.dataStore.edit { it[key] = value }
30-
}
31-
3225
fun toDesc(context: Context): String =
3326
when (this) {
3427
UseDeviceTheme -> context.getString(R.string.use_device_theme)

app/src/main/java/me/ash/reader/infrastructure/preference/Preference.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,25 @@ package me.ash.reader.infrastructure.preference
22

33
import android.content.Context
44
import androidx.datastore.preferences.core.Preferences
5+
import androidx.datastore.preferences.core.edit
56
import kotlinx.coroutines.CoroutineScope
67
import kotlinx.coroutines.launch
78
import me.ash.reader.ui.ext.PreferenceKey
9+
import me.ash.reader.ui.ext.dataStore
10+
import me.ash.reader.ui.ext.set
811
import org.json.JSONObject
912

1013
sealed interface AppPreference {
1114
val value: Any
1215
val key: PreferenceKey
1316

14-
interface IntPreference : AppPreference {
17+
interface IntPreference : AppPreference, Editable {
1518
override val value: Int
1619
override val key: PreferenceKey.IntKey
20+
21+
override suspend fun put(context: Context) {
22+
context.dataStore.edit { it[key] = value }
23+
}
1724
}
1825

1926
interface LongPreference : AppPreference {

app/src/main/java/me/ash/reader/ui/ext/DataStoreExt.kt

Lines changed: 11 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import me.ash.reader.ui.ext.PreferenceKey.FloatKey
2727
import me.ash.reader.ui.ext.PreferenceKey.IntKey
2828
import me.ash.reader.ui.ext.PreferenceKey.LongKey
2929
import me.ash.reader.ui.ext.PreferenceKey.StringKey
30-
import org.json.JSONObject
3130

3231
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
3332

@@ -51,32 +50,17 @@ val Context.initialFilter: Int
5150
val Context.languages: Int
5251
get() = this.dataStore.get(DataStoreKey.languages) ?: 0
5352

53+
@Deprecated("Use AppPreference.Editable.put instead")
5454
suspend fun DataStore<Preferences>.put(dataStoreKeys: String, value: Any) {
55-
val key = DataStoreKey.keys[dataStoreKeys]?.key ?: return
55+
val key = PreferenceKey.keys[dataStoreKeys] ?: return
5656
this.edit {
5757
withContext(Dispatchers.IO) {
58-
when (value) {
59-
is Int -> {
60-
it[key as Preferences.Key<Int>] = value
61-
}
62-
is Long -> {
63-
it[key as Preferences.Key<Long>] = value
64-
}
65-
is String -> {
66-
it[key as Preferences.Key<String>] = value
67-
}
68-
is Boolean -> {
69-
it[key as Preferences.Key<Boolean>] = value
70-
}
71-
is Float -> {
72-
it[key as Preferences.Key<Float>] = value
73-
}
74-
is Double -> {
75-
it[key as Preferences.Key<Double>] = value
76-
}
77-
else -> {
78-
throw IllegalArgumentException("Unsupported type")
79-
}
58+
when (key) {
59+
is BooleanKey -> if (value is Boolean) it[key] = value
60+
is FloatKey -> if (value is Float) it[key] = value
61+
is IntKey -> if (value is Int) it[key] = value
62+
is LongKey -> if (value is Long) it[key] = value
63+
is StringKey -> if (value is String) it[key] = value
8064
}
8165
}
8266
}
@@ -85,18 +69,17 @@ suspend fun DataStore<Preferences>.put(dataStoreKeys: String, value: Any) {
8569
@Suppress("UNCHECKED_CAST")
8670
fun <T> DataStore<Preferences>.get(key: String): T? {
8771
return runBlocking {
72+
val key = PreferenceKey.keys[key] ?: return@runBlocking null
8873
this@get.data
8974
.catch { exception ->
9075
if (exception is IOException) {
91-
Log.e("RLog", "Get data store error $exception")
92-
exception.printStackTrace()
9376
emit(emptyPreferences())
9477
} else {
9578
throw exception
9679
}
9780
}
98-
.map { it[DataStoreKey.keys[key]?.key as Preferences.Key<T>] }
99-
.first() as T
81+
.first()[key.key]
82+
as? T
10083
}
10184
}
10285

@@ -451,158 +434,6 @@ data class DataStoreKey<T>(val key: Preferences.Key<T>, val type: Class<T>) {
451434

452435
// Languages
453436
const val languages = "languages"
454-
455-
val keys: MutableMap<String, DataStoreKey<*>> =
456-
mutableMapOf(
457-
// Version
458-
isFirstLaunch to
459-
DataStoreKey(booleanPreferencesKey(isFirstLaunch), Boolean::class.java),
460-
newVersionPublishDate to
461-
DataStoreKey(stringPreferencesKey(newVersionPublishDate), String::class.java),
462-
newVersionLog to
463-
DataStoreKey(stringPreferencesKey(newVersionLog), String::class.java),
464-
newVersionSizeString to
465-
DataStoreKey(stringPreferencesKey(newVersionSizeString), String::class.java),
466-
newVersionDownloadUrl to
467-
DataStoreKey(stringPreferencesKey(newVersionDownloadUrl), String::class.java),
468-
newVersionNumber to
469-
DataStoreKey(stringPreferencesKey(newVersionNumber), String::class.java),
470-
skipVersionNumber to
471-
DataStoreKey(stringPreferencesKey(skipVersionNumber), String::class.java),
472-
currentAccountId to
473-
DataStoreKey(intPreferencesKey(currentAccountId), Int::class.java),
474-
currentAccountType to
475-
DataStoreKey(intPreferencesKey(currentAccountType), Int::class.java),
476-
themeIndex to DataStoreKey(intPreferencesKey(themeIndex), Int::class.java),
477-
customPrimaryColor to
478-
DataStoreKey(stringPreferencesKey(customPrimaryColor), String::class.java),
479-
darkTheme to DataStoreKey(intPreferencesKey(darkTheme), Int::class.java),
480-
amoledDarkTheme to
481-
DataStoreKey(booleanPreferencesKey(amoledDarkTheme), Boolean::class.java),
482-
basicFonts to DataStoreKey(intPreferencesKey(basicFonts), Int::class.java),
483-
// Feeds page
484-
feedsFilterBarStyle to
485-
DataStoreKey(intPreferencesKey(feedsFilterBarStyle), Int::class.java),
486-
feedsFilterBarPadding to
487-
DataStoreKey(intPreferencesKey(feedsFilterBarPadding), Int::class.java),
488-
feedsFilterBarTonalElevation to
489-
DataStoreKey(intPreferencesKey(feedsFilterBarTonalElevation), Int::class.java),
490-
feedsTopBarTonalElevation to
491-
DataStoreKey(intPreferencesKey(feedsTopBarTonalElevation), Int::class.java),
492-
feedsGroupListExpand to
493-
DataStoreKey(booleanPreferencesKey(feedsGroupListExpand), Boolean::class.java),
494-
feedsGroupListTonalElevation to
495-
DataStoreKey(intPreferencesKey(feedsGroupListTonalElevation), Int::class.java),
496-
// Flow page
497-
flowFilterBarStyle to
498-
DataStoreKey(intPreferencesKey(flowFilterBarStyle), Int::class.java),
499-
flowFilterBarPadding to
500-
DataStoreKey(intPreferencesKey(flowFilterBarPadding), Int::class.java),
501-
flowFilterBarTonalElevation to
502-
DataStoreKey(intPreferencesKey(flowFilterBarTonalElevation), Int::class.java),
503-
flowTopBarTonalElevation to
504-
DataStoreKey(intPreferencesKey(flowTopBarTonalElevation), Int::class.java),
505-
flowArticleListFeedIcon to
506-
DataStoreKey(
507-
booleanPreferencesKey(flowArticleListFeedIcon),
508-
Boolean::class.java,
509-
),
510-
flowArticleListFeedName to
511-
DataStoreKey(
512-
booleanPreferencesKey(flowArticleListFeedName),
513-
Boolean::class.java,
514-
),
515-
flowArticleListImage to
516-
DataStoreKey(booleanPreferencesKey(flowArticleListImage), Boolean::class.java),
517-
flowArticleListDesc to
518-
DataStoreKey(booleanPreferencesKey(flowArticleListDesc), Boolean::class.java),
519-
flowArticleListTime to
520-
DataStoreKey(booleanPreferencesKey(flowArticleListTime), Boolean::class.java),
521-
flowArticleListDateStickyHeader to
522-
DataStoreKey(
523-
booleanPreferencesKey(flowArticleListDateStickyHeader),
524-
Boolean::class.java,
525-
),
526-
flowArticleListTonalElevation to
527-
DataStoreKey(intPreferencesKey(flowArticleListTonalElevation), Int::class.java),
528-
flowArticleListReadIndicator to
529-
DataStoreKey(intPreferencesKey(flowArticleListReadIndicator), Int::class.java),
530-
flowSortUnreadArticles to
531-
DataStoreKey(
532-
booleanPreferencesKey(flowSortUnreadArticles),
533-
Boolean::class.java,
534-
),
535-
// Reading page
536-
readingRenderer to
537-
DataStoreKey(intPreferencesKey(readingRenderer), Int::class.java),
538-
readingBoldCharacters to
539-
DataStoreKey(booleanPreferencesKey(readingBoldCharacters), Boolean::class.java),
540-
readingPageTonalElevation to
541-
DataStoreKey(intPreferencesKey(readingPageTonalElevation), Int::class.java),
542-
readingTextFontSize to
543-
DataStoreKey(intPreferencesKey(readingTextFontSize), Int::class.java),
544-
readingTextLineHeight to
545-
DataStoreKey(floatPreferencesKey(readingTextLineHeight), Float::class.java),
546-
readingTextLetterSpacing to
547-
DataStoreKey(floatPreferencesKey(readingTextLetterSpacing), Float::class.java),
548-
readingTextHorizontalPadding to
549-
DataStoreKey(intPreferencesKey(readingTextHorizontalPadding), Int::class.java),
550-
readingTextBold to
551-
DataStoreKey(booleanPreferencesKey(readingTextBold), Boolean::class.java),
552-
readingTextAlign to
553-
DataStoreKey(intPreferencesKey(readingTextAlign), Int::class.java),
554-
readingTitleAlign to
555-
DataStoreKey(intPreferencesKey(readingTitleAlign), Int::class.java),
556-
readingSubheadAlign to
557-
DataStoreKey(intPreferencesKey(readingSubheadAlign), Int::class.java),
558-
readingTheme to DataStoreKey(intPreferencesKey(readingTheme), Int::class.java),
559-
readingFonts to DataStoreKey(intPreferencesKey(readingFonts), Int::class.java),
560-
readingAutoHideToolbar to
561-
DataStoreKey(
562-
booleanPreferencesKey(readingAutoHideToolbar),
563-
Boolean::class.java,
564-
),
565-
readingTitleBold to
566-
DataStoreKey(booleanPreferencesKey(readingTitleBold), Boolean::class.java),
567-
readingSubheadBold to
568-
DataStoreKey(booleanPreferencesKey(readingSubheadBold), Boolean::class.java),
569-
readingTitleUpperCase to
570-
DataStoreKey(booleanPreferencesKey(readingTitleUpperCase), Boolean::class.java),
571-
readingSubheadUpperCase to
572-
DataStoreKey(
573-
booleanPreferencesKey(readingSubheadUpperCase),
574-
Boolean::class.java,
575-
),
576-
readingImageMaximize to
577-
DataStoreKey(booleanPreferencesKey(readingImageMaximize), Boolean::class.java),
578-
readingImageHorizontalPadding to
579-
DataStoreKey(intPreferencesKey(readingImageHorizontalPadding), Int::class.java),
580-
readingImageRoundedCorners to
581-
DataStoreKey(intPreferencesKey(readingImageRoundedCorners), Int::class.java),
582-
// Interaction
583-
initialPage to DataStoreKey(intPreferencesKey(initialPage), Int::class.java),
584-
initialFilter to DataStoreKey(intPreferencesKey(initialFilter), Int::class.java),
585-
swipeStartAction to
586-
DataStoreKey(intPreferencesKey(swipeStartAction), Int::class.java),
587-
swipeEndAction to DataStoreKey(intPreferencesKey(swipeEndAction), Int::class.java),
588-
markAsReadOnScroll to
589-
DataStoreKey(booleanPreferencesKey(markAsReadOnScroll), Boolean::class.java),
590-
hideEmptyGroups to
591-
DataStoreKey(booleanPreferencesKey(hideEmptyGroups), Boolean::class.java),
592-
pullToLoadNextFeed to
593-
DataStoreKey(booleanPreferencesKey(pullToLoadNextFeed), Boolean::class.java),
594-
pullToSwitchArticle to
595-
DataStoreKey(booleanPreferencesKey(pullToSwitchArticle), Boolean::class.java),
596-
openLink to DataStoreKey(intPreferencesKey(openLink), Int::class.java),
597-
openLinkAppSpecificBrowser to
598-
DataStoreKey(
599-
stringPreferencesKey(openLinkAppSpecificBrowser),
600-
String::class.java,
601-
),
602-
sharedContent to DataStoreKey(intPreferencesKey(sharedContent), Int::class.java),
603-
// Languages
604-
languages to DataStoreKey(intPreferencesKey(languages), Int::class.java),
605-
)
606437
}
607438
}
608439

0 commit comments

Comments
 (0)