add an option to navigate to the next unread category/feed when marking all as read (#1807)

This commit is contained in:
Athou
2025-06-04 08:58:58 +02:00
parent f4730e9338
commit 59b0103ed5
39 changed files with 174 additions and 5 deletions

View File

@@ -3,7 +3,7 @@ import { client } from "app/client"
import { Constants } from "app/constants"
import { type EntrySource, type EntrySourceType, entriesSlice, setMarkAllAsReadConfirmationDialogOpen, setSearch } from "app/entries/slice"
import type { RootState } from "app/store"
import { reloadTree } from "app/tree/thunks"
import { reloadTree, selectNextUnreadTreeItem } from "app/tree/thunks"
import type { Entry, MarkRequest, TagRequest } from "app/types"
import { reloadTags } from "app/user/thunks"
import { scrollToWithCallback } from "app/utils"
@@ -130,11 +130,12 @@ export const markAllAsReadWithConfirmationIfRequired = createAppAsyncThunk(
const source = state.entries.source
const entriesTimestamp = state.entries.timestamp ?? Date.now()
const markAllAsReadConfirmation = state.user.settings?.markAllAsReadConfirmation
const markAllAsReadNavigateToNextUnread = state.user.settings?.markAllAsReadNavigateToNextUnread
if (markAllAsReadConfirmation) {
thunkApi.dispatch(setMarkAllAsReadConfirmationDialogOpen(true))
} else {
thunkApi.dispatch(
await thunkApi.dispatch(
markAllEntries({
sourceType: source.type,
req: {
@@ -145,6 +146,9 @@ export const markAllAsReadWithConfirmationIfRequired = createAppAsyncThunk(
},
})
)
const isAllCategorySelected = source.type === "category" && source.id === Constants.categories.all.id
if (markAllAsReadNavigateToNextUnread && !isAllCategorySelected)
await thunkApi.dispatch(selectNextUnreadTreeItem({ direction: "forward" }))
}
}
)

View File

@@ -248,6 +248,7 @@ export interface Settings {
starIconDisplayMode: IconDisplayMode
externalLinkIconDisplayMode: IconDisplayMode
markAllAsReadConfirmation: boolean
markAllAsReadNavigateToNextUnread: boolean
customContextMenu: boolean
mobileFooter: boolean
unreadCountTitle: boolean

View File

@@ -8,6 +8,7 @@ import {
changeExternalLinkIconDisplayMode,
changeLanguage,
changeMarkAllAsReadConfirmation,
changeMarkAllAsReadNavigateToUnread,
changeMobileFooter,
changePrimaryColor,
changeReadingMode,
@@ -114,6 +115,10 @@ export const userSlice = createSlice({
if (!state.settings) return
state.settings.markAllAsReadConfirmation = action.meta.arg
})
builder.addCase(changeMarkAllAsReadNavigateToUnread.pending, (state, action) => {
if (!state.settings) return
state.settings.markAllAsReadNavigateToNextUnread = action.meta.arg
})
builder.addCase(changeCustomContextMenu.pending, (state, action) => {
if (!state.settings) return
state.settings.customContextMenu = action.meta.arg
@@ -149,6 +154,7 @@ export const userSlice = createSlice({
changeStarIconDisplayMode.fulfilled,
changeExternalLinkIconDisplayMode.fulfilled,
changeMarkAllAsReadConfirmation.fulfilled,
changeMarkAllAsReadNavigateToUnread.fulfilled,
changeCustomContextMenu.fulfilled,
changeMobileFooter.fulfilled,
changeUnreadCountTitle.fulfilled,

View File

@@ -89,6 +89,15 @@ export const changeMarkAllAsReadConfirmation = createAppAsyncThunk(
}
)
export const changeMarkAllAsReadNavigateToUnread = createAppAsyncThunk(
"settings/markAllAsReadNavigateToUnread",
(markAllAsReadNavigateToNextUnread: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, markAllAsReadNavigateToNextUnread })
}
)
export const changeCustomContextMenu = createAppAsyncThunk("settings/customContextMenu", (customContextMenu: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return

View File

@@ -1,8 +1,10 @@
import { Trans } from "@lingui/react/macro"
import { Button, Code, Group, Modal, Slider, Stack, Text } from "@mantine/core"
import { Constants } from "app/constants"
import { setMarkAllAsReadConfirmationDialogOpen } from "app/entries/slice"
import { markAllEntries } from "app/entries/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import { selectNextUnreadTreeItem } from "app/tree/thunks"
import { useState } from "react"
export function MarkAllAsReadConfirmationDialog() {
@@ -11,10 +13,12 @@ export function MarkAllAsReadConfirmationDialog() {
const source = useAppSelector(state => state.entries.source)
const sourceLabel = useAppSelector(state => state.entries.sourceLabel)
const entriesTimestamp = useAppSelector(state => state.entries.timestamp) ?? Date.now()
const markAllAsReadNavigateToNextUnread = useAppSelector(state => state.user.settings?.markAllAsReadNavigateToNextUnread)
const dispatch = useAppDispatch()
const onConfirm = () => {
dispatch(
const onConfirm = async () => {
dispatch(setMarkAllAsReadConfirmationDialogOpen(false))
await dispatch(
markAllEntries({
sourceType: source.type,
req: {
@@ -25,7 +29,9 @@ export function MarkAllAsReadConfirmationDialog() {
},
})
)
dispatch(setMarkAllAsReadConfirmationDialogOpen(false))
const isAllCategorySelected = source.type === "category" && source.id === Constants.categories.all.id
if (markAllAsReadNavigateToNextUnread && !isAllCategorySelected) await dispatch(selectNextUnreadTreeItem({ direction: "forward" }))
}
return (

View File

@@ -12,6 +12,7 @@ import {
changeExternalLinkIconDisplayMode,
changeLanguage,
changeMarkAllAsReadConfirmation,
changeMarkAllAsReadNavigateToUnread,
changeMobileFooter,
changePrimaryColor,
changeScrollMarks,
@@ -36,6 +37,7 @@ export function DisplaySettings() {
const starIconDisplayMode = useAppSelector(state => state.user.settings?.starIconDisplayMode)
const externalLinkIconDisplayMode = useAppSelector(state => state.user.settings?.externalLinkIconDisplayMode)
const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation)
const markAllAsReadNavigateToNextUnread = useAppSelector(state => state.user.settings?.markAllAsReadNavigateToNextUnread)
const customContextMenu = useAppSelector(state => state.user.settings?.customContextMenu)
const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter)
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
@@ -127,6 +129,12 @@ export function DisplaySettings() {
onChange={async e => await dispatch(changeMarkAllAsReadConfirmation(e.currentTarget.checked))}
/>
<Switch
label={<Trans>Navigate to the next category/feed with unread entries when marking all entries as read</Trans>}
checked={markAllAsReadNavigateToNextUnread}
onChange={async e => await dispatch(changeMarkAllAsReadNavigateToUnread(e.currentTarget.checked))}
/>
<Switch
label={<Trans>On mobile, show action buttons at the bottom of the screen</Trans>}
checked={mobileFooter}

View File

@@ -602,6 +602,10 @@ msgstr "الاسم"
msgid "Navigate to a subscription by entering its name"
msgstr "انتقل إلى اشتراك بإدخال اسمه"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Nom"
msgid "Navigate to a subscription by entering its name"
msgstr "Navegueu a una subscripció introduint-ne el nom"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Jméno"
msgid "Navigate to a subscription by entering its name"
msgstr "Přejděte na předplatné zadáním jeho názvu"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Enw"
msgid "Navigate to a subscription by entering its name"
msgstr "Llywiwch i danysgrifiad trwy nodi ei enw"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Navn"
msgid "Navigate to a subscription by entering its name"
msgstr "Naviger til et abonnement ved at indtaste dets navn"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr ""
msgid "Navigate to a subscription by entering its name"
msgstr "Navigieren Sie zu einem Abonnement, indem Sie seinen Namen eingeben"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Name"
msgid "Navigate to a subscription by entering its name"
msgstr "Navigate to a subscription by entering its name"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr "Navigate to the next category/feed with unread entries when marking all entries as read"
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -603,6 +603,10 @@ msgstr "Nombre"
msgid "Navigate to a subscription by entering its name"
msgstr "Navegar a una suscripción introduciendo su nombre"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "نام"
msgid "Navigate to a subscription by entering its name"
msgstr "با وارد کردن نام اشتراک، به آن بروید"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Nimi"
msgid "Navigate to a subscription by entering its name"
msgstr "Siirry tilaukseen kirjoittamalla sen nimi"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Nom"
msgid "Navigate to a subscription by entering its name"
msgstr "Naviguer vers un abonnement en entrant son nom"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Nome"
msgid "Navigate to a subscription by entering its name"
msgstr "Navega a unha subscrición introducindo o seu nome"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Név"
msgid "Navigate to a subscription by entering its name"
msgstr "Navigáljon egy előfizetéshez a nevének megadásával"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Nama"
msgid "Navigate to a subscription by entering its name"
msgstr "Navigasikan ke langganan dengan memasukkan namanya"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Nome"
msgid "Navigate to a subscription by entering its name"
msgstr "Navigare verso un abbonamento inserendo il suo nome"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "名前"
msgid "Navigate to a subscription by entering its name"
msgstr "名前を入力してサブスクリプションに移動します"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "이름"
msgid "Navigate to a subscription by entering its name"
msgstr "이름을 입력하여 구독으로 이동"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Nama"
msgid "Navigate to a subscription by entering its name"
msgstr "Navigasi ke langganan dengan memasukkan namanya"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Navn"
msgid "Navigate to a subscription by entering its name"
msgstr "Naviger til et abonnement ved å skrive inn navnet"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Naam"
msgid "Navigate to a subscription by entering its name"
msgstr "Navigeer naar een abonnement door de naam in te voeren"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Navn"
msgid "Navigate to a subscription by entering its name"
msgstr "Naviger til et abonnement ved å skrive inn navnet"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Nazwa"
msgid "Navigate to a subscription by entering its name"
msgstr "Przejdź do subskrypcji, wpisując jej nazwę"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Nome"
msgid "Navigate to a subscription by entering its name"
msgstr "Navegue até uma assinatura digitando seu nome"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Имя"
msgid "Navigate to a subscription by entering its name"
msgstr "Перейдите к подписке, введя ее имя."
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Meno"
msgid "Navigate to a subscription by entering its name"
msgstr "Prejdite na predplatné zadaním jeho názvu"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "Namn"
msgid "Navigate to a subscription by entering its name"
msgstr "Navigera till ett abonnemang genom att ange dess namn"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "İsim"
msgid "Navigate to a subscription by entering its name"
msgstr "Adını girerek bir aboneliğe gidin"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -602,6 +602,10 @@ msgstr "​​名称"
msgid "Navigate to a subscription by entering its name"
msgstr "通过输入订阅名称导航到订阅"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"

View File

@@ -93,6 +93,7 @@ public class UserSettings extends AbstractModel {
private String primaryColor;
private boolean markAllAsReadConfirmation;
private boolean markAllAsReadNavigateToNextUnread;
private boolean customContextMenu;
private boolean mobileFooter;
private boolean unreadCountTitle;

View File

@@ -67,6 +67,11 @@ public class Settings implements Serializable {
@Schema(description = "ask for confirmation when marking all entries as read", requiredMode = RequiredMode.REQUIRED)
private boolean markAllAsReadConfirmation;
@Schema(
description = "navigate to the next unread category or feed after marking all entries as read",
requiredMode = RequiredMode.REQUIRED)
private boolean markAllAsReadNavigateToNextUnread;
@Schema(description = "show commafeed's own context menu on right click", requiredMode = RequiredMode.REQUIRED)
private boolean customContextMenu;

View File

@@ -119,6 +119,7 @@ public class UserREST {
s.setStarIconDisplayMode(settings.getStarIconDisplayMode().name());
s.setExternalLinkIconDisplayMode(settings.getExternalLinkIconDisplayMode().name());
s.setMarkAllAsReadConfirmation(settings.isMarkAllAsReadConfirmation());
s.setMarkAllAsReadNavigateToNextUnread(settings.isMarkAllAsReadNavigateToNextUnread());
s.setCustomContextMenu(settings.isCustomContextMenu());
s.setMobileFooter(settings.isMobileFooter());
s.setUnreadCountTitle(settings.isUnreadCountTitle());
@@ -146,6 +147,7 @@ public class UserREST {
s.setStarIconDisplayMode(IconDisplayMode.on_desktop.name());
s.setExternalLinkIconDisplayMode(IconDisplayMode.on_desktop.name());
s.setMarkAllAsReadConfirmation(true);
s.setMarkAllAsReadNavigateToNextUnread(false);
s.setCustomContextMenu(true);
s.setMobileFooter(false);
s.setUnreadCountTitle(false);
@@ -180,6 +182,7 @@ public class UserREST {
s.setStarIconDisplayMode(IconDisplayMode.valueOf(settings.getStarIconDisplayMode()));
s.setExternalLinkIconDisplayMode(IconDisplayMode.valueOf(settings.getExternalLinkIconDisplayMode()));
s.setMarkAllAsReadConfirmation(settings.isMarkAllAsReadConfirmation());
s.setMarkAllAsReadNavigateToNextUnread(settings.isMarkAllAsReadNavigateToNextUnread());
s.setCustomContextMenu(settings.isCustomContextMenu());
s.setMobileFooter(settings.isMobileFooter());
s.setUnreadCountTitle(settings.isUnreadCountTitle());

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="add-markAllAsReadNavigateToNextUnread" author="athou">
<addColumn tableName="USERSETTINGS">
<column name="markAllAsReadNavigateToNextUnread" type="BOOLEAN" valueBoolean="false">
<constraints nullable="false" />
</column>
</addColumn>
</changeSet>
</databaseChangeLog>

View File

@@ -35,5 +35,6 @@
<include file="changelogs/db.changelog-5.2.xml" />
<include file="changelogs/db.changelog-5.3.xml" />
<include file="changelogs/db.changelog-5.8.xml" />
<include file="changelogs/db.changelog-5.11.xml" />
</databaseChangeLog>