Move reader "tap zone state" to "reader store"
This commit is contained in:
@@ -30,6 +30,10 @@ import {
|
||||
createReaderProgressBarStoreSlice,
|
||||
ReaderProgressBarStoreSlice,
|
||||
} from '@/features/reader/overlay/progress-bar/ReaderProgressBarStore.tsx';
|
||||
import {
|
||||
createReaderTapZoneStoreSlice,
|
||||
ReaderTapZoneStoreSlice,
|
||||
} from '@/features/reader/tap-zones/ReaderTapZoneStore.tsx';
|
||||
|
||||
interface ReaderPagesStoreSlice {
|
||||
pages: ReaderStatePages & {
|
||||
@@ -48,7 +52,8 @@ interface ReaderStore
|
||||
ReaderAutoScrollStoreSlice,
|
||||
ReaderPagesStoreSlice,
|
||||
ReaderChaptersStoreSlice,
|
||||
ReaderProgressBarStoreSlice {
|
||||
ReaderProgressBarStoreSlice,
|
||||
ReaderTapZoneStoreSlice {
|
||||
reset: () => void;
|
||||
manga: TMangaReader | undefined;
|
||||
setManga: (manga: TMangaReader | undefined) => void;
|
||||
@@ -157,6 +162,7 @@ export const useReaderStore = create<ReaderStore>()(
|
||||
...DEFAULT_READER_SETTINGS_WITH_DEFAULT_FLAG,
|
||||
};
|
||||
get().progressBar.reset();
|
||||
get().tapZone.reset();
|
||||
}),
|
||||
setManga: (manga) =>
|
||||
set((draft) => {
|
||||
@@ -188,6 +194,7 @@ export const useReaderStore = create<ReaderStore>()(
|
||||
...createReaderPagesStoreSlice(set, get, store),
|
||||
...createReaderChaptersStoreSlice(set, get, store),
|
||||
...createReaderProgressBarStoreSlice(set, get, store),
|
||||
...createReaderTapZoneStoreSlice(set, get, store),
|
||||
})),
|
||||
);
|
||||
export const useReaderStoreShallow = <T>(selector: (state: ReaderStore) => T): T =>
|
||||
|
||||
@@ -1,14 +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 { ReactNode } from 'react';
|
||||
import { ReaderTapZoneContextProvider } from '@/features/reader/tap-zones/ReaderTapZoneContext.tsx';
|
||||
|
||||
export const ReaderContextProvider = ({ children }: { children?: ReactNode }) => (
|
||||
<ReaderTapZoneContextProvider>{children}</ReaderTapZoneContextProvider>
|
||||
);
|
||||
@@ -24,7 +24,6 @@ import { HotkeyScope } from '@/features/hotkeys/Hotkeys.types.ts';
|
||||
import { ReaderControls } from '@/features/reader/services/ReaderControls.ts';
|
||||
import { ScrollOffset } from '@/base/Base.types.ts';
|
||||
import { getOptionForDirection } from '@/features/theme/services/ThemeCreator.ts';
|
||||
import { useReaderTapZoneContext } from '@/features/reader/tap-zones/ReaderTapZoneContext.tsx';
|
||||
import { getReaderStore, useReaderStoreShallow } from '@/features/reader/ReaderStore.ts';
|
||||
|
||||
const useHotkeys = (...args: Parameters<typeof useHotKeysHook>): ReturnType<typeof useHotKeysHook> => {
|
||||
@@ -66,7 +65,6 @@ export const ReaderHotkeys = ({
|
||||
const { hotkeys } = useReaderStoreShallow((state) => ({
|
||||
hotkeys: state.settings.hotkeys,
|
||||
}));
|
||||
const { setShowPreview } = useReaderTapZoneContext();
|
||||
const exitReader = ReaderService.useExit();
|
||||
|
||||
const openChapter = ReaderControls.useOpenChapter();
|
||||
@@ -99,7 +97,7 @@ export const ReaderHotkeys = ({
|
||||
themeDirection,
|
||||
scrollElementRef.current,
|
||||
openChapter,
|
||||
setShowPreview,
|
||||
getReaderStore().tapZone.setShowPreview,
|
||||
scrollAmount,
|
||||
);
|
||||
},
|
||||
@@ -131,7 +129,7 @@ export const ReaderHotkeys = ({
|
||||
themeDirection,
|
||||
scrollElementRef.current,
|
||||
openChapter,
|
||||
setShowPreview,
|
||||
getReaderStore().tapZone.setShowPreview,
|
||||
scrollAmount,
|
||||
);
|
||||
},
|
||||
|
||||
@@ -28,7 +28,6 @@ import { ReaderHotkeys } from '@/features/reader/hotkeys/ReaderHotkeys.tsx';
|
||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||
import { NavbarContextType } from '@/features/navigation-bar/NavigationBar.types.ts';
|
||||
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
||||
import { TReaderTapZoneContext } from '@/features/reader/tap-zones/TapZoneLayout.types.ts';
|
||||
import { useReaderResetStates } from '@/features/reader/hooks/useReaderResetStates.ts';
|
||||
import { useReaderSetSettingsState } from '@/features/reader/hooks/useReaderSetSettingsState.ts';
|
||||
import { useReaderShowSettingPreviewOnChange } from '@/features/reader/hooks/useReaderShowSettingPreviewOnChange.ts';
|
||||
@@ -42,8 +41,7 @@ import { ReaderAutoScroll } from '@/features/reader/auto-scroll/ReaderAutoScroll
|
||||
const BaseReader = ({
|
||||
setOverride,
|
||||
readerNavBarWidth,
|
||||
setShowPreview,
|
||||
}: Pick<NavbarContextType, 'setOverride' | 'readerNavBarWidth'> & Pick<TReaderTapZoneContext, 'setShowPreview'>) => {
|
||||
}: Pick<NavbarContextType, 'setOverride' | 'readerNavBarWidth'>) => {
|
||||
const { t } = useTranslation();
|
||||
const manga = useReaderStoreShallow((state) => state.manga);
|
||||
const overlay = useReaderStoreShallow((state) => state.overlay);
|
||||
@@ -76,6 +74,7 @@ const BaseReader = ({
|
||||
shouldShowTapZoneLayoutPreview: state.settings.shouldShowTapZoneLayoutPreview,
|
||||
setSettings: state.settings.setSettings,
|
||||
}));
|
||||
const setShowPreview = useReaderStore((state) => state.tapZone.setShowPreview);
|
||||
|
||||
const scrollElementRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ import {
|
||||
isEndOfPageInViewport,
|
||||
isPageInViewport,
|
||||
} from '@/features/reader/viewer/pager/ReaderPager.utils.tsx';
|
||||
import { useReaderTapZoneContext } from '@/features/reader/tap-zones/ReaderTapZoneContext.tsx';
|
||||
import { TapZoneRegionType, TReaderTapZoneContext } from '@/features/reader/tap-zones/TapZoneLayout.types.ts';
|
||||
import { ReaderTapZoneService } from '@/features/reader/tap-zones/ReaderTapZoneService.ts';
|
||||
import { isContinuousReadingMode } from '@/features/reader/settings/ReaderSettings.utils.tsx';
|
||||
@@ -334,7 +333,6 @@ export class ReaderControls {
|
||||
forceDirection?: Direction,
|
||||
hideOverlay?: boolean,
|
||||
) => void {
|
||||
const { setShowPreview } = useReaderTapZoneContext();
|
||||
const openChapter = ReaderControls.useOpenChapter();
|
||||
|
||||
return useCallback(
|
||||
@@ -371,7 +369,7 @@ export class ReaderControls {
|
||||
|
||||
if (hideOverlay) {
|
||||
getReaderStore().overlay.setIsVisible(false);
|
||||
setShowPreview(false);
|
||||
getReaderStore().tapZone.setShowPreview(false);
|
||||
}
|
||||
|
||||
const hideTransitionPage = () => setTransitionPageMode(ReaderTransitionPageMode.NONE);
|
||||
@@ -565,7 +563,6 @@ export class ReaderControls {
|
||||
scrollElement: HTMLElement | null,
|
||||
): (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void {
|
||||
const { direction: themeDirection } = useTheme();
|
||||
const { setShowPreview } = useReaderTapZoneContext();
|
||||
const openPage = ReaderControls.useOpenPage();
|
||||
const openChapter = ReaderControls.useOpenChapter();
|
||||
|
||||
@@ -582,7 +579,7 @@ export class ReaderControls {
|
||||
const rectRelativeY = e.clientY - rect.top;
|
||||
const action = ReaderTapZoneService.getAction(rectRelativeX, rectRelativeY);
|
||||
|
||||
setShowPreview(false);
|
||||
getReaderStore().tapZone.setShowPreview(false);
|
||||
|
||||
const isContinuousReadingModeActive = isContinuousReadingMode(readingMode.value);
|
||||
const scrollDirection =
|
||||
@@ -603,7 +600,7 @@ export class ReaderControls {
|
||||
themeDirection,
|
||||
scrollElement,
|
||||
openChapter,
|
||||
setShowPreview,
|
||||
getReaderStore().tapZone.setShowPreview,
|
||||
scrollAmount,
|
||||
);
|
||||
} else {
|
||||
|
||||
@@ -13,7 +13,6 @@ import { TabsMenu } from '@/base/components/tabs/TabsMenu.tsx';
|
||||
import { ReaderService } from '@/features/reader/services/ReaderService.ts';
|
||||
import { MediaQuery } from '@/base/utils/MediaQuery.tsx';
|
||||
import { IReaderSettings, IReaderSettingsWithDefaultFlag } from '@/features/reader/Reader.types.ts';
|
||||
import { useReaderTapZoneContext } from '@/features/reader/tap-zones/ReaderTapZoneContext.tsx';
|
||||
import { applyStyles } from '@/base/utils/ApplyStyles.ts';
|
||||
import { READER_SETTING_TABS, ReaderSettingTab } from '@/features/reader/settings/ReaderSettings.constants.tsx';
|
||||
import { TabPanel } from '@/base/components/tabs/TabPanel.tsx';
|
||||
@@ -23,8 +22,8 @@ import { ReaderFilterSettings } from '@/features/reader/filters/settings/ReaderF
|
||||
import { ReaderBehaviourSettings } from '@/features/reader/settings/behaviour/ReaderBehaviourSettings.tsx';
|
||||
import { ReaderDefaultLayoutSettings } from '@/features/reader/settings/layout/ReaderDefaultLayoutSettings.tsx';
|
||||
import { ReaderHotkeysSettings } from '@/features/reader/hotkeys/settings/ReaderHotkeysSettings.tsx';
|
||||
import { TReaderTapZoneContext } from '@/features/reader/tap-zones/TapZoneLayout.types.ts';
|
||||
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
||||
import { useReaderStore } from '@/features/reader/ReaderStore.ts';
|
||||
|
||||
const BaseReaderSettingsTabs = ({
|
||||
activeTab,
|
||||
@@ -33,21 +32,20 @@ const BaseReaderSettingsTabs = ({
|
||||
settings,
|
||||
updateSetting,
|
||||
deleteSetting,
|
||||
setShowPreview,
|
||||
mode: overlayMode,
|
||||
setTransparent,
|
||||
}: Pick<TReaderTapZoneContext, 'setShowPreview'> &
|
||||
Pick<ReturnType<typeof ReaderService.useOverlayMode>, 'mode'> & {
|
||||
activeTab: number;
|
||||
setActiveTab: (tab: number) => void;
|
||||
settings: IReaderSettingsWithDefaultFlag;
|
||||
updateSetting: (...args: Parameters<typeof ReaderService.updateSetting>) => void;
|
||||
areDefaultSettings?: boolean;
|
||||
deleteSetting: (setting: keyof IReaderSettings) => void;
|
||||
setTransparent?: (transparent: boolean) => void;
|
||||
}) => {
|
||||
}: Pick<ReturnType<typeof ReaderService.useOverlayMode>, 'mode'> & {
|
||||
activeTab: number;
|
||||
setActiveTab: (tab: number) => void;
|
||||
settings: IReaderSettingsWithDefaultFlag;
|
||||
updateSetting: (...args: Parameters<typeof ReaderService.updateSetting>) => void;
|
||||
areDefaultSettings?: boolean;
|
||||
deleteSetting: (setting: keyof IReaderSettings) => void;
|
||||
setTransparent?: (transparent: boolean) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const isTouchDevice = MediaQuery.useIsTouchDevice();
|
||||
const setShowPreview = useReaderStore((state) => state.tapZone.setShowPreview);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -186,8 +184,4 @@ const BaseReaderSettingsTabs = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const ReaderSettingsTabs = withPropsFrom(
|
||||
BaseReaderSettingsTabs,
|
||||
[useReaderTapZoneContext, ReaderService.useOverlayMode],
|
||||
['setShowPreview', 'mode'],
|
||||
);
|
||||
export const ReaderSettingsTabs = withPropsFrom(BaseReaderSettingsTabs, [ReaderService.useOverlayMode], ['mode']);
|
||||
|
||||
@@ -1,25 +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 { TReaderTapZoneContext } from '@/features/reader/tap-zones/TapZoneLayout.types.ts';
|
||||
|
||||
export const ReaderTapZoneContext = createContext<TReaderTapZoneContext>({
|
||||
showPreview: false,
|
||||
setShowPreview: () => undefined,
|
||||
});
|
||||
|
||||
export const useReaderTapZoneContext = () => useContext(ReaderTapZoneContext);
|
||||
|
||||
export const ReaderTapZoneContextProvider = ({ children }: { children: ReactNode }) => {
|
||||
const [showPreview, setShowPreview] = useState(false);
|
||||
|
||||
const value = useMemo(() => ({ showPreview, setShowPreview }), [showPreview]);
|
||||
|
||||
return <ReaderTapZoneContext.Provider value={value}>{children}</ReaderTapZoneContext.Provider>;
|
||||
};
|
||||
33
src/features/reader/tap-zones/ReaderTapZoneStore.tsx
Normal file
33
src/features/reader/tap-zones/ReaderTapZoneStore.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 { TReaderTapZoneContext } from '@/features/reader/tap-zones/TapZoneLayout.types.ts';
|
||||
|
||||
export interface ReaderTapZoneStoreSlice {
|
||||
tapZone: TReaderTapZoneContext & {
|
||||
reset: () => void;
|
||||
};
|
||||
}
|
||||
|
||||
const DEFAULT_STATE = {
|
||||
showPreview: false,
|
||||
} satisfies Pick<ReaderTapZoneStoreSlice['tapZone'], 'showPreview'>;
|
||||
|
||||
export const createReaderTapZoneStoreSlice = <T extends ReaderTapZoneStoreSlice>(
|
||||
...[set, get]: Parameters<ImmerStateCreator<T>>
|
||||
): ReaderTapZoneStoreSlice => ({
|
||||
tapZone: {
|
||||
...DEFAULT_STATE,
|
||||
setShowPreview: (showPreview) =>
|
||||
set((draft) => {
|
||||
draft.tapZone.showPreview = showPreview;
|
||||
}),
|
||||
reset: () => set(() => ({ tapZone: { ...get().tapZone, ...DEFAULT_STATE } })),
|
||||
},
|
||||
});
|
||||
@@ -9,28 +9,24 @@
|
||||
import Box from '@mui/material/Box';
|
||||
import { useCallback, useLayoutEffect, useState } from 'react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { useReaderTapZoneContext } from '@/features/reader/tap-zones/ReaderTapZoneContext.tsx';
|
||||
import { ReaderTapZoneService } from '@/features/reader/tap-zones/ReaderTapZoneService.ts';
|
||||
import { useNavBarContext } from '@/features/navigation-bar/NavbarContext.tsx';
|
||||
import { useResizeObserver } from '@/base/hooks/useResizeObserver.tsx';
|
||||
import { ReadingDirection } from '@/features/reader/Reader.types.ts';
|
||||
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
||||
import { NavbarContextType } from '@/features/navigation-bar/NavigationBar.types.ts';
|
||||
import { TReaderTapZoneContext } from '@/features/reader/tap-zones/TapZoneLayout.types.ts';
|
||||
import { useReaderStoreShallow } from '@/features/reader/ReaderStore.ts';
|
||||
import { useReaderStore, useReaderStoreShallow } from '@/features/reader/ReaderStore.ts';
|
||||
|
||||
const CANVAS_ID = 'reader-tap-zone-layout-canvas';
|
||||
|
||||
const BaseTapZoneLayout = ({
|
||||
readerNavBarWidth,
|
||||
showPreview,
|
||||
}: Pick<NavbarContextType, 'readerNavBarWidth'> & Pick<TReaderTapZoneContext, 'showPreview'>) => {
|
||||
const BaseTapZoneLayout = ({ readerNavBarWidth }: Pick<NavbarContextType, 'readerNavBarWidth'>) => {
|
||||
const theme = useTheme();
|
||||
const { tapZoneLayout, tapZoneInvertMode, readingDirection } = useReaderStoreShallow((state) => ({
|
||||
tapZoneLayout: state.settings.tapZoneLayout.value,
|
||||
tapZoneInvertMode: state.settings.tapZoneInvertMode.value,
|
||||
readingDirection: state.settings.readingDirection.value,
|
||||
}));
|
||||
const showPreview = useReaderStore((state) => state.tapZone.showPreview);
|
||||
|
||||
const [width, setWidth] = useState(0);
|
||||
const [height, setHeight] = useState(0);
|
||||
@@ -71,8 +67,4 @@ const BaseTapZoneLayout = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const TapZoneLayout = withPropsFrom(
|
||||
BaseTapZoneLayout,
|
||||
[useNavBarContext, useReaderTapZoneContext],
|
||||
['readerNavBarWidth', 'showPreview'],
|
||||
);
|
||||
export const TapZoneLayout = withPropsFrom(BaseTapZoneLayout, [useNavBarContext], ['readerNavBarWidth']);
|
||||
|
||||
@@ -38,8 +38,6 @@ import {
|
||||
import { useMouseDragScroll } from '@/base/hooks/useMouseDragScroll.tsx';
|
||||
import { applyStyles } from '@/base/utils/ApplyStyles.ts';
|
||||
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
||||
import { TReaderTapZoneContext } from '@/features/reader/tap-zones/TapZoneLayout.types.ts';
|
||||
import { useReaderTapZoneContext } from '@/features/reader/tap-zones/ReaderTapZoneContext.tsx';
|
||||
import { useReaderAutoScroll } from '@/features/reader/auto-scroll/hooks/useReaderAutoScroll.ts';
|
||||
import { useReaderHideOverlayOnUserScroll } from '@/features/reader/overlay/hooks/useReaderHideOverlayOnUserScroll.ts';
|
||||
import { useReaderHorizontalModeInvertXYScrolling } from '@/features/reader/viewer/hooks/useReaderHorizontalModeInvertXYScrolling.ts';
|
||||
@@ -73,12 +71,9 @@ const BaseReaderViewer = forwardRef(
|
||||
{
|
||||
readerNavBarWidth,
|
||||
updateCurrentPageIndex,
|
||||
showPreview,
|
||||
setShowPreview,
|
||||
}: Pick<NavbarContextType, 'readerNavBarWidth'> &
|
||||
TReaderTapZoneContext & {
|
||||
updateCurrentPageIndex: ReturnType<typeof ReaderControls.useUpdateCurrentPageIndex>;
|
||||
},
|
||||
}: Pick<NavbarContextType, 'readerNavBarWidth'> & {
|
||||
updateCurrentPageIndex: ReturnType<typeof ReaderControls.useUpdateCurrentPageIndex>;
|
||||
},
|
||||
|
||||
ref: ForwardedRef<HTMLDivElement | null>,
|
||||
) => {
|
||||
@@ -149,6 +144,10 @@ const BaseReaderViewer = forwardRef(
|
||||
shouldStretchPage: state.settings.shouldStretchPage.value,
|
||||
isStaticNav: state.settings.isStaticNav,
|
||||
}));
|
||||
const { showPreview, setShowPreview } = useReaderStoreShallow((state) => ({
|
||||
showPreview: state.tapZone.showPreview,
|
||||
setShowPreview: state.tapZone.setShowPreview,
|
||||
}));
|
||||
const { resumeMode = ReaderResumeMode.START } = useLocation<ReaderOpenChapterLocationState>().state ?? {
|
||||
resumeMode: ReaderResumeMode.START,
|
||||
};
|
||||
@@ -435,10 +434,6 @@ const BaseReaderViewer = forwardRef(
|
||||
|
||||
export const ReaderViewer = withPropsFrom(
|
||||
memo(BaseReaderViewer),
|
||||
[
|
||||
() => ({ updateCurrentPageIndex: ReaderControls.useUpdateCurrentPageIndex() }),
|
||||
useReaderTapZoneContext,
|
||||
useNavBarContext,
|
||||
],
|
||||
['readerNavBarWidth', 'updateCurrentPageIndex', 'showPreview', 'setShowPreview'],
|
||||
[() => ({ updateCurrentPageIndex: ReaderControls.useUpdateCurrentPageIndex() }), useNavBarContext],
|
||||
['readerNavBarWidth', 'updateCurrentPageIndex'],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user