Add "scroll amount" setting

This commit is contained in:
schroda
2025-03-27 02:09:35 +01:00
parent b93c2d95e5
commit 72fb053971
7 changed files with 81 additions and 19 deletions

View File

@@ -273,6 +273,9 @@
"other": "Other" "other": "Other"
}, },
"settings": { "settings": {
"dialog": {
"title": "Per-language extension settings"
},
"repositories": { "repositories": {
"custom": { "custom": {
"dialog": { "dialog": {
@@ -293,9 +296,6 @@
"title": "Extension repositories" "title": "Extension repositories"
} }
} }
},
"dialog": {
"title": "Per-language extension settings"
} }
}, },
"state": { "state": {
@@ -427,12 +427,14 @@
"hidden": "Hidden", "hidden": "Hidden",
"horizontal": "Horizontal", "horizontal": "Horizontal",
"info": "Information", "info": "Information",
"large": "Large",
"left": "Left", "left": "Left",
"light": "Light", "light": "Light",
"links": "Links", "links": "Links",
"load_in_progress": "Still loading required data…", "load_in_progress": "Still loading required data…",
"loading": "Loading…", "loading": "Loading…",
"logged_in": "Logged in", "logged_in": "Logged in",
"medium": "Medium",
"menu": "Menu", "menu": "Menu",
"mobile": "Mobile", "mobile": "Mobile",
"more": "More", "more": "More",
@@ -446,6 +448,7 @@
"previous": "Previous", "previous": "Previous",
"right": "Right", "right": "Right",
"share": "Share", "share": "Share",
"small": "Small",
"sort": "Sort", "sort": "Sort",
"standard": "Standard", "standard": "Standard",
"started": "Started", "started": "Started",
@@ -990,6 +993,7 @@
"ltr": "Left to right", "ltr": "Left to right",
"rtl": "Right to left" "rtl": "Right to left"
}, },
"scroll_amount": "Scroll amount",
"source_series": "Series settings", "source_series": "Series settings",
"tap_zones": { "tap_zones": {
"edge": "Edge", "edge": "Edge",

View File

@@ -18,7 +18,6 @@ import {
AUTO_SCROLL_SPEED, AUTO_SCROLL_SPEED,
CONTINUOUS_READING_MODE_TO_SCROLL_DIRECTION, CONTINUOUS_READING_MODE_TO_SCROLL_DIRECTION,
READER_PAGE_SCALE_MODE_VALUES, READER_PAGE_SCALE_MODE_VALUES,
ReaderScrollAmount,
READING_DIRECTION_VALUES, READING_DIRECTION_VALUES,
READING_MODE_VALUES, READING_MODE_VALUES,
} from '@/modules/reader/constants/ReaderSettings.constants.tsx'; } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
@@ -79,6 +78,7 @@ export const ReaderHotkeys = ({
readingMode, readingMode,
readingDirection, readingDirection,
autoScroll, autoScroll,
scrollAmount,
} = ReaderService.useSettings(); } = ReaderService.useSettings();
const automaticScrolling = useReaderAutoScrollContext(); const automaticScrolling = useReaderAutoScrollContext();
const { setShowPreview } = useReaderTapZoneContext(); const { setShowPreview } = useReaderTapZoneContext();
@@ -106,10 +106,10 @@ export const ReaderHotkeys = ({
openChapter, openChapter,
setIsOverlayVisible, setIsOverlayVisible,
setShowPreview, setShowPreview,
ReaderScrollAmount.SMALL, scrollAmount,
), ),
{ preventDefault: true }, { preventDefault: true },
[readingMode.value, readingDirection.value, themeDirection, openChapter], [readingMode.value, readingDirection.value, themeDirection, openChapter, scrollAmount],
); );
useHotkeys( useHotkeys(
hotkeys[ReaderHotkey.SCROLL_FORWARD], hotkeys[ReaderHotkey.SCROLL_FORWARD],
@@ -125,10 +125,10 @@ export const ReaderHotkeys = ({
openChapter, openChapter,
setIsOverlayVisible, setIsOverlayVisible,
setShowPreview, setShowPreview,
ReaderScrollAmount.SMALL, scrollAmount,
), ),
{ preventDefault: true }, { preventDefault: true },
[readingMode.value, readingDirection.value, themeDirection, openChapter], [readingMode.value, readingDirection.value, themeDirection, openChapter, scrollAmount],
); );
useHotkeys( useHotkeys(
hotkeys[ReaderHotkey.PREVIOUS_CHAPTER], hotkeys[ReaderHotkey.PREVIOUS_CHAPTER],

View File

@@ -18,6 +18,7 @@ import { isOffsetDoubleSpreadPagesEditable } from '@/modules/reader/utils/Reader
import { SliderInput } from '@/modules/core/components/inputs/SliderInput.tsx'; import { SliderInput } from '@/modules/core/components/inputs/SliderInput.tsx';
import { DEFAULT_READER_SETTINGS } from '@/modules/reader/constants/ReaderSettings.constants.tsx'; import { DEFAULT_READER_SETTINGS } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
import { ReaderSettingAutoScroll } from '@/modules/reader/components/settings/behaviour/ReaderSettingAutoScroll.tsx'; import { ReaderSettingAutoScroll } from '@/modules/reader/components/settings/behaviour/ReaderSettingAutoScroll.tsx';
import { ReaderSettingScrollAmount } from '@/modules/reader/components/settings/behaviour/ReaderSettingScrollAmount.tsx';
export const ReaderBehaviourSettings = ({ export const ReaderBehaviourSettings = ({
settings, settings,
@@ -37,6 +38,10 @@ export const ReaderBehaviourSettings = ({
exitMode={settings.exitMode} exitMode={settings.exitMode}
setExitMode={(value) => updateSetting('exitMode', value)} setExitMode={(value) => updateSetting('exitMode', value)}
/> />
<ReaderSettingScrollAmount
scrollAmount={settings.scrollAmount}
setScrollAmount={(value) => updateSetting('scrollAmount', value)}
/>
<CheckboxInput <CheckboxInput
label={t('reader.settings.label.skip_dup_chapters')} label={t('reader.settings.label.skip_dup_chapters')}
checked={settings.shouldSkipDupChapters} checked={settings.shouldSkipDupChapters}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { useTranslation } from 'react-i18next';
import { IReaderSettings } from '@/modules/reader/types/Reader.types.ts';
import { ValueToDisplayData } from '@/modules/core/Core.types.ts';
import { ButtonSelectInput } from '@/modules/core/components/inputs/ButtonSelectInput.tsx';
import { ReaderScrollAmount } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
const VALUE_TO_DISPLAY_DATA: ValueToDisplayData<ReaderScrollAmount> = {
[ReaderScrollAmount.SMALL]: {
title: 'global.label.small',
icon: null,
},
[ReaderScrollAmount.MEDIUM]: {
title: 'global.label.medium',
icon: null,
},
[ReaderScrollAmount.LARGE]: {
title: 'global.label.large',
icon: null,
},
};
const READER_SCROLL_AMOUNT_VALUES = Object.values(ReaderScrollAmount).filter((value) => typeof value === 'number');
export const ReaderSettingScrollAmount = ({
scrollAmount,
setScrollAmount,
}: Pick<IReaderSettings, 'scrollAmount'> & {
setScrollAmount: (amount: ReaderScrollAmount) => void;
}) => {
const { t } = useTranslation();
return (
<ButtonSelectInput
label={t('reader.settings.scroll_amount')}
value={scrollAmount}
values={READER_SCROLL_AMOUNT_VALUES}
setValue={setScrollAmount}
valueToDisplayData={VALUE_TO_DISPLAY_DATA}
/>
);
};

View File

@@ -36,7 +36,14 @@ import { TranslationKey } from '@/Base.types.ts';
import { TapZoneLayouts } from '@/modules/reader/types/TapZoneLayout.types.ts'; import { TapZoneLayouts } from '@/modules/reader/types/TapZoneLayout.types.ts';
import { WebtoonPageIcon } from '@/assets/icons/svg/WebtoonPageIcon.tsx'; import { WebtoonPageIcon } from '@/assets/icons/svg/WebtoonPageIcon.tsx';
export const DEFAULT_READER_PROFILE = ReadingMode.SINGLE_PAGE; /**
* percentage values
*/
export enum ReaderScrollAmount {
SMALL = 25,
MEDIUM = 75,
LARGE = 95,
}
export const READING_DIRECTION_TO_THEME_DIRECTION: Record<ReadingDirection, Direction> = { export const READING_DIRECTION_TO_THEME_DIRECTION: Record<ReadingDirection, Direction> = {
[ReadingDirection.LTR]: 'ltr', [ReadingDirection.LTR]: 'ltr',
@@ -63,6 +70,7 @@ const GLOBAL_READER_SETTING_OBJECT: Record<keyof IReaderSettingsGlobal, undefine
shouldShowTapZoneLayoutPreview: undefined, shouldShowTapZoneLayoutPreview: undefined,
shouldInformAboutMissingChapter: undefined, shouldInformAboutMissingChapter: undefined,
shouldInformAboutScanlatorChange: undefined, shouldInformAboutScanlatorChange: undefined,
scrollAmount: undefined,
}; };
export const GLOBAL_READER_SETTING_KEYS = Object.keys(GLOBAL_READER_SETTING_OBJECT); export const GLOBAL_READER_SETTING_KEYS = Object.keys(GLOBAL_READER_SETTING_OBJECT);
@@ -146,6 +154,7 @@ export const DEFAULT_READER_SETTINGS: IReaderSettings = {
shouldShowTapZoneLayoutPreview: true, shouldShowTapZoneLayoutPreview: true,
shouldInformAboutMissingChapter: true, shouldInformAboutMissingChapter: true,
shouldInformAboutScanlatorChange: true, shouldInformAboutScanlatorChange: true,
scrollAmount: ReaderScrollAmount.LARGE,
}; };
export const READER_PROGRESS_BAR_POSITION_TO_PLACEMENT: Record<ProgressBarPosition, TooltipProps['placement']> = { export const READER_PROGRESS_BAR_POSITION_TO_PLACEMENT: Record<ProgressBarPosition, TooltipProps['placement']> = {
@@ -267,15 +276,6 @@ export const READER_SETTING_TABS: Record<
}, },
}; };
/**
* percentage values
*/
export enum ReaderScrollAmount {
SMALL = 25,
MEDIUM = 75,
LARGE = 95,
}
export const READER_HOTKEYS = Object.values(ReaderHotkey).filter( export const READER_HOTKEYS = Object.values(ReaderHotkey).filter(
(hotkey) => typeof hotkey === 'number', (hotkey) => typeof hotkey === 'number',
) as ReaderHotkey[]; ) as ReaderHotkey[];

View File

@@ -587,7 +587,7 @@ export class ReaderControls {
const { setIsVisible: setIsOverlayVisible } = useReaderOverlayContext(); const { setIsVisible: setIsOverlayVisible } = useReaderOverlayContext();
const { currentPageIndex, pages } = userReaderStatePagesContext(); const { currentPageIndex, pages } = userReaderStatePagesContext();
const { setShowPreview } = useReaderTapZoneContext(); const { setShowPreview } = useReaderTapZoneContext();
const { readingMode, readingDirection, isStaticNav } = ReaderService.useSettings(); const { readingMode, readingDirection, isStaticNav, scrollAmount } = ReaderService.useSettings();
const openPage = ReaderControls.useOpenPage(); const openPage = ReaderControls.useOpenPage();
const openChapter = ReaderControls.useOpenChapter(); const openChapter = ReaderControls.useOpenChapter();
@@ -625,6 +625,7 @@ export class ReaderControls {
openChapter, openChapter,
setIsOverlayVisible, setIsOverlayVisible,
setShowPreview, setShowPreview,
scrollAmount,
); );
} else { } else {
openPage(action === TapZoneRegionType.PREVIOUS ? 'previous' : 'next', 'ltr'); openPage(action === TapZoneRegionType.PREVIOUS ? 'previous' : 'next', 'ltr');
@@ -644,6 +645,7 @@ export class ReaderControls {
openChapter, openChapter,
themeDirection, themeDirection,
isStaticNav, isStaticNav,
scrollAmount,
], ],
); );
} }

