Add "scroll amount" setting
This commit is contained in:
@@ -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",
|
||||||
|
|||||||
@@ -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],
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -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[];
|
||||||
|
|||||||
@@ -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,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user