/* * 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, ReaderScrollAmount, ReadingMode, 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 } from '@/modules/reader/constants/ReaderSettings.constants.tsx'; import { ScrollOffset } from '@/modules/core/Core.types.ts'; import { getOptionForDirection } from '@/modules/theme/services/ThemeCreator.ts'; const BaseReaderAutoScrollContextProvider = ({ children, openPage, readingMode, autoScroll, themeDirection, combinedDirection, }: Pick & { children: ReactNode; openPage: ReturnType; themeDirection: Direction; combinedDirection: Direction; }) => { const [scrollRef, setScrollRef] = useState(); const [direction, setDirection] = useState(ScrollOffset.FORWARD); const isScrollingInvertedBasedOnReadingDirection = readingMode === ReadingMode.CONTINUOUS_HORIZONTAL && themeDirection !== combinedDirection; const invertScrolling = isScrollingInvertedBasedOnReadingDirection ? getOptionForDirection( direction === ScrollOffset.BACKWARD, direction === ScrollOffset.FORWARD, combinedDirection, ) : direction === ScrollOffset.BACKWARD; const isContinuousReadingModeActive = isContinuousReadingMode(readingMode); const changePage = useCallback(() => { openPage('next', 'ltr'); }, [openPage]); 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, setDirection, ...automaticScrolling, }), [scrollRef, automaticScrolling], ); return {children}; }; export const ReaderAutoScrollContextProvider = withPropsFrom( memo(BaseReaderAutoScrollContextProvider), [ ReaderService.useSettingsWithoutDefaultFlag, () => ({ openPage: ReaderControls.useOpenPage() }), () => ({ themeDirection: useTheme().direction }), () => ({ combinedDirection: ReaderService.useGetThemeDirection() }), ], ['openPage', 'readingMode', 'themeDirection', 'combinedDirection', 'autoScroll'], );