Set default styles

This commit is contained in:
Ash 2022-05-02 19:02:20 +08:00
parent fa3c5e3601
commit 1ba205343e
33 changed files with 461 additions and 524 deletions

View File

@ -18,6 +18,7 @@ import coil.memory.MemoryCache
import coil.request.* import coil.request.*
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CompletableDeferred
import me.ash.reader.data.preference.SettingsProvider
import me.ash.reader.ui.page.common.HomeEntry import me.ash.reader.ui.page.common.HomeEntry
@AndroidEntryPoint @AndroidEntryPoint
@ -28,9 +29,11 @@ class MainActivity : ComponentActivity(), ImageLoader {
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
Log.i("RLog", "onCreate: ${ProfileInstallerInitializer().create(this)}") Log.i("RLog", "onCreate: ${ProfileInstallerInitializer().create(this)}")
setContent { setContent {
SettingsProvider {
HomeEntry() HomeEntry()
} }
} }
}
override val components: ComponentRegistry override val components: ComponentRegistry
get() = ComponentRegistry.Builder().add(SvgDecoder.Factory()).build() get() = ComponentRegistry.Builder().add(SvgDecoder.Factory()).build()

View File

@ -0,0 +1,22 @@
package me.ash.reader.data.preference
import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put
object CustomPrimaryColorPreference {
const val default = ""
fun put(context: Context, scope: CoroutineScope, value: String) {
scope.launch {
context.dataStore.put(DataStoreKeys.CustomPrimaryColor, value)
}
}
fun fromPreferences(preferences: Preferences) =
preferences[DataStoreKeys.CustomPrimaryColor.key] ?: default
}

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -15,7 +13,7 @@ sealed class FeedsFilterBarFilledPreference(val value: Boolean) : Preference() {
object OFF : FeedsFilterBarFilledPreference(false) object OFF : FeedsFilterBarFilledPreference(false)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FeedsFilterBarFilled, DataStoreKeys.FeedsFilterBarFilled,
value value
@ -27,15 +25,13 @@ sealed class FeedsFilterBarFilledPreference(val value: Boolean) : Preference() {
val default = OFF val default = OFF
val values = listOf(ON, OFF) val values = listOf(ON, OFF)
val Context.feedsFilterBarFilled: Flow<FeedsFilterBarFilledPreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FeedsFilterBarFilled.key]) {
when (it[DataStoreKeys.FeedsFilterBarFilled.key]) {
true -> ON true -> ON
false -> OFF false -> OFF
else -> default else -> default
} }
} }
}
} }
operator fun FeedsFilterBarFilledPreference.not(): FeedsFilterBarFilledPreference = operator fun FeedsFilterBarFilledPreference.not(): FeedsFilterBarFilledPreference =

View File

@ -1,28 +1,22 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.compose.runtime.Immutable import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put import me.ash.reader.ui.ext.put
@Immutable
object FeedsFilterBarPaddingPreference { object FeedsFilterBarPaddingPreference {
const val default = 0 const val default = 60
val Context.feedsFilterBarPadding: Flow<Int>
get() = this.dataStore.data.map {
it[DataStoreKeys.FeedsFilterBarPadding.key] ?: default
}
fun put(context: Context, scope: CoroutineScope, value: Int) { fun put(context: Context, scope: CoroutineScope, value: Int) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put(DataStoreKeys.FeedsFilterBarPadding, value) context.dataStore.put(DataStoreKeys.FeedsFilterBarPadding, value)
} }
} }
fun fromPreferences(preferences: Preferences) =
preferences[DataStoreKeys.FeedsFilterBarPadding.key] ?: default
} }

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
@ -17,7 +15,7 @@ sealed class FeedsFilterBarStylePreference(val value: Int) : Preference() {
object IconLabelOnlySelected : FeedsFilterBarStylePreference(2) object IconLabelOnlySelected : FeedsFilterBarStylePreference(2)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FeedsFilterBarStyle, DataStoreKeys.FeedsFilterBarStyle,
value value
@ -36,14 +34,12 @@ sealed class FeedsFilterBarStylePreference(val value: Int) : Preference() {
val default = Icon val default = Icon
val values = listOf(Icon, IconLabel, IconLabelOnlySelected) val values = listOf(Icon, IconLabel, IconLabelOnlySelected)
val Context.feedsFilterBarStyle: Flow<FeedsFilterBarStylePreference> fun fromPreferences(preferences: Preferences): FeedsFilterBarStylePreference =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FeedsFilterBarStyle.key]) {
when (it[DataStoreKeys.FeedsFilterBarStyle.key]) {
0 -> Icon 0 -> Icon
1 -> IconLabel 1 -> IconLabel
2 -> IconLabelOnlySelected 2 -> IconLabelOnlySelected
else -> default else -> default
} }
} }
}
} }

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -19,7 +17,7 @@ sealed class FeedsFilterBarTonalElevationPreference(val value: Int) : Preference
object Level5 : FeedsFilterBarTonalElevationPreference(12) object Level5 : FeedsFilterBarTonalElevationPreference(12)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FeedsFilterBarTonalElevation, DataStoreKeys.FeedsFilterBarTonalElevation,
value value
@ -41,9 +39,8 @@ sealed class FeedsFilterBarTonalElevationPreference(val value: Int) : Preference
val default = Level0 val default = Level0
val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5) val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5)
val Context.feedsFilterBarTonalElevation: Flow<FeedsFilterBarTonalElevationPreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FeedsFilterBarTonalElevation.key]) {
when (it[DataStoreKeys.FeedsFilterBarTonalElevation.key]) {
0 -> Level0 0 -> Level0
1 -> Level1 1 -> Level1
3 -> Level2 3 -> Level2
@ -53,5 +50,4 @@ sealed class FeedsFilterBarTonalElevationPreference(val value: Int) : Preference
else -> default else -> default
} }
} }
}
} }

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -15,7 +13,7 @@ sealed class FeedsGroupListExpandPreference(val value: Boolean) : Preference() {
object OFF : FeedsGroupListExpandPreference(false) object OFF : FeedsGroupListExpandPreference(false)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FeedsGroupListExpand, DataStoreKeys.FeedsGroupListExpand,
value value
@ -27,15 +25,13 @@ sealed class FeedsGroupListExpandPreference(val value: Boolean) : Preference() {
val default = ON val default = ON
val values = listOf(ON, OFF) val values = listOf(ON, OFF)
val Context.feedsGroupListExpand: Flow<FeedsGroupListExpandPreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FeedsGroupListExpand.key]) {
when (it[DataStoreKeys.FeedsGroupListExpand.key]) {
true -> ON true -> ON
false -> OFF false -> OFF
else -> default else -> default
} }
} }
}
} }
operator fun FeedsGroupListExpandPreference.not(): FeedsGroupListExpandPreference = operator fun FeedsGroupListExpandPreference.not(): FeedsGroupListExpandPreference =

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -19,7 +17,7 @@ sealed class FeedsGroupListTonalElevationPreference(val value: Int) : Preference
object Level5 : FeedsGroupListTonalElevationPreference(12) object Level5 : FeedsGroupListTonalElevationPreference(12)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FeedsGroupListTonalElevation, DataStoreKeys.FeedsGroupListTonalElevation,
value value
@ -41,9 +39,8 @@ sealed class FeedsGroupListTonalElevationPreference(val value: Int) : Preference
val default = Level0 val default = Level0
val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5) val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5)
val Context.feedsGroupListTonalElevation: Flow<FeedsGroupListTonalElevationPreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FeedsGroupListTonalElevation.key]) {
when (it[DataStoreKeys.FeedsGroupListTonalElevation.key]) {
0 -> Level0 0 -> Level0
1 -> Level1 1 -> Level1
3 -> Level2 3 -> Level2
@ -53,5 +50,4 @@ sealed class FeedsGroupListTonalElevationPreference(val value: Int) : Preference
else -> default else -> default
} }
} }
}
} }

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -19,7 +17,7 @@ sealed class FeedsTopBarTonalElevationPreference(val value: Int) : Preference()
object Level5 : FeedsTopBarTonalElevationPreference(12) object Level5 : FeedsTopBarTonalElevationPreference(12)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FeedsTopBarTonalElevation, DataStoreKeys.FeedsTopBarTonalElevation,
value value
@ -41,9 +39,8 @@ sealed class FeedsTopBarTonalElevationPreference(val value: Int) : Preference()
val default = Level0 val default = Level0
val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5) val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5)
val Context.feedsTopBarTonalElevation: Flow<FeedsTopBarTonalElevationPreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FeedsTopBarTonalElevation.key]) {
when (it[DataStoreKeys.FeedsTopBarTonalElevation.key]) {
0 -> Level0 0 -> Level0
1 -> Level1 1 -> Level1
3 -> Level2 3 -> Level2
@ -53,5 +50,4 @@ sealed class FeedsTopBarTonalElevationPreference(val value: Int) : Preference()
else -> default else -> default
} }
} }
}
} }

View File