View File

@@ -14,6 +14,7 @@ import { ReaderStatePages } from '@/modules/reader/types/ReaderProgressBar.types
import { TMangaReader } from '@/modules/manga/Manga.types.ts'; import { TMangaReader } from '@/modules/manga/Manga.types.ts';
import { useAutomaticScrolling } from '@/modules/core/hooks/useAutomaticScrolling.ts'; import { useAutomaticScrolling } from '@/modules/core/hooks/useAutomaticScrolling.ts';
import { NavbarContextType } from '@/modules/navigation-bar/NavigationBar.types.ts'; import { NavbarContextType } from '@/modules/navigation-bar/NavigationBar.types.ts';
import { ReaderScrollAmount } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
export enum ProgressBarType { export enum ProgressBarType {
HIDDEN, HIDDEN,
@@ -158,6 +159,7 @@ export interface IReaderSettingsGlobal {
shouldShowTapZoneLayoutPreview: boolean; shouldShowTapZoneLayoutPreview: boolean;
shouldInformAboutMissingChapter: boolean; shouldInformAboutMissingChapter: boolean;
shouldInformAboutScanlatorChange: boolean; shouldInformAboutScanlatorChange: boolean;
scrollAmount: ReaderScrollAmount;
} }
export interface IReaderSettingsManga { export interface IReaderSettingsManga {