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 (