@ -1,45 +0,0 @@
package me.ash.reader.data.preference
import android.content.Context
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put
sealed class FlowArticleListDatePreference(val value: Boolean) : Preference() {
object ON : FlowArticleListDatePreference(true)
object OFF : FlowArticleListDatePreference(false)
override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) {
context.dataStore.put(
DataStoreKeys.FlowArticleListDate,
value
)
}
}
companion object {
val default = ON
val values = listOf(ON, OFF)
val Context.flowArticleListDate: Flow<FlowArticleListDatePreference>
get() = this.dataStore.data.map {
when (it[DataStoreKeys.FlowArticleListDate.key]) {
true -> ON
false -> OFF
else -> default
}
}
}
}
operator fun FlowArticleListDatePreference.not(): FlowArticleListDatePreference =
when (value) {
true -> FlowArticleListDatePreference.OFF
false -> FlowArticleListDatePreference.ON
}

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -15,7 +13,7 @@ sealed class FlowArticleListDescPreference(val value: Boolean) : Preference() {
object OFF : FlowArticleListDescPreference(false) object OFF : FlowArticleListDescPreference(false)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FlowArticleListDesc, DataStoreKeys.FlowArticleListDesc,
value value
@ -27,15 +25,13 @@ sealed class FlowArticleListDescPreference(val value: Boolean) : Preference() {
val default = ON val default = ON
val values = listOf(ON, OFF) val values = listOf(ON, OFF)
val Context.flowArticleListDesc: Flow<FlowArticleListDescPreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FlowArticleListDesc.key]) {
when (it[DataStoreKeys.FlowArticleListDesc.key]) {
true -> ON true -> ON
false -> OFF false -> OFF
else -> default else -> default
} }
} }
}
} }
operator fun FlowArticleListDescPreference.not(): FlowArticleListDescPreference = operator fun FlowArticleListDescPreference.not(): FlowArticleListDescPreference =

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -15,7 +13,7 @@ sealed class FlowArticleListFeedIconPreference(val value: Boolean) : Preference(
object OFF : FlowArticleListFeedIconPreference(false) object OFF : FlowArticleListFeedIconPreference(false)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FlowArticleListFeedIcon, DataStoreKeys.FlowArticleListFeedIcon,
value value
@ -27,15 +25,13 @@ sealed class FlowArticleListFeedIconPreference(val value: Boolean) : Preference(
val default = ON val default = ON
val values = listOf(ON, OFF) val values = listOf(ON, OFF)
val Context.flowArticleListFeedIcon: Flow<FlowArticleListFeedIconPreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FlowArticleListFeedIcon.key]) {
when (it[DataStoreKeys.FlowArticleListFeedIcon.key]) {
true -> ON true -> ON
false -> OFF false -> OFF
else -> default else -> default
} }
} }
}
} }
operator fun FlowArticleListFeedIconPreference.not(): FlowArticleListFeedIconPreference = operator fun FlowArticleListFeedIconPreference.not(): FlowArticleListFeedIconPreference =

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -15,7 +13,7 @@ sealed class FlowArticleListFeedNamePreference(val value: Boolean) : Preference(
object OFF : FlowArticleListFeedNamePreference(false) object OFF : FlowArticleListFeedNamePreference(false)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FlowArticleListFeedName, DataStoreKeys.FlowArticleListFeedName,
value value
@ -27,15 +25,13 @@ sealed class FlowArticleListFeedNamePreference(val value: Boolean) : Preference(
val default = ON val default = ON
val values = listOf(ON, OFF) val values = listOf(ON, OFF)
val Context.flowArticleListFeedName: Flow<FlowArticleListFeedNamePreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FlowArticleListFeedName.key]) {
when (it[DataStoreKeys.FlowArticleListFeedName.key]) {
true -> ON true -> ON
false -> OFF false -> OFF
else -> default else -> default
} }
} }
}
} }
operator fun FlowArticleListFeedNamePreference.not(): FlowArticleListFeedNamePreference = operator fun FlowArticleListFeedNamePreference.not(): FlowArticleListFeedNamePreference =

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -15,7 +13,7 @@ sealed class FlowArticleListImagePreference(val value: Boolean) : Preference() {
object OFF : FlowArticleListImagePreference(false) object OFF : FlowArticleListImagePreference(false)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FlowArticleListImage, DataStoreKeys.FlowArticleListImage,
value value
@ -27,15 +25,13 @@ sealed class FlowArticleListImagePreference(val value: Boolean) : Preference() {
val default = ON val default = ON
val values = listOf(ON, OFF) val values = listOf(ON, OFF)
val Context.flowArticleListImage: Flow<FlowArticleListImagePreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FlowArticleListImage.key]) {
when (it[DataStoreKeys.FlowArticleListImage.key]) {
true -> ON true -> ON
false -> OFF false -> OFF
else -> default else -> default
} }
} }
}
} }
operator fun FlowArticleListImagePreference.not(): FlowArticleListImagePreference = operator fun FlowArticleListImagePreference.not(): FlowArticleListImagePreference =

View File

@ -0,0 +1,41 @@
package me.ash.reader.data.preference
import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put
sealed class FlowArticleListTimePreference(val value: Boolean) : Preference() {
object ON : FlowArticleListTimePreference(true)
object OFF : FlowArticleListTimePreference(false)
override fun put(context: Context, scope: CoroutineScope) {
scope.launch {
context.dataStore.put(
DataStoreKeys.FlowArticleListTime,
value
)
}
}
companion object {
val default = ON
val values = listOf(ON, OFF)
fun fromPreferences(preferences: Preferences) =
when (preferences[DataStoreKeys.FlowArticleListTime.key]) {
true -> ON
false -> OFF
else -> default
}
}
}
operator fun FlowArticleListTimePreference.not(): FlowArticleListTimePreference =
when (value) {
true -> FlowArticleListTimePreference.OFF
false -> FlowArticleListTimePreference.ON
}

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -19,7 +17,7 @@ sealed class FlowArticleListTonalElevationPreference(val value: Int) : Preferenc
object Level5 : FlowArticleListTonalElevationPreference(12) object Level5 : FlowArticleListTonalElevationPreference(12)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FlowArticleListTonalElevation, DataStoreKeys.FlowArticleListTonalElevation,
value value
@ -41,9 +39,8 @@ sealed class FlowArticleListTonalElevationPreference(val value: Int) : Preferenc
val default = Level0 val default = Level0
val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5) val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5)
val Context.flowArticleListTonalElevation: Flow<FlowArticleListTonalElevationPreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FlowArticleListTonalElevation.key]) {
when (it[DataStoreKeys.FlowArticleListTonalElevation.key]) {
0 -> Level0 0 -> Level0
1 -> Level1 1 -> Level1
3 -> Level2 3 -> Level2
@ -53,5 +50,4 @@ sealed class FlowArticleListTonalElevationPreference(val value: Int) : Preferenc
else -> default else -> default
} }
} }
}
} }

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -15,7 +13,7 @@ sealed class FlowFilterBarFilledPreference(val value: Boolean) : Preference() {
object OFF : FlowFilterBarFilledPreference(false) object OFF : FlowFilterBarFilledPreference(false)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FlowFilterBarFilled, DataStoreKeys.FlowFilterBarFilled,
value value
@ -27,15 +25,13 @@ sealed class FlowFilterBarFilledPreference(val value: Boolean) : Preference() {
val default = OFF val default = OFF
val values = listOf(ON, OFF) val values = listOf(ON, OFF)
val Context.flowFilterBarFilled: Flow<FlowFilterBarFilledPreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FlowFilterBarFilled.key]) {
when (it[DataStoreKeys.FlowFilterBarFilled.key]) {
true -> ON true -> ON
false -> OFF false -> OFF
else -> default else -> default
} }
} }
}
} }
operator fun FlowFilterBarFilledPreference.not(): FlowFilterBarFilledPreference = operator fun FlowFilterBarFilledPreference.not(): FlowFilterBarFilledPreference =

View File

@ -1,28 +1,22 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.compose.runtime.Immutable import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put import me.ash.reader.ui.ext.put
@Immutable
object FlowFilterBarPaddingPreference { object FlowFilterBarPaddingPreference {
const val default = 0 const val default = 60
val Context.flowFilterBarPadding: Flow<Int>
get() = this.dataStore.data.map {
it[DataStoreKeys.FlowFilterBarPadding.key] ?: default
}
fun put(context: Context, scope: CoroutineScope, value: Int) { fun put(context: Context, scope: CoroutineScope, value: Int) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put(DataStoreKeys.FlowFilterBarPadding, value) context.dataStore.put(DataStoreKeys.FlowFilterBarPadding, value)
} }
} }
fun fromPreferences(preferences: Preferences) =
preferences[DataStoreKeys.FlowFilterBarPadding.key] ?: default
} }

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
@ -17,7 +15,7 @@ sealed class FlowFilterBarStylePreference(val value: Int) : Preference() {
object IconLabelOnlySelected : FlowFilterBarStylePreference(2) object IconLabelOnlySelected : FlowFilterBarStylePreference(2)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FlowFilterBarStyle, DataStoreKeys.FlowFilterBarStyle,
value value
@ -36,14 +34,12 @@ sealed class FlowFilterBarStylePreference(val value: Int) : Preference() {
val default = Icon val default = Icon
val values = listOf(Icon, IconLabel, IconLabelOnlySelected) val values = listOf(Icon, IconLabel, IconLabelOnlySelected)
val Context.flowFilterBarStyle: Flow<FlowFilterBarStylePreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FlowFilterBarStyle.key]) {
when (it[DataStoreKeys.FlowFilterBarStyle.key]) {
0 -> Icon 0 -> Icon
1 -> IconLabel 1 -> IconLabel
2 -> IconLabelOnlySelected 2 -> IconLabelOnlySelected
else -> default else -> default
} }
} }
}
} }

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -19,7 +17,7 @@ sealed class FlowFilterBarTonalElevationPreference(val value: Int) : Preference(
object Level5 : FlowFilterBarTonalElevationPreference(12) object Level5 : FlowFilterBarTonalElevationPreference(12)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FlowFilterBarTonalElevation, DataStoreKeys.FlowFilterBarTonalElevation,
value value
@ -41,9 +39,8 @@ sealed class FlowFilterBarTonalElevationPreference(val value: Int) : Preference(
val default = Level0 val default = Level0
val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5) val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5)
val Context.flowFilterBarTonalElevation: Flow<FlowFilterBarTonalElevationPreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FlowFilterBarTonalElevation.key]) {
when (it[DataStoreKeys.FlowFilterBarTonalElevation.key]) {
0 -> Level0 0 -> Level0
1 -> Level1 1 -> Level1
3 -> Level2 3 -> Level2
@ -53,5 +50,4 @@ sealed class FlowFilterBarTonalElevationPreference(val value: Int) : Preference(
else -> default else -> default
} }
} }
}
} }

