Move reader "chapters state" to "reader store"
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ReaderStatePages, ReaderTransitionPageMode } from '@/features/reader/Reader.types.ts';
|
import { ReaderStateChapters, ReaderStatePages, ReaderTransitionPageMode } from '@/features/reader/Reader.types.ts';
|
||||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
|
|
||||||
export const READER_DEFAULT_PAGES_STATE: Omit<
|
export const READER_DEFAULT_PAGES_STATE: Omit<
|
||||||
@@ -39,3 +39,22 @@ export const READER_DEFAULT_PAGES_STATE: Omit<
|
|||||||
transitionPageMode: ReaderTransitionPageMode.NONE,
|
transitionPageMode: ReaderTransitionPageMode.NONE,
|
||||||
retryFailedPagesKeyPrefix: '',
|
retryFailedPagesKeyPrefix: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const READER_DEFAULT_CHAPTERS_STATE = {
|
||||||
|
chapters: {
|
||||||
|
chapters: [],
|
||||||
|
isCurrentChapterReady: false,
|
||||||
|
visibleChapters: {
|
||||||
|
leading: 0,
|
||||||
|
trailing: 0,
|
||||||
|
lastLeadingChapterSourceOrder: 99999,
|
||||||
|
lastTrailingChapterSourceOrder: -1,
|
||||||
|
isLeadingChapterPreloadMode: true,
|
||||||
|
isTrailingChapterPreloadMode: true,
|
||||||
|
scrollIntoView: false,
|
||||||
|
resumeMode: undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} satisfies {
|
||||||
|
chapters: Omit<ReaderStateChapters, 'setReaderStateChapters'>;
|
||||||
|
};
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ import {
|
|||||||
createReaderAutoScrollStoreSlice,
|
createReaderAutoScrollStoreSlice,
|
||||||
ReaderAutoScrollStoreSlice,
|
ReaderAutoScrollStoreSlice,
|
||||||
} from '@/features/reader/auto-scroll/ReaderAutoScrollStore.ts';
|
} from '@/features/reader/auto-scroll/ReaderAutoScrollStore.ts';
|
||||||
import { ReaderStatePages } from '@/features/reader/Reader.types.ts';
|
import { ReaderStateChapters, ReaderStatePages } from '@/features/reader/Reader.types.ts';
|
||||||
import { ImmerStateCreator } from '@/lib/zustand/Zustand.types.ts';
|
import { ImmerStateCreator } from '@/lib/zustand/Zustand.types.ts';
|
||||||
import { READER_DEFAULT_PAGES_STATE } from '@/features/reader/ReaderStore.constants.ts';
|
import { READER_DEFAULT_CHAPTERS_STATE, READER_DEFAULT_PAGES_STATE } from '@/features/reader/ReaderStore.constants.ts';
|
||||||
|
|
||||||
interface ReaderPagesStoreSlice {
|
interface ReaderPagesStoreSlice {
|
||||||
pages: ReaderStatePages & {
|
pages: ReaderStatePages & {
|
||||||
@@ -28,7 +28,17 @@ interface ReaderPagesStoreSlice {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ReaderStore extends ReaderOverlayStoreSlice, ReaderAutoScrollStoreSlice, ReaderPagesStoreSlice {
|
interface ReaderChaptersStoreSlice {
|
||||||
|
chapters: ReaderStateChapters & {
|
||||||
|
reset: () => void;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ReaderStore
|
||||||
|
extends ReaderOverlayStoreSlice,
|
||||||
|
ReaderAutoScrollStoreSlice,
|
||||||
|
ReaderPagesStoreSlice,
|
||||||
|
ReaderChaptersStoreSlice {
|
||||||
reset: () => void;
|
reset: () => void;
|
||||||
manga: TMangaReader | undefined;
|
manga: TMangaReader | undefined;
|
||||||
setManga: (manga: TMangaReader | undefined) => void;
|
setManga: (manga: TMangaReader | undefined) => void;
|
||||||
@@ -94,6 +104,30 @@ const createReaderPagesStoreSlice = <T extends ReaderPagesStoreSlice>(
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const createReaderChaptersStoreSlice = <T extends ReaderChaptersStoreSlice>(
|
||||||
|
...[set, get]: Parameters<ImmerStateCreator<T>>
|
||||||
|
): ReaderChaptersStoreSlice => ({
|
||||||
|
chapters: {
|
||||||
|
...READER_DEFAULT_CHAPTERS_STATE.chapters,
|
||||||
|
reset: () => set(() => ({ chapters: { ...get().chapters, ...READER_DEFAULT_CHAPTERS_STATE.chapters } })),
|
||||||
|
setReaderStateChapters: (state) =>
|
||||||
|
set((draft) => {
|
||||||
|
if (typeof state === 'function') {
|
||||||
|
draft.chapters = {
|
||||||
|
...get().chapters,
|
||||||
|
...state(get().chapters),
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
draft.chapters = {
|
||||||
|
...get().chapters,
|
||||||
|
...state,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const useReaderStore = create<ReaderStore>()(
|
export const useReaderStore = create<ReaderStore>()(
|
||||||
immer((set, get, store) => ({
|
immer((set, get, store) => ({
|
||||||
...DEFAULT_STATE,
|
...DEFAULT_STATE,
|
||||||
@@ -104,6 +138,7 @@ export const useReaderStore = create<ReaderStore>()(
|
|||||||
get().overlay.reset();
|
get().overlay.reset();
|
||||||
get().autoScroll.reset();
|
get().autoScroll.reset();
|
||||||
get().pages.reset();
|
get().pages.reset();
|
||||||
|
get().chapters.reset();
|
||||||
}),
|
}),
|
||||||
setManga: (manga) =>
|
setManga: (manga) =>
|
||||||
set((draft) => {
|
set((draft) => {
|
||||||
@@ -123,6 +158,7 @@ export const useReaderStore = create<ReaderStore>()(
|
|||||||
...createReaderOverlayStoreSlice(set, get, store),
|
...createReaderOverlayStoreSlice(set, get, store),
|
||||||
...createReaderAutoScrollStoreSlice(set, get, store),
|
...createReaderAutoScrollStoreSlice(set, get, store),
|
||||||
...createReaderPagesStoreSlice(set, get, store),
|
...createReaderPagesStoreSlice(set, get, store),
|
||||||
|
...createReaderChaptersStoreSlice(set, get, store),
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
export const useReaderStoreShallow = <T>(selector: (state: ReaderStore) => T): T =>
|
export const useReaderStoreShallow = <T>(selector: (state: ReaderStore) => T): T =>
|
||||||
|
|||||||
@@ -1,47 +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, ReactNode, useContext, useMemo, useState } from 'react';
|
|
||||||
import { ReaderStateChapters } from '@/features/reader/Reader.types.ts';
|
|
||||||
|
|
||||||
export const READER_STATE_CHAPTERS_DEFAULTS: Omit<ReaderStateChapters, 'setReaderStateChapters'> = {
|
|
||||||
chapters: [],
|
|
||||||
isCurrentChapterReady: false,
|
|
||||||
visibleChapters: {
|
|
||||||
leading: 0,
|
|
||||||
trailing: 0,
|
|
||||||
lastLeadingChapterSourceOrder: 99999,
|
|
||||||
lastTrailingChapterSourceOrder: -1,
|
|
||||||
isLeadingChapterPreloadMode: true,
|
|
||||||
isTrailingChapterPreloadMode: true,
|
|
||||||
scrollIntoView: false,
|
|
||||||
resumeMode: undefined,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ReaderStateChaptersContext = createContext<ReaderStateChapters>({
|
|
||||||
...READER_STATE_CHAPTERS_DEFAULTS,
|
|
||||||
setReaderStateChapters: () => {},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const useReaderStateChaptersContext = () => useContext(ReaderStateChaptersContext);
|
|
||||||
|
|
||||||
export const ReaderStateChaptersContextProvider = ({ children }: { children: ReactNode }) => {
|
|
||||||
const [state, setState] =
|
|
||||||
useState<Omit<ReaderStateChapters, 'setReaderStateChapters'>>(READER_STATE_CHAPTERS_DEFAULTS);
|
|
||||||
|
|
||||||
const value = useMemo(
|
|
||||||
() => ({
|
|
||||||
...state,
|
|
||||||
setReaderStateChapters: setState,
|
|
||||||
}),
|
|
||||||
[state],
|
|
||||||
);
|
|
||||||
|
|
||||||
return <ReaderStateChaptersContext.Provider value={value}>{children}</ReaderStateChaptersContext.Provider>;
|
|
||||||
};
|
|
||||||
@@ -7,11 +7,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { ReaderStateChaptersContextProvider } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { ReaderStateSettingsContextProvider } from '@/features/reader/contexts/state/ReaderStateSettingsContext.tsx';
|
import { ReaderStateSettingsContextProvider } from '@/features/reader/contexts/state/ReaderStateSettingsContext.tsx';
|
||||||
|
|
||||||
export const ReaderStateContextProvider = ({ children }: { children: ReactNode }) => (
|
export const ReaderStateContextProvider = ({ children }: { children: ReactNode }) => (
|
||||||
<ReaderStateChaptersContextProvider>
|
<ReaderStateSettingsContextProvider>{children}</ReaderStateSettingsContextProvider>
|
||||||
<ReaderStateSettingsContextProvider>{children}</ReaderStateSettingsContextProvider>
|
|
||||||
</ReaderStateChaptersContextProvider>
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,19 +7,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { ReaderStateChapters, TReaderStateSettingsContext } from '@/features/reader/Reader.types.ts';
|
import { TReaderStateSettingsContext } from '@/features/reader/Reader.types.ts';
|
||||||
import { DEFAULT_READER_SETTINGS_WITH_DEFAULT_FLAG } from '@/features/reader/settings/ReaderSettingsMetadata.ts';
|
import { DEFAULT_READER_SETTINGS_WITH_DEFAULT_FLAG } from '@/features/reader/settings/ReaderSettingsMetadata.ts';
|
||||||
import { READER_STATE_CHAPTERS_DEFAULTS } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { getReaderStore } from '@/features/reader/ReaderStore.ts';
|
import { getReaderStore } from '@/features/reader/ReaderStore.ts';
|
||||||
|
|
||||||
export const useReaderResetStates = (
|
export const useReaderResetStates = (setSettings: TReaderStateSettingsContext['setSettings']) => {
|
||||||
setReaderStateChapters: ReaderStateChapters['setReaderStateChapters'],
|
|
||||||
setSettings: TReaderStateSettingsContext['setSettings'],
|
|
||||||
) => {
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() => () => {
|
() => () => {
|
||||||
getReaderStore().reset();
|
getReaderStore().reset();
|
||||||
setReaderStateChapters(READER_STATE_CHAPTERS_DEFAULTS);
|
|
||||||
|
|
||||||
setSettings(DEFAULT_READER_SETTINGS_WITH_DEFAULT_FLAG);
|
setSettings(DEFAULT_READER_SETTINGS_WITH_DEFAULT_FLAG);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,11 +16,12 @@ import {
|
|||||||
ReaderOpenChapterLocationState,
|
ReaderOpenChapterLocationState,
|
||||||
ReaderStateChapters,
|
ReaderStateChapters,
|
||||||
} from '@/features/reader/Reader.types.ts';
|
} from '@/features/reader/Reader.types.ts';
|
||||||
import { READER_STATE_CHAPTERS_DEFAULTS } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { filterChapters } from '@/features/chapter/utils/ChapterList.util.tsx';
|
import { filterChapters } from '@/features/chapter/utils/ChapterList.util.tsx';
|
||||||
import { ChapterListOptions } from '@/features/chapter/Chapter.types.ts';
|
import { ChapterListOptions } from '@/features/chapter/Chapter.types.ts';
|
||||||
import { getReaderChapterFromCache } from '@/features/reader/Reader.utils.ts';
|
import { getReaderChapterFromCache } from '@/features/reader/Reader.utils.ts';
|
||||||
import { DirectionOffset } from '@/base/Base.types.ts';
|
import { DirectionOffset } from '@/base/Base.types.ts';
|
||||||
|
import { getReaderStore } from '@/features/reader/ReaderStore.ts';
|
||||||
|
import { READER_DEFAULT_CHAPTERS_STATE } from '@/features/reader/ReaderStore.constants.ts';
|
||||||
|
|
||||||
export const useReaderSetChaptersState = (
|
export const useReaderSetChaptersState = (
|
||||||
chaptersResponse: ReturnType<typeof requestManager.useGetMangaChapters<GetChaptersReaderQuery>>,
|
chaptersResponse: ReturnType<typeof requestManager.useGetMangaChapters<GetChaptersReaderQuery>>,
|
||||||
@@ -28,7 +29,6 @@ export const useReaderSetChaptersState = (
|
|||||||
mangaChapters: ReaderStateChapters['mangaChapters'],
|
mangaChapters: ReaderStateChapters['mangaChapters'],
|
||||||
initialChapter: ReaderStateChapters['initialChapter'],
|
initialChapter: ReaderStateChapters['initialChapter'],
|
||||||
chapterForDuplicatesHandling: ReaderStateChapters['chapterForDuplicatesHandling'],
|
chapterForDuplicatesHandling: ReaderStateChapters['chapterForDuplicatesHandling'],
|
||||||
setReaderStateChapters: ReaderStateChapters['setReaderStateChapters'],
|
|
||||||
shouldSkipDupChapters: IReaderSettings['shouldSkipDupChapters'],
|
shouldSkipDupChapters: IReaderSettings['shouldSkipDupChapters'],
|
||||||
shouldSkipFilteredChapters: IReaderSettings['shouldSkipFilteredChapters'],
|
shouldSkipFilteredChapters: IReaderSettings['shouldSkipFilteredChapters'],
|
||||||
chapterListOptions: ChapterListOptions,
|
chapterListOptions: ChapterListOptions,
|
||||||
@@ -78,7 +78,7 @@ export const useReaderSetChaptersState = (
|
|||||||
navigate('', { replace: true, state: { ...locationState, updateInitialChapter: undefined } });
|
navigate('', { replace: true, state: { ...locationState, updateInitialChapter: undefined } });
|
||||||
}
|
}
|
||||||
|
|
||||||
setReaderStateChapters((prevState) => {
|
getReaderStore().chapters.setReaderStateChapters((prevState) => {
|
||||||
const hasCurrentChapterChanged = newCurrentChapter?.id !== prevState.currentChapter?.id;
|
const hasCurrentChapterChanged = newCurrentChapter?.id !== prevState.currentChapter?.id;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -93,13 +93,13 @@ export const useReaderSetChaptersState = (
|
|||||||
isCurrentChapterReady: hasCurrentChapterChanged ? false : prevState.isCurrentChapterReady,
|
isCurrentChapterReady: hasCurrentChapterChanged ? false : prevState.isCurrentChapterReady,
|
||||||
visibleChapters: hasInitialChapterChanged
|
visibleChapters: hasInitialChapterChanged
|
||||||
? {
|
? {
|
||||||
...READER_STATE_CHAPTERS_DEFAULTS.visibleChapters,
|
...READER_DEFAULT_CHAPTERS_STATE.chapters.visibleChapters,
|
||||||
lastLeadingChapterSourceOrder:
|
lastLeadingChapterSourceOrder:
|
||||||
newInitialChapter?.sourceOrder ??
|
newInitialChapter?.sourceOrder ??
|
||||||
READER_STATE_CHAPTERS_DEFAULTS.visibleChapters.lastLeadingChapterSourceOrder,
|
READER_DEFAULT_CHAPTERS_STATE.chapters.visibleChapters.lastLeadingChapterSourceOrder,
|
||||||
lastTrailingChapterSourceOrder:
|
lastTrailingChapterSourceOrder:
|
||||||
newInitialChapter?.sourceOrder ??
|
newInitialChapter?.sourceOrder ??
|
||||||
READER_STATE_CHAPTERS_DEFAULTS.visibleChapters.lastTrailingChapterSourceOrder,
|
READER_DEFAULT_CHAPTERS_STATE.chapters.visibleChapters.lastTrailingChapterSourceOrder,
|
||||||
isLeadingChapterPreloadMode: false,
|
isLeadingChapterPreloadMode: false,
|
||||||
isTrailingChapterPreloadMode: false,
|
isTrailingChapterPreloadMode: false,
|
||||||
// do not set "scrollIntoView" to "true" for the initial render
|
// do not set "scrollIntoView" to "true" for the initial render
|
||||||
|
|||||||
@@ -24,9 +24,6 @@ import { makeToast } from '@/base/utils/Toast.ts';
|
|||||||
import { MobileHeaderProps } from '@/features/reader/overlay/ReaderOverlay.types.ts';
|
import { MobileHeaderProps } from '@/features/reader/overlay/ReaderOverlay.types.ts';
|
||||||
import { LoadingPlaceholder } from '@/base/components/feedback/LoadingPlaceholder.tsx';
|
import { LoadingPlaceholder } from '@/base/components/feedback/LoadingPlaceholder.tsx';
|
||||||
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
||||||
import { ReaderStateChapters } from '@/features/reader/Reader.types.ts';
|
|
||||||
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
|
||||||
import { useReaderStateChaptersContext } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { ReaderLibraryButton } from '@/features/reader/overlay/navigation/components/ReaderLibraryButton.tsx';
|
import { ReaderLibraryButton } from '@/features/reader/overlay/navigation/components/ReaderLibraryButton.tsx';
|
||||||
import { ReaderBookmarkButton } from '@/features/reader/overlay/navigation/components/ReaderBookmarkButton.tsx';
|
import { ReaderBookmarkButton } from '@/features/reader/overlay/navigation/components/ReaderBookmarkButton.tsx';
|
||||||
import { FALLBACK_CHAPTER } from '@/features/chapter/Chapter.constants.ts';
|
import { FALLBACK_CHAPTER } from '@/features/chapter/Chapter.constants.ts';
|
||||||
@@ -37,12 +34,10 @@ import { useReaderStoreShallow } from '@/features/reader/ReaderStore.ts';
|
|||||||
|
|
||||||
const DEFAULT_MANGA = { ...FALLBACK_MANGA, title: '' };
|
const DEFAULT_MANGA = { ...FALLBACK_MANGA, title: '' };
|
||||||
|
|
||||||
const BaseReaderOverlayHeaderMobile = forwardRef<
|
const BaseReaderOverlayHeaderMobile = forwardRef<HTMLDivElement, MobileHeaderProps>(({ isVisible }, ref) => {
|
||||||
HTMLDivElement,
|
|
||||||
MobileHeaderProps & Pick<ReaderStateChapters, 'currentChapter'>
|
|
||||||
>(({ isVisible, currentChapter }, ref) => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const popupState = usePopupState({ popupId: 'reader-overlay-more-menu', variant: 'popover' });
|
const popupState = usePopupState({ popupId: 'reader-overlay-more-menu', variant: 'popover' });
|
||||||
|
const currentChapter = useReaderStoreShallow((state) => state.chapters.currentChapter);
|
||||||
|
|
||||||
const manga = useReaderStoreShallow((state) => state.manga);
|
const manga = useReaderStoreShallow((state) => state.manga);
|
||||||
const scrollbar = useReaderStoreShallow((state) => state.scrollbar);
|
const scrollbar = useReaderStoreShallow((state) => state.scrollbar);
|
||||||
@@ -129,8 +124,4 @@ const BaseReaderOverlayHeaderMobile = forwardRef<
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ReaderOverlayHeaderMobile = withPropsFrom(
|
export const ReaderOverlayHeaderMobile = memo(BaseReaderOverlayHeaderMobile);
|
||||||
memo(BaseReaderOverlayHeaderMobile),
|
|
||||||
[useReaderStateChaptersContext],
|
|
||||||
['currentChapter'],
|
|
||||||
);
|
|
||||||
|
|||||||
@@ -24,11 +24,10 @@ import { ReaderNavBarDesktopQuickSettings } from '@/features/reader/overlay/navi
|
|||||||
import { ReaderNavBarDesktopActions } from '@/features/reader/overlay/navigation/desktop/components/ReaderNavBarDesktopActions.tsx';
|
import { ReaderNavBarDesktopActions } from '@/features/reader/overlay/navigation/desktop/components/ReaderNavBarDesktopActions.tsx';
|
||||||
import { useNavBarContext } from '@/features/navigation-bar/NavbarContext.tsx';
|
import { useNavBarContext } from '@/features/navigation-bar/NavbarContext.tsx';
|
||||||
import { useResizeObserver } from '@/base/hooks/useResizeObserver.tsx';
|
import { useResizeObserver } from '@/base/hooks/useResizeObserver.tsx';
|
||||||
import { useReaderStateChaptersContext } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { ReaderService } from '@/features/reader/services/ReaderService.ts';
|
import { ReaderService } from '@/features/reader/services/ReaderService.ts';
|
||||||
import { LoadingPlaceholder } from '@/base/components/feedback/LoadingPlaceholder.tsx';
|
import { LoadingPlaceholder } from '@/base/components/feedback/LoadingPlaceholder.tsx';
|
||||||
import { NavbarContextType } from '@/features/navigation-bar/NavigationBar.types.ts';
|
import { NavbarContextType } from '@/features/navigation-bar/NavigationBar.types.ts';
|
||||||
import { IReaderSettings, ReaderStateChapters } from '@/features/reader/Reader.types.ts';
|
import { IReaderSettings } from '@/features/reader/Reader.types.ts';
|
||||||
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
||||||
import { ReaderExitButton } from '@/features/reader/overlay/navigation/components/ReaderExitButton.tsx';
|
import { ReaderExitButton } from '@/features/reader/overlay/navigation/components/ReaderExitButton.tsx';
|
||||||
import { useReaderStoreShallow } from '@/features/reader/ReaderStore.ts';
|
import { useReaderStoreShallow } from '@/features/reader/ReaderStore.ts';
|
||||||
@@ -55,17 +54,18 @@ const BaseReaderNavBarDesktop = ({
|
|||||||
isVisible,
|
isVisible,
|
||||||
openSettings,
|
openSettings,
|
||||||
setReaderNavBarWidth,
|
setReaderNavBarWidth,
|
||||||
chapters,
|
|
||||||
currentChapter,
|
|
||||||
previousChapter,
|
|
||||||
nextChapter,
|
|
||||||
isStaticNav,
|
isStaticNav,
|
||||||
}: ReaderNavBarDesktopProps &
|
}: ReaderNavBarDesktopProps &
|
||||||
Pick<NavbarContextType, 'setReaderNavBarWidth'> &
|
Pick<NavbarContextType, 'setReaderNavBarWidth'> &
|
||||||
Pick<ReaderStateChapters, 'currentChapter' | 'previousChapter' | 'nextChapter' | 'chapters'> &
|
|
||||||
Pick<IReaderSettings, 'isStaticNav'>) => {
|
Pick<IReaderSettings, 'isStaticNav'>) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const manga = useReaderStoreShallow((state) => state.manga);
|
const manga = useReaderStoreShallow((state) => state.manga);
|
||||||
|
const { chapters, currentChapter, previousChapter, nextChapter } = useReaderStoreShallow((state) => ({
|
||||||
|
chapters: state.chapters.chapters,
|
||||||
|
currentChapter: state.chapters.currentChapter,
|
||||||
|
previousChapter: state.chapters.previousChapter,
|
||||||
|
nextChapter: state.chapters.nextChapter,
|
||||||
|
}));
|
||||||
|
|
||||||
const [navBarElement, setNavBarElement] = useState<HTMLDivElement | null>();
|
const [navBarElement, setNavBarElement] = useState<HTMLDivElement | null>();
|
||||||
useResizeObserver(
|
useResizeObserver(
|
||||||
@@ -146,6 +146,6 @@ const BaseReaderNavBarDesktop = ({
|
|||||||
|
|
||||||
export const ReaderNavBarDesktop = withPropsFrom(
|
export const ReaderNavBarDesktop = withPropsFrom(
|
||||||
memo(BaseReaderNavBarDesktop),
|
memo(BaseReaderNavBarDesktop),
|
||||||
[useNavBarContext, useReaderStateChaptersContext, ReaderService.useSettingsWithoutDefaultFlag],
|
[useNavBarContext, ReaderService.useSettingsWithoutDefaultFlag],
|
||||||
['setReaderNavBarWidth', 'chapters', 'currentChapter', 'previousChapter', 'nextChapter', 'isStaticNav'],
|
['setReaderNavBarWidth', 'isStaticNav'],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -15,10 +15,7 @@ import { memo, useMemo, useRef } from 'react';
|
|||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
|
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
|
||||||
import { Chapters } from '@/features/chapter/services/Chapters.ts';
|
import { Chapters } from '@/features/chapter/services/Chapters.ts';
|
||||||
import { ReaderStateChapters } from '@/features/reader/Reader.types.ts';
|
|
||||||
import { DownloadStateIndicator } from '@/base/components/downloads/DownloadStateIndicator.tsx';
|
import { DownloadStateIndicator } from '@/base/components/downloads/DownloadStateIndicator.tsx';
|
||||||
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
|
||||||
import { useReaderStateChaptersContext } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { ReaderLibraryButton } from '@/features/reader/overlay/navigation/components/ReaderLibraryButton.tsx';
|
import { ReaderLibraryButton } from '@/features/reader/overlay/navigation/components/ReaderLibraryButton.tsx';
|
||||||
import { ReaderBookmarkButton } from '@/features/reader/overlay/navigation/components/ReaderBookmarkButton.tsx';
|
import { ReaderBookmarkButton } from '@/features/reader/overlay/navigation/components/ReaderBookmarkButton.tsx';
|
||||||
import { CHAPTER_ACTION_TO_TRANSLATION, FALLBACK_CHAPTER } from '@/features/chapter/Chapter.constants.ts';
|
import { CHAPTER_ACTION_TO_TRANSLATION, FALLBACK_CHAPTER } from '@/features/chapter/Chapter.constants.ts';
|
||||||
@@ -26,8 +23,13 @@ import { IconBrowser } from '@/assets/icons/IconBrowser.tsx';
|
|||||||
import { IconWebView } from '@/assets/icons/IconWebView.tsx';
|
import { IconWebView } from '@/assets/icons/IconWebView.tsx';
|
||||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
import { useReaderStoreShallow } from '@/features/reader/ReaderStore.ts';
|
import { useReaderStoreShallow } from '@/features/reader/ReaderStore.ts';
|
||||||
|
import { ChapterDownloadInfo, ChapterIdInfo } from '@/features/chapter/Chapter.types.ts';
|
||||||
|
|
||||||
const DownloadButton = ({ currentChapter }: Required<Pick<ReaderStateChapters, 'currentChapter'>>) => {
|
const DownloadButton = ({
|
||||||
|
currentChapter,
|
||||||
|
}: {
|
||||||
|
currentChapter: NullAndUndefined<ChapterIdInfo & ChapterDownloadInfo>;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const downloadStatus = Chapters.useDownloadStatusFromCache(currentChapter?.id ?? -1);
|
const downloadStatus = Chapters.useDownloadStatusFromCache(currentChapter?.id ?? -1);
|
||||||
@@ -59,76 +61,64 @@ const DownloadButton = ({ currentChapter }: Required<Pick<ReaderStateChapters, '
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const BaseReaderNavBarDesktopActions = memo(
|
export const ReaderNavBarDesktopActions = memo(() => {
|
||||||
({ currentChapter }: Required<Pick<ReaderStateChapters, 'currentChapter'>>) => {
|
const currentChapter = useReaderStoreShallow((state) => state.chapters.currentChapter);
|
||||||
const { id, isBookmarked, realUrl } = currentChapter ?? FALLBACK_CHAPTER;
|
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { id, isBookmarked, realUrl } = currentChapter ?? FALLBACK_CHAPTER;
|
||||||
const { pageLoadStates, setPageLoadStates, setRetryFailedPagesKeyPrefix } = useReaderStoreShallow((state) => ({
|
|
||||||
pageLoadStates: state.pages.pageLoadStates,
|
|
||||||
setPageLoadStates: state.pages.setPageLoadStates,
|
|
||||||
setRetryFailedPagesKeyPrefix: state.pages.setRetryFailedPagesKeyPrefix,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const pageRetryKeyPrefix = useRef<number>(0);
|
const { t } = useTranslation();
|
||||||
|
const { pageLoadStates, setPageLoadStates, setRetryFailedPagesKeyPrefix } = useReaderStoreShallow((state) => ({
|
||||||
|
pageLoadStates: state.pages.pageLoadStates,
|
||||||
|
setPageLoadStates: state.pages.setPageLoadStates,
|
||||||
|
setRetryFailedPagesKeyPrefix: state.pages.setRetryFailedPagesKeyPrefix,
|
||||||
|
}));
|
||||||
|
|
||||||
const haveSomePagesFailedToLoad = useMemo(
|
const pageRetryKeyPrefix = useRef<number>(0);
|
||||||
() => pageLoadStates.some((pageLoadState) => pageLoadState.error),
|
|
||||||
[pageLoadStates],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
const haveSomePagesFailedToLoad = useMemo(
|
||||||
<Stack sx={{ flexDirection: 'row', justifyContent: 'center', gap: 1 }}>
|
() => pageLoadStates.some((pageLoadState) => pageLoadState.error),
|
||||||
<ReaderLibraryButton />
|
[pageLoadStates],
|
||||||
<ReaderBookmarkButton id={id} isBookmarked={isBookmarked} />
|
);
|
||||||
<CustomTooltip title={t('reader.button.retry_load_pages')} disabled={!haveSomePagesFailedToLoad}>
|
|
||||||
<IconButton
|
|
||||||
onClick={() => {
|
|
||||||
setPageLoadStates((statePageLoadStates) =>
|
|
||||||
statePageLoadStates.map((pageLoadState) => ({
|
|
||||||
url: pageLoadState.url,
|
|
||||||
loaded: pageLoadState.loaded,
|
|
||||||
})),
|
|
||||||
);
|
|
||||||
setRetryFailedPagesKeyPrefix(`${pageRetryKeyPrefix.current}`);
|
|
||||||
pageRetryKeyPrefix.current = (pageRetryKeyPrefix.current + 1) % 1000;
|
|
||||||
}}
|
|
||||||
disabled={!haveSomePagesFailedToLoad}
|
|
||||||
color="inherit"
|
|
||||||
>
|
|
||||||
<ReplayIcon />
|
|
||||||
</IconButton>
|
|
||||||
</CustomTooltip>
|
|
||||||
<DownloadButton currentChapter={currentChapter} />
|
|
||||||
<CustomTooltip title={t('global.button.open_browser')} disabled={!realUrl}>
|
|
||||||
<IconButton
|
|
||||||
disabled={!realUrl}
|
|
||||||
href={realUrl ?? ''}
|
|
||||||
rel="noreferrer"
|
|
||||||
target="_blank"
|
|
||||||
color="inherit"
|
|
||||||
>
|
|
||||||
<IconBrowser />
|
|
||||||
</IconButton>
|
|
||||||
</CustomTooltip>
|
|
||||||
<CustomTooltip title={t('global.button.open_webview')} disabled={!realUrl}>
|
|
||||||
<IconButton
|
|
||||||
disabled={!realUrl}
|
|
||||||
href={realUrl ? requestManager.getWebviewUrl(realUrl) : ''}
|
|
||||||
rel="noreferrer"
|
|
||||||
target="_blank"
|
|
||||||
color="inherit"
|
|
||||||
>
|
|
||||||
<IconWebView />
|
|
||||||
</IconButton>
|
|
||||||
</CustomTooltip>
|
|
||||||
</Stack>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
export const ReaderNavBarDesktopActions = withPropsFrom(
|
return (
|
||||||
BaseReaderNavBarDesktopActions,
|
<Stack sx={{ flexDirection: 'row', justifyContent: 'center', gap: 1 }}>
|
||||||
[useReaderStateChaptersContext],
|
<ReaderLibraryButton />
|
||||||
['currentChapter'],
|
<ReaderBookmarkButton id={id} isBookmarked={isBookmarked} />
|
||||||
);
|
<CustomTooltip title={t('reader.button.retry_load_pages')} disabled={!haveSomePagesFailedToLoad}>
|
||||||
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
setPageLoadStates((statePageLoadStates) =>
|
||||||
|
statePageLoadStates.map((pageLoadState) => ({
|
||||||
|
url: pageLoadState.url,
|
||||||
|
loaded: pageLoadState.loaded,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
setRetryFailedPagesKeyPrefix(`${pageRetryKeyPrefix.current}`);
|
||||||
|
pageRetryKeyPrefix.current = (pageRetryKeyPrefix.current + 1) % 1000;
|
||||||
|
}}
|
||||||
|
disabled={!haveSomePagesFailedToLoad}
|
||||||
|
color="inherit"
|
||||||
|
>
|
||||||
|
<ReplayIcon />
|
||||||
|
</IconButton>
|
||||||
|
</CustomTooltip>
|
||||||
|
<DownloadButton currentChapter={currentChapter} />
|
||||||
|
<CustomTooltip title={t('global.button.open_browser')} disabled={!realUrl}>
|
||||||
|
<IconButton disabled={!realUrl} href={realUrl ?? ''} rel="noreferrer" target="_blank" color="inherit">
|
||||||
|
<IconBrowser />
|
||||||
|
</IconButton>
|
||||||
|
</CustomTooltip>
|
||||||
|
<CustomTooltip title={t('global.button.open_webview')} disabled={!realUrl}>
|
||||||
|
<IconButton
|
||||||
|
disabled={!realUrl}
|
||||||
|
href={realUrl ? requestManager.getWebviewUrl(realUrl) : ''}
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
color="inherit"
|
||||||
|
>
|
||||||
|
<IconWebView />
|
||||||
|
</IconButton>
|
||||||
|
</CustomTooltip>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|||||||
@@ -23,20 +23,19 @@ import { ReaderBottomBarMobileProps } from '@/features/reader/overlay/ReaderOver
|
|||||||
import { MobileReaderProgressBar } from '@/features/reader/overlay/progress-bar/mobile/MobileReaderProgressBar.tsx';
|
import { MobileReaderProgressBar } from '@/features/reader/overlay/progress-bar/mobile/MobileReaderProgressBar.tsx';
|
||||||
import { ReaderChapterList } from '@/features/reader/overlay/navigation/components/ReaderChapterList.tsx';
|
import { ReaderChapterList } from '@/features/reader/overlay/navigation/components/ReaderChapterList.tsx';
|
||||||
import { ReaderBottomBarMobileQuickSettings } from '@/features/reader/overlay/navigation/mobile/quick-settings/ReaderBottomBarMobileQuickSettings.tsx';
|
import { ReaderBottomBarMobileQuickSettings } from '@/features/reader/overlay/navigation/mobile/quick-settings/ReaderBottomBarMobileQuickSettings.tsx';
|
||||||
import { useReaderStateChaptersContext } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { ReaderStateChapters } from '@/features/reader/Reader.types.ts';
|
|
||||||
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
|
||||||
import { useResizeObserver } from '@/base/hooks/useResizeObserver.tsx';
|
import { useResizeObserver } from '@/base/hooks/useResizeObserver.tsx';
|
||||||
import { useReaderStoreShallow } from '@/features/reader/ReaderStore.ts';
|
import { useReaderStoreShallow } from '@/features/reader/ReaderStore.ts';
|
||||||
|
|
||||||
const BaseReaderBottomBarMobile = ({
|
const BaseReaderBottomBarMobile = ({
|
||||||
openSettings,
|
openSettings,
|
||||||
isVisible,
|
isVisible,
|
||||||
currentChapter,
|
|
||||||
chapters,
|
|
||||||
topOffset = 0,
|
topOffset = 0,
|
||||||
}: ReaderBottomBarMobileProps & Pick<ReaderStateChapters, 'currentChapter' | 'chapters'> & { topOffset?: number }) => {
|
}: ReaderBottomBarMobileProps & { topOffset?: number }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { currentChapter, chapters } = useReaderStoreShallow((state) => ({
|
||||||
|
currentChapter: state.chapters.currentChapter,
|
||||||
|
chapters: state.chapters.chapters,
|
||||||
|
}));
|
||||||
|
|
||||||
const chapterListPopupState = usePopupState({ variant: 'dialog', popupId: 'reader-chapter-list-dialog' });
|
const chapterListPopupState = usePopupState({ variant: 'dialog', popupId: 'reader-chapter-list-dialog' });
|
||||||
const quickSettingsPopupState = usePopupState({ variant: 'dialog', popupId: 'reader-quick-settings-dialog' });
|
const quickSettingsPopupState = usePopupState({ variant: 'dialog', popupId: 'reader-quick-settings-dialog' });
|
||||||
@@ -130,8 +129,4 @@ const BaseReaderBottomBarMobile = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ReaderBottomBarMobile = withPropsFrom(
|
export const ReaderBottomBarMobile = memo(BaseReaderBottomBarMobile);
|
||||||
memo(BaseReaderBottomBarMobile),
|
|
||||||
[useReaderStateChaptersContext],
|
|
||||||
['currentChapter', 'chapters'],
|
|
||||||
);
|
|
||||||
|
|||||||
@@ -15,14 +15,13 @@ import Box from '@mui/material/Box';
|
|||||||
import { ComponentProps, memo, useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
import { ComponentProps, memo, useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
||||||
import Slide, { SlideProps } from '@mui/material/Slide';
|
import Slide, { SlideProps } from '@mui/material/Slide';
|
||||||
import { ReaderProgressBar } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.tsx';
|
import { ReaderProgressBar } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.tsx';
|
||||||
import { useReaderStateChaptersContext } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { ReaderService } from '@/features/reader/services/ReaderService.ts';
|
import { ReaderService } from '@/features/reader/services/ReaderService.ts';
|
||||||
import {
|
import {
|
||||||
getPage,
|
getPage,
|
||||||
getProgressBarPositionInfo,
|
getProgressBarPositionInfo,
|
||||||
} from '@/features/reader/overlay/progress-bar/ReaderProgressBar.utils.tsx';
|
} from '@/features/reader/overlay/progress-bar/ReaderProgressBar.utils.tsx';
|
||||||
import { getOptionForDirection } from '@/features/theme/services/ThemeCreator.ts';
|
import { getOptionForDirection } from '@/features/theme/services/ThemeCreator.ts';
|
||||||
import { IReaderSettings, ProgressBarPosition, ReaderStateChapters } from '@/features/reader/Reader.types.ts';
|
import { IReaderSettings, ProgressBarPosition } from '@/features/reader/Reader.types.ts';
|
||||||
import { ReaderProgressBarDirectionWrapper } from '@/features/reader/overlay/progress-bar/components/ReaderProgressBarDirectionWrapper.tsx';
|
import { ReaderProgressBarDirectionWrapper } from '@/features/reader/overlay/progress-bar/components/ReaderProgressBarDirectionWrapper.tsx';
|
||||||
import { useReaderProgressBarContext } from '@/features/reader/overlay/progress-bar/ReaderProgressBarContext.tsx';
|
import { useReaderProgressBarContext } from '@/features/reader/overlay/progress-bar/ReaderProgressBarContext.tsx';
|
||||||
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
||||||
@@ -43,8 +42,6 @@ const PROGRESS_BAR_POSITION_TO_SLIDE_DIRECTION: Record<ProgressBarPosition, Slid
|
|||||||
};
|
};
|
||||||
|
|
||||||
const BaseMobileReaderProgressBar = ({
|
const BaseMobileReaderProgressBar = ({
|
||||||
previousChapter,
|
|
||||||
nextChapter,
|
|
||||||
setIsMaximized,
|
setIsMaximized,
|
||||||
isDragging,
|
isDragging,
|
||||||
direction: readerDirection,
|
direction: readerDirection,
|
||||||
@@ -52,8 +49,7 @@ const BaseMobileReaderProgressBar = ({
|
|||||||
progressBarPositionAutoVertical,
|
progressBarPositionAutoVertical,
|
||||||
topOffset = 0,
|
topOffset = 0,
|
||||||
bottomOffset = 0,
|
bottomOffset = 0,
|
||||||
}: Pick<ReaderStateChapters, 'previousChapter' | 'nextChapter'> &
|
}: Pick<TReaderProgressBarContext, 'setIsMaximized' | 'isDragging'> &
|
||||||
Pick<TReaderProgressBarContext, 'setIsMaximized' | 'isDragging'> &
|
|
||||||
Pick<IReaderSettings, 'progressBarPosition' | 'progressBarPositionAutoVertical'> & {
|
Pick<IReaderSettings, 'progressBarPosition' | 'progressBarPositionAutoVertical'> & {
|
||||||
direction: ReturnType<typeof ReaderService.useGetThemeDirection>;
|
direction: ReturnType<typeof ReaderService.useGetThemeDirection>;
|
||||||
topOffset?: number;
|
topOffset?: number;
|
||||||
@@ -66,6 +62,10 @@ const BaseMobileReaderProgressBar = ({
|
|||||||
currentPageIndex: state.pages.currentPageIndex,
|
currentPageIndex: state.pages.currentPageIndex,
|
||||||
pages: state.pages.pages,
|
pages: state.pages.pages,
|
||||||
}));
|
}));
|
||||||
|
const { previousChapter, nextChapter } = useReaderStore((state) => ({
|
||||||
|
previousChapter: state.chapters.previousChapter,
|
||||||
|
nextChapter: state.chapters.nextChapter,
|
||||||
|
}));
|
||||||
|
|
||||||
const [, setRefreshProgressBarPosition] = useState({});
|
const [, setRefreshProgressBarPosition] = useState({});
|
||||||
useResizeObserver(
|
useResizeObserver(
|
||||||
@@ -354,18 +354,9 @@ const BaseMobileReaderProgressBar = ({
|
|||||||
export const MobileReaderProgressBar = withPropsFrom(
|
export const MobileReaderProgressBar = withPropsFrom(
|
||||||
memo(BaseMobileReaderProgressBar),
|
memo(BaseMobileReaderProgressBar),
|
||||||
[
|
[
|
||||||
useReaderStateChaptersContext,
|
|
||||||
useReaderProgressBarContext,
|
useReaderProgressBarContext,
|
||||||
() => ({ direction: ReaderService.useGetThemeDirection() }),
|
() => ({ direction: ReaderService.useGetThemeDirection() }),
|
||||||
ReaderService.useSettingsWithoutDefaultFlag,
|
ReaderService.useSettingsWithoutDefaultFlag,
|
||||||
],
|
],
|
||||||
[
|
['setIsMaximized', 'isDragging', 'direction', 'progressBarPosition', 'progressBarPositionAutoVertical'],
|
||||||
'previousChapter',
|
|
||||||
'nextChapter',
|
|
||||||
'setIsMaximized',
|
|
||||||
'isDragging',
|
|
||||||
'direction',
|
|
||||||
'progressBarPosition',
|
|
||||||
'progressBarPositionAutoVertical',
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -30,13 +30,11 @@ import { ReaderHotkeys } from '@/features/reader/hotkeys/ReaderHotkeys.tsx';
|
|||||||
import {
|
import {
|
||||||
IReaderSettings,
|
IReaderSettings,
|
||||||
IReaderSettingsWithDefaultFlag,
|
IReaderSettingsWithDefaultFlag,
|
||||||
ReaderStateChapters,
|
|
||||||
TReaderStateSettingsContext,
|
TReaderStateSettingsContext,
|
||||||
} from '@/features/reader/Reader.types.ts';
|
} from '@/features/reader/Reader.types.ts';
|
||||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||||
import { NavbarContextType } from '@/features/navigation-bar/NavigationBar.types.ts';
|
import { NavbarContextType } from '@/features/navigation-bar/NavigationBar.types.ts';
|
||||||
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
||||||
import { useReaderStateChaptersContext } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { TReaderTapZoneContext } from '@/features/reader/tap-zones/TapZoneLayout.types.ts';
|
import { TReaderTapZoneContext } from '@/features/reader/tap-zones/TapZoneLayout.types.ts';
|
||||||
import { useReaderTapZoneContext } from '@/features/reader/tap-zones/ReaderTapZoneContext.tsx';
|
import { useReaderTapZoneContext } from '@/features/reader/tap-zones/ReaderTapZoneContext.tsx';
|
||||||
import { useReaderResetStates } from '@/features/reader/hooks/useReaderResetStates.ts';
|
import { useReaderResetStates } from '@/features/reader/hooks/useReaderResetStates.ts';
|
||||||
@@ -61,11 +59,6 @@ const BaseReader = ({
|
|||||||
shouldShowReadingModePreview,
|
shouldShowReadingModePreview,
|
||||||
shouldShowTapZoneLayoutPreview,
|
shouldShowTapZoneLayoutPreview,
|
||||||
setSettings,
|
setSettings,
|
||||||
mangaChapters,
|
|
||||||
initialChapter,
|
|
||||||
chapterForDuplicatesHandling,
|
|
||||||
currentChapter,
|
|
||||||
setReaderStateChapters,
|
|
||||||
setShowPreview,
|
setShowPreview,
|
||||||
}: Pick<NavbarContextType, 'setOverride' | 'readerNavBarWidth'> &
|
}: Pick<NavbarContextType, 'setOverride' | 'readerNavBarWidth'> &
|
||||||
Pick<TReaderStateSettingsContext, 'setSettings'> &
|
Pick<TReaderStateSettingsContext, 'setSettings'> &
|
||||||
@@ -78,18 +71,18 @@ const BaseReader = ({
|
|||||||
| 'shouldShowTapZoneLayoutPreview'
|
| 'shouldShowTapZoneLayoutPreview'
|
||||||
> &
|
> &
|
||||||
Pick<IReaderSettingsWithDefaultFlag, 'readingMode' | 'tapZoneLayout' | 'tapZoneInvertMode'> &
|
Pick<IReaderSettingsWithDefaultFlag, 'readingMode' | 'tapZoneLayout' | 'tapZoneInvertMode'> &
|
||||||
Pick<
|
|
||||||
ReaderStateChapters,
|
|
||||||
| 'mangaChapters'
|
|
||||||
| 'initialChapter'
|
|
||||||
| 'chapterForDuplicatesHandling'
|
|
||||||
| 'currentChapter'
|
|
||||||
| 'setReaderStateChapters'
|
|
||||||
> &
|
|
||||||
Pick<TReaderTapZoneContext, 'setShowPreview'>) => {
|
Pick<TReaderTapZoneContext, 'setShowPreview'>) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const manga = useReaderStoreShallow((state) => state.manga);
|
const manga = useReaderStoreShallow((state) => state.manga);
|
||||||
const overlay = useReaderStoreShallow((state) => state.overlay);
|
const overlay = useReaderStoreShallow((state) => state.overlay);
|
||||||
|
const { mangaChapters, initialChapter, chapterForDuplicatesHandling, currentChapter } = useReaderStoreShallow(
|
||||||
|
(state) => ({
|
||||||
|
mangaChapters: state.chapters.mangaChapters,
|
||||||
|
initialChapter: state.chapters.initialChapter,
|
||||||
|
chapterForDuplicatesHandling: state.chapters.chapterForDuplicatesHandling,
|
||||||
|
currentChapter: state.chapters.currentChapter,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
const scrollElementRef = useRef<HTMLDivElement | null>(null);
|
const scrollElementRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
@@ -130,7 +123,7 @@ const BaseReader = ({
|
|||||||
useReaderStore.getState().setManga(mangaResponse.data?.manga);
|
useReaderStore.getState().setManga(mangaResponse.data?.manga);
|
||||||
}, [mangaResponse.data?.manga]);
|
}, [mangaResponse.data?.manga]);
|
||||||
|
|
||||||
useReaderResetStates(setReaderStateChapters, setSettings);
|
useReaderResetStates(setSettings);
|
||||||
useReaderSetSettingsState(
|
useReaderSetSettingsState(
|
||||||
mangaResponse,
|
mangaResponse,
|
||||||
defaultSettingsResponse,
|
defaultSettingsResponse,
|
||||||
@@ -156,7 +149,6 @@ const BaseReader = ({
|
|||||||
mangaChapters,
|
mangaChapters,
|
||||||
initialChapter,
|
initialChapter,
|
||||||
chapterForDuplicatesHandling,
|
chapterForDuplicatesHandling,
|
||||||
setReaderStateChapters,
|
|
||||||
shouldSkipDupChapters,
|
shouldSkipDupChapters,
|
||||||
shouldSkipFilteredChapters,
|
shouldSkipFilteredChapters,
|
||||||
chapterListOptions,
|
chapterListOptions,
|
||||||
@@ -263,7 +255,6 @@ export const Reader = withPropsFrom(
|
|||||||
memo(BaseReader),
|
memo(BaseReader),
|
||||||
[
|
[
|
||||||
useNavBarContext,
|
useNavBarContext,
|
||||||
useReaderStateChaptersContext,
|
|
||||||
useReaderStateSettingsContext,
|
useReaderStateSettingsContext,
|
||||||
() => {
|
() => {
|
||||||
const {
|
const {
|
||||||
@@ -299,11 +290,6 @@ export const Reader = withPropsFrom(
|
|||||||
'shouldShowReadingModePreview',
|
'shouldShowReadingModePreview',
|
||||||
'shouldShowTapZoneLayoutPreview',
|
'shouldShowTapZoneLayoutPreview',
|
||||||
'setSettings',
|
'setSettings',
|
||||||
'mangaChapters',
|
|
||||||
'initialChapter',
|
|
||||||
'chapterForDuplicatesHandling',
|
|
||||||
'currentChapter',
|
|
||||||
'setReaderStateChapters',
|
|
||||||
'setShowPreview',
|
'setShowPreview',
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { MutableRefObject, RefObject, useCallback, useEffect, useMemo } from 'react';
|
import { MutableRefObject, RefObject, useCallback, useEffect } from 'react';
|
||||||
import { Direction, useTheme } from '@mui/material/styles';
|
import { Direction, useTheme } from '@mui/material/styles';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { TFunction } from 'i18next';
|
import { TFunction } from 'i18next';
|
||||||
@@ -19,7 +19,6 @@ import {
|
|||||||
} from '@/features/reader/overlay/progress-bar/ReaderProgressBar.utils.tsx';
|
} from '@/features/reader/overlay/progress-bar/ReaderProgressBar.utils.tsx';
|
||||||
import { getOptionForDirection } from '@/features/theme/services/ThemeCreator.ts';
|
import { getOptionForDirection } from '@/features/theme/services/ThemeCreator.ts';
|
||||||
import { ReaderService } from '@/features/reader/services/ReaderService.ts';
|
import { ReaderService } from '@/features/reader/services/ReaderService.ts';
|
||||||
import { useReaderStateChaptersContext } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import {
|
import {
|
||||||
PageInViewportType,
|
PageInViewportType,
|
||||||
ProgressBarPosition,
|
ProgressBarPosition,
|
||||||
@@ -173,19 +172,20 @@ export class ReaderControls {
|
|||||||
shouldInformAboutScanlatorChange,
|
shouldInformAboutScanlatorChange,
|
||||||
shouldUseInfiniteScroll,
|
shouldUseInfiniteScroll,
|
||||||
} = ReaderService.useSettings();
|
} = ReaderService.useSettings();
|
||||||
const {
|
|
||||||
currentChapter,
|
|
||||||
previousChapter,
|
|
||||||
nextChapter,
|
|
||||||
chapters,
|
|
||||||
visibleChapters: { lastLeadingChapterSourceOrder, lastTrailingChapterSourceOrder },
|
|
||||||
setReaderStateChapters,
|
|
||||||
} = useReaderStateChaptersContext();
|
|
||||||
|
|
||||||
const openChapter = ReaderService.useNavigateToChapter();
|
const openChapter = ReaderService.useNavigateToChapter();
|
||||||
|
|
||||||
return useCallback(
|
return useCallback(
|
||||||
(offset, doTransitionCheck = true, scrollIntoView = true) => {
|
(offset, doTransitionCheck = true, scrollIntoView = true) => {
|
||||||
|
const {
|
||||||
|
currentChapter,
|
||||||
|
previousChapter,
|
||||||
|
nextChapter,
|
||||||
|
chapters,
|
||||||
|
visibleChapters: { lastLeadingChapterSourceOrder, lastTrailingChapterSourceOrder },
|
||||||
|
setReaderStateChapters,
|
||||||
|
} = getReaderStore().chapters;
|
||||||
|
|
||||||
if (!currentChapter) {
|
if (!currentChapter) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -266,13 +266,10 @@ export class ReaderControls {
|
|||||||
},
|
},
|
||||||
[
|
[
|
||||||
t,
|
t,
|
||||||
currentChapter?.id,
|
|
||||||
openChapter,
|
openChapter,
|
||||||
readingMode.value,
|
readingMode.value,
|
||||||
shouldInformAboutMissingChapter,
|
shouldInformAboutMissingChapter,
|
||||||
shouldInformAboutScanlatorChange,
|
shouldInformAboutScanlatorChange,
|
||||||
lastLeadingChapterSourceOrder,
|
|
||||||
lastTrailingChapterSourceOrder,
|
|
||||||
shouldUseInfiniteScroll,
|
shouldUseInfiniteScroll,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -343,7 +340,6 @@ export class ReaderControls {
|
|||||||
forceDirection?: Direction,
|
forceDirection?: Direction,
|
||||||
hideOverlay?: boolean,
|
hideOverlay?: boolean,
|
||||||
) => void {
|
) => void {
|
||||||
const { previousChapter, nextChapter } = useReaderStateChaptersContext();
|
|
||||||
const { setShowPreview } = useReaderTapZoneContext();
|
const { setShowPreview } = useReaderTapZoneContext();
|
||||||
const { readingDirection, readingMode, shouldShowTransitionPage } = ReaderService.useSettings();
|
const { readingDirection, readingMode, shouldShowTransitionPage } = ReaderService.useSettings();
|
||||||
const openChapter = ReaderControls.useOpenChapter();
|
const openChapter = ReaderControls.useOpenChapter();
|
||||||
@@ -398,7 +394,7 @@ export class ReaderControls {
|
|||||||
isFirstPage &&
|
isFirstPage &&
|
||||||
(!shouldShowTransitionPage || isPreviousTransitionPageVisible) &&
|
(!shouldShowTransitionPage || isPreviousTransitionPageVisible) &&
|
||||||
convertedPage === 'previous' &&
|
convertedPage === 'previous' &&
|
||||||
!!previousChapter;
|
!!getReaderStore().chapters.previousChapter;
|
||||||
if (shouldOpenPreviousChapter) {
|
if (shouldOpenPreviousChapter) {
|
||||||
openChapter('previous');
|
openChapter('previous');
|
||||||
return;
|
return;
|
||||||
@@ -408,7 +404,7 @@ export class ReaderControls {
|
|||||||
isLastPage &&
|
isLastPage &&
|
||||||
(!shouldShowTransitionPage || isNextTransitionPageVisible) &&
|
(!shouldShowTransitionPage || isNextTransitionPageVisible) &&
|
||||||
convertedPage === 'next' &&
|
convertedPage === 'next' &&
|
||||||
!!nextChapter;
|
!!getReaderStore().chapters.nextChapter;
|
||||||
if (shouldOpenNextChapter) {
|
if (shouldOpenNextChapter) {
|
||||||
openChapter('next');
|
openChapter('next');
|
||||||
return;
|
return;
|
||||||
@@ -442,7 +438,7 @@ export class ReaderControls {
|
|||||||
|
|
||||||
setPageToScrollToIndex(isPreviousMode ? previousPageIndex : nextPageIndex);
|
setPageToScrollToIndex(isPreviousMode ? previousPageIndex : nextPageIndex);
|
||||||
},
|
},
|
||||||
[direction, openChapter, !!previousChapter, !!nextChapter, shouldShowTransitionPage, readingMode.value],
|
[direction, openChapter, shouldShowTransitionPage, readingMode.value],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,26 +447,24 @@ export class ReaderControls {
|
|||||||
debounceChapterUpdate?: boolean,
|
debounceChapterUpdate?: boolean,
|
||||||
endReached?: boolean,
|
endReached?: boolean,
|
||||||
) => void {
|
) => void {
|
||||||
const { currentChapter, chapters, previousChapter, nextChapter, visibleChapters, setReaderStateChapters } =
|
|
||||||
useReaderStateChaptersContext();
|
|
||||||
const updateChapter = ReaderService.useUpdateChapter();
|
const updateChapter = ReaderService.useUpdateChapter();
|
||||||
const {
|
const {
|
||||||
settings: { downloadAheadLimit },
|
settings: { downloadAheadLimit },
|
||||||
} = useMetadataServerSettings();
|
} = useMetadataServerSettings();
|
||||||
|
|
||||||
const nextChapters = useMemo(() => {
|
|
||||||
if (!currentChapter) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Chapters.getNextChapters(currentChapter, chapters, {
|
|
||||||
offset: DirectionOffset.NEXT,
|
|
||||||
});
|
|
||||||
}, [currentChapter?.id, chapters]);
|
|
||||||
|
|
||||||
return useCallback(
|
return useCallback(
|
||||||
(pageIndex, debounceChapterUpdate = true, endReached = false) => {
|
(pageIndex, debounceChapterUpdate = true, endReached = false) => {
|
||||||
const { currentPageIndex, setCurrentPageIndex } = getReaderStore().pages;
|
const {
|
||||||
|
pages: { currentPageIndex, setCurrentPageIndex },
|
||||||
|
chapters: {
|
||||||
|
currentChapter,
|
||||||
|
chapters,
|
||||||
|
previousChapter,
|
||||||
|
nextChapter,
|
||||||
|
visibleChapters,
|
||||||
|
setReaderStateChapters,
|
||||||
|
},
|
||||||
|
} = getReaderStore();
|
||||||
|
|
||||||
if (pageIndex === currentPageIndex && !endReached) {
|
if (pageIndex === currentPageIndex && !endReached) {
|
||||||
return;
|
return;
|
||||||
@@ -482,6 +476,10 @@ export class ReaderControls {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nextChapters = Chapters.getNextChapters(currentChapter, chapters, {
|
||||||
|
offset: DirectionOffset.NEXT,
|
||||||
|
});
|
||||||
|
|
||||||
const direction = currentPageIndex > pageIndex ? DirectionOffset.PREVIOUS : DirectionOffset.NEXT;
|
const direction = currentPageIndex > pageIndex ? DirectionOffset.PREVIOUS : DirectionOffset.NEXT;
|
||||||
|
|
||||||
ReaderService.downloadAhead(currentChapter, nextChapter, nextChapters, pageIndex, downloadAheadLimit);
|
ReaderService.downloadAhead(currentChapter, nextChapter, nextChapters, pageIndex, downloadAheadLimit);
|
||||||
@@ -518,14 +516,7 @@ export class ReaderControls {
|
|||||||
|
|
||||||
handleCurrentPageIndexChange();
|
handleCurrentPageIndexChange();
|
||||||
},
|
},
|
||||||
[
|
[downloadAheadLimit],
|
||||||
currentChapter?.id,
|
|
||||||
previousChapter?.id,
|
|
||||||
nextChapter?.id,
|
|
||||||
nextChapters,
|
|
||||||
downloadAheadLimit,
|
|
||||||
visibleChapters,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Direction, useTheme } from '@mui/material/styles';
|
import { Direction, useTheme } from '@mui/material/styles';
|
||||||
import { t as translate } from 'i18next';
|
import { t as translate } from 'i18next';
|
||||||
@@ -36,7 +36,6 @@ import { useBackButton } from '@/base/hooks/useBackButton.ts';
|
|||||||
import { GLOBAL_READER_SETTING_KEYS } from '@/features/reader/settings/ReaderSettings.constants.tsx';
|
import { GLOBAL_READER_SETTING_KEYS } from '@/features/reader/settings/ReaderSettings.constants.tsx';
|
||||||
import { useReaderStateSettingsContext } from '@/features/reader/contexts/state/ReaderStateSettingsContext.tsx';
|
import { useReaderStateSettingsContext } from '@/features/reader/contexts/state/ReaderStateSettingsContext.tsx';
|
||||||
import { UpdateChapterPatchInput } from '@/lib/graphql/generated/graphql.ts';
|
import { UpdateChapterPatchInput } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { useReaderStateChaptersContext } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { useMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.ts';
|
import { useMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.ts';
|
||||||
import {
|
import {
|
||||||
getChapterIdsForDownloadAhead,
|
getChapterIdsForDownloadAhead,
|
||||||
@@ -155,30 +154,26 @@ export class ReaderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static useUpdateChapter(): (patch: UpdateChapterPatchInput) => void {
|
static useUpdateChapter(): (patch: UpdateChapterPatchInput) => void {
|
||||||
const { currentChapter, mangaChapters, chapters } = useReaderStateChaptersContext();
|
|
||||||
const { shouldSkipDupChapters } = ReaderService.useSettings();
|
const { shouldSkipDupChapters } = ReaderService.useSettings();
|
||||||
const {
|
const {
|
||||||
settings: { deleteChaptersWhileReading, deleteChaptersWithBookmark, updateProgressAfterReading },
|
settings: { deleteChaptersWhileReading, deleteChaptersWithBookmark, updateProgressAfterReading },
|
||||||
} = useMetadataServerSettings();
|
} = useMetadataServerSettings();
|
||||||
|
|
||||||
const previousChapters = useMemo(() => {
|
|
||||||
if (!currentChapter) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Chapters.getNextChapters(currentChapter, chapters, {
|
|
||||||
offset: DirectionOffset.PREVIOUS,
|
|
||||||
});
|
|
||||||
}, [currentChapter?.id, chapters]);
|
|
||||||
|
|
||||||
return useCallback(
|
return useCallback(
|
||||||
(patch) => {
|
(patch) => {
|
||||||
const { manga } = getReaderStore();
|
const {
|
||||||
|
manga,
|
||||||
|
chapters: { currentChapter, mangaChapters, chapters },
|
||||||
|
} = getReaderStore();
|
||||||
|
|
||||||
if (!manga || !currentChapter || !mangaChapters) {
|
if (!manga || !currentChapter || !mangaChapters) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const previousChapters = Chapters.getNextChapters(currentChapter, chapters, {
|
||||||
|
offset: DirectionOffset.PREVIOUS,
|
||||||
|
});
|
||||||
|
|
||||||
const update = async () => {
|
const update = async () => {
|
||||||
const chapterIdsToUpdate = Chapters.getIds(
|
const chapterIdsToUpdate = Chapters.getIds(
|
||||||
shouldSkipDupChapters
|
shouldSkipDupChapters
|
||||||
@@ -234,15 +229,7 @@ export class ReaderService {
|
|||||||
|
|
||||||
ReaderService.getOrCreateChapterUpdateQueue(currentChapter.id).enqueue(`${currentChapter.id}`, update);
|
ReaderService.getOrCreateChapterUpdateQueue(currentChapter.id).enqueue(`${currentChapter.id}`, update);
|
||||||
},
|
},
|
||||||
[
|
[shouldSkipDupChapters, deleteChaptersWhileReading, deleteChaptersWithBookmark, updateProgressAfterReading],
|
||||||
currentChapter?.id,
|
|
||||||
mangaChapters,
|
|
||||||
previousChapters,
|
|
||||||
shouldSkipDupChapters,
|
|
||||||
deleteChaptersWhileReading,
|
|
||||||
deleteChaptersWithBookmark,
|
|
||||||
updateProgressAfterReading,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import {
|
|||||||
PageInViewportType,
|
PageInViewportType,
|
||||||
ReaderOpenChapterLocationState,
|
ReaderOpenChapterLocationState,
|
||||||
ReaderResumeMode,
|
ReaderResumeMode,
|
||||||
ReaderStateChapters,
|
|
||||||
ReadingDirection,
|
ReadingDirection,
|
||||||
ReadingMode,
|
ReadingMode,
|
||||||
} from '@/features/reader/Reader.types.ts';
|
} from '@/features/reader/Reader.types.ts';
|
||||||
@@ -49,7 +48,6 @@ import { useReaderHorizontalModeInvertXYScrolling } from '@/features/reader/view
|
|||||||
import { useReaderHideCursorOnInactivity } from '@/features/reader/viewer/hooks/useReaderHideCursorOnInactivity.ts';
|
import { useReaderHideCursorOnInactivity } from '@/features/reader/viewer/hooks/useReaderHideCursorOnInactivity.ts';
|
||||||
import { useReaderScrollToStartOnPageChange } from '@/features/reader/viewer/hooks/useReaderScrollToStartOnPageChange.ts';
|
import { useReaderScrollToStartOnPageChange } from '@/features/reader/viewer/hooks/useReaderScrollToStartOnPageChange.ts';
|
||||||
import { useReaderHandlePageSelection } from '@/features/reader/viewer/hooks/useReaderHandlePageSelection.ts';
|
import { useReaderHandlePageSelection } from '@/features/reader/viewer/hooks/useReaderHandlePageSelection.ts';
|
||||||
import { useReaderStateChaptersContext } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { ReaderChapterViewer } from '@/features/reader/viewer/ReaderChapterViewer.tsx';
|
import { ReaderChapterViewer } from '@/features/reader/viewer/ReaderChapterViewer.tsx';
|
||||||
import {
|
import {
|
||||||
getPreviousNextChapterVisibility,
|
getPreviousNextChapterVisibility,
|
||||||
@@ -90,12 +88,6 @@ const BaseReaderViewer = forwardRef(
|
|||||||
updateCurrentPageIndex,
|
updateCurrentPageIndex,
|
||||||
showPreview,
|
showPreview,
|
||||||
setShowPreview,
|
setShowPreview,
|
||||||
initialChapter,
|
|
||||||
currentChapter,
|
|
||||||
chapters,
|
|
||||||
visibleChapters,
|
|
||||||
setReaderStateChapters,
|
|
||||||
isCurrentChapterReady,
|
|
||||||
}: Pick<
|
}: Pick<
|
||||||
IReaderSettings,
|
IReaderSettings,
|
||||||
| 'readingMode'
|
| 'readingMode'
|
||||||
@@ -111,15 +103,6 @@ const BaseReaderViewer = forwardRef(
|
|||||||
| 'isStaticNav'
|
| 'isStaticNav'
|
||||||
> &
|
> &
|
||||||
Pick<NavbarContextType, 'readerNavBarWidth'> &
|
Pick<NavbarContextType, 'readerNavBarWidth'> &
|
||||||
Pick<
|
|
||||||
ReaderStateChapters,
|
|
||||||
| 'initialChapter'
|
|
||||||
| 'currentChapter'
|
|
||||||
| 'chapters'
|
|
||||||
| 'visibleChapters'
|
|
||||||
| 'setReaderStateChapters'
|
|
||||||
| 'isCurrentChapterReady'
|
|
||||||
> &
|
|
||||||
TReaderTapZoneContext & {
|
TReaderTapZoneContext & {
|
||||||
updateCurrentPageIndex: ReturnType<typeof ReaderControls.useUpdateCurrentPageIndex>;
|
updateCurrentPageIndex: ReturnType<typeof ReaderControls.useUpdateCurrentPageIndex>;
|
||||||
},
|
},
|
||||||
@@ -155,6 +138,21 @@ const BaseReaderViewer = forwardRef(
|
|||||||
retryFailedPagesKeyPrefix: state.pages.retryFailedPagesKeyPrefix,
|
retryFailedPagesKeyPrefix: state.pages.retryFailedPagesKeyPrefix,
|
||||||
setTransitionPageMode: state.pages.setTransitionPageMode,
|
setTransitionPageMode: state.pages.setTransitionPageMode,
|
||||||
}));
|
}));
|
||||||
|
const {
|
||||||
|
initialChapter,
|
||||||
|
currentChapter,
|
||||||
|
chapters,
|
||||||
|
visibleChapters,
|
||||||
|
setReaderStateChapters,
|
||||||
|
isCurrentChapterReady,
|
||||||
|
} = useReaderStoreShallow((state) => ({
|
||||||
|
initialChapter: state.chapters.initialChapter,
|
||||||
|
currentChapter: state.chapters.currentChapter,
|
||||||
|
chapters: state.chapters.chapters,
|
||||||
|
visibleChapters: state.chapters.visibleChapters,
|
||||||
|
setReaderStateChapters: state.chapters.setReaderStateChapters,
|
||||||
|
isCurrentChapterReady: state.chapters.isCurrentChapterReady,
|
||||||
|
}));
|
||||||
const { resumeMode = ReaderResumeMode.START } = useLocation<ReaderOpenChapterLocationState>().state ?? {
|
const { resumeMode = ReaderResumeMode.START } = useLocation<ReaderOpenChapterLocationState>().state ?? {
|
||||||
resumeMode: ReaderResumeMode.START,
|
resumeMode: ReaderResumeMode.START,
|
||||||
};
|
};
|
||||||
@@ -446,7 +444,6 @@ export const ReaderViewer = withPropsFrom(
|
|||||||
ReaderService.useSettingsWithoutDefaultFlag,
|
ReaderService.useSettingsWithoutDefaultFlag,
|
||||||
() => ({ updateCurrentPageIndex: ReaderControls.useUpdateCurrentPageIndex() }),
|
() => ({ updateCurrentPageIndex: ReaderControls.useUpdateCurrentPageIndex() }),
|
||||||
useReaderTapZoneContext,
|
useReaderTapZoneContext,
|
||||||
useReaderStateChaptersContext,
|
|
||||||
useNavBarContext,
|
useNavBarContext,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -465,11 +462,5 @@ export const ReaderViewer = withPropsFrom(
|
|||||||
'updateCurrentPageIndex',
|
'updateCurrentPageIndex',
|
||||||
'showPreview',
|
'showPreview',
|
||||||
'setShowPreview',
|
'setShowPreview',
|
||||||
'initialChapter',
|
|
||||||
'currentChapter',
|
|
||||||
'chapters',
|
|
||||||
'visibleChapters',
|
|
||||||
'setReaderStateChapters',
|
|
||||||
'isCurrentChapterReady',
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import Button from '@mui/material/Button';
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { ComponentProps, memo, useMemo } from 'react';
|
import { ComponentProps, memo, useMemo } from 'react';
|
||||||
import { alpha, useTheme } from '@mui/material/styles';
|
import { alpha, useTheme } from '@mui/material/styles';
|
||||||
import { useReaderStateChaptersContext } from '@/features/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
|
||||||
import { IReaderSettings, ReaderTransitionPageMode, ReadingMode } from '@/features/reader/Reader.types.ts';
|
import { IReaderSettings, ReaderTransitionPageMode, ReadingMode } from '@/features/reader/Reader.types.ts';
|
||||||
import { isTransitionPageVisible } from '@/features/reader/viewer/pager/ReaderPager.utils.tsx';
|
import { isTransitionPageVisible } from '@/features/reader/viewer/pager/ReaderPager.utils.tsx';
|
||||||
import { useBackButton } from '@/base/hooks/useBackButton.ts';
|
import { useBackButton } from '@/base/hooks/useBackButton.ts';
|
||||||
@@ -224,7 +223,7 @@ export const ReaderTransitionPage = withPropsFrom(
|
|||||||
memo(BaseReaderTransitionPage) as typeof BaseReaderTransitionPage,
|
memo(BaseReaderTransitionPage) as typeof BaseReaderTransitionPage,
|
||||||
[
|
[
|
||||||
({ chapterId }: Pick<ComponentProps<typeof BaseReaderTransitionPage>, 'chapterId'>) => {
|
({ chapterId }: Pick<ComponentProps<typeof BaseReaderTransitionPage>, 'chapterId'>) => {
|
||||||
const { chapters } = useReaderStateChaptersContext();
|
const chapters = useReaderStoreShallow((state) => state.chapters.chapters);
|
||||||
|
|
||||||
const currentChapterIndex = useMemo(
|
const currentChapterIndex = useMemo(
|
||||||
() => chapters.findIndex((chapter) => chapter.id === chapterId),
|
() => chapters.findIndex((chapter) => chapter.id === chapterId),
|
||||||
@@ -248,7 +247,7 @@ export const ReaderTransitionPage = withPropsFrom(
|
|||||||
ReaderService.useSettingsWithoutDefaultFlag,
|
ReaderService.useSettingsWithoutDefaultFlag,
|
||||||
({ chapterId, type }: Pick<ComponentProps<typeof BaseReaderTransitionPage>, 'chapterId' | 'type'>) => {
|
({ chapterId, type }: Pick<ComponentProps<typeof BaseReaderTransitionPage>, 'chapterId' | 'type'>) => {
|
||||||
const handleBack = useBackButton();
|
const handleBack = useBackButton();
|
||||||
const { chapters } = useReaderStateChaptersContext();
|
const chapters = useReaderStoreShallow((state) => state.chapters.chapters);
|
||||||
|
|
||||||
const currentChapterIndex = useMemo(
|
const currentChapterIndex = useMemo(
|
||||||
() => chapters.findIndex((chapter) => chapter.id === chapterId),
|
() => chapters.findIndex((chapter) => chapter.id === chapterId),
|
||||||
|
|||||||
Reference in New Issue
Block a user