From f60b537115c0b96f46bb6620df5afa7ed0d890bb Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Sat, 20 Sep 2025 14:29:48 +0200 Subject: [PATCH] Move reader "progress bar state" to "reader store" --- src/features/reader/ReaderStore.ts | 9 ++++- .../reader/contexts/ReaderContextProvider.tsx | 5 +-- .../overlay/components/ReaderPageNumber.tsx | 13 +++---- .../progress-bar/ReaderProgressBar.tsx | 17 ++++----- .../progress-bar/ReaderProgressBarContext.tsx | 31 --------------- .../progress-bar/ReaderProgressBarStore.tsx | 38 +++++++++++++++++++ .../desktop/StandardReaderProgressBar.tsx | 21 +++++----- .../mobile/MobileReaderProgressBar.tsx | 14 +++---- 8 files changed, 76 insertions(+), 72 deletions(-) delete mode 100644 src/features/reader/overlay/progress-bar/ReaderProgressBarContext.tsx create mode 100644 src/features/reader/overlay/progress-bar/ReaderProgressBarStore.tsx diff --git a/src/features/reader/ReaderStore.ts b/src/features/reader/ReaderStore.ts index 2f13549f..e3e39f65 100644 --- a/src/features/reader/ReaderStore.ts +++ b/src/features/reader/ReaderStore.ts @@ -26,6 +26,10 @@ import { import { ImmerStateCreator } from '@/lib/zustand/Zustand.types.ts'; import { READER_DEFAULT_CHAPTERS_STATE, READER_DEFAULT_PAGES_STATE } from '@/features/reader/ReaderStore.constants.ts'; import { DEFAULT_READER_SETTINGS_WITH_DEFAULT_FLAG } from '@/features/reader/settings/ReaderSettingsMetadata.ts'; +import { + createReaderProgressBarStoreSlice, + ReaderProgressBarStoreSlice, +} from '@/features/reader/overlay/progress-bar/ReaderProgressBarStore.tsx'; interface ReaderPagesStoreSlice { pages: ReaderStatePages & { @@ -43,7 +47,8 @@ interface ReaderStore extends ReaderOverlayStoreSlice, ReaderAutoScrollStoreSlice, ReaderPagesStoreSlice, - ReaderChaptersStoreSlice { + ReaderChaptersStoreSlice, + ReaderProgressBarStoreSlice { reset: () => void; manga: TMangaReader | undefined; setManga: (manga: TMangaReader | undefined) => void; @@ -151,6 +156,7 @@ export const useReaderStore = create()( ...get().settings, ...DEFAULT_READER_SETTINGS_WITH_DEFAULT_FLAG, }; + get().progressBar.reset(); }), setManga: (manga) => set((draft) => { @@ -181,6 +187,7 @@ export const useReaderStore = create()( ...createReaderAutoScrollStoreSlice(set, get, store), ...createReaderPagesStoreSlice(set, get, store), ...createReaderChaptersStoreSlice(set, get, store), + ...createReaderProgressBarStoreSlice(set, get, store), })), ); export const useReaderStoreShallow = (selector: (state: ReaderStore) => T): T => diff --git a/src/features/reader/contexts/ReaderContextProvider.tsx b/src/features/reader/contexts/ReaderContextProvider.tsx index e64090ac..b616dd1e 100644 --- a/src/features/reader/contexts/ReaderContextProvider.tsx +++ b/src/features/reader/contexts/ReaderContextProvider.tsx @@ -7,11 +7,8 @@ */ import { ReactNode } from 'react'; -import { ReaderProgressBarContextProvider } from '@/features/reader/overlay/progress-bar/ReaderProgressBarContext.tsx'; import { ReaderTapZoneContextProvider } from '@/features/reader/tap-zones/ReaderTapZoneContext.tsx'; export const ReaderContextProvider = ({ children }: { children?: ReactNode }) => ( - - {children} - + {children} ); diff --git a/src/features/reader/overlay/components/ReaderPageNumber.tsx b/src/features/reader/overlay/components/ReaderPageNumber.tsx index 605ab58f..1e1ca86c 100644 --- a/src/features/reader/overlay/components/ReaderPageNumber.tsx +++ b/src/features/reader/overlay/components/ReaderPageNumber.tsx @@ -14,20 +14,16 @@ import { ReaderService } from '@/features/reader/services/ReaderService.ts'; import { ProgressBarType, ReadingDirection } from '@/features/reader/Reader.types.ts'; import { getPage } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.utils.tsx'; import { useNavBarContext } from '@/features/navigation-bar/NavbarContext.tsx'; -import { useReaderProgressBarContext } from '@/features/reader/overlay/progress-bar/ReaderProgressBarContext.tsx'; import { reverseString } from '@/base/utils/Strings.ts'; import { NavbarContextType } from '@/features/navigation-bar/NavigationBar.types.ts'; -import { TReaderProgressBarContext } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.types.ts'; import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx'; -import { useReaderStoreShallow } from '@/features/reader/ReaderStore.ts'; +import { useReaderStore, useReaderStoreShallow } from '@/features/reader/ReaderStore.ts'; const BaseReaderPageNumber = ({ isDesktop, readerNavBarWidth, - isMaximized, }: Pick, 'isDesktop'> & - Pick & - Pick) => { + Pick) => { const scrollbar = useReaderStoreShallow((state) => state.scrollbar); const { currentPageIndex, pages, totalPages } = useReaderStoreShallow((state) => ({ currentPageIndex: state.pages.currentPageIndex, @@ -39,6 +35,7 @@ const BaseReaderPageNumber = ({ shouldShowPageNumber: state.settings.shouldShowPageNumber, progressBarType: state.settings.progressBarType, })); + const isMaximized = useReaderStore((state) => state.progressBar.isMaximized); const pageName = useMemo(() => { const currentPageName = getPage(currentPageIndex, pages).name; @@ -90,6 +87,6 @@ const BaseReaderPageNumber = ({ export const ReaderPageNumber = withPropsFrom( BaseReaderPageNumber, - [ReaderService.useOverlayMode, useNavBarContext, useReaderProgressBarContext], - ['isDesktop', 'readerNavBarWidth', 'isMaximized'], + [ReaderService.useOverlayMode, useNavBarContext], + ['isDesktop', 'readerNavBarWidth'], ); diff --git a/src/features/reader/overlay/progress-bar/ReaderProgressBar.tsx b/src/features/reader/overlay/progress-bar/ReaderProgressBar.tsx index ba0744e5..56f2352a 100644 --- a/src/features/reader/overlay/progress-bar/ReaderProgressBar.tsx +++ b/src/features/reader/overlay/progress-bar/ReaderProgressBar.tsx @@ -11,10 +11,7 @@ import { ComponentProps, memo, ReactNode, useCallback, useMemo, useRef, useState import ClickAwayListener from '@mui/material/ClickAwayListener'; import { TypographyProps } from '@mui/material/Typography'; import { StackProps } from '@mui/material/Stack'; -import { - ReaderProgressBarProps, - TReaderProgressBarContext, -} from '@/features/reader/overlay/progress-bar/ReaderProgressBar.types.ts'; +import { ReaderProgressBarProps } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.types.ts'; import { ReaderProgressBarPageNumber } from '@/features/reader/overlay/progress-bar/components/ReaderProgressBarPageNumber.tsx'; import { ReaderProgressBarContainer } from '@/features/reader/overlay/progress-bar/components/ReaderProgressBarContainer.tsx'; import { ReaderProgressBarRoot } from '@/features/reader/overlay/progress-bar/components/ReaderProgressBarRoot.tsx'; @@ -32,7 +29,6 @@ import { ReaderProgressBarSlotsActionArea } from '@/features/reader/overlay/prog import { ReaderService } from '@/features/reader/services/ReaderService.ts'; import { ReaderControls } from '@/features/reader/services/ReaderControls.ts'; import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx'; -import { useReaderProgressBarContext } from '@/features/reader/overlay/progress-bar/ReaderProgressBarContext.tsx'; import { ReaderProgressBarSlotWrapper } from '@/features/reader/overlay/progress-bar/components/ReaderProgressBarSlotWrapper.tsx'; import { useResizeObserver } from '@/base/hooks/useResizeObserver.tsx'; import { ReadingMode } from '@/features/reader/Reader.types.ts'; @@ -43,13 +39,10 @@ const BaseReaderProgressBar = ({ slots, createProgressBarSlot, progressBarPosition, - isDragging, - setIsDragging, openPage, direction, fullSegmentClicks, }: ReaderProgressBarProps & - Pick & Pick, 'createProgressBarSlot'> & { slotProps?: { container?: StackProps; @@ -79,6 +72,10 @@ const BaseReaderProgressBar = ({ currentPageIndex: state.pages.currentPageIndex, })); const readingMode = useReaderStore((state) => state.settings.readingMode.value); + const { isDragging, setIsDragging } = useReaderStoreShallow((state) => ({ + isDragging: state.progressBar.isDragging, + setIsDragging: state.progressBar.setIsDragging, + })); const progressBarRef = useRef(null); const draggingDetectionTimeout = useRef(undefined); @@ -249,6 +246,6 @@ const BaseReaderProgressBar = ({ export const ReaderProgressBar = withPropsFrom( memo(BaseReaderProgressBar), - [useReaderProgressBarContext, () => ({ openPage: ReaderControls.useOpenPage() })], - ['isDragging', 'setIsDragging', 'openPage'], + [() => ({ openPage: ReaderControls.useOpenPage() })], + ['openPage'], ); diff --git a/src/features/reader/overlay/progress-bar/ReaderProgressBarContext.tsx b/src/features/reader/overlay/progress-bar/ReaderProgressBarContext.tsx deleted file mode 100644 index dcfaaa31..00000000 --- a/src/features/reader/overlay/progress-bar/ReaderProgressBarContext.tsx +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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, ReactNode, useMemo, useState } from 'react'; -import { TReaderProgressBarContext } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.types.ts'; - -export const ReaderProgressBarContext = createContext({ - isMaximized: false, - setIsMaximized: () => undefined, - isDragging: false, - setIsDragging: () => undefined, -}); - -export const useReaderProgressBarContext = () => useContext(ReaderProgressBarContext); - -export const ReaderProgressBarContextProvider = ({ children }: { children: ReactNode }) => { - const [isMaximized, setIsMaximized] = useState(false); - const [isDragging, setIsDragging] = useState(false); - - const value = useMemo( - () => ({ isMaximized, setIsMaximized, isDragging, setIsDragging }), - [isMaximized, isDragging], - ); - - return {children}; -}; diff --git a/src/features/reader/overlay/progress-bar/ReaderProgressBarStore.tsx b/src/features/reader/overlay/progress-bar/ReaderProgressBarStore.tsx new file mode 100644 index 00000000..64402301 --- /dev/null +++ b/src/features/reader/overlay/progress-bar/ReaderProgressBarStore.tsx @@ -0,0 +1,38 @@ +/* + * 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 { ImmerStateCreator } from '@/lib/zustand/Zustand.types.ts'; +import { TReaderProgressBarContext } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.types.ts'; + +export interface ReaderProgressBarStoreSlice { + progressBar: TReaderProgressBarContext & { + reset: () => void; + }; +} + +const DEFAULT_STATE = { + isMaximized: false, + isDragging: false, +} satisfies Pick; + +export const createReaderProgressBarStoreSlice = ( + ...[set, get]: Parameters> +): ReaderProgressBarStoreSlice => ({ + progressBar: { + ...DEFAULT_STATE, + setIsMaximized: (maximized) => + set((draft) => { + draft.progressBar.isMaximized = maximized; + }), + setIsDragging: (dragging) => + set((draft) => { + draft.progressBar.isDragging = dragging; + }), + reset: () => set(() => ({ progressBar: { ...get().progressBar, ...DEFAULT_STATE } })), + }, +}); diff --git a/src/features/reader/overlay/progress-bar/desktop/StandardReaderProgressBar.tsx b/src/features/reader/overlay/progress-bar/desktop/StandardReaderProgressBar.tsx index dcb1af53..d91c729f 100644 --- a/src/features/reader/overlay/progress-bar/desktop/StandardReaderProgressBar.tsx +++ b/src/features/reader/overlay/progress-bar/desktop/StandardReaderProgressBar.tsx @@ -14,11 +14,9 @@ import { ProgressBarType } from '@/features/reader/Reader.types.ts'; import { applyStyles } from '@/base/utils/ApplyStyles.ts'; import { getProgressBarPositionInfo } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.utils.tsx'; import { ReaderProgressBarDirectionWrapper } from '@/features/reader/overlay/progress-bar/components/ReaderProgressBarDirectionWrapper.tsx'; -import { TReaderProgressBarContext } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.types.ts'; import { NavbarContextType } from '@/features/navigation-bar/NavigationBar.types.ts'; import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx'; import { useNavBarContext } from '@/features/navigation-bar/NavbarContext.tsx'; -import { useReaderProgressBarContext } from '@/features/reader/overlay/progress-bar/ReaderProgressBarContext.tsx'; import { ReaderProgressBarSlotDesktop } from '@/features/reader/overlay/progress-bar/desktop/components/ReaderProgressBarSlotDesktop.tsx'; import { useResizeObserver } from '@/base/hooks/useResizeObserver.tsx'; import { getProgressBarPosition } from '@/features/reader/settings/ReaderSettings.utils.tsx'; @@ -26,14 +24,10 @@ import { useReaderStore, useReaderStoreShallow } from '@/features/reader/ReaderS const BaseStandardReaderProgressBar = ({ readerNavBarWidth, - isMaximized, - setIsMaximized, - isDragging, readerDirection, -}: Pick & - Pick & { - readerDirection: ReturnType; - }) => { +}: Pick & { + readerDirection: ReturnType; +}) => { const theme = useTheme(); const scrollbar = useReaderStoreShallow((state) => state.scrollbar); @@ -45,6 +39,11 @@ const BaseStandardReaderProgressBar = ({ progressBarPosition: state.settings.progressBarPosition, progressBarPositionAutoVertical: state.settings.progressBarPositionAutoVertical, })); + const { isMaximized, setIsMaximized, isDragging } = useReaderStoreShallow((state) => ({ + isMaximized: state.progressBar.isMaximized, + setIsMaximized: state.progressBar.setIsMaximized, + isDragging: state.progressBar.isDragging, + })); const [, setRefreshProgressBarPosition] = useState({}); useResizeObserver( @@ -243,6 +242,6 @@ const BaseStandardReaderProgressBar = ({ export const StandardReaderProgressBar = withPropsFrom( memo(BaseStandardReaderProgressBar), - [useNavBarContext, useReaderProgressBarContext, () => ({ readerDirection: ReaderService.useGetThemeDirection() })], - ['readerNavBarWidth', 'isMaximized', 'setIsMaximized', 'isDragging', 'readerDirection'], + [useNavBarContext, () => ({ readerDirection: ReaderService.useGetThemeDirection() })], + ['readerNavBarWidth', 'readerDirection'], ); diff --git a/src/features/reader/overlay/progress-bar/mobile/MobileReaderProgressBar.tsx b/src/features/reader/overlay/progress-bar/mobile/MobileReaderProgressBar.tsx index 6e0fa142..04b4d763 100644 --- a/src/features/reader/overlay/progress-bar/mobile/MobileReaderProgressBar.tsx +++ b/src/features/reader/overlay/progress-bar/mobile/MobileReaderProgressBar.tsx @@ -23,9 +23,7 @@ import { import { getOptionForDirection } from '@/features/theme/services/ThemeCreator.ts'; import { ProgressBarPosition } from '@/features/reader/Reader.types.ts'; import { ReaderProgressBarDirectionWrapper } from '@/features/reader/overlay/progress-bar/components/ReaderProgressBarDirectionWrapper.tsx'; -import { useReaderProgressBarContext } from '@/features/reader/overlay/progress-bar/ReaderProgressBarContext.tsx'; import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx'; -import { TReaderProgressBarContext } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.types.ts'; import { ReaderProgressBarSlotMobile } from '@/features/reader/overlay/progress-bar/mobile/components/ReaderProgressBarSlotMobile.tsx'; import { applyStyles } from '@/base/utils/ApplyStyles.ts'; import { useResizeObserver } from '@/base/hooks/useResizeObserver.tsx'; @@ -42,12 +40,10 @@ const PROGRESS_BAR_POSITION_TO_SLIDE_DIRECTION: Record & { +}: { direction: ReturnType; topOffset?: number; bottomOffset?: number; @@ -67,6 +63,10 @@ const BaseMobileReaderProgressBar = ({ progressBarPosition: state.settings.progressBarPosition, progressBarPositionAutoVertical: state.settings.progressBarPositionAutoVertical, })); + const { setIsMaximized, isDragging } = useReaderStoreShallow((state) => ({ + setIsMaximized: state.progressBar.setIsMaximized, + isDragging: state.progressBar.isDragging, + })); const [, setRefreshProgressBarPosition] = useState({}); useResizeObserver( @@ -354,6 +354,6 @@ const BaseMobileReaderProgressBar = ({ export const MobileReaderProgressBar = withPropsFrom( memo(BaseMobileReaderProgressBar), - [useReaderProgressBarContext, () => ({ direction: ReaderService.useGetThemeDirection() })], - ['setIsMaximized', 'isDragging', 'direction'], + [() => ({ direction: ReaderService.useGetThemeDirection() })], + ['direction'], );