View File

@ -1,10 +1,8 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
@ -19,7 +17,7 @@ sealed class FlowTopBarTonalElevationPreference(val value: Int) : Preference() {
object Level5 : FlowTopBarTonalElevationPreference(12) object Level5 : FlowTopBarTonalElevationPreference(12)
override fun put(context: Context, scope: CoroutineScope) { override fun put(context: Context, scope: CoroutineScope) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put( context.dataStore.put(
DataStoreKeys.FlowTopBarTonalElevation, DataStoreKeys.FlowTopBarTonalElevation,
value value
@ -41,9 +39,8 @@ sealed class FlowTopBarTonalElevationPreference(val value: Int) : Preference() {
val default = Level0 val default = Level0
val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5) val values = listOf(Level0, Level1, Level2, Level3, Level4, Level5)
val Context.flowTopBarTonalElevation: Flow<FlowTopBarTonalElevationPreference> fun fromPreferences(preferences: Preferences) =
get() = this.dataStore.data.map { when (preferences[DataStoreKeys.FlowTopBarTonalElevation.key]) {
when (it[DataStoreKeys.FlowTopBarTonalElevation.key]) {
0 -> Level0 0 -> Level0
1 -> Level1 1 -> Level1
3 -> Level2 3 -> Level2
@ -53,5 +50,4 @@ sealed class FlowTopBarTonalElevationPreference(val value: Int) : Preference() {
else -> default else -> default
} }
} }
}
} }

View File

@ -0,0 +1,147 @@
package me.ash.reader.data.preference
import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.flow.map
import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.ext.dataStore
data class Settings(
val themeIndex: Int = ThemeIndexPreference.default,
val customPrimaryColor: String = CustomPrimaryColorPreference.default,
val feedsFilterBarStyle: FeedsFilterBarStylePreference = FeedsFilterBarStylePreference.default,
val feedsFilterBarFilled: FeedsFilterBarFilledPreference = FeedsFilterBarFilledPreference.default,
val feedsFilterBarPadding: Int = FeedsFilterBarPaddingPreference.default,
val feedsFilterBarTonalElevation: FeedsFilterBarTonalElevationPreference = FeedsFilterBarTonalElevationPreference.default,
val feedsTopBarTonalElevation: FeedsTopBarTonalElevationPreference = FeedsTopBarTonalElevationPreference.default,
val feedsGroupListExpand: FeedsGroupListExpandPreference = FeedsGroupListExpandPreference.default,
val feedsGroupListTonalElevation: FeedsGroupListTonalElevationPreference = FeedsGroupListTonalElevationPreference.default,
val flowFilterBarStyle: FlowFilterBarStylePreference = FlowFilterBarStylePreference.default,
val flowFilterBarFilled: FlowFilterBarFilledPreference = FlowFilterBarFilledPreference.default,
val flowFilterBarPadding: Int = FlowFilterBarPaddingPreference.default,
val flowFilterBarTonalElevation: FlowFilterBarTonalElevationPreference = FlowFilterBarTonalElevationPreference.default,
val flowTopBarTonalElevation: FlowTopBarTonalElevationPreference = FlowTopBarTonalElevationPreference.default,
val flowArticleListFeedIcon: FlowArticleListFeedIconPreference = FlowArticleListFeedIconPreference.default,
val flowArticleListFeedName: FlowArticleListFeedNamePreference = FlowArticleListFeedNamePreference.default,
val flowArticleListImage: FlowArticleListImagePreference = FlowArticleListImagePreference.default,
val flowArticleListDesc: FlowArticleListDescPreference = FlowArticleListDescPreference.default,
val flowArticleListTime: FlowArticleListTimePreference = FlowArticleListTimePreference.default,
val flowArticleListTonalElevation: FlowArticleListTonalElevationPreference = FlowArticleListTonalElevationPreference.default,
)
fun Preferences.toSettings(): Settings {
return Settings(
themeIndex = ThemeIndexPreference.fromPreferences(this),
customPrimaryColor = CustomPrimaryColorPreference.fromPreferences(this),
feedsFilterBarStyle = FeedsFilterBarStylePreference.fromPreferences(this),
feedsFilterBarFilled = FeedsFilterBarFilledPreference.fromPreferences(this),
feedsFilterBarPadding = FeedsFilterBarPaddingPreference.fromPreferences(this),
feedsFilterBarTonalElevation = FeedsFilterBarTonalElevationPreference.fromPreferences(this),
feedsTopBarTonalElevation = FeedsTopBarTonalElevationPreference.fromPreferences(this),
feedsGroupListExpand = FeedsGroupListExpandPreference.fromPreferences(this),
feedsGroupListTonalElevation = FeedsGroupListTonalElevationPreference.fromPreferences(this),
flowFilterBarStyle = FlowFilterBarStylePreference.fromPreferences(this),
flowFilterBarFilled = FlowFilterBarFilledPreference.fromPreferences(this),
flowFilterBarPadding = FlowFilterBarPaddingPreference.fromPreferences(this),
flowFilterBarTonalElevation = FlowFilterBarTonalElevationPreference.fromPreferences(this),
flowTopBarTonalElevation = FlowTopBarTonalElevationPreference.fromPreferences(this),
flowArticleListFeedIcon = FlowArticleListFeedIconPreference.fromPreferences(this),
flowArticleListFeedName = FlowArticleListFeedNamePreference.fromPreferences(this),
flowArticleListImage = FlowArticleListImagePreference.fromPreferences(this),
flowArticleListDesc = FlowArticleListDescPreference.fromPreferences(this),
flowArticleListTime = FlowArticleListTimePreference.fromPreferences(this),
flowArticleListTonalElevation = FlowArticleListTonalElevationPreference.fromPreferences(this),
)
}
@Composable
fun SettingsProvider(
content: @Composable () -> Unit,
) {
val context = LocalContext.current
val settings = remember {
context.dataStore.data.map {
Log.i("RLog", "AppTheme: ${it}")
it.toSettings()
}
}.collectAsStateValue(initial = Settings())
CompositionLocalProvider(
LocalThemeIndex provides settings.themeIndex,
LocalCustomPrimaryColor provides settings.customPrimaryColor,
LocalFeedsTopBarTonalElevation provides settings.feedsTopBarTonalElevation,
LocalFeedsGroupListExpand provides settings.feedsGroupListExpand,
LocalFeedsGroupListTonalElevation provides settings.feedsGroupListTonalElevation,
LocalFeedsFilterBarStyle provides settings.feedsFilterBarStyle,
LocalFeedsFilterBarFilled provides settings.feedsFilterBarFilled,
LocalFeedsFilterBarPadding provides settings.feedsFilterBarPadding,
LocalFeedsFilterBarTonalElevation provides settings.feedsFilterBarTonalElevation,
LocalFlowTopBarTonalElevation provides settings.flowTopBarTonalElevation,
LocalFlowArticleListFeedIcon provides settings.flowArticleListFeedIcon,
LocalFlowArticleListFeedName provides settings.flowArticleListFeedName,
LocalFlowArticleListImage provides settings.flowArticleListImage,
LocalFlowArticleListDesc provides settings.flowArticleListDesc,
LocalFlowArticleListTime provides settings.flowArticleListTime,
LocalFlowArticleListTonalElevation provides settings.flowArticleListTonalElevation,
LocalFlowFilterBarStyle provides settings.flowFilterBarStyle,
LocalFlowFilterBarFilled provides settings.flowFilterBarFilled,
LocalFlowFilterBarPadding provides settings.flowFilterBarPadding,
LocalFlowFilterBarTonalElevation provides settings.flowFilterBarTonalElevation,
) {
content()
}
}
val LocalThemeIndex =
compositionLocalOf { ThemeIndexPreference.default }
val LocalCustomPrimaryColor =
compositionLocalOf { CustomPrimaryColorPreference.default }
val LocalFeedsFilterBarStyle =
compositionLocalOf<FeedsFilterBarStylePreference> { FeedsFilterBarStylePreference.default }
val LocalFeedsFilterBarFilled =
compositionLocalOf<FeedsFilterBarFilledPreference> { FeedsFilterBarFilledPreference.default }
val LocalFeedsFilterBarPadding =
compositionLocalOf { FeedsFilterBarPaddingPreference.default }
val LocalFeedsFilterBarTonalElevation =
compositionLocalOf<FeedsFilterBarTonalElevationPreference> { FeedsFilterBarTonalElevationPreference.default }
val LocalFeedsTopBarTonalElevation =
compositionLocalOf<FeedsTopBarTonalElevationPreference> { FeedsTopBarTonalElevationPreference.default }
val LocalFeedsGroupListExpand =
compositionLocalOf<FeedsGroupListExpandPreference> { FeedsGroupListExpandPreference.default }
val LocalFeedsGroupListTonalElevation =
compositionLocalOf<FeedsGroupListTonalElevationPreference> { FeedsGroupListTonalElevationPreference.default }
val LocalFlowFilterBarStyle =
compositionLocalOf<FlowFilterBarStylePreference> { FlowFilterBarStylePreference.default }
val LocalFlowFilterBarFilled =
compositionLocalOf<FlowFilterBarFilledPreference> { FlowFilterBarFilledPreference.default }
val LocalFlowFilterBarPadding =
compositionLocalOf { FlowFilterBarPaddingPreference.default }
val LocalFlowFilterBarTonalElevation =
compositionLocalOf<FlowFilterBarTonalElevationPreference> { FlowFilterBarTonalElevationPreference.default }
val LocalFlowTopBarTonalElevation =
compositionLocalOf<FlowTopBarTonalElevationPreference> { FlowTopBarTonalElevationPreference.default }
val LocalFlowArticleListFeedIcon =
compositionLocalOf<FlowArticleListFeedIconPreference> { FlowArticleListFeedIconPreference.default }
val LocalFlowArticleListFeedName =
compositionLocalOf<FlowArticleListFeedNamePreference> { FlowArticleListFeedNamePreference.default }
val LocalFlowArticleListImage =
compositionLocalOf<FlowArticleListImagePreference> { FlowArticleListImagePreference.default }
val LocalFlowArticleListDesc =
compositionLocalOf<FlowArticleListDescPreference> { FlowArticleListDescPreference.default }
val LocalFlowArticleListTime =
compositionLocalOf<FlowArticleListTimePreference> { FlowArticleListTimePreference.default }
val LocalFlowArticleListTonalElevation =
compositionLocalOf<FlowArticleListTonalElevationPreference> { FlowArticleListTonalElevationPreference.default }

View File

@ -1,28 +1,23 @@
package me.ash.reader.data.preference package me.ash.reader.data.preference
import android.content.Context import android.content.Context
import androidx.compose.runtime.Immutable import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put import me.ash.reader.ui.ext.put
@Immutable object ThemeIndexPreference {
object ThemePreference {
const val default = 5 const val default = 5
val Context.Theme: Flow<Int>
get() = this.dataStore.data.map {
it[DataStoreKeys.ThemeIndex.key] ?: default
}
fun put(context: Context, scope: CoroutineScope, value: Int) { fun put(context: Context, scope: CoroutineScope, value: Int) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
context.dataStore.put(DataStoreKeys.ThemeIndex, value) context.dataStore.put(DataStoreKeys.ThemeIndex, value)
} }
} }
fun fromPreferences(preferences: Preferences) =
preferences[DataStoreKeys.ThemeIndex.key] ?: default
} }

