Make hiding empty groups toggleable (#921)
This commit is contained in:
parent
39dc3bceee
commit
1ffdb2f4f7
@ -0,0 +1,48 @@
|
||||
package me.ash.reader.infrastructure.preference
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import me.ash.reader.ui.ext.DataStoreKey
|
||||
import me.ash.reader.ui.ext.DataStoreKey.Companion.hideEmptyGroups
|
||||
import me.ash.reader.ui.ext.dataStore
|
||||
import me.ash.reader.ui.ext.put
|
||||
|
||||
val LocalHideEmptyGroups =
|
||||
compositionLocalOf<HideEmptyGroupsPreference> { HideEmptyGroupsPreference.default }
|
||||
|
||||
sealed class HideEmptyGroupsPreference(val value: Boolean) : Preference() {
|
||||
data object ON : HideEmptyGroupsPreference(true)
|
||||
data object OFF : HideEmptyGroupsPreference(false)
|
||||
|
||||
override fun put(context: Context, scope: CoroutineScope) {
|
||||
scope.launch {
|
||||
context.dataStore.put(
|
||||
hideEmptyGroups,
|
||||
value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun toggle(context: Context, scope: CoroutineScope) = scope.launch {
|
||||
context.dataStore.put(
|
||||
hideEmptyGroups,
|
||||
!value
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val default = ON
|
||||
val values = listOf(ON, OFF)
|
||||
|
||||
fun fromPreferences(preferences: Preferences) =
|
||||
when (preferences[DataStoreKey.keys[hideEmptyGroups]?.key as Preferences.Key<Boolean>]) {
|
||||
true -> ON
|
||||
false -> OFF
|
||||
else -> default
|
||||
}
|
||||
}
|
||||
}
|
@ -81,6 +81,7 @@ fun Preferences.toSettings(): Settings {
|
||||
swipeStartAction = SwipeStartActionPreference.fromPreferences(this),
|
||||
swipeEndAction = SwipeEndActionPreference.fromPreferences(this),
|
||||
markAsReadOnScroll = MarkAsReadOnScrollPreference.fromPreferences(this),
|
||||
hideEmptyGroups = HideEmptyGroupsPreference.fromPreferences(this),
|
||||
pullToSwitchArticle = PullToSwitchArticlePreference.fromPreference(this),
|
||||
openLink = OpenLinkPreference.fromPreferences(this),
|
||||
openLinkSpecificBrowser = OpenLinkSpecificBrowserPreference.fromPreferences(this),
|
||||
|
@ -79,6 +79,7 @@ data class Settings(
|
||||
val swipeStartAction: SwipeStartActionPreference = SwipeStartActionPreference.default,
|
||||
val swipeEndAction: SwipeEndActionPreference = SwipeEndActionPreference.default,
|
||||
val markAsReadOnScroll: MarkAsReadOnScrollPreference = MarkAsReadOnScrollPreference.default,
|
||||
val hideEmptyGroups: HideEmptyGroupsPreference = HideEmptyGroupsPreference.default,
|
||||
val pullToSwitchArticle: PullToSwitchArticlePreference = PullToSwitchArticlePreference.default,
|
||||
val openLink: OpenLinkPreference = OpenLinkPreference.default,
|
||||
val openLinkSpecificBrowser: OpenLinkSpecificBrowserPreference = OpenLinkSpecificBrowserPreference.default,
|
||||
@ -170,6 +171,7 @@ fun SettingsProvider(
|
||||
LocalArticleListSwipeStartAction provides settings.swipeStartAction,
|
||||
LocalArticleListSwipeEndAction provides settings.swipeEndAction,
|
||||
LocalMarkAsReadOnScroll provides settings.markAsReadOnScroll,
|
||||
LocalHideEmptyGroups provides settings.hideEmptyGroups,
|
||||
LocalPullToSwitchArticle provides settings.pullToSwitchArticle,
|
||||
LocalOpenLink provides settings.openLink,
|
||||
LocalOpenLinkSpecificBrowser provides settings.openLinkSpecificBrowser,
|
||||
|
@ -162,6 +162,7 @@ data class DataStoreKey<T>(
|
||||
const val swipeStartAction = "swipeStartAction"
|
||||
const val swipeEndAction = "swipeEndAction"
|
||||
const val markAsReadOnScroll = "markAsReadOnScroll"
|
||||
const val hideEmptyGroups = "hideEmptyGroups"
|
||||
const val pullToSwitchArticle = "pullToSwitchArticle"
|
||||
const val openLink = "openLink"
|
||||
const val openLinkAppSpecificBrowser = "openLinkAppSpecificBrowser"
|
||||
@ -239,6 +240,7 @@ data class DataStoreKey<T>(
|
||||
booleanPreferencesKey(markAsReadOnScroll),
|
||||
Boolean::class.java
|
||||
),
|
||||
hideEmptyGroups to DataStoreKey(booleanPreferencesKey(hideEmptyGroups), Boolean::class.java),
|
||||
pullToSwitchArticle to DataStoreKey(booleanPreferencesKey(pullToSwitchArticle), Boolean::class.java),
|
||||
openLink to DataStoreKey(intPreferencesKey(openLink), Int::class.java),
|
||||
openLinkAppSpecificBrowser to DataStoreKey(stringPreferencesKey(openLinkAppSpecificBrowser), String::class.java),
|
||||
|
@ -66,6 +66,7 @@ import me.ash.reader.infrastructure.preference.LocalFeedsFilterBarTonalElevation
|
||||
import me.ash.reader.infrastructure.preference.LocalFeedsGroupListExpand
|
||||
import me.ash.reader.infrastructure.preference.LocalFeedsGroupListTonalElevation
|
||||
import me.ash.reader.infrastructure.preference.LocalFeedsTopBarTonalElevation
|
||||
import me.ash.reader.infrastructure.preference.LocalHideEmptyGroups
|
||||
import me.ash.reader.infrastructure.preference.LocalNewVersionNumber
|
||||
import me.ash.reader.infrastructure.preference.LocalSkipVersionNumber
|
||||
import me.ash.reader.ui.component.FilterBar
|
||||
@ -198,9 +199,11 @@ fun FeedsPage(
|
||||
feedsViewModel.fetchAccount()
|
||||
}
|
||||
|
||||
val hideEmptyGroups = LocalHideEmptyGroups.current.value
|
||||
|
||||
LaunchedEffect(filterUiState, isSyncing) {
|
||||
snapshotFlow { filterUiState }.collect {
|
||||
feedsViewModel.pullFeeds(it)
|
||||
feedsViewModel.pullFeeds(it, hideEmptyGroups)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ class FeedsViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
fun pullFeeds(filterState: FilterState) {
|
||||
fun pullFeeds(filterState: FilterState, hideEmptyGroups: Boolean) {
|
||||
val isStarred = filterState.filter.isStarred()
|
||||
val isUnread = filterState.filter.isUnread()
|
||||
_feedsUiState.update {
|
||||
@ -77,7 +77,7 @@ class FeedsViewModel @Inject constructor(
|
||||
while (groupIterator.hasNext()) {
|
||||
val groupWithFeed = groupIterator.next()
|
||||
val groupImportant = importantMap[groupWithFeed.group.id] ?: 0
|
||||
if ((isStarred || isUnread) && groupImportant == 0) {
|
||||
if (hideEmptyGroups && (isStarred || isUnread) && groupImportant == 0) {
|
||||
groupIterator.remove()
|
||||
continue
|
||||
}
|
||||
@ -87,7 +87,7 @@ class FeedsViewModel @Inject constructor(
|
||||
val feed = feedIterator.next()
|
||||
val feedImportant = importantMap[feed.id] ?: 0
|
||||
groupWithFeed.group.feeds++
|
||||
if ((isStarred || isUnread) && feedImportant == 0) {
|
||||
if (hideEmptyGroups && (isStarred || isUnread) && feedImportant == 0) {
|
||||
feedIterator.remove()
|
||||
continue
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import me.ash.reader.infrastructure.preference.InitialFilterPreference
|
||||
import me.ash.reader.infrastructure.preference.InitialPagePreference
|
||||
import me.ash.reader.infrastructure.preference.LocalArticleListSwipeEndAction
|
||||
import me.ash.reader.infrastructure.preference.LocalArticleListSwipeStartAction
|
||||
import me.ash.reader.infrastructure.preference.LocalHideEmptyGroups
|
||||
import me.ash.reader.infrastructure.preference.LocalInitialFilter
|
||||
import me.ash.reader.infrastructure.preference.LocalInitialPage
|
||||
import me.ash.reader.infrastructure.preference.LocalMarkAsReadOnScroll
|
||||
@ -58,6 +59,7 @@ fun InteractionPage(
|
||||
val swipeToStartAction = LocalArticleListSwipeStartAction.current
|
||||
val swipeToEndAction = LocalArticleListSwipeEndAction.current
|
||||
val markAsReadOnScroll = LocalMarkAsReadOnScroll.current
|
||||
val hideEmptyGroups = LocalHideEmptyGroups.current
|
||||
val pullToSwitchArticle = LocalPullToSwitchArticle.current
|
||||
val openLink = LocalOpenLink.current
|
||||
val openLinkSpecificBrowser = LocalOpenLinkSpecificBrowser.current
|
||||
@ -112,6 +114,22 @@ fun InteractionPage(
|
||||
) {}
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
Subtitle(
|
||||
modifier = Modifier.padding(horizontal = 24.dp),
|
||||
text = stringResource(R.string.feeds_page),
|
||||
)
|
||||
SettingItem(
|
||||
title = stringResource(R.string.hide_empty_groups),
|
||||
onClick = {
|
||||
hideEmptyGroups.toggle(context, scope)
|
||||
},
|
||||
) {
|
||||
RYSwitch(activated = hideEmptyGroups.value) {
|
||||
hideEmptyGroups.toggle(context, scope)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
Subtitle(
|
||||
modifier = Modifier.padding(horizontal = 24.dp),
|
||||
text = stringResource(R.string.article_list),
|
||||
|
@ -459,6 +459,7 @@
|
||||
<string name="bionic_reading_domain" translatable="false">bionic-reading.com</string>
|
||||
<string name="bionic_reading_link" translatable="false">https://bionic-reading.com</string>
|
||||
<string name="mark_as_read_on_scroll">Mark as read on scroll</string>
|
||||
<string name="hide_empty_groups">Hide empty groups</string>
|
||||
<string name="become_a_sponsor">Become a sponsor</string>
|
||||
<string name="sponsor_desc">We build and upkeep this free, open-source app in our off-hours. If you enjoy it, please consider supporting us with a small donation! ☕️</string>
|
||||
<string name="toolbars">Toolbars</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user