Add the StickyHeader switch for the article list

This commit is contained in:
Ash 2022-05-02 21:03:33 +08:00
parent 1ba205343e
commit 263c583f49
10 changed files with 86 additions and 9 deletions

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 FlowArticleListDateStickyHeaderPreference(val value: Boolean) : Preference() {
object ON : FlowArticleListDateStickyHeaderPreference(true)
object OFF : FlowArticleListDateStickyHeaderPreference(false)
override fun put(context: Context, scope: CoroutineScope) {
scope.launch {
context.dataStore.put(
DataStoreKeys.FlowArticleListDateStickyHeader,
value
)
}
}
companion object {
val default = ON
val values = listOf(ON, OFF)
fun fromPreferences(preferences: Preferences) =
when (preferences[DataStoreKeys.FlowArticleListDateStickyHeader.key]) {
true -> ON
false -> OFF
else -> default
}
}
}
operator fun FlowArticleListDateStickyHeaderPreference.not(): FlowArticleListDateStickyHeaderPreference =
when (value) {
true -> FlowArticleListDateStickyHeaderPreference.OFF
false -> FlowArticleListDateStickyHeaderPreference.ON
}

View File

@ -33,6 +33,7 @@ data class Settings(
val flowArticleListImage: FlowArticleListImagePreference = FlowArticleListImagePreference.default, val flowArticleListImage: FlowArticleListImagePreference = FlowArticleListImagePreference.default,
val flowArticleListDesc: FlowArticleListDescPreference = FlowArticleListDescPreference.default, val flowArticleListDesc: FlowArticleListDescPreference = FlowArticleListDescPreference.default,
val flowArticleListTime: FlowArticleListTimePreference = FlowArticleListTimePreference.default, val flowArticleListTime: FlowArticleListTimePreference = FlowArticleListTimePreference.default,
val flowArticleListDateStickyHeader: FlowArticleListDateStickyHeaderPreference = FlowArticleListDateStickyHeaderPreference.default,
val flowArticleListTonalElevation: FlowArticleListTonalElevationPreference = FlowArticleListTonalElevationPreference.default, val flowArticleListTonalElevation: FlowArticleListTonalElevationPreference = FlowArticleListTonalElevationPreference.default,
) )
@ -59,6 +60,7 @@ fun Preferences.toSettings(): Settings {
flowArticleListImage = FlowArticleListImagePreference.fromPreferences(this), flowArticleListImage = FlowArticleListImagePreference.fromPreferences(this),
flowArticleListDesc = FlowArticleListDescPreference.fromPreferences(this), flowArticleListDesc = FlowArticleListDescPreference.fromPreferences(this),
flowArticleListTime = FlowArticleListTimePreference.fromPreferences(this), flowArticleListTime = FlowArticleListTimePreference.fromPreferences(this),
flowArticleListDateStickyHeader = FlowArticleListDateStickyHeaderPreference.fromPreferences(this),
flowArticleListTonalElevation = FlowArticleListTonalElevationPreference.fromPreferences(this), flowArticleListTonalElevation = FlowArticleListTonalElevationPreference.fromPreferences(this),
) )
} }
@ -93,6 +95,7 @@ fun SettingsProvider(
LocalFlowArticleListImage provides settings.flowArticleListImage, LocalFlowArticleListImage provides settings.flowArticleListImage,
LocalFlowArticleListDesc provides settings.flowArticleListDesc, LocalFlowArticleListDesc provides settings.flowArticleListDesc,
LocalFlowArticleListTime provides settings.flowArticleListTime, LocalFlowArticleListTime provides settings.flowArticleListTime,
LocalFlowArticleListDateStickyHeader provides settings.flowArticleListDateStickyHeader,
LocalFlowArticleListTonalElevation provides settings.flowArticleListTonalElevation, LocalFlowArticleListTonalElevation provides settings.flowArticleListTonalElevation,
LocalFlowFilterBarStyle provides settings.flowFilterBarStyle, LocalFlowFilterBarStyle provides settings.flowFilterBarStyle,
LocalFlowFilterBarFilled provides settings.flowFilterBarFilled, LocalFlowFilterBarFilled provides settings.flowFilterBarFilled,
@ -143,5 +146,7 @@ val LocalFlowArticleListDesc =
compositionLocalOf<FlowArticleListDescPreference> { FlowArticleListDescPreference.default } compositionLocalOf<FlowArticleListDescPreference> { FlowArticleListDescPreference.default }
val LocalFlowArticleListTime = val LocalFlowArticleListTime =
compositionLocalOf<FlowArticleListTimePreference> { FlowArticleListTimePreference.default } compositionLocalOf<FlowArticleListTimePreference> { FlowArticleListTimePreference.default }
val LocalFlowArticleListDateStickyHeader =
compositionLocalOf<FlowArticleListDateStickyHeaderPreference> { FlowArticleListDateStickyHeaderPreference.default }
val LocalFlowArticleListTonalElevation = val LocalFlowArticleListTonalElevation =
compositionLocalOf<FlowArticleListTonalElevationPreference> { FlowArticleListTonalElevationPreference.default } compositionLocalOf<FlowArticleListTonalElevationPreference> { FlowArticleListTonalElevationPreference.default }

View File

@ -45,8 +45,8 @@ fun Switch(
.alpha(if (enable) 1f else 0.5f), .alpha(if (enable) 1f else 0.5f),
shape = CircleShape, shape = CircleShape,
color = animateColorAsState( color = animateColorAsState(
if (activated) (tonalPalettes primary 40) onDark (tonalPalettes neutralVariant 50) if (activated) (tonalPalettes primary 40) onDark (tonalPalettes secondary 50)
else (tonalPalettes neutralVariant 50) onDark (tonalPalettes neutral 60) else (tonalPalettes neutralVariant 50) onDark (tonalPalettes neutral 30)
).value ).value
) { ) {
Box( Box(
@ -61,7 +61,7 @@ fun Switch(
shape = CircleShape, shape = CircleShape,
color = animateColorAsState( color = animateColorAsState(
if (activated) tonalPalettes primary 90 if (activated) tonalPalettes primary 90
else (tonalPalettes neutralVariant 70) onDark (tonalPalettes neutral 30) else (tonalPalettes neutralVariant 70) onDark (tonalPalettes neutral 60)
).value ).value
) {} ) {}
} }

View File

@ -215,6 +215,11 @@ sealed class DataStoreKeys<T> {
get() = booleanPreferencesKey("flowArticleListTime") get() = booleanPreferencesKey("flowArticleListTime")
} }
object FlowArticleListDateStickyHeader : DataStoreKeys<Boolean>() {
override val key: Preferences.Key<Boolean>
get() = booleanPreferencesKey("flowArticleListDateStickyHeader")
}
object FlowArticleListTonalElevation : DataStoreKeys<Int>() { object FlowArticleListTonalElevation : DataStoreKeys<Int>() {
override val key: Preferences.Key<Int> override val key: Preferences.Key<Int>
get() = intPreferencesKey("flowArticleListTonalElevation") get() = intPreferencesKey("flowArticleListTonalElevation")

View File

@ -14,6 +14,7 @@ import me.ash.reader.data.entity.ArticleWithFeed
fun LazyListScope.ArticleList( fun LazyListScope.ArticleList(
pagingItems: LazyPagingItems<FlowItemView>, pagingItems: LazyPagingItems<FlowItemView>,
articleListFeedIcon: Boolean, articleListFeedIcon: Boolean,
articleListDateStickyHeader: Boolean,
articleListTonalElevation: Int, articleListTonalElevation: Int,
onClick: (ArticleWithFeed) -> Unit = {}, onClick: (ArticleWithFeed) -> Unit = {},
) { ) {
@ -31,9 +32,15 @@ fun LazyListScope.ArticleList(
is FlowItemView.Date -> { is FlowItemView.Date -> {
val separator = pagingItems[index] as FlowItemView.Date val separator = pagingItems[index] as FlowItemView.Date
if (separator.showSpacer) item { Spacer(modifier = Modifier.height(40.dp)) } if (separator.showSpacer) item { Spacer(modifier = Modifier.height(40.dp)) }
stickyHeader { if (articleListDateStickyHeader) {
stickyHeader(key = separator.date) {
StickyHeader(separator.date, articleListFeedIcon, articleListTonalElevation) StickyHeader(separator.date, articleListFeedIcon, articleListTonalElevation)
} }
} else {
item(key = separator.date) {
StickyHeader(separator.date, articleListFeedIcon, articleListTonalElevation)
}
}
} }
else -> {} else -> {}
} }

View File

@ -58,6 +58,7 @@ fun FlowPage(
val topBarTonalElevation = LocalFlowTopBarTonalElevation.current val topBarTonalElevation = LocalFlowTopBarTonalElevation.current
val articleListTonalElevation = LocalFlowArticleListTonalElevation.current val articleListTonalElevation = LocalFlowArticleListTonalElevation.current
val articleListFeedIcon = LocalFlowArticleListFeedIcon.current val articleListFeedIcon = LocalFlowArticleListFeedIcon.current
val articleListDateStickyHeader = LocalFlowArticleListDateStickyHeader.current
val filterBarStyle = LocalFlowFilterBarStyle.current val filterBarStyle = LocalFlowFilterBarStyle.current
val filterBarFilled = LocalFlowFilterBarFilled.current val filterBarFilled = LocalFlowFilterBarFilled.current
val filterBarPadding = LocalFlowFilterBarPadding.current val filterBarPadding = LocalFlowFilterBarPadding.current
@ -260,6 +261,7 @@ fun FlowPage(
ArticleList( ArticleList(
pagingItems = pagingItems, pagingItems = pagingItems,
articleListFeedIcon = articleListFeedIcon.value, articleListFeedIcon = articleListFeedIcon.value,
articleListDateStickyHeader = articleListDateStickyHeader.value,
articleListTonalElevation = articleListTonalElevation.value, articleListTonalElevation = articleListTonalElevation.value,
) { ) {
onSearch = false onSearch = false

View File

@ -1,5 +1,6 @@
package me.ash.reader.ui.page.settings.color.feeds package me.ash.reader.ui.page.settings.color.feeds
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
@ -294,6 +295,7 @@ fun FeedsPagePreview(
Column( Column(
modifier = Modifier modifier = Modifier
.animateContentSize()
.background( .background(
color = MaterialTheme.colorScheme.surfaceColorAtElevation( color = MaterialTheme.colorScheme.surfaceColorAtElevation(
groupListTonalElevation.value.dp groupListTonalElevation.value.dp

View File

@ -1,6 +1,7 @@
package me.ash.reader.ui.page.settings.color.flow package me.ash.reader.ui.page.settings.color.flow
import android.annotation.SuppressLint import android.annotation.SuppressLint
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
@ -51,7 +52,8 @@ fun FlowPageStyle(
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 = LocalFlowArticleListTime.current val articleListTime = LocalFlowArticleListTime.current
val articleListStickyDate = LocalFlowArticleListDateStickyHeader.current
val articleListTonalElevation = LocalFlowArticleListTonalElevation.current val articleListTonalElevation = LocalFlowArticleListTonalElevation.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
@ -190,11 +192,21 @@ fun FlowPageStyle(
SettingItem( SettingItem(
title = stringResource(R.string.display_article_date), title = stringResource(R.string.display_article_date),
onClick = { onClick = {
(!articleListDate).put(context, scope) (!articleListTime).put(context, scope)
}, },
) { ) {
Switch(activated = articleListDate.value) { Switch(activated = articleListTime.value) {
(!articleListDate).put(context, scope) (!articleListTime).put(context, scope)
}
}
SettingItem(
title = stringResource(R.string.article_date_sticky_header),
onClick = {
(!articleListStickyDate).put(context, scope)
},
) {
Switch(activated = articleListStickyDate.value) {
(!articleListStickyDate).put(context, scope)
} }
} }
SettingItem( SettingItem(
@ -343,6 +355,7 @@ fun FlowPagePreview(
Column( Column(
modifier = Modifier modifier = Modifier
.animateContentSize()
.background( .background(
color = MaterialTheme.colorScheme.surfaceColorAtElevation( color = MaterialTheme.colorScheme.surfaceColorAtElevation(
articleListTonalElevation.value.dp articleListTonalElevation.value.dp

View File

@ -134,6 +134,7 @@
<string name="display_article_image">显示文章插图</string> <string name="display_article_image">显示文章插图</string>
<string name="display_feed_name">显示订阅源名称</string> <string name="display_feed_name">显示订阅源名称</string>
<string name="display_feed_favicon">显示订阅源图标</string> <string name="display_feed_favicon">显示订阅源图标</string>
<string name="article_date_sticky_header">文章发布日期粘性标签(实验性)</string>
<string name="article_list">文章列表</string> <string name="article_list">文章列表</string>
<string name="group_list">分组列表</string> <string name="group_list">分组列表</string>
<string name="always_expand">始终展开</string> <string name="always_expand">始终展开</string>

View File

@ -134,6 +134,7 @@
<string name="display_article_image">Display Article Images</string> <string name="display_article_image">Display Article Images</string>
<string name="display_feed_name">Display Feed Names</string> <string name="display_feed_name">Display Feed Names</string>
<string name="display_feed_favicon">Display Feed Favicons</string> <string name="display_feed_favicon">Display Feed Favicons</string>
<string name="article_date_sticky_header">Article Publish Date Sticky Header (Experimental)</string>
<string name="article_list">Article List</string> <string name="article_list">Article List</string>
<string name="group_list">Group List</string> <string name="group_list">Group List</string>
<string name="always_expand">Always Expand</string> <string name="always_expand">Always Expand</string>