Add "automatic scrolling"

This commit is contained in:
schroda
2024-12-27 00:30:19 +01:00
parent 6b0df5329b
commit e2075a651e
18 changed files with 520 additions and 19 deletions

View File

@@ -0,0 +1,19 @@
/*
* 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 { createContext, useContext } from 'react';
import { TReaderAutoScrollContext } from '@/modules/reader/types/Reader.types.ts';
export const ReaderAutoScrollContext = createContext<TReaderAutoScrollContext>({
isActive: false,
setScrollRef: () => {},
start: () => {},
cancel: () => {},
});
export const useReaderAutoScrollContext = () => useContext(ReaderAutoScrollContext);

View File

@@ -0,0 +1,75 @@
/*
* 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 { memo, ReactNode, useCallback, useMemo, useState } from 'react';
import { Direction, useTheme } from '@mui/material/styles';
import { useAutomaticScrolling } from '@/modules/core/hooks/useAutomaticScrolling.ts';
import { IReaderSettings, TReaderAutoScrollContext } from '@/modules/reader/types/Reader.types.ts';
import { ReaderAutoScrollContext } from '@/modules/reader/contexts/ReaderAutoScrollContext.tsx';
import { ReaderControls } from '@/modules/reader/services/ReaderControls';
import { isContinuousReadingMode } from '@/modules/reader/utils/ReaderSettings.utils.tsx';
import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx';
import { ReaderService } from '@/modules/reader/services/ReaderService.ts';
import {
CONTINUOUS_READING_MODE_TO_SCROLL_DIRECTION,
ReaderScrollAmount,
} from '@/modules/reader/constants/ReaderSettings.constants.tsx';
const BaseReaderAutoScrollContextProvider = ({
children,
openPage,
readingMode,
autoScroll,
themeDirection,
combinedDirection,
}: Pick<IReaderSettings, 'readingMode' | 'autoScroll'> & {
children: ReactNode;
openPage: ReturnType<typeof ReaderControls.useOpenPage>;
themeDirection: Direction;
combinedDirection: Direction;
}) => {
const [scrollRef, setScrollRef] = useState<TReaderAutoScrollContext['scrollRef']>();
const invertScrolling = themeDirection !== combinedDirection;
const isContinuousReadingModeActive = isContinuousReadingMode(readingMode);
const changePage = useCallback(() => {
openPage('next');
}, []);
const automaticScrolling = useAutomaticScrolling(
isContinuousReadingModeActive ? scrollRef : changePage,
autoScroll.value,
CONTINUOUS_READING_MODE_TO_SCROLL_DIRECTION[readingMode],
ReaderScrollAmount.MEDIUM,
invertScrolling,
autoScroll.smooth,
);
const value = useMemo(
() => ({
scrollRef,
setScrollRef,
...automaticScrolling,
}),
[scrollRef, automaticScrolling],
);
return <ReaderAutoScrollContext.Provider value={value}>{children}</ReaderAutoScrollContext.Provider>;
};
export const ReaderAutoScrollContextProvider = withPropsFrom(
memo(BaseReaderAutoScrollContextProvider),
[
ReaderService.useSettingsWithoutDefaultFlag,
() => ({ openPage: ReaderControls.useOpenPage() }),
() => ({ themeDirection: useTheme().direction }),
() => ({ combinedDirection: ReaderService.useGetThemeDirection() }),
],
['openPage', 'readingMode', 'themeDirection', 'combinedDirection', 'autoScroll'],
);

View File

@@ -12,13 +12,16 @@ import { ReaderProgressBarContextProvider } from '@/modules/reader/contexts/Read
import { ReaderOverlayContextProvider } from '@/modules/reader/contexts/ReaderOverlayContextProvider.tsx';
import { ReaderStateContextProvider } from '@/modules/reader/contexts/state/ReaderStateContextProvider.tsx';
import { ReaderScrollbarContextProvider } from '@/modules/reader/contexts/ReaderScrollbarContextProvider.tsx';
import { ReaderAutoScrollContextProvider } from '@/modules/reader/contexts/ReaderAutoScrollContextProvider.tsx';
export const ReaderContextProvider = ({ children }: { children?: ReactNode }) => (
<ReaderStateContextProvider>
<ReaderTapZoneContextProvider>
<ReaderOverlayContextProvider>
<ReaderProgressBarContextProvider>
<ReaderScrollbarContextProvider>{children}</ReaderScrollbarContextProvider>
<ReaderScrollbarContextProvider>
<ReaderAutoScrollContextProvider>{children}</ReaderAutoScrollContextProvider>
</ReaderScrollbarContextProvider>
</ReaderProgressBarContextProvider>
</ReaderOverlayContextProvider>
</ReaderTapZoneContextProvider>