From a92a7217ff2b43f953c7f41a9cdc0605e9ae9356 Mon Sep 17 00:00:00 2001 From: Athou Date: Mon, 29 Jan 2024 17:59:28 +0100 Subject: [PATCH] add a setting to completely disable scrolling to selected entry (#1157) --- commafeed-client/src/app/entries/thunks.ts | 4 +- commafeed-client/src/app/types.ts | 4 +- commafeed-client/src/app/user/slice.ts | 8 +-- commafeed-client/src/app/user/thunks.ts | 6 +- .../components/settings/DisplaySettings.tsx | 59 ++++++++++++------- commafeed-client/src/locales/ar/messages.po | 18 +++++- commafeed-client/src/locales/ca/messages.po | 18 +++++- commafeed-client/src/locales/cs/messages.po | 18 +++++- commafeed-client/src/locales/cy/messages.po | 18 +++++- commafeed-client/src/locales/da/messages.po | 18 +++++- commafeed-client/src/locales/de/messages.po | 18 +++++- commafeed-client/src/locales/en/messages.po | 20 ++++++- commafeed-client/src/locales/es/messages.po | 18 +++++- commafeed-client/src/locales/fa/messages.po | 18 +++++- commafeed-client/src/locales/fi/messages.po | 18 +++++- commafeed-client/src/locales/fr/messages.po | 22 ++++++- commafeed-client/src/locales/gl/messages.po | 18 +++++- commafeed-client/src/locales/hu/messages.po | 18 +++++- commafeed-client/src/locales/id/messages.po | 18 +++++- commafeed-client/src/locales/it/messages.po | 18 +++++- commafeed-client/src/locales/ja/messages.po | 18 +++++- commafeed-client/src/locales/ko/messages.po | 18 +++++- commafeed-client/src/locales/ms/messages.po | 18 +++++- commafeed-client/src/locales/nb/messages.po | 18 +++++- commafeed-client/src/locales/nl/messages.po | 18 +++++- commafeed-client/src/locales/nn/messages.po | 18 +++++- commafeed-client/src/locales/pl/messages.po | 18 +++++- commafeed-client/src/locales/pt/messages.po | 18 +++++- commafeed-client/src/locales/ru/messages.po | 18 +++++- commafeed-client/src/locales/sk/messages.po | 18 +++++- commafeed-client/src/locales/sv/messages.po | 18 +++++- commafeed-client/src/locales/tr/messages.po | 20 ++++++- commafeed-client/src/locales/zh/messages.po | 18 +++++- .../commafeed/backend/model/UserSettings.java | 9 ++- .../commafeed/frontend/model/Settings.java | 5 +- .../commafeed/frontend/resource/UserREST.java | 7 ++- .../resources/changelogs/db.changelog-4.3.xml | 22 +++++++ .../src/main/resources/migrations.xml | 1 + 38 files changed, 567 insertions(+), 70 deletions(-) create mode 100644 commafeed-server/src/main/resources/changelogs/db.changelog-4.3.xml diff --git a/commafeed-client/src/app/entries/thunks.ts b/commafeed-client/src/app/entries/thunks.ts index 2a4e3744..36e25457 100644 --- a/commafeed-client/src/app/entries/thunks.ts +++ b/commafeed-client/src/app/entries/thunks.ts @@ -162,9 +162,9 @@ export const selectEntry = createAppAsyncThunk( if (arg.scrollToEntry) { const entryElement = document.getElementById(Constants.dom.entryId(entry)) if (entryElement) { - const alwaysScrollToEntry = state.user.settings?.alwaysScrollToEntry + const scrollMode = state.user.settings?.scrollMode const entryEntirelyVisible = Constants.layout.isTopVisible(entryElement) && Constants.layout.isBottomVisible(entryElement) - if (alwaysScrollToEntry || !entryEntirelyVisible) { + if (scrollMode === "always" || (scrollMode === "if_needed" && !entryEntirelyVisible)) { const scrollSpeed = state.user.settings?.scrollSpeed thunkApi.dispatch(entriesSlice.actions.setScrollingToEntry(true)) scrollToEntry(entryElement, scrollSpeed, () => thunkApi.dispatch(entriesSlice.actions.setScrollingToEntry(false))) diff --git a/commafeed-client/src/app/types.ts b/commafeed-client/src/app/types.ts index b5ccbb38..e642cb20 100644 --- a/commafeed-client/src/app/types.ts +++ b/commafeed-client/src/app/types.ts @@ -205,7 +205,7 @@ export interface Settings { customCss?: string customJs?: string scrollSpeed: number - alwaysScrollToEntry: boolean + scrollMode: ScrollMode markAllAsReadConfirmation: boolean customContextMenu: boolean mobileFooter: boolean @@ -289,3 +289,5 @@ export type ReadingMode = "all" | "unread" export type ReadingOrder = "asc" | "desc" export type ViewMode = "title" | "cozy" | "detailed" | "expanded" + +export type ScrollMode = "always" | "never" | "if_needed" diff --git a/commafeed-client/src/app/user/slice.ts b/commafeed-client/src/app/user/slice.ts index 7a7b1899..bafe5639 100644 --- a/commafeed-client/src/app/user/slice.ts +++ b/commafeed-client/src/app/user/slice.ts @@ -3,7 +3,6 @@ import { showNotification } from "@mantine/notifications" import { createSlice, isAnyOf } from "@reduxjs/toolkit" import { type Settings, type UserModel } from "app/types" import { - changeAlwaysScrollToEntry, changeCustomContextMenu, changeLanguage, changeMarkAllAsReadConfirmation, @@ -11,6 +10,7 @@ import { changeReadingMode, changeReadingOrder, changeScrollMarks, + changeScrollMode, changeScrollSpeed, changeSharingSetting, changeShowRead, @@ -65,9 +65,9 @@ export const userSlice = createSlice({ if (!state.settings) return state.settings.scrollMarks = action.meta.arg }) - builder.addCase(changeAlwaysScrollToEntry.pending, (state, action) => { + builder.addCase(changeScrollMode.pending, (state, action) => { if (!state.settings) return - state.settings.alwaysScrollToEntry = action.meta.arg + state.settings.scrollMode = action.meta.arg }) builder.addCase(changeMarkAllAsReadConfirmation.pending, (state, action) => { if (!state.settings) return @@ -91,7 +91,7 @@ export const userSlice = createSlice({ changeScrollSpeed.fulfilled, changeShowRead.fulfilled, changeScrollMarks.fulfilled, - changeAlwaysScrollToEntry.fulfilled, + changeScrollMode.fulfilled, changeMarkAllAsReadConfirmation.fulfilled, changeCustomContextMenu.fulfilled, changeMobileFooter.fulfilled, diff --git a/commafeed-client/src/app/user/thunks.ts b/commafeed-client/src/app/user/thunks.ts index 31247d73..fa6a25fb 100644 --- a/commafeed-client/src/app/user/thunks.ts +++ b/commafeed-client/src/app/user/thunks.ts @@ -1,7 +1,7 @@ import { createAppAsyncThunk } from "app/async-thunk" import { client } from "app/client" import { reloadEntries } from "app/entries/thunks" -import type { ReadingMode, ReadingOrder, SharingSettings } from "app/types" +import type { ReadingMode, ReadingOrder, ScrollMode, SharingSettings } from "app/types" export const reloadSettings = createAppAsyncThunk("settings/reload", async () => await client.user.getSettings().then(r => r.data)) export const reloadProfile = createAppAsyncThunk("profile/reload", async () => await client.user.getProfile().then(r => r.data)) @@ -38,10 +38,10 @@ export const changeScrollMarks = createAppAsyncThunk("settings/scrollMarks", (sc if (!settings) return client.user.saveSettings({ ...settings, scrollMarks }) }) -export const changeAlwaysScrollToEntry = createAppAsyncThunk("settings/alwaysScrollToEntry", (alwaysScrollToEntry: boolean, thunkApi) => { +export const changeScrollMode = createAppAsyncThunk("settings/scrollMode", (scrollMode: ScrollMode, thunkApi) => { const { settings } = thunkApi.getState().user if (!settings) return - client.user.saveSettings({ ...settings, alwaysScrollToEntry }) + client.user.saveSettings({ ...settings, scrollMode }) }) export const changeMarkAllAsReadConfirmation = createAppAsyncThunk( "settings/markAllAsReadConfirmation", diff --git a/commafeed-client/src/components/settings/DisplaySettings.tsx b/commafeed-client/src/components/settings/DisplaySettings.tsx index bf4e0993..0c0942b1 100644 --- a/commafeed-client/src/components/settings/DisplaySettings.tsx +++ b/commafeed-client/src/components/settings/DisplaySettings.tsx @@ -1,33 +1,40 @@ import { Trans } from "@lingui/macro" -import { Divider, Select, SimpleGrid, Stack, Switch } from "@mantine/core" +import { Divider, Group, Radio, Select, SimpleGrid, Stack, Switch } from "@mantine/core" import { Constants } from "app/constants" import { useAppDispatch, useAppSelector } from "app/store" -import { type SharingSettings } from "app/types" +import { type ScrollMode, type SharingSettings } from "app/types" import { - changeAlwaysScrollToEntry, changeCustomContextMenu, changeLanguage, changeMarkAllAsReadConfirmation, changeMobileFooter, changeScrollMarks, + changeScrollMode, changeScrollSpeed, changeSharingSetting, changeShowRead, } from "app/user/thunks" import { locales } from "i18n" +import { type ReactNode } from "react" export function DisplaySettings() { const language = useAppSelector(state => state.user.settings?.language) const scrollSpeed = useAppSelector(state => state.user.settings?.scrollSpeed) const showRead = useAppSelector(state => state.user.settings?.showRead) const scrollMarks = useAppSelector(state => state.user.settings?.scrollMarks) - const alwaysScrollToEntry = useAppSelector(state => state.user.settings?.alwaysScrollToEntry) + const scrollMode = useAppSelector(state => state.user.settings?.scrollMode) const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation) const customContextMenu = useAppSelector(state => state.user.settings?.customContextMenu) const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter) const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings) const dispatch = useAppDispatch() + const scrollModeOptions: Record = { + always: Always, + never: Never, + if_needed: If the entry doesn't entirely fit on the screen, + } + return (