diff --git a/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktop.tsx b/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktop.tsx index ec14f202..01129a7e 100644 --- a/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktop.tsx +++ b/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktop.tsx @@ -33,8 +33,7 @@ import { ReaderService } from '@/modules/reader/services/ReaderService.ts'; import { LoadingPlaceholder } from '@/modules/core/components/placeholder/LoadingPlaceholder.tsx'; import { MangaIdInfo } from '@/modules/manga/Manga.types.ts'; import { NavbarContextType } from '@/modules/navigation-bar/NavigationBar.types.ts'; -import { ReaderStateChapters, TReaderStateMangaContext } from '@/modules/reader/types/Reader.types.ts'; -import { ReaderStatePages } from '@/modules/reader/types/ReaderProgressBar.types.ts'; +import { IReaderSettings, ReaderStateChapters, TReaderStateMangaContext } from '@/modules/reader/types/Reader.types.ts'; import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx'; const useGetPreviousNavBarStaticValue = (isVisible: boolean, isStaticNav: boolean) => { @@ -65,20 +64,13 @@ const BaseReaderNavBarDesktop = ({ currentChapter, previousChapter, nextChapter, - pages, - currentPageIndex, - pageLoadStates, - setPageLoadStates, - setRetryFailedPagesKeyPrefix, + isStaticNav, exit, }: ReaderNavBarDesktopProps & Pick & Pick & Pick & - Pick< - ReaderStatePages, - 'pages' | 'currentPageIndex' | 'pageLoadStates' | 'setPageLoadStates' | 'setRetryFailedPagesKeyPrefix' - > & { + Pick & { exit: ReturnType; }) => { const { t } = useTranslation(); @@ -86,29 +78,28 @@ const BaseReaderNavBarDesktop = ({ const getOptionForDirection = useGetOptionForDirection(); const updateReaderSettings = ReaderService.useCreateUpdateSetting(manga ?? DEFAULT_MANGA); - const settings = ReaderService.useSettings(); const [navBarElement, setNavBarElement] = useState(); useResizeObserver( navBarElement, useCallback(() => { - if (!settings?.isStaticNav) { + if (!isStaticNav) { return; } setReaderNavBarWidth(navBarElement!.offsetWidth); - }, [navBarElement, settings?.isStaticNav]), + }, [navBarElement, isStaticNav]), ); useLayoutEffect(() => () => setReaderNavBarWidth(0), []); - const wasNavBarStatic = useGetPreviousNavBarStaticValue(isVisible, settings.isStaticNav); + const wasNavBarStatic = useGetPreviousNavBarStaticValue(isVisible, isStaticNav); const changedNavBarStaticValue = wasNavBarStatic && isVisible; const drawerTransitionDuration = changedNavBarStaticValue ? 0 : undefined; return ( setNavBarElement(ref), @@ -126,9 +117,9 @@ const BaseReaderNavBarDesktop = ({ { setReaderNavBarWidth(0); - updateReaderSettings('isStaticNav', !settings.isStaticNav); + updateReaderSettings('isStaticNav', !isStaticNav); }} - color={settings.isStaticNav ? 'primary' : 'inherit'} + color={isStaticNav ? 'primary' : 'inherit'} > @@ -142,12 +133,7 @@ const BaseReaderNavBarDesktop = ({ chapterTitle={currentChapter.name} scanlator={currentChapter.scanlator} /> - + ) : ( @@ -155,7 +141,7 @@ const BaseReaderNavBarDesktop = ({ - + - manga && ReaderService.deleteSetting(manga, ...args)} - /> + @@ -184,6 +164,7 @@ export const ReaderNavBarDesktop = withPropsFrom( useReaderStateMangaContext, useReaderStateChaptersContext, userReaderStatePagesContext, + ReaderService.useSettingsWithoutDefaultFlag, () => ({ exit: ReaderService.useExit() }), ], [ @@ -193,11 +174,7 @@ export const ReaderNavBarDesktop = withPropsFrom( 'currentChapter', 'previousChapter', 'nextChapter', - 'pages', - 'currentPageIndex', - 'pageLoadStates', - 'setPageLoadStates', - 'setRetryFailedPagesKeyPrefix', + 'isStaticNav', 'exit', ], ); diff --git a/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopActions.tsx b/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopActions.tsx index 6eeee1ca..9177a958 100644 --- a/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopActions.tsx +++ b/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopActions.tsx @@ -15,7 +15,7 @@ import BookmarkBorderIcon from '@mui/icons-material/BookmarkBorder'; import OpenInNewIcon from '@mui/icons-material/OpenInNew'; import DownloadIcon from '@mui/icons-material/Download'; import ReplayIcon from '@mui/icons-material/Replay'; -import { useMemo, useRef } from 'react'; +import { memo, useMemo, useRef } from 'react'; import DeleteIcon from '@mui/icons-material/Delete'; import { actionToTranslationKey, ChapterAction, Chapters } from '@/modules/chapter/services/Chapters.ts'; import { ReaderStateChapters } from '@/modules/reader/types/Reader.types.ts'; @@ -23,6 +23,9 @@ import { requestManager } from '@/lib/requests/RequestManager.ts'; import { DownloadStateIndicator } from '@/modules/core/components/DownloadStateIndicator.tsx'; import { DownloadStatusFieldsFragment } from '@/lib/graphql/generated/graphql.ts'; import { ReaderStatePages } from '@/modules/reader/types/ReaderProgressBar.types.ts'; +import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx'; +import { useReaderStateChaptersContext } from '@/modules/reader/contexts/state/ReaderStateChaptersContext.tsx'; +import { userReaderStatePagesContext } from '@/modules/reader/contexts/state/ReaderStatePagesContext.tsx'; const DownloadButton = ({ currentChapter, @@ -59,62 +62,78 @@ const DownloadButton = ({ ); }; -export const ReaderNavBarDesktopActions = ({ - currentChapter, - pageLoadStates, - setPageLoadStates, - setRetryFailedPagesKeyPrefix, -}: Required> & - Pick) => { - const { id, isBookmarked, realUrl } = currentChapter ?? { id: -1, isBookmarked: false, realUrl: '' }; +const BaseReaderNavBarDesktopActions = memo( + ({ + currentChapter, + pageLoadStates, + setPageLoadStates, + setRetryFailedPagesKeyPrefix, + }: Required> & + Pick) => { + const { id, isBookmarked, realUrl } = currentChapter ?? { id: -1, isBookmarked: false, realUrl: '' }; - const { t } = useTranslation(); + const { t } = useTranslation(); - const pageRetryKeyPrefix = useRef(0); + const pageRetryKeyPrefix = useRef(0); - const { data: downloaderData } = requestManager.useGetDownloadStatus(); - const queue = downloaderData?.downloadStatus.queue ?? []; + const { data: downloaderData } = requestManager.useGetDownloadStatus(); + const queue = downloaderData?.downloadStatus.queue ?? []; - const downloadChapter = useMemo( - () => queue.find((queueItem) => queueItem.chapter.id === currentChapter?.id), - [queue, id], - ); + const downloadChapter = useMemo( + () => queue.find((queueItem) => queueItem.chapter.id === currentChapter?.id), + [queue, id], + ); - const haveSomePagesFailedToLoad = useMemo( - () => pageLoadStates.some((pageLoadState) => pageLoadState.error), - [pageLoadStates], - ); + const haveSomePagesFailedToLoad = useMemo( + () => pageLoadStates.some((pageLoadState) => pageLoadState.error), + [pageLoadStates], + ); - const bookmarkAction: Extract = isBookmarked ? 'unbookmark' : 'bookmark'; + const bookmarkAction: Extract = isBookmarked + ? 'unbookmark' + : 'bookmark'; - return ( - - - Chapters.performAction(bookmarkAction, [id], {})} color="inherit"> - {isBookmarked ? : } - - - - { - setPageLoadStates((statePageLoadStates) => - statePageLoadStates.map((pageLoadState) => ({ loaded: pageLoadState.loaded })), - ); - setRetryFailedPagesKeyPrefix(`${pageRetryKeyPrefix.current}`); - pageRetryKeyPrefix.current = (pageRetryKeyPrefix.current + 1) % 1000; - }} - disabled={!haveSomePagesFailedToLoad} - color="inherit" - > - - - - - - - - - - - ); -}; + return ( + + + Chapters.performAction(bookmarkAction, [id], {})} color="inherit"> + {isBookmarked ? : } + + + + { + setPageLoadStates((statePageLoadStates) => + statePageLoadStates.map((pageLoadState) => ({ loaded: pageLoadState.loaded })), + ); + setRetryFailedPagesKeyPrefix(`${pageRetryKeyPrefix.current}`); + pageRetryKeyPrefix.current = (pageRetryKeyPrefix.current + 1) % 1000; + }} + disabled={!haveSomePagesFailedToLoad} + color="inherit" + > + + + + + + + + + + + ); + }, +); + +export const ReaderNavBarDesktopActions = withPropsFrom( + BaseReaderNavBarDesktopActions, + [useReaderStateChaptersContext, userReaderStatePagesContext], + ['currentChapter', 'pageLoadStates', 'setPageLoadStates', 'setRetryFailedPagesKeyPrefix'], +); diff --git a/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopMetadata.tsx b/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopMetadata.tsx index 60da6f3b..9131a179 100644 --- a/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopMetadata.tsx +++ b/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopMetadata.tsx @@ -11,49 +11,52 @@ import Tooltip from '@mui/material/Tooltip'; import Link from '@mui/material/Link'; import { Link as RouterLink } from 'react-router-dom'; +import { memo } from 'react'; import { TypographyMaxLines } from '@/modules/core/components/TypographyMaxLines'; import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; -export const ReaderNavBarDesktopMetadata = ({ - mangaId, - mangaTitle, - chapterTitle, - scanlator, -}: { - mangaId: number; - mangaTitle: string; - chapterTitle: string; - scanlator?: string | null; -}) => ( - - - - - {mangaTitle} - - - - - - {chapterTitle} - - - {scanlator && ( - - - {scanlator} +export const ReaderNavBarDesktopMetadata = memo( + ({ + mangaId, + mangaTitle, + chapterTitle, + scanlator, + }: { + mangaId: number; + mangaTitle: string; + chapterTitle: string; + scanlator?: string | null; + }) => ( + + + + + {mangaTitle} + - )} - + + + {chapterTitle} + + + {scanlator && ( + + + {scanlator} + + + )} + + ), ); diff --git a/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopPageNavigation.tsx b/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopPageNavigation.tsx index 830f18a4..46f13159 100644 --- a/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopPageNavigation.tsx +++ b/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopPageNavigation.tsx @@ -22,6 +22,7 @@ import { ReaderNavBarDesktopNextPreviousButton } from '@/modules/reader/componen import { READING_DIRECTION_TO_THEME_DIRECTION } from '@/modules/reader/constants/ReaderSettings.constants.tsx'; import { IReaderSettings } from '@/modules/reader/types/Reader.types.ts'; import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx'; +import { userReaderStatePagesContext } from '@/modules/reader/contexts/state/ReaderStatePagesContext.tsx'; const BaseReaderNavBarDesktopPageNavigation = ({ currentPageIndex, @@ -81,6 +82,10 @@ const BaseReaderNavBarDesktopPageNavigation = ({ export const ReaderNavBarDesktopPageNavigation = withPropsFrom( memo(BaseReaderNavBarDesktopPageNavigation), - [() => ({ openPage: ReaderControls.useOpenPage() }), ReaderService.useSettingsWithoutDefaultFlag], - ['readingDirection', 'openPage'], + [ + userReaderStatePagesContext, + () => ({ openPage: ReaderControls.useOpenPage() }), + ReaderService.useSettingsWithoutDefaultFlag, + ], + ['currentPageIndex', 'pages', 'readingDirection', 'openPage'], ); diff --git a/src/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopQuickSettings.tsx b/src/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopQuickSettings.tsx index 33f96656..12873c85 100644 --- a/src/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopQuickSettings.tsx +++ b/src/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopQuickSettings.tsx @@ -14,25 +14,40 @@ import { ReaderNavBarDesktopPageScale } from '@/modules/reader/components/overla import { ReaderNavBarDesktopReadingMode } from '@/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopReadingMode.tsx'; import { ReaderNavBarDesktopOffsetDoubleSpread } from '@/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopOffsetDoubleSpread.tsx'; import { ReaderNavBarDesktopReadingDirection } from '@/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopReadingDirection.tsx'; -import { ReaderSettingsTypeProps } from '@/modules/reader/types/Reader.types.ts'; +import { IReaderSettingsWithDefaultFlag, TReaderStateMangaContext } from '@/modules/reader/types/Reader.types.ts'; import { ReaderNavBarDesktopProps } from '@/modules/reader/types/ReaderOverlay.types.ts'; +import { ReaderService } from '@/modules/reader/services/ReaderService.ts'; +import { MangaIdInfo } from '@/modules/manga/Manga.types.ts'; +import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx'; +import { useReaderStateMangaContext } from '@/modules/reader/contexts/state/ReaderStateMangaContext.tsx'; -export const ReaderNavBarDesktopQuickSettings = ({ - settings: { readingMode, shouldOffsetDoubleSpreads, pageScaleMode, shouldStretchPage, readingDirection }, - updateSetting, +const DEFAULT_MANGA: MangaIdInfo = { id: -1 }; +const BaseReaderNavBarDesktopQuickSettings = ({ + manga, + readingMode, + shouldOffsetDoubleSpreads, + pageScaleMode, + shouldStretchPage, + readingDirection, openSettings, - isDefaultable, - onDefault, -}: ReaderSettingsTypeProps & Pick) => { +}: Pick & + Pick & + Pick< + IReaderSettingsWithDefaultFlag, + 'readingMode' | 'shouldOffsetDoubleSpreads' | 'pageScaleMode' | 'shouldStretchPage' | 'readingDirection' + >) => { const { t } = useTranslation(); + const updateSetting = ReaderService.useCreateUpdateSetting(manga ?? DEFAULT_MANGA); + const deleteSetting = ReaderService.useCreateDeleteSetting(manga ?? DEFAULT_MANGA); + return ( updateSetting('readingMode', value)} - isDefaultable={isDefaultable} - onDefault={() => onDefault?.('readingMode')} + isDefaultable + onDefault={() => deleteSetting('readingMode')} /> onDefault?.('pageScaleMode')} + isDefaultable + onDefault={() => deleteSetting('pageScaleMode')} /> updateSetting('readingDirection', value)} - isDefaultable={isDefaultable} - onDefault={() => onDefault?.('readingDirection')} + isDefaultable + onDefault={() => deleteSetting('readingDirection')} />