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),
|
swipeStartAction = SwipeStartActionPreference.fromPreferences(this),
|
||||||
swipeEndAction = SwipeEndActionPreference.fromPreferences(this),
|
swipeEndAction = SwipeEndActionPreference.fromPreferences(this),
|
||||||
markAsReadOnScroll = MarkAsReadOnScrollPreference.fromPreferences(this),
|
markAsReadOnScroll = MarkAsReadOnScrollPreference.fromPreferences(this),
|
||||||
|
hideEmptyGroups = HideEmptyGroupsPreference.fromPreferences(this),
|
||||||
pullToSwitchArticle = PullToSwitchArticlePreference.fromPreference(this),
|
pullToSwitchArticle = PullToSwitchArticlePreference.fromPreference(this),
|
||||||
openLink = OpenLinkPreference.fromPreferences(this),
|
openLink = OpenLinkPreference.fromPreferences(this),
|
||||||
openLinkSpecificBrowser = OpenLinkSpecificBrowserPreference.fromPreferences(this),
|
openLinkSpecificBrowser = OpenLinkSpecificBrowserPreference.fromPreferences(this),
|
||||||
|
@ -79,6 +79,7 @@ data class Settings(
|
|||||||
val swipeStartAction: SwipeStartActionPreference = SwipeStartActionPreference.default,
|
val swipeStartAction: SwipeStartActionPreference = SwipeStartActionPreference.default,
|
||||||
val swipeEndAction: SwipeEndActionPreference = SwipeEndActionPreference.default,
|
val swipeEndAction: SwipeEndActionPreference = SwipeEndActionPreference.default,
|
||||||
val markAsReadOnScroll: MarkAsReadOnScrollPreference = MarkAsReadOnScrollPreference.default,
|
val markAsReadOnScroll: MarkAsReadOnScrollPreference = MarkAsReadOnScrollPreference.default,
|
||||||
|
val hideEmptyGroups: HideEmptyGroupsPreference = HideEmptyGroupsPreference.default,
|
||||||
val pullToSwitchArticle: PullToSwitchArticlePreference = PullToSwitchArticlePreference.default,
|
val pullToSwitchArticle: PullToSwitchArticlePreference = PullToSwitchArticlePreference.default,
|
||||||
val openLink: OpenLinkPreference = OpenLinkPreference.default,
|
val openLink: OpenLinkPreference = OpenLinkPreference.default,
|
||||||
val openLinkSpecificBrowser: OpenLinkSpecificBrowserPreference = OpenLinkSpecificBrowserPreference.default,
|
val openLinkSpecificBrowser: OpenLinkSpecificBrowserPreference = OpenLinkSpecificBrowserPreference.default,
|
||||||
@ -170,6 +171,7 @@ fun SettingsProvider(
|
|||||||
LocalArticleListSwipeStartAction provides settings.swipeStartAction,
|
LocalArticleListSwipeStartAction provides settings.swipeStartAction,
|
||||||
LocalArticleListSwipeEndAction provides settings.swipeEndAction,
|
LocalArticleListSwipeEndAction provides settings.swipeEndAction,
|
||||||
LocalMarkAsReadOnScroll provides settings.markAsReadOnScroll,
|
LocalMarkAsReadOnScroll provides settings.markAsReadOnScroll,
|
||||||
|
LocalHideEmptyGroups provides settings.hideEmptyGroups,
|
||||||
LocalPullToSwitchArticle provides settings.pullToSwitchArticle,
|
LocalPullToSwitchArticle provides settings.pullToSwitchArticle,
|
||||||
LocalOpenLink provides settings.openLink,
|
LocalOpenLink provides settings.openLink,
|
||||||
LocalOpenLinkSpecificBrowser provides settings.openLinkSpecificBrowser,
|
LocalOpenLinkSpecificBrowser provides settings.openLinkSpecificBrowser,
|
||||||
|
@ -162,6 +162,7 @@ data class DataStoreKey<T>(
|
|||||||
const val swipeStartAction = "swipeStartAction"
|
const val swipeStartAction = "swipeStartAction"
|
||||||
const val swipeEndAction = "swipeEndAction"
|
const val swipeEndAction = "swipeEndAction"
|
||||||
const val markAsReadOnScroll = "markAsReadOnScroll"
|
const val markAsReadOnScroll = "markAsReadOnScroll"
|
||||||
|
const val hideEmptyGroups = "hideEmptyGroups"
|
||||||
const val pullToSwitchArticle = "pullToSwitchArticle"
|
const val pullToSwitchArticle = "pullToSwitchArticle"
|
||||||
const val openLink = "openLink"
|
const val openLink = "openLink"
|
||||||
const val openLinkAppSpecificBrowser = "openLinkAppSpecificBrowser"
|
const val openLinkAppSpecificBrowser = "openLinkAppSpecificBrowser"
|
||||||
@ -239,6 +240,7 @@ data class DataStoreKey<T>(
|
|||||||
booleanPreferencesKey(markAsReadOnScroll),
|
booleanPreferencesKey(markAsReadOnScroll),
|
||||||
Boolean::class.java
|
Boolean::class.java
|
||||||
),
|
),
|
||||||
|
hideEmptyGroups to DataStoreKey(booleanPreferencesKey(hideEmptyGroups), Boolean::class.java),
|
||||||
pullToSwitchArticle to DataStoreKey(booleanPreferencesKey(pullToSwitchArticle), Boolean::class.java),
|
pullToSwitchArticle to DataStoreKey(booleanPreferencesKey(pullToSwitchArticle), Boolean::class.java),
|
||||||
openLink to DataStoreKey(intPreferencesKey(openLink), Int::class.java),
|
openLink to DataStoreKey(intPreferencesKey(openLink), Int::class.java),
|
||||||
openLinkAppSpecificBrowser to DataStoreKey(stringPreferencesKey(openLinkAppSpecificBrowser), String::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.LocalFeedsGroupListExpand
|
||||||
import me.ash.reader.infrastructure.preference.LocalFeedsGroupListTonalElevation
|
import me.ash.reader.infrastructure.preference.LocalFeedsGroupListTonalElevation
|
||||||
import me.ash.reader.infrastructure.preference.LocalFeedsTopBarTonalElevation
|
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.LocalNewVersionNumber
|
||||||
import me.ash.reader.infrastructure.preference.LocalSkipVersionNumber
|
import me.ash.reader.infrastructure.preference.LocalSkipVersionNumber
|
||||||
import me.ash.reader.ui.component.FilterBar
|
import me.ash.reader.ui.component.FilterBar
|
||||||
@ -198,9 +199,11 @@ fun FeedsPage(
|
|||||||
feedsViewModel.fetchAccount()
|
feedsViewModel.fetchAccount()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val hideEmptyGroups = LocalHideEmptyGroups.current.value
|
||||||
|
|
||||||
LaunchedEffect(filterUiState, isSyncing) {
|
LaunchedEffect(filterUiState, isSyncing) {
|
||||||
snapshotFlow { filterUiState }.collect {
|
snapshotFlow { filterUiState }.collect {
|
||||||
feedsViewModel.pullFeeds(it)
|
feedsViewModel.pullFeeds(it, hideEmptyGroups)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ class FeedsViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
fun pullFeeds(filterState: FilterState) {
|
fun pullFeeds(filterState: FilterState, hideEmptyGroups: Boolean) {
|
||||||
val isStarred = filterState.filter.isStarred()
|
val isStarred = filterState.filter.isStarred()
|
||||||
val isUnread = filterState.filter.isUnread()
|
val isUnread = filterState.filter.isUnread()
|
||||||
_feedsUiState.update {
|
_feedsUiState.update {
|
||||||
@ -77,7 +77,7 @@ class FeedsViewModel @Inject constructor(
|
|||||||
while (groupIterator.hasNext()) {
|
while (groupIterator.hasNext()) {
|
||||||
val groupWithFeed = groupIterator.next()
|
val groupWithFeed = groupIterator.next()
|
||||||
val groupImportant = importantMap[groupWithFeed.group.id] ?: 0
|
val groupImportant = importantMap[groupWithFeed.group.id] ?: 0
|
||||||
if ((isStarred || isUnread) && groupImportant == 0) {
|
if (hideEmptyGroups && (isStarred || isUnread) && groupImportant == 0) {
|
||||||
groupIterator.remove()
|
groupIterator.remove()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ class FeedsViewModel @Inject constructor(
|
|||||||
val feed = feedIterator.next()
|
val feed = feedIterator.next()
|
||||||
val feedImportant = importantMap[feed.id] ?: 0
|
val feedImportant = importantMap[feed.id] ?: 0
|
||||||
groupWithFeed.group.feeds++
|
groupWithFeed.group.feeds++
|
||||||
if ((isStarred || isUnread) && feedImportant == 0) {
|
if (hideEmptyGroups && (isStarred || isUnread) && feedImportant == 0) {
|
||||||
feedIterator.remove()
|
feedIterator.remove()
|
||||||
continue
|
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.InitialPagePreference
|
||||||
import me.ash.reader.infrastructure.preference.LocalArticleListSwipeEndAction
|
import me.ash.reader.infrastructure.preference.LocalArticleListSwipeEndAction
|
||||||
import me.ash.reader.infrastructure.preference.LocalArticleListSwipeStartAction
|
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.LocalInitialFilter
|
||||||
import me.ash.reader.infrastructure.preference.LocalInitialPage
|
import me.ash.reader.infrastructure.preference.LocalInitialPage
|
||||||
import me.ash.reader.infrastructure.preference.LocalMarkAsReadOnScroll
|
import me.ash.reader.infrastructure.preference.LocalMarkAsReadOnScroll
|
||||||
@ -58,6 +59,7 @@ fun InteractionPage(
|
|||||||
val swipeToStartAction = LocalArticleListSwipeStartAction.current
|
val swipeToStartAction = LocalArticleListSwipeStartAction.current
|
||||||
val swipeToEndAction = LocalArticleListSwipeEndAction.current
|
val swipeToEndAction = LocalArticleListSwipeEndAction.current
|
||||||
val markAsReadOnScroll = LocalMarkAsReadOnScroll.current
|
val markAsReadOnScroll = LocalMarkAsReadOnScroll.current
|
||||||
|
val hideEmptyGroups = LocalHideEmptyGroups.current
|
||||||
val pullToSwitchArticle = LocalPullToSwitchArticle.current
|
val pullToSwitchArticle = LocalPullToSwitchArticle.current
|
||||||
val openLink = LocalOpenLink.current
|
val openLink = LocalOpenLink.current
|
||||||
val openLinkSpecificBrowser = LocalOpenLinkSpecificBrowser.current
|
val openLinkSpecificBrowser = LocalOpenLinkSpecificBrowser.current
|
||||||
@ -112,6 +114,22 @@ fun InteractionPage(
|
|||||||
) {}
|
) {}
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
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(
|
Subtitle(
|
||||||
modifier = Modifier.padding(horizontal = 24.dp),
|
modifier = Modifier.padding(horizontal = 24.dp),
|
||||||
text = stringResource(R.string.article_list),
|
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_domain" translatable="false">bionic-reading.com</string>
|
||||||
<string name="bionic_reading_link" translatable="false">https://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="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="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="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>
|
<string name="toolbars">Toolbars</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user