View File

@ -5,10 +5,12 @@ import android.util.Log
import androidx.datastore.core.DataStore import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.* import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStore import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import java.io.IOException import java.io.IOException
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings") val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
@ -32,8 +34,6 @@ val Context.currentAccountId: Int
val Context.currentAccountType: Int val Context.currentAccountType: Int
get() = this.dataStore.get(DataStoreKeys.CurrentAccountType)!! get() = this.dataStore.get(DataStoreKeys.CurrentAccountType)!!
val Context.customPrimaryColor: String
get() = this.dataStore.get(DataStoreKeys.CustomPrimaryColor) ?: ""
val Context.initialPage: Int val Context.initialPage: Int
get() = this.dataStore.get(DataStoreKeys.InitialPage) ?: 0 get() = this.dataStore.get(DataStoreKeys.InitialPage) ?: 0
val Context.initialFilter: Int val Context.initialFilter: Int
@ -41,8 +41,10 @@ val Context.initialFilter: Int
suspend fun <T> DataStore<Preferences>.put(dataStoreKeys: DataStoreKeys<T>, value: T) { suspend fun <T> DataStore<Preferences>.put(dataStoreKeys: DataStoreKeys<T>, value: T) {
this.edit { this.edit {
withContext(Dispatchers.IO) {
it[dataStoreKeys.key] = value it[dataStoreKeys.key] = value
} }
}
} }
fun <T> DataStore<Preferences>.putBlocking(dataStoreKeys: DataStoreKeys<T>, value: T) { fun <T> DataStore<Preferences>.putBlocking(dataStoreKeys: DataStoreKeys<T>, value: T) {
@ -208,9 +210,9 @@ sealed class DataStoreKeys<T> {
get() = booleanPreferencesKey("flowArticleListDesc") get() = booleanPreferencesKey("flowArticleListDesc")
} }
object FlowArticleListDate : DataStoreKeys<Boolean>() { object FlowArticleListTime : DataStoreKeys<Boolean>() {
override val key: Preferences.Key<Boolean> override val key: Preferences.Key<Boolean>
get() = booleanPreferencesKey("flowArticleListDate") get() = booleanPreferencesKey("flowArticleListTime")
} }
object FlowArticleListTonalElevation : DataStoreKeys<Int>() { object FlowArticleListTonalElevation : DataStoreKeys<Int>() {

View File

@ -36,6 +36,7 @@ fun HomeEntry(
homeViewModel: HomeViewModel = hiltViewModel(), homeViewModel: HomeViewModel = hiltViewModel(),
) { ) {
val context = LocalContext.current val context = LocalContext.current
val viewState = homeViewModel.viewState.collectAsStateValue() val viewState = homeViewModel.viewState.collectAsStateValue()
val filterState = homeViewModel.filterState.collectAsStateValue() val filterState = homeViewModel.filterState.collectAsStateValue()
val pagingItems = viewState.pagingData.collectAsLazyPagingItems() val pagingItems = viewState.pagingData.collectAsLazyPagingItems()

View File

@ -29,6 +29,7 @@ import androidx.navigation.NavHostController
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.data.entity.toVersion import me.ash.reader.data.entity.toVersion
import me.ash.reader.data.preference.*
import me.ash.reader.data.repository.SyncWorker.Companion.getIsSyncing import me.ash.reader.data.repository.SyncWorker.Companion.getIsSyncing
import me.ash.reader.ui.component.Banner import me.ash.reader.ui.component.Banner
import me.ash.reader.ui.component.DisplayText import me.ash.reader.ui.component.DisplayText
@ -45,7 +46,6 @@ import me.ash.reader.ui.page.home.feeds.option.group.GroupOptionDrawer
import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeDialog import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeDialog
import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewAction import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewAction
import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewModel import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewModel
import me.ash.reader.ui.theme.*
import me.ash.reader.ui.theme.palette.onDark import me.ash.reader.ui.theme.palette.onDark
@SuppressLint("FlowOperatorInvokedInComposition") @SuppressLint("FlowOperatorInvokedInComposition")
@ -127,17 +127,17 @@ fun FeedsPage(
Scaffold( Scaffold(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(topBarTonalElevation.dp)) .background(MaterialTheme.colorScheme.surfaceColorAtElevation(topBarTonalElevation.value.dp))
.statusBarsPadding() .statusBarsPadding()
.navigationBarsPadding(), .navigationBarsPadding(),
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
groupListTonalElevation.dp groupListTonalElevation.value.dp
) onDark MaterialTheme.colorScheme.surface, ) onDark MaterialTheme.colorScheme.surface,
topBar = { topBar = {
SmallTopAppBar( SmallTopAppBar(
colors = TopAppBarDefaults.smallTopAppBarColors( colors = TopAppBarDefaults.smallTopAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
topBarTonalElevation.dp topBarTonalElevation.value.dp
), ),
), ),
title = {}, title = {},
@ -222,8 +222,8 @@ fun FeedsPage(
// Crossfade(targetState = groupWithFeed) { groupWithFeed -> // Crossfade(targetState = groupWithFeed) { groupWithFeed ->
Column { Column {
GroupItem( GroupItem(
isExpanded = groupListExpand, isExpanded = groupListExpand.value,
tonalElevation = groupListTonalElevation.dp, tonalElevation = groupListTonalElevation.value.dp,
group = groupWithFeed.group, group = groupWithFeed.group,
feeds = groupWithFeed.feeds, feeds = groupWithFeed.feeds,
groupOnClick = { groupOnClick = {
@ -262,10 +262,10 @@ fun FeedsPage(
bottomBar = { bottomBar = {
FilterBar( FilterBar(
filter = filterState.filter, filter = filterState.filter,
filterBarStyle = filterBarStyle, filterBarStyle = filterBarStyle.value,
filterBarFilled = filterBarFilled, filterBarFilled = filterBarFilled.value,
filterBarPadding = filterBarPadding.dp, filterBarPadding = filterBarPadding.dp,
filterBarTonalElevation = filterBarTonalElevation.dp, filterBarTonalElevation = filterBarTonalElevation.value.dp,
) { ) {
filterChange( filterChange(
navController = navController, navController = navController,

View File

@ -21,8 +21,8 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.data.entity.ArticleWithFeed import me.ash.reader.data.entity.ArticleWithFeed
import me.ash.reader.data.preference.*
import me.ash.reader.ui.ext.formatAsString import me.ash.reader.ui.ext.formatAsString
import me.ash.reader.ui.theme.*
@Composable @Composable
fun ArticleItem( fun ArticleItem(
@ -35,7 +35,7 @@ fun ArticleItem(
val articleListFeedName = LocalFlowArticleListFeedName.current val articleListFeedName = LocalFlowArticleListFeedName.current
val articleListImage = LocalFlowArticleListImage.current val articleListImage = LocalFlowArticleListImage.current
val articleListDesc = LocalFlowArticleListDesc.current val articleListDesc = LocalFlowArticleListDesc.current
val articleListDate = LocalFlowArticleListDate.current val articleListDate = LocalFlowArticleListTime.current
Column( Column(
modifier = Modifier modifier = Modifier
@ -51,11 +51,11 @@ fun ArticleItem(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
// Feed name // Feed name
if (articleListFeedName) { if (articleListFeedName.value) {
Text( Text(
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.padding(start = if (articleListFeedIcon) 30.dp else 0.dp), .padding(start = if (articleListFeedIcon.value) 30.dp else 0.dp),
text = articleWithFeed.feed.name, text = articleWithFeed.feed.name,
color = MaterialTheme.colorScheme.tertiary, color = MaterialTheme.colorScheme.tertiary,
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
@ -64,12 +64,12 @@ fun ArticleItem(
) )
} }
if (articleListDate) { if (articleListDate.value) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
if (!articleListFeedName) { if (!articleListFeedName.value) {
Spacer(Modifier.width(if (articleListFeedIcon) 30.dp else 0.dp)) Spacer(Modifier.width(if (articleListFeedIcon.value) 30.dp else 0.dp))
} }
// Starred // Starred
if (articleWithFeed.article.isStarred) { if (articleWithFeed.article.isStarred) {
@ -99,7 +99,7 @@ fun ArticleItem(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
) { ) {
// Feed icon // Feed icon
if (articleListFeedIcon) { if (articleListFeedIcon.value) {
Row( Row(
modifier = Modifier modifier = Modifier
.size(20.dp) .size(20.dp)
@ -117,11 +117,11 @@ fun ArticleItem(
text = articleWithFeed.article.title, text = articleWithFeed.article.title,
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
maxLines = if (articleListDesc) 2 else 4, maxLines = if (articleListDesc.value) 2 else 4,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
) )
// Description // Description
if (articleListDesc) { if (articleListDesc.value) {
Text( Text(
text = articleWithFeed.article.shortDescription, text = articleWithFeed.article.shortDescription,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f), color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f),

View File

@ -15,7 +15,6 @@ import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -27,6 +26,7 @@ import androidx.paging.compose.LazyPagingItems
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.data.preference.*
import me.ash.reader.data.repository.SyncWorker.Companion.getIsSyncing import me.ash.reader.data.repository.SyncWorker.Companion.getIsSyncing
import me.ash.reader.ui.component.DisplayText import me.ash.reader.ui.component.DisplayText
import me.ash.reader.ui.component.FeedbackIconButton import me.ash.reader.ui.component.FeedbackIconButton
@ -39,7 +39,6 @@ import me.ash.reader.ui.page.home.FilterBar
import me.ash.reader.ui.page.home.FilterState import me.ash.reader.ui.page.home.FilterState
import me.ash.reader.ui.page.home.HomeViewAction import me.ash.reader.ui.page.home.HomeViewAction
import me.ash.reader.ui.page.home.HomeViewModel import me.ash.reader.ui.page.home.HomeViewModel
import me.ash.reader.ui.theme.*
import me.ash.reader.ui.theme.palette.onDark import me.ash.reader.ui.theme.palette.onDark
@OptIn( @OptIn(
@ -55,7 +54,6 @@ fun FlowPage(
homeViewModel: HomeViewModel, homeViewModel: HomeViewModel,
pagingItems: LazyPagingItems<FlowItemView>, pagingItems: LazyPagingItems<FlowItemView>,
) { ) {
val context = LocalContext.current
val keyboardController = LocalSoftwareKeyboardController.current val keyboardController = LocalSoftwareKeyboardController.current
val topBarTonalElevation = LocalFlowTopBarTonalElevation.current val topBarTonalElevation = LocalFlowTopBarTonalElevation.current
val articleListTonalElevation = LocalFlowArticleListTonalElevation.current val articleListTonalElevation = LocalFlowArticleListTonalElevation.current
@ -109,18 +107,18 @@ fun FlowPage(
Scaffold( Scaffold(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(topBarTonalElevation.dp)) .background(MaterialTheme.colorScheme.surfaceColorAtElevation(topBarTonalElevation.value.dp))
.statusBarsPadding() .statusBarsPadding()
.navigationBarsPadding(), .navigationBarsPadding(),
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
articleListTonalElevation.dp articleListTonalElevation.value.dp
) onDark MaterialTheme.colorScheme.surface, ) onDark MaterialTheme.colorScheme.surface,
topBar = { topBar = {
SmallTopAppBar( SmallTopAppBar(
title = {}, title = {},
colors = TopAppBarDefaults.smallTopAppBarColors( colors = TopAppBarDefaults.smallTopAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
topBarTonalElevation.dp topBarTonalElevation.value.dp
), ),
), ),
navigationIcon = { navigationIcon = {
@ -199,7 +197,7 @@ fun FlowPage(
state = listState, state = listState,
) { ) {
item { item {
DisplayTextHeader(filterState, isSyncing, articleListFeedIcon) DisplayTextHeader(filterState, isSyncing, articleListFeedIcon.value)
AnimatedVisibility( AnimatedVisibility(
visible = markAsRead, visible = markAsRead,
enter = fadeIn() + expandVertically(), enter = fadeIn() + expandVertically(),
@ -261,8 +259,8 @@ fun FlowPage(
} }
ArticleList( ArticleList(
pagingItems = pagingItems, pagingItems = pagingItems,
articleListFeedIcon = articleListFeedIcon, articleListFeedIcon = articleListFeedIcon.value,
articleListTonalElevation = articleListTonalElevation, articleListTonalElevation = articleListTonalElevation.value,
) { ) {
onSearch = false onSearch = false
navController.navigate("${RouteName.READING}/${it.article.id}") { navController.navigate("${RouteName.READING}/${it.article.id}") {
@ -281,10 +279,10 @@ fun FlowPage(
bottomBar = { bottomBar = {
FilterBar( FilterBar(
filter = filterState.filter, filter = filterState.filter,
filterBarStyle = filterBarStyle, filterBarStyle = filterBarStyle.value,
filterBarFilled = filterBarFilled, filterBarFilled = filterBarFilled.value,
filterBarPadding = filterBarPadding.dp, filterBarPadding = filterBarPadding.dp,
filterBarTonalElevation = filterBarTonalElevation.dp, filterBarTonalElevation = filterBarTonalElevation.value.dp,
) { ) {
flowViewModel.dispatch(FlowViewAction.ScrollToItem(0)) flowViewModel.dispatch(FlowViewAction.ScrollToItem(0))
homeViewModel.dispatch(HomeViewAction.ChangeFilter(filterState.copy(filter = it))) homeViewModel.dispatch(HomeViewAction.ChangeFilter(filterState.copy(filter = it)))

View File

@ -1,6 +1,7 @@
package me.ash.reader.ui.page.settings.color package me.ash.reader.ui.page.settings.color
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context
import android.os.Build import android.os.Build
import androidx.compose.animation.* import androidx.compose.animation.*
import androidx.compose.foundation.background import androidx.compose.foundation.background
@ -24,21 +25,16 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.data.preference.ThemePreference import me.ash.reader.data.preference.CustomPrimaryColorPreference
import me.ash.reader.data.preference.LocalCustomPrimaryColor
import me.ash.reader.data.preference.LocalThemeIndex
import me.ash.reader.data.preference.ThemeIndexPreference
import me.ash.reader.ui.component.* import me.ash.reader.ui.component.*
import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.customPrimaryColor
import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put
import me.ash.reader.ui.page.common.RouteName import me.ash.reader.ui.page.common.RouteName
import me.ash.reader.ui.page.settings.SettingItem import me.ash.reader.ui.page.settings.SettingItem
import me.ash.reader.ui.svg.PALETTE import me.ash.reader.ui.svg.PALETTE
import me.ash.reader.ui.svg.SVGString import me.ash.reader.ui.svg.SVGString
import me.ash.reader.ui.theme.LocalTheme
import me.ash.reader.ui.theme.LocalUseDarkTheme import me.ash.reader.ui.theme.LocalUseDarkTheme
import me.ash.reader.ui.theme.palette.* import me.ash.reader.ui.theme.palette.*
import me.ash.reader.ui.theme.palette.TonalPalettes.Companion.toTonalPalettes import me.ash.reader.ui.theme.palette.TonalPalettes.Companion.toTonalPalettes
@ -52,9 +48,11 @@ fun ColorAndStyle(
) { ) {
val context = LocalContext.current val context = LocalContext.current
val useDarkTheme = LocalUseDarkTheme.current val useDarkTheme = LocalUseDarkTheme.current
val theme = LocalTheme.current val themeIndex = LocalThemeIndex.current
val customPrimaryColor = LocalCustomPrimaryColor.current
val wallpaperTonalPalettes = extractTonalPalettesFromUserWallpaper() val wallpaperTonalPalettes = extractTonalPalettesFromUserWallpaper()
var radioButtonSelected by remember { mutableStateOf(if (theme > 4) 0 else 1) } var radioButtonSelected by remember { mutableStateOf(if (themeIndex > 4) 0 else 1) }
Scaffold( Scaffold(
modifier = Modifier modifier = Modifier
@ -118,6 +116,7 @@ fun ColorAndStyle(
onClick = {}, onClick = {},
) { ) {
Palettes( Palettes(
context = context,
palettes = wallpaperTonalPalettes.run { palettes = wallpaperTonalPalettes.run {
if (this.size > 5) { if (this.size > 5) {
this.subList(5, wallpaperTonalPalettes.size) this.subList(5, wallpaperTonalPalettes.size)
@ -125,7 +124,9 @@ fun ColorAndStyle(
emptyList() emptyList()
} }
}, },
themeIndex = themeIndex,
themeIndexPrefix = 5, themeIndexPrefix = 5,
customPrimaryColor = customPrimaryColor,
) )
}, },
BlockRadioGroupButtonItem( BlockRadioGroupButtonItem(
@ -133,7 +134,10 @@ fun ColorAndStyle(
onClick = {}, onClick = {},
) { ) {
Palettes( Palettes(
palettes = wallpaperTonalPalettes.subList(0, 5) context = context,
themeIndex = themeIndex,
palettes = wallpaperTonalPalettes.subList(0, 5),
customPrimaryColor = customPrimaryColor,
) )
}, },
), ),
@ -199,20 +203,16 @@ fun ColorAndStyle(
@Composable @Composable
fun Palettes( fun Palettes(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
context: Context,
palettes: List<TonalPalettes>, palettes: List<TonalPalettes>,
themeIndex: Int = 0,
themeIndexPrefix: Int = 0, themeIndexPrefix: Int = 0,
customPrimaryColor: String = "",
) { ) {
val context = LocalContext.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val themeIndex = context.dataStore.data
.map { it[DataStoreKeys.ThemeIndex.key] ?: 5 }
.collectAsState(initial = 5).value
val customPrimaryColor = context.dataStore.data
.map { it[DataStoreKeys.CustomPrimaryColor.key] ?: "" }
.collectAsState(initial = "").value
val tonalPalettes = customPrimaryColor.safeHexToColor().toTonalPalettes() val tonalPalettes = customPrimaryColor.safeHexToColor().toTonalPalettes()
var addDialogVisible by remember { mutableStateOf(false) } var addDialogVisible by remember { mutableStateOf(false) }
var customColorValue by remember { mutableStateOf(context.customPrimaryColor) } var customColorValue by remember { mutableStateOf(customPrimaryColor) }
if (palettes.isEmpty()) { if (palettes.isEmpty()) {
Row( Row(
@ -252,9 +252,10 @@ fun Palettes(
isCustom = isCustom, isCustom = isCustom,
onClick = { onClick = {
if (isCustom) { if (isCustom) {
customColorValue = customPrimaryColor
addDialogVisible = true addDialogVisible = true
} else { } else {
ThemePreference.put(context, scope, themeIndexPrefix + index) ThemeIndexPreference.put(context, scope, themeIndexPrefix + index)
} }
}, },
palette = if (isCustom) tonalPalettes else palette palette = if (isCustom) tonalPalettes else palette
@ -274,16 +275,12 @@ fun Palettes(
}, },
onDismissRequest = { onDismissRequest = {
addDialogVisible = false addDialogVisible = false
customColorValue = context.customPrimaryColor
}, },
onConfirm = { onConfirm = {
it.checkColorHex()?.let { it.checkColorHex()?.let {
scope.launch(Dispatchers.IO) { CustomPrimaryColorPreference.put(context, scope, it)
context.dataStore.put(DataStoreKeys.CustomPrimaryColor, it) ThemeIndexPreference.put(context, scope, 4)
context.dataStore.put(DataStoreKeys.ThemeIndex, 4)
}
addDialogVisible = false addDialogVisible = false
customColorValue = it
} }
} }
) )

View File

@ -24,15 +24,7 @@ import me.ash.reader.data.entity.Feed
import me.ash.reader.data.entity.Filter import me.ash.reader.data.entity.Filter
import me.ash.reader.data.entity.Group import me.ash.reader.data.entity.Group
import me.ash.reader.data.preference.* import me.ash.reader.data.preference.*
import me.ash.reader.data.preference.FeedsFilterBarFilledPreference.Companion.feedsFilterBarFilled
import me.ash.reader.data.preference.FeedsFilterBarPaddingPreference.feedsFilterBarPadding
import me.ash.reader.data.preference.FeedsFilterBarStylePreference.Companion.feedsFilterBarStyle
import me.ash.reader.data.preference.FeedsFilterBarTonalElevationPreference.Companion.feedsFilterBarTonalElevation
import me.ash.reader.data.preference.FeedsGroupListExpandPreference.Companion.feedsGroupListExpand
import me.ash.reader.data.preference.FeedsGroupListTonalElevationPreference.Companion.feedsGroupListTonalElevation
import me.ash.reader.data.preference.FeedsTopBarTonalElevationPreference.Companion.feedsTopBarTonalElevation
import me.ash.reader.ui.component.* import me.ash.reader.ui.component.*
import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.ext.surfaceColorAtElevation import me.ash.reader.ui.ext.surfaceColorAtElevation
import me.ash.reader.ui.page.home.FilterBar import me.ash.reader.ui.page.home.FilterBar
import me.ash.reader.ui.page.home.feeds.GroupItem import me.ash.reader.ui.page.home.feeds.GroupItem
@ -46,21 +38,15 @@ fun FeedsPageStyle(
navController: NavHostController, navController: NavHostController,
) { ) {
val context = LocalContext.current val context = LocalContext.current
val filterBarStyle = LocalFeedsFilterBarStyle.current
val filterBarFilled = LocalFeedsFilterBarFilled.current
val filterBarPadding = LocalFeedsFilterBarPadding.current
val filterBarTonalElevation = LocalFeedsFilterBarTonalElevation.current
val topBarTonalElevation = LocalFeedsTopBarTonalElevation.current
val groupListExpand = LocalFeedsGroupListExpand.current
val groupListTonalElevation = LocalFeedsGroupListTonalElevation.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val filterBarStyle =
context.feedsFilterBarStyle.collectAsStateValue(initial = FeedsFilterBarStylePreference.default)
val filterBarFilled =
context.feedsFilterBarFilled.collectAsStateValue(initial = FeedsFilterBarFilledPreference.default)
val filterBarPadding =
context.feedsFilterBarPadding.collectAsStateValue(initial = FeedsFilterBarPaddingPreference.default)
val filterBarTonalElevation =
context.feedsFilterBarTonalElevation.collectAsStateValue(initial = FeedsFilterBarTonalElevationPreference.default)
val topBarTonalElevation =
context.feedsTopBarTonalElevation.collectAsStateValue(initial = FeedsTopBarTonalElevationPreference.default)
val groupListExpand =
context.feedsGroupListExpand.collectAsStateValue(initial = FeedsGroupListExpandPreference.default)
val groupListTonalElevation =
context.feedsGroupListTonalElevation.collectAsStateValue(initial = FeedsGroupListTonalElevationPreference.default)
var filterBarStyleDialogVisible by remember { mutableStateOf(false) } var filterBarStyleDialogVisible by remember { mutableStateOf(false) }
var filterBarPaddingDialogVisible by remember { mutableStateOf(false) } var filterBarPaddingDialogVisible by remember { mutableStateOf(false) }
@ -141,7 +127,7 @@ fun FeedsPageStyle(
topBarTonalElevationDialogVisible = true topBarTonalElevationDialogVisible = true
}, },
) {} ) {}
Tips(text = stringResource(R.string.tips_top_bar_tonal_elevation)) // Tips(text = stringResource(R.string.tips_top_bar_tonal_elevation))
Spacer(modifier = Modifier.height(24.dp)) Spacer(modifier = Modifier.height(24.dp))
} }
@ -254,7 +240,7 @@ fun FeedsPageStyle(
options = FeedsFilterBarTonalElevationPreference.values.map { options = FeedsFilterBarTonalElevationPreference.values.map {
RadioDialogOption( RadioDialogOption(
text = it.getDesc(context), text = it.getDesc(context),
selected = filterBarTonalElevation == it, selected = it == filterBarTonalElevation,
) { ) {
it.put(context, scope) it.put(context, scope)
} }
@ -269,7 +255,7 @@ fun FeedsPageStyle(
options = FeedsTopBarTonalElevationPreference.values.map { options = FeedsTopBarTonalElevationPreference.values.map {
RadioDialogOption( RadioDialogOption(
text = it.getDesc(context), text = it.getDesc(context),
selected = topBarTonalElevation == it, selected = it == topBarTonalElevation,
) { ) {
it.put(context, scope) it.put(context, scope)
} }
@ -284,7 +270,7 @@ fun FeedsPageStyle(
options = FeedsGroupListTonalElevationPreference.values.map { options = FeedsGroupListTonalElevationPreference.values.map {
RadioDialogOption( RadioDialogOption(
text = it.getDesc(context), text = it.getDesc(context),
selected = groupListTonalElevation == it, selected = it == groupListTonalElevation,
) { ) {
it.put(context, scope) it.put(context, scope)
} }

View File

@ -26,19 +26,7 @@ import me.ash.reader.data.entity.ArticleWithFeed
import me.ash.reader.data.entity.Feed import me.ash.reader.data.entity.Feed
import me.ash.reader.data.entity.Filter import me.ash.reader.data.entity.Filter
import me.ash.reader.data.preference.* import me.ash.reader.data.preference.*
import me.ash.reader.data.preference.FlowArticleListDatePreference.Companion.flowArticleListDate
import me.ash.reader.data.preference.FlowArticleListDescPreference.Companion.flowArticleListDesc
import me.ash.reader.data.preference.FlowArticleListFeedIconPreference.Companion.flowArticleListFeedIcon
import me.ash.reader.data.preference.FlowArticleListFeedNamePreference.Companion.flowArticleListFeedName
import me.ash.reader.data.preference.FlowArticleListImagePreference.Companion.flowArticleListImage
import me.ash.reader.data.preference.FlowArticleListTonalElevationPreference.Companion.flowArticleListTonalElevation
import me.ash.reader.data.preference.FlowFilterBarFilledPreference.Companion.flowFilterBarFilled
import me.ash.reader.data.preference.FlowFilterBarPaddingPreference.flowFilterBarPadding
import me.ash.reader.data.preference.FlowFilterBarStylePreference.Companion.flowFilterBarStyle
import me.ash.reader.data.preference.FlowFilterBarTonalElevationPreference.Companion.flowFilterBarTonalElevation
import me.ash.reader.data.preference.FlowTopBarTonalElevationPreference.Companion.flowTopBarTonalElevation
import me.ash.reader.ui.component.* import me.ash.reader.ui.component.*
import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.ext.surfaceColorAtElevation import me.ash.reader.ui.ext.surfaceColorAtElevation
import me.ash.reader.ui.page.home.FilterBar import me.ash.reader.ui.page.home.FilterBar
import me.ash.reader.ui.page.home.flow.ArticleItem import me.ash.reader.ui.page.home.flow.ArticleItem
@ -54,29 +42,19 @@ fun FlowPageStyle(
navController: NavHostController, navController: NavHostController,
) { ) {
val context = LocalContext.current val context = LocalContext.current
val filterBarStyle = LocalFlowFilterBarStyle.current
val filterBarFilled = LocalFlowFilterBarFilled.current
val filterBarPadding = LocalFlowFilterBarPadding.current
val filterBarTonalElevation = LocalFlowFilterBarTonalElevation.current
val topBarTonalElevation = LocalFlowTopBarTonalElevation.current
val articleListFeedIcon = LocalFlowArticleListFeedIcon.current
val articleListFeedName = LocalFlowArticleListFeedName.current
val articleListImage = LocalFlowArticleListImage.current
val articleListDesc = LocalFlowArticleListDesc.current
val articleListDate = LocalFlowArticleListTime.current
val articleListTonalElevation = LocalFlowArticleListTonalElevation.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val filterBarStyle =
context.flowFilterBarStyle.collectAsStateValue(initial = FlowFilterBarStylePreference.default)
val filterBarFilled =
context.flowFilterBarFilled.collectAsStateValue(initial = FlowFilterBarFilledPreference.default)
val filterBarPadding =
context.flowFilterBarPadding.collectAsStateValue(initial = FlowFilterBarPaddingPreference.default)
val filterBarTonalElevation =
context.flowFilterBarTonalElevation.collectAsStateValue(initial = FlowFilterBarTonalElevationPreference.default)
val topBarTonalElevation =
context.flowTopBarTonalElevation.collectAsStateValue(initial = FlowTopBarTonalElevationPreference.default)
val articleListFeedIcon =
context.flowArticleListFeedIcon.collectAsStateValue(initial = FlowArticleListFeedIconPreference.default)
val articleListFeedName =
context.flowArticleListFeedName.collectAsStateValue(initial = FlowArticleListFeedNamePreference.default)
val articleListImage =
context.flowArticleListImage.collectAsStateValue(initial = FlowArticleListImagePreference.default)
val articleListDesc =
context.flowArticleListDesc.collectAsStateValue(initial = FlowArticleListDescPreference.default)
val articleListDate =
context.flowArticleListDate.collectAsStateValue(initial = FlowArticleListDatePreference.default)
val articleListTonalElevation =
context.flowArticleListTonalElevation.collectAsStateValue(initial = FlowArticleListTonalElevationPreference.default)
var filterBarStyleDialogVisible by remember { mutableStateOf(false) } var filterBarStyleDialogVisible by remember { mutableStateOf(false) }
var filterBarPaddingDialogVisible by remember { mutableStateOf(false) } var filterBarPaddingDialogVisible by remember { mutableStateOf(false) }
@ -162,7 +140,7 @@ fun FlowPageStyle(
topBarTonalElevationDialogVisible = true topBarTonalElevationDialogVisible = true
}, },
) {} ) {}
Tips(text = stringResource(R.string.tips_top_bar_tonal_elevation)) // Tips(text = stringResource(R.string.tips_top_bar_tonal_elevation))
Spacer(modifier = Modifier.height(24.dp)) Spacer(modifier = Modifier.height(24.dp))
} }
@ -280,7 +258,7 @@ fun FlowPageStyle(
options = FlowFilterBarStylePreference.values.map { options = FlowFilterBarStylePreference.values.map {
RadioDialogOption( RadioDialogOption(
text = it.getDesc(context), text = it.getDesc(context),
selected = filterBarStyle == it, selected = it == filterBarStyle,
) { ) {
it.put(context, scope) it.put(context, scope)
} }
@ -312,7 +290,7 @@ fun FlowPageStyle(
options = FlowFilterBarTonalElevationPreference.values.map { options = FlowFilterBarTonalElevationPreference.values.map {
RadioDialogOption( RadioDialogOption(
text = it.getDesc(context), text = it.getDesc(context),
selected = filterBarTonalElevation == it, selected = it == filterBarTonalElevation,
) { ) {
it.put(context, scope) it.put(context, scope)
} }
@ -327,7 +305,7 @@ fun FlowPageStyle(
options = FlowTopBarTonalElevationPreference.values.map { options = FlowTopBarTonalElevationPreference.values.map {
RadioDialogOption( RadioDialogOption(
text = it.getDesc(context), text = it.getDesc(context),
selected = topBarTonalElevation == it, selected = it == topBarTonalElevation,
) { ) {
it.put(context, scope) it.put(context, scope)
} }
@ -342,7 +320,7 @@ fun FlowPageStyle(
options = FlowArticleListTonalElevationPreference.values.map { options = FlowArticleListTonalElevationPreference.values.map {
RadioDialogOption( RadioDialogOption(
text = it.getDesc(context), text = it.getDesc(context),
selected = articleListTonalElevation == it, selected = it == articleListTonalElevation,
) { ) {
it.put(context, scope) it.put(context, scope)
} }

View File

@ -10,11 +10,9 @@ import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.R import me.ash.reader.R
@ -32,7 +30,6 @@ fun Interaction(
navController: NavHostController, navController: NavHostController,
) { ) {
val context = LocalContext.current val context = LocalContext.current
val view = LocalView.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
var initialPageDialogVisible by remember { mutableStateOf(false) } var initialPageDialogVisible by remember { mutableStateOf(false) }
var initialFilterDialogVisible by remember { mutableStateOf(false) } var initialFilterDialogVisible by remember { mutableStateOf(false) }
@ -116,7 +113,7 @@ fun Interaction(
text = stringResource(R.string.feeds_page), text = stringResource(R.string.feeds_page),
selected = initialPage == 0, selected = initialPage == 0,
) { ) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put(DataStoreKeys.InitialPage, 0) context.dataStore.put(DataStoreKeys.InitialPage, 0)
} }
}, },
@ -124,7 +121,7 @@ fun Interaction(
text = stringResource(R.string.flow_page), text = stringResource(R.string.flow_page),
selected = initialPage == 1, selected = initialPage == 1,
) { ) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put(DataStoreKeys.InitialPage, 1) context.dataStore.put(DataStoreKeys.InitialPage, 1)
} }
}, },
@ -141,7 +138,7 @@ fun Interaction(
text = stringResource(R.string.starred), text = stringResource(R.string.starred),
selected = initialFilter == 0, selected = initialFilter == 0,
) { ) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put(DataStoreKeys.InitialFilter, 0) context.dataStore.put(DataStoreKeys.InitialFilter, 0)
} }
}, },
@ -149,7 +146,7 @@ fun Interaction(
text = stringResource(R.string.unread), text = stringResource(R.string.unread),
selected = initialFilter == 1, selected = initialFilter == 1,
) { ) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put(DataStoreKeys.InitialFilter, 1) context.dataStore.put(DataStoreKeys.InitialFilter, 1)
} }
}, },
@ -157,7 +154,7 @@ fun Interaction(
text = stringResource(R.string.all), text = stringResource(R.string.all),
selected = initialFilter == 2, selected = initialFilter == 2,
) { ) {
scope.launch(Dispatchers.IO) { scope.launch {
context.dataStore.put(DataStoreKeys.InitialFilter, 2) context.dataStore.put(DataStoreKeys.InitialFilter, 2)
} }
}, },

View File

@ -1,33 +1,11 @@
package me.ash.reader.ui.theme package me.ash.reader.ui.theme
import android.annotation.SuppressLint
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.platform.LocalContext import me.ash.reader.data.preference.LocalThemeIndex
import me.ash.reader.data.preference.*
import me.ash.reader.data.preference.FeedsFilterBarFilledPreference.Companion.feedsFilterBarFilled
import me.ash.reader.data.preference.FeedsFilterBarPaddingPreference.feedsFilterBarPadding
import me.ash.reader.data.preference.FeedsFilterBarStylePreference.Companion.feedsFilterBarStyle
import me.ash.reader.data.preference.FeedsFilterBarTonalElevationPreference.Companion.feedsFilterBarTonalElevation
import me.ash.reader.data.preference.FeedsGroupListExpandPreference.Companion.feedsGroupListExpand
import me.ash.reader.data.preference.FeedsGroupListTonalElevationPreference.Companion.feedsGroupListTonalElevation
import me.ash.reader.data.preference.FeedsTopBarTonalElevationPreference.Companion.feedsTopBarTonalElevation
import me.ash.reader.data.preference.FlowArticleListDatePreference.Companion.flowArticleListDate
import me.ash.reader.data.preference.FlowArticleListDescPreference.Companion.flowArticleListDesc
import me.ash.reader.data.preference.FlowArticleListFeedIconPreference.Companion.flowArticleListFeedIcon
import me.ash.reader.data.preference.FlowArticleListFeedNamePreference.Companion.flowArticleListFeedName
import me.ash.reader.data.preference.FlowArticleListImagePreference.Companion.flowArticleListImage
import me.ash.reader.data.preference.FlowArticleListTonalElevationPreference.Companion.flowArticleListTonalElevation
import me.ash.reader.data.preference.FlowFilterBarFilledPreference.Companion.flowFilterBarFilled
import me.ash.reader.data.preference.FlowFilterBarPaddingPreference.flowFilterBarPadding
import me.ash.reader.data.preference.FlowFilterBarStylePreference.Companion.flowFilterBarStyle
import me.ash.reader.data.preference.FlowFilterBarTonalElevationPreference.Companion.flowFilterBarTonalElevation
import me.ash.reader.data.preference.FlowTopBarTonalElevationPreference.Companion.flowTopBarTonalElevation
import me.ash.reader.data.preference.ThemePreference.Theme
import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.theme.palette.LocalTonalPalettes import me.ash.reader.ui.theme.palette.LocalTonalPalettes
import me.ash.reader.ui.theme.palette.TonalPalettes import me.ash.reader.ui.theme.palette.TonalPalettes
import me.ash.reader.ui.theme.palette.core.ProvideZcamViewingConditions import me.ash.reader.ui.theme.palette.core.ProvideZcamViewingConditions
@ -36,122 +14,31 @@ import me.ash.reader.ui.theme.palette.dynamicDarkColorScheme
import me.ash.reader.ui.theme.palette.dynamicLightColorScheme import me.ash.reader.ui.theme.palette.dynamicLightColorScheme
val LocalUseDarkTheme = compositionLocalOf { false } val LocalUseDarkTheme = compositionLocalOf { false }
val LocalTheme = compositionLocalOf { ThemePreference.default }
val LocalFeedsFilterBarStyle = compositionLocalOf { FeedsFilterBarStylePreference.default.value }
val LocalFeedsFilterBarFilled = compositionLocalOf { FeedsFilterBarFilledPreference.default.value }
val LocalFeedsFilterBarPadding = compositionLocalOf { FeedsFilterBarPaddingPreference.default }
val LocalFeedsFilterBarTonalElevation =
compositionLocalOf { FeedsFilterBarTonalElevationPreference.default.value }
val LocalFeedsTopBarTonalElevation =
compositionLocalOf { FeedsTopBarTonalElevationPreference.default.value }
val LocalFeedsGroupListExpand =
compositionLocalOf { FeedsGroupListExpandPreference.default.value }
val LocalFeedsGroupListTonalElevation =
compositionLocalOf { FeedsGroupListTonalElevationPreference.default.value }
val LocalFlowFilterBarStyle = compositionLocalOf { FlowFilterBarStylePreference.default.value }
val LocalFlowFilterBarFilled = compositionLocalOf { FlowFilterBarFilledPreference.default.value }
val LocalFlowFilterBarPadding = compositionLocalOf { FlowFilterBarPaddingPreference.default }
val LocalFlowFilterBarTonalElevation =
compositionLocalOf { FlowFilterBarTonalElevationPreference.default.value }
val LocalFlowTopBarTonalElevation =
compositionLocalOf { FlowTopBarTonalElevationPreference.default.value }
val LocalFlowArticleListFeedIcon =
compositionLocalOf { FlowArticleListFeedIconPreference.default.value }
val LocalFlowArticleListFeedName =
compositionLocalOf { FlowArticleListFeedNamePreference.default.value }
val LocalFlowArticleListImage = compositionLocalOf { FlowArticleListImagePreference.default.value }
val LocalFlowArticleListDesc = compositionLocalOf { FlowArticleListDescPreference.default.value }
val LocalFlowArticleListDate = compositionLocalOf { FlowArticleListDatePreference.default.value }
val LocalFlowArticleListTonalElevation =
compositionLocalOf { FlowArticleListTonalElevationPreference.default.value }
@SuppressLint("FlowOperatorInvokedInComposition")
@Composable @Composable
fun AppTheme( fun AppTheme(
useDarkTheme: Boolean = isSystemInDarkTheme(), useDarkTheme: Boolean = isSystemInDarkTheme(),
wallpaperPalettes: List<TonalPalettes> = extractTonalPalettesFromUserWallpaper(), wallpaperPalettes: List<TonalPalettes> = extractTonalPalettesFromUserWallpaper(),
content: @Composable () -> Unit content: @Composable () -> Unit
) { ) {
val context = LocalContext.current val themeIndex = LocalThemeIndex.current
val theme = context.Theme.collectAsStateValue(initial = ThemePreference.default)
val tonalPalettes = wallpaperPalettes[ val tonalPalettes = wallpaperPalettes[
if (theme >= wallpaperPalettes.size) { if (themeIndex >= wallpaperPalettes.size) {
when { when {
wallpaperPalettes.size == 5 -> 0 wallpaperPalettes.size == 5 -> 0
wallpaperPalettes.size > 5 -> 5 wallpaperPalettes.size > 5 -> 5
else -> 0 else -> 0
} }
} else { } else {
theme themeIndex
} }
] ]
val feedsFilterBarStyle =
context.feedsFilterBarStyle.collectAsStateValue(initial = FeedsFilterBarStylePreference.default)
val feedsFilterBarFilled =
context.feedsFilterBarFilled.collectAsStateValue(initial = FeedsFilterBarFilledPreference.default)
val feedsFilterBarPadding =
context.feedsFilterBarPadding.collectAsStateValue(initial = FeedsFilterBarPaddingPreference.default)
val feedsFilterBarTonalElevation =
context.feedsFilterBarTonalElevation.collectAsStateValue(initial = FeedsFilterBarTonalElevationPreference.default)
val feedsTopBarTonalElevation =
context.feedsTopBarTonalElevation.collectAsStateValue(initial = FeedsTopBarTonalElevationPreference.default)
val feedsGroupListExpand =
context.feedsGroupListExpand.collectAsStateValue(initial = FeedsGroupListExpandPreference.default)
val feedsGroupListTonalElevation =
context.feedsGroupListTonalElevation.collectAsStateValue(initial = FeedsGroupListTonalElevationPreference.default)
val flowFilterBarStyle =
context.flowFilterBarStyle.collectAsStateValue(initial = FlowFilterBarStylePreference.default)
val flowFilterBarFilled =
context.flowFilterBarFilled.collectAsStateValue(initial = FlowFilterBarFilledPreference.default)
val flowFilterBarPadding =
context.flowFilterBarPadding.collectAsStateValue(initial = FlowFilterBarPaddingPreference.default)
val flowFilterBarTonalElevation =
context.flowFilterBarTonalElevation.collectAsStateValue(initial = FlowFilterBarTonalElevationPreference.default)
val flowTopBarTonalElevation =
context.flowTopBarTonalElevation.collectAsStateValue(initial = FlowTopBarTonalElevationPreference.default)
val flowArticleListFeedIcon =
context.flowArticleListFeedIcon.collectAsStateValue(initial = FlowArticleListFeedIconPreference.default)
val flowArticleListFeedName =
context.flowArticleListFeedName.collectAsStateValue(initial = FlowArticleListFeedNamePreference.default)
val flowArticleListImage =
context.flowArticleListImage.collectAsStateValue(initial = FlowArticleListImagePreference.default)
val flowArticleListDesc =
context.flowArticleListDesc.collectAsStateValue(initial = FlowArticleListDescPreference.default)
val flowArticleListDate =
context.flowArticleListDate.collectAsStateValue(initial = FlowArticleListDatePreference.default)
val flowArticleListTonalElevation =
context.flowArticleListTonalElevation.collectAsStateValue(initial = FlowArticleListTonalElevationPreference.default)
ProvideZcamViewingConditions { ProvideZcamViewingConditions {
CompositionLocalProvider( CompositionLocalProvider(
LocalTonalPalettes provides tonalPalettes.also { it.Preheating() }, LocalTonalPalettes provides tonalPalettes.also { it.Preheating() },
LocalUseDarkTheme provides useDarkTheme, LocalUseDarkTheme provides useDarkTheme,
LocalTheme provides theme,
LocalFeedsFilterBarStyle provides feedsFilterBarStyle.value,
LocalFeedsFilterBarFilled provides feedsFilterBarFilled.value,
LocalFeedsFilterBarPadding provides feedsFilterBarPadding,
LocalFeedsFilterBarTonalElevation provides feedsFilterBarTonalElevation.value,
LocalFeedsTopBarTonalElevation provides feedsTopBarTonalElevation.value,
LocalFeedsGroupListExpand provides feedsGroupListExpand.value,
LocalFeedsGroupListTonalElevation provides feedsGroupListTonalElevation.value,
LocalFlowFilterBarStyle provides flowFilterBarStyle.value,
LocalFlowFilterBarFilled provides flowFilterBarFilled.value,
LocalFlowFilterBarPadding provides flowFilterBarPadding,
LocalFlowFilterBarTonalElevation provides flowFilterBarTonalElevation.value,
LocalFlowTopBarTonalElevation provides flowTopBarTonalElevation.value,
LocalFlowArticleListFeedIcon provides flowArticleListFeedIcon.value,
LocalFlowArticleListFeedName provides flowArticleListFeedName.value,
LocalFlowArticleListImage provides flowArticleListImage.value,
LocalFlowArticleListDesc provides flowArticleListDesc.value,
LocalFlowArticleListDate provides flowArticleListDate.value,
LocalFlowArticleListTonalElevation provides flowArticleListTonalElevation.value,
) { ) {
MaterialTheme( MaterialTheme(
colorScheme = colorScheme =