From cff0ed5ec3f77a5961fbff2975522680e9afd6e9 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Wed, 11 Dec 2024 20:10:59 +0100 Subject: [PATCH] Extract app routes into constant --- src/App.tsx | 70 ++++---- .../components/ServerUpdateChecker.tsx | 3 +- src/modules/backup/screens/Backup.tsx | 5 +- .../category/components/CategorySelect.tsx | 3 +- src/modules/chapter/services/Chapters.ts | 3 +- src/modules/core/AppRoute.constants.ts | 157 ++++++++++++++++++ src/modules/core/hooks/useBackButton.ts | 3 +- .../downloads/screens/DownloadQueue.tsx | 3 +- src/modules/extension/screens/Extensions.tsx | 3 +- .../global-search/screens/SearchAll.tsx | 7 +- .../library/screens/LibrarySettings.tsx | 3 +- .../components/ContinueReadingButton.tsx | 3 +- .../manga/components/MangaActionMenuItems.tsx | 3 +- .../manga/components/MangaToolbarMenu.tsx | 5 +- .../manga/components/TrackMangaButton.tsx | 4 +- .../manga/components/cards/MangaCard.tsx | 5 +- .../hooks/useManageMangaLibraryState.tsx | 3 +- .../migration/components/MigrateDialog.tsx | 9 +- .../migration/components/MigrationCard.tsx | 3 +- .../components/DefaultNavBar.tsx | 11 +- .../overlay/ReaderOverlayHeaderMobile.tsx | 3 +- .../desktop/ReaderNavBarDesktopMetadata.tsx | 7 +- .../viewer/ReaderTransitionPage.tsx | 3 +- src/modules/reader/services/ReaderService.ts | 3 +- src/modules/settings/screens/Settings.tsx | 25 +-- src/modules/source/components/SourceCard.tsx | 7 +- src/modules/source/screens/SourceMangas.tsx | 3 +- src/modules/source/screens/Sources.tsx | 7 +- src/modules/tracker/components/TrackManga.tsx | 3 +- .../tracker/screens/TrackerOAuthLogin.tsx | 3 +- src/modules/updates/screens/Updates.tsx | 8 +- 31 files changed, 292 insertions(+), 86 deletions(-) create mode 100644 src/modules/core/AppRoute.constants.ts diff --git a/src/App.tsx b/src/App.tsx index 7c8247f4..5179f4b8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,6 +22,7 @@ import { lazyLoadFallback } from '@/modules/core/utils/LazyLoad.tsx'; import { ErrorBoundary } from '@/modules/core/components/ErrorBoundary.tsx'; import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx'; import { Reader } from '@/modules/reader/screens/Reader.tsx'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; const { Browse } = loadable(() => import('@/modules/browse/screens/Browse.tsx'), lazyLoadFallback); const { DownloadQueue } = loadable(() => import('@/modules/downloads/screens/DownloadQueue.tsx'), lazyLoadFallback); @@ -113,48 +114,51 @@ const MainApp = () => { {/* General Routes */} - } /> - } /> - + } /> + } /> + } /> - } /> - } /> - } /> - + } /> + } /> + } /> + } /> - } /> + } + /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> {/* Manga Routes */} - - } /> - } /> - } /> - } /> + + } /> + } /> + } /> + } /> - } /> - - + } /> + + } /> - } /> - } /> - } /> - + } /> + } /> + } /> + } /> - } /> + } /> - } /> + } /> @@ -164,7 +168,7 @@ const MainApp = () => { const ReaderApp = () => ( - } /> + } /> ); @@ -181,8 +185,8 @@ export const App: React.FC = () => ( - } /> - } /> + } /> + } /> diff --git a/src/modules/app-updates/components/ServerUpdateChecker.tsx b/src/modules/app-updates/components/ServerUpdateChecker.tsx index 38a6d7c4..82bb52e0 100644 --- a/src/modules/app-updates/components/ServerUpdateChecker.tsx +++ b/src/modules/app-updates/components/ServerUpdateChecker.tsx @@ -20,6 +20,7 @@ import { VersionUpdateInfoDialog } from '@/modules/app-updates/components/Versio import { useMetadataServerSettings } from '@/modules/settings/services/ServerSettingsMetadata.ts'; import { useLocalStorage } from '@/modules/core/hooks/useStorage.tsx'; import { getVersion } from '@/modules/app-updates/services/AppUpdateChecker.tsx'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; const disabledUpdateCheck = () => Promise.resolve(); @@ -87,7 +88,7 @@ export const ServerUpdateChecker = () => { return null; } - const isAboutPage = window.location.pathname === '/settings/about'; + const isAboutPage = window.location.pathname === AppRoutes.settings.childRoutes.about.path; if (isAboutPage) { return null; } diff --git a/src/modules/backup/screens/Backup.tsx b/src/modules/backup/screens/Backup.tsx index 3ff8dfbf..c63da5b9 100644 --- a/src/modules/backup/screens/Backup.tsx +++ b/src/modules/backup/screens/Backup.tsx @@ -35,6 +35,7 @@ import { LoadingPlaceholder } from '@/modules/core/components/placeholder/Loadin import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder/EmptyViewAbsoluteCentered.tsx'; import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; import { ServerSettings } from '@/modules/settings/Settings.types.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; type BackupSettingsType = Pick; @@ -357,7 +358,7 @@ export function Backup() { diff --git a/src/modules/chapter/services/Chapters.ts b/src/modules/chapter/services/Chapters.ts index f269fa6f..38b207b2 100644 --- a/src/modules/chapter/services/Chapters.ts +++ b/src/modules/chapter/services/Chapters.ts @@ -22,6 +22,7 @@ import { CHAPTER_LIST_FIELDS } from '@/lib/graphql/fragments/ChapterFragments.ts import { DirectionOffset, TranslationKey } from '@/Base.types.ts'; import { MangaIdInfo } from '@/modules/manga/Manga.types.ts'; import { ReaderResumeMode } from '@/modules/reader/types/Reader.types.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; export type ChapterAction = 'download' | 'delete' | 'bookmark' | 'unbookmark' | 'mark_as_read' | 'mark_as_unread'; @@ -118,7 +119,7 @@ export class Chapters { } static getReaderUrl(chapter: Chapter): string { - return `/manga/${chapter.mangaId}/chapter/${chapter.sourceOrder}`; + return AppRoutes.reader.path(chapter.mangaId, chapter.sourceOrder); } static isDownloading(id: number): boolean { diff --git a/src/modules/core/AppRoute.constants.ts b/src/modules/core/AppRoute.constants.ts new file mode 100644 index 00000000..00a07210 --- /dev/null +++ b/src/modules/core/AppRoute.constants.ts @@ -0,0 +1,157 @@ +/* + * 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 { SourceType } from '@/lib/graphql/generated/graphql.ts'; +import { MangaIdInfo } from '@/modules/manga/Manga.types.ts'; +import { ChapterSourceOrderInfo } from '@/modules/chapter/services/Chapters.ts'; + +type AppRouteInfo = { + match: string; + path?: string | ((...args: any[]) => string); +}; + +type TAppRoutes = Record; + +export const AppRoutes = { + root: { + match: '/', + path: '/', + }, + matchAll: { + match: '*', + }, + settings: { + path: '/settings', + match: 'settings', + childRoutes: { + about: { + match: 'about', + path: '/settings/about', + }, + categories: { + match: 'categories', + path: '/settings/categories', + }, + reader: { + match: 'reader', + path: '/settings/reader', + }, + library: { + match: 'library', + path: '/settings/library', + + childRoutes: { + duplicates: { + match: 'duplicates', + path: '/settings/library/duplicates', + }, + }, + }, + download: { + match: 'download', + path: '/settings/download', + }, + backup: { + match: 'backup', + path: '/settings/backup', + }, + server: { + match: 'server', + path: '/settings/server', + }, + webui: { + match: 'webui', + path: '/settings/webui', + }, + browse: { + match: 'browse', + path: '/settings/browse', + }, + device: { + match: 'device', + path: '/settings/device', + }, + tracking: { + match: 'tracking', + path: '/settings/tracking', + }, + appearance: { + match: 'appearance', + path: '/settings/appearance', + }, + }, + }, + sources: { + match: 'sources', + path: '/sources', + + childRoutes: { + browse: { + match: ':sourceId', + path: (sourceId: SourceType['id']) => `/sources/${sourceId}`, + }, + configure: { + match: ':sourceId/configure', + path: (sourceId: SourceType['id']) => `/sources/${sourceId}/configure`, + }, + searchAll: { + match: 'all/search', + path: '/sources/all/search', + }, + }, + }, + downloads: { + match: 'downloads', + path: '/downloads', + }, + manga: { + match: 'manga/:id', + path: (mangaId: MangaIdInfo['id']) => `/manga/${mangaId}`, + + childRoutes: { + reader: { + match: 'chapter/:chapterNum', + path: (mangaId: MangaIdInfo['id'], chapterNum: ChapterSourceOrderInfo['sourceOrder']) => + `/manga/${mangaId}/chapter/${chapterNum}`, + }, + }, + }, + library: { + match: 'library', + path: '/library', + }, + updates: { + match: 'updates', + path: '/updates', + }, + browse: { + match: 'browse', + path: '/browse', + }, + migrate: { + match: 'migrate/source/:sourceId', + path: (sourceId: SourceType['id']) => `/migrate/source/${sourceId}`, + + childRoutes: { + search: { + match: 'manga/:mangaId/search', + path: (sourceId: SourceType['id'], mangaId: MangaIdInfo['id']) => + `/migrate/source/${sourceId}/manga/${mangaId}/search`, + }, + }, + }, + tracker: { + match: 'tracker/login/oauth', + path: '/tracker/login/oauth', + }, + reader: { + match: '/manga/:mangaId/chapter/:chapterIndex', + path: (mangaId: MangaIdInfo['id'], chapterIndex: ChapterSourceOrderInfo['sourceOrder']) => + `/manga/${mangaId}/chapter/${chapterIndex}`, + }, +} satisfies TAppRoutes; diff --git a/src/modules/core/hooks/useBackButton.ts b/src/modules/core/hooks/useBackButton.ts index cbb2acb5..8f113bf7 100644 --- a/src/modules/core/hooks/useBackButton.ts +++ b/src/modules/core/hooks/useBackButton.ts @@ -8,6 +8,7 @@ import { useLocation, useNavigate } from 'react-router-dom'; import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; const PAGES_TO_IGNORE: readonly RegExp[] = [/\/manga\/[0-9]+\/chapter\/[0-9]+/g]; @@ -27,6 +28,6 @@ export const useBackButton = () => { return; } - navigate('/library'); + navigate(AppRoutes.library.path); }; }; diff --git a/src/modules/downloads/screens/DownloadQueue.tsx b/src/modules/downloads/screens/DownloadQueue.tsx index 5c4f6533..aa7735e3 100644 --- a/src/modules/downloads/screens/DownloadQueue.tsx +++ b/src/modules/downloads/screens/DownloadQueue.tsx @@ -35,6 +35,7 @@ import { LoadingPlaceholder } from '@/modules/core/components/placeholder/Loadin import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; import { ChapterDownloadStatus, ChapterIdInfo } from '@/modules/chapter/services/Chapters.ts'; import { DownloaderState, DownloadState } from '@/lib/graphql/generated/graphql.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; const HeightPreservingItem = ({ children, ...props }: BoxProps) => ( // the height is necessary to prevent the item container from collapsing, which confuses Virtuoso measurements @@ -59,7 +60,7 @@ const DownloadChapterItem = ({ return ( - + {t('extension.label.add_repository_info')} - diff --git a/src/modules/global-search/screens/SearchAll.tsx b/src/modules/global-search/screens/SearchAll.tsx index b8ac8b4b..0e8ffe30 100644 --- a/src/modules/global-search/screens/SearchAll.tsx +++ b/src/modules/global-search/screens/SearchAll.tsx @@ -29,6 +29,7 @@ import { SourceType } from '@/lib/graphql/generated/graphql.ts'; import { BaseMangaGrid } from '@/modules/manga/components/BaseMangaGrid.tsx'; import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder/EmptyViewAbsoluteCentered.tsx'; import { translateExtensionLanguage } from '@/modules/extension/Extensions.utils.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; type SourceLoadingState = { isLoading: boolean; hasResults: boolean; emptySearch: boolean }; type SourceToLoadingStateMap = Map; @@ -149,7 +150,11 @@ const SourceSearchPreview = React.memo( return ( <> - + {displayName} {translateExtensionLanguage(lang)} diff --git a/src/modules/library/screens/LibrarySettings.tsx b/src/modules/library/screens/LibrarySettings.tsx index 897bf660..f6c8d5c2 100644 --- a/src/modules/library/screens/LibrarySettings.tsx +++ b/src/modules/library/screens/LibrarySettings.tsx @@ -37,6 +37,7 @@ import { import { GET_CATEGORIES_SETTINGS } from '@/lib/graphql/queries/CategoryQuery.ts'; import { GET_MANGAS_BASE } from '@/lib/graphql/queries/MangaQuery.ts'; import { MetadataLibrarySettings } from '@/modules/library/Library.types.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; const removeNonLibraryMangasFromCategories = async (): Promise => { try { @@ -182,7 +183,7 @@ export function LibrarySettings() { secondary={t('library.settings.advanced.database.cleanup.label.description')} /> - + e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()} diff --git a/src/modules/manga/components/MangaActionMenuItems.tsx b/src/modules/manga/components/MangaActionMenuItems.tsx index 295bd228..b5db1c6d 100644 --- a/src/modules/manga/components/MangaActionMenuItems.tsx +++ b/src/modules/manga/components/MangaActionMenuItems.tsx @@ -35,6 +35,7 @@ import { NestedMenuItem } from '@/modules/core/components/menu/NestedMenuItem.ts import { MangaChapterStatFieldsFragment, MangaType } from '@/lib/graphql/generated/graphql.ts'; import { MangaAction, MangaDownloadInfo, MangaIdInfo, MangaUnreadInfo } from '@/modules/manga/Manga.types.ts'; import { actionToTranslationKey } from '@/modules/manga/Manga.constants.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; const ACTION_DISABLES_SELECTION_MODE: MangaAction[] = ['remove_from_library'] as const; @@ -156,7 +157,7 @@ export const MangaActionMenuItems = ({ )} {isSingleMode && ( diff --git a/src/modules/manga/components/MangaToolbarMenu.tsx b/src/modules/manga/components/MangaToolbarMenu.tsx index b9f16ff4..f903f88b 100644 --- a/src/modules/manga/components/MangaToolbarMenu.tsx +++ b/src/modules/manga/components/MangaToolbarMenu.tsx @@ -23,6 +23,7 @@ import { useTheme } from '@mui/material/styles'; import useMediaQuery from '@mui/material/useMediaQuery'; import { useCategorySelect } from '@/modules/category/hooks/useCategorySelect.tsx'; import { MangaType } from '@/lib/graphql/generated/graphql.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; interface IProps { manga: Pick; @@ -65,7 +66,7 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => { <> @@ -125,7 +126,7 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => { diff --git a/src/modules/manga/components/TrackMangaButton.tsx b/src/modules/manga/components/TrackMangaButton.tsx index 50f83134..594f796d 100644 --- a/src/modules/manga/components/TrackMangaButton.tsx +++ b/src/modules/manga/components/TrackMangaButton.tsx @@ -19,8 +19,8 @@ import { Trackers } from '@/modules/tracker/services/Trackers.ts'; import { CustomIconButton } from '@/modules/core/components/buttons/CustomIconButton.tsx'; import { GetTrackersSettingsQuery, MangaType } from '@/lib/graphql/generated/graphql.ts'; import { GET_TRACKERS_SETTINGS } from '@/lib/graphql/queries/TrackerQuery.ts'; - import { MangaTrackRecordInfo } from '@/modules/manga/Manga.types.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; export const TrackMangaButton = ({ manga }: { manga: MangaTrackRecordInfo & Pick }) => { const { t } = useTranslation(); @@ -40,7 +40,7 @@ export const TrackMangaButton = ({ manga }: { manga: MangaTrackRecordInfo & Pick } if (!loggedInTrackers.length) { - navigate('/settings/tracking'); + navigate(AppRoutes.tracker.path); return; } diff --git a/src/modules/manga/components/cards/MangaCard.tsx b/src/modules/manga/components/cards/MangaCard.tsx index bb3aacc1..281885a8 100644 --- a/src/modules/manga/components/cards/MangaCard.tsx +++ b/src/modules/manga/components/cards/MangaCard.tsx @@ -20,6 +20,7 @@ import { MangaCardMode, MangaCardProps } from '@/modules/manga/Manga.types.ts'; import { ContinueReadingButton } from '@/modules/manga/components/ContinueReadingButton.tsx'; import { MangaBadges } from '@/modules/manga/components/MangaBadges.tsx'; import { GridLayout } from '@/modules/core/Core.types.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; const getMangaLinkTo = ( mode: MangaCardMode, @@ -31,9 +32,9 @@ const getMangaLinkTo = ( case 'default': case 'source': case 'duplicate': - return `/manga/${mangaId}/`; + return AppRoutes.manga.path(mangaId); case 'migrate.search': - return `/migrate/source/${sourceId}/manga/${mangaId}/search?query=${mangaTitle}`; + return `${AppRoutes.migrate.childRoutes.search.path(sourceId ?? '-1', mangaId)}?query=${mangaTitle}`; case 'migrate.select': return ''; default: diff --git a/src/modules/manga/hooks/useManageMangaLibraryState.tsx b/src/modules/manga/hooks/useManageMangaLibraryState.tsx index 5607664e..93e38fd4 100644 --- a/src/modules/manga/hooks/useManageMangaLibraryState.tsx +++ b/src/modules/manga/hooks/useManageMangaLibraryState.tsx @@ -20,6 +20,7 @@ import { Mangas } from '@/modules/manga/services/Mangas.ts'; import { awaitConfirmation } from '@/modules/core/utils/AwaitableDialog.tsx'; import { GetCategoriesBaseQuery, GetCategoriesBaseQueryVariables, MangaType } from '@/lib/graphql/generated/graphql.ts'; import { GET_CATEGORIES_BASE } from '@/lib/graphql/queries/CategoryQuery.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; export const useManageMangaLibraryState = ( manga: Pick & Partial>, @@ -136,7 +137,7 @@ export const useManageMangaLibraryState = ( extra: { show: true, title: t('migrate.dialog.action.button.show_entry'), contain: true }, confirm: { title: t('global.button.add') }, }, - onExtra: () => navigate(`/manga/${duplicatedLibraryMangas!.data.mangas.nodes[0].id}`), + onExtra: () => navigate(AppRoutes.manga.path(duplicatedLibraryMangas!.data.mangas.nodes[0].id)), }); } diff --git a/src/modules/migration/components/MigrateDialog.tsx b/src/modules/migration/components/MigrateDialog.tsx index c9a1a67c..791e0099 100644 --- a/src/modules/migration/components/MigrateDialog.tsx +++ b/src/modules/migration/components/MigrateDialog.tsx @@ -26,6 +26,7 @@ import { import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; import { MetadataMigrationSettings } from '@/modules/migration/Migration.types.ts'; import { MigrateMode } from '@/modules/manga/Manga.types.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; export const MigrateDialog = ({ mangaIdToMigrateTo, onClose }: { mangaIdToMigrateTo: number; onClose: () => void }) => { const { t } = useTranslation(); @@ -63,7 +64,7 @@ export const MigrateDialog = ({ mangaIdToMigrateTo, onClose }: { mangaIdToMigrat deleteChapters, }); - navigate(`/manga/${mangaIdToMigrateTo}`, { replace: true }); + navigate(AppRoutes.manga.path(mangaIdToMigrateTo), { replace: true }); } catch (e) { setIsMigrationInProcess(false); } @@ -108,7 +109,11 @@ export const MigrateDialog = ({ mangaIdToMigrateTo, onClose }: { mangaIdToMigrat width: '100%', }} > - diff --git a/src/modules/migration/components/MigrationCard.tsx b/src/modules/migration/components/MigrationCard.tsx index e4e63dbc..83c1d48b 100644 --- a/src/modules/migration/components/MigrationCard.tsx +++ b/src/modules/migration/components/MigrationCard.tsx @@ -19,6 +19,7 @@ import { requestManager } from '@/lib/requests/RequestManager.ts'; import { GetMigratableSourcesQuery } from '@/lib/graphql/generated/graphql.ts'; import { SpinnerImage } from '@/modules/core/components/SpinnerImage.tsx'; import { translateExtensionLanguage } from '@/modules/extension/Extensions.utils.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; export type TMigratableSource = NonNullable & { mangaCount: number; @@ -33,7 +34,7 @@ export const MigrationCard = ({ id, name, lang, iconUrl, mangaCount }: TMigratab return ( - + = [ { - path: '/library', + path: AppRoutes.library.path, title: 'library.title', SelectedIconComponent: CollectionsBookmarkIcon, IconComponent: CollectionsOutlinedBookmarkIcon, show: 'both', }, { - path: '/updates', + path: AppRoutes.updates.path, title: 'updates.title', SelectedIconComponent: NewReleasesIcon, IconComponent: NewReleasesOutlinedIcon, show: 'both', }, { - path: '/browse', + path: AppRoutes.browse.path, title: 'global.label.browse', SelectedIconComponent: ExploreIcon, IconComponent: ExploreOutlinedIcon, show: 'both', }, { - path: '/downloads', + path: AppRoutes.downloads.path, title: 'download.title', SelectedIconComponent: GetAppIcon, IconComponent: GetAppOutlinedIcon, show: 'both', }, { - path: '/settings', + path: AppRoutes.settings.path, title: 'settings.title', SelectedIconComponent: SettingsIcon, IconComponent: SettingsIcon, diff --git a/src/modules/reader/components/overlay/ReaderOverlayHeaderMobile.tsx b/src/modules/reader/components/overlay/ReaderOverlayHeaderMobile.tsx index c34fc8ed..d3f699e4 100644 --- a/src/modules/reader/components/overlay/ReaderOverlayHeaderMobile.tsx +++ b/src/modules/reader/components/overlay/ReaderOverlayHeaderMobile.tsx @@ -32,6 +32,7 @@ import { useReaderScrollbarContext } from '@/modules/reader/contexts/ReaderScrol import { useReaderStateMangaContext } from '@/modules/reader/contexts/state/ReaderStateMangaContext.tsx'; import { useReaderStateChaptersContext } from '@/modules/reader/contexts/state/ReaderStateChaptersContext.tsx'; import { LoadingPlaceholder } from '@/modules/core/components/placeholder/LoadingPlaceholder'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; const DEFAULT_MANGA = { id: -1, title: '' }; const DEFAULT_CHAPTER = { id: -1, name: '', realUrl: '', isBookmarked: false }; @@ -79,7 +80,7 @@ export const ReaderOverlayHeaderMobile = ({ isVisible }: MobileHeaderProps) => { {title} diff --git a/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopMetadata.tsx b/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopMetadata.tsx index 0d99422a..2719b9d7 100644 --- a/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopMetadata.tsx +++ b/src/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopMetadata.tsx @@ -12,6 +12,7 @@ import Link from '@mui/material/Link'; import { Link as RouterLink } from 'react-router-dom'; import { TypographyMaxLines } from '@/modules/core/components/TypographyMaxLines'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; export const ReaderNavBarDesktopMetadata = ({ mangaId, @@ -25,7 +26,11 @@ export const ReaderNavBarDesktopMetadata = ({ - + {mangaTitle} diff --git a/src/modules/reader/components/viewer/ReaderTransitionPage.tsx b/src/modules/reader/components/viewer/ReaderTransitionPage.tsx index 14d7714e..0095313d 100644 --- a/src/modules/reader/components/viewer/ReaderTransitionPage.tsx +++ b/src/modules/reader/components/viewer/ReaderTransitionPage.tsx @@ -27,6 +27,7 @@ import { useReaderStateMangaContext } from '@/modules/reader/contexts/state/Read import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts'; import { isContinuousReadingMode } from '@/modules/reader/utils/ReaderSettings.utils.tsx'; import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; const ChapterInfo = ({ title, @@ -173,7 +174,7 @@ export const ReaderTransitionPage = ({ e.stopPropagation(); }} variant="contained" - to={`/manga/${manga?.id}`} + to={AppRoutes.manga.path(manga?.id ?? -1)} > {t('reader.transition_page.exit.manga_page')} diff --git a/src/modules/reader/services/ReaderService.ts b/src/modules/reader/services/ReaderService.ts index 3d65351b..920227c4 100644 --- a/src/modules/reader/services/ReaderService.ts +++ b/src/modules/reader/services/ReaderService.ts @@ -43,6 +43,7 @@ import { } from '@/modules/reader/utils/Reader.utils.ts'; import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; import { Queue } from '@/lib/Queue.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; const DIRECTION_TO_INVERTED: Record = { ltr: 'rtl', @@ -330,7 +331,7 @@ export class ReaderService { return () => {}; } - return navigate(`/manga/${manga.id}`); + return navigate(AppRoutes.manga.path(manga.id)); }, [manga]); switch (exitMode) { diff --git a/src/modules/settings/screens/Settings.tsx b/src/modules/settings/screens/Settings.tsx index d4efb828..69739b48 100644 --- a/src/modules/settings/screens/Settings.tsx +++ b/src/modules/settings/screens/Settings.tsx @@ -29,6 +29,7 @@ import { ListItemLink } from '@/modules/core/components/ListItemLink.tsx'; import { NavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import { makeToast } from '@/modules/core/utils/Toast.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; export function Settings() { const { t } = useTranslation(); @@ -57,43 +58,43 @@ export function Settings() { return ( - + - + - + - + - + - + - + @@ -109,31 +110,31 @@ export function Settings() { secondary={t('settings.clear_cache.label.description')} /> - + - + - + - + - + diff --git a/src/modules/source/components/SourceCard.tsx b/src/modules/source/components/SourceCard.tsx index 7beb8da9..e297770e 100644 --- a/src/modules/source/components/SourceCard.tsx +++ b/src/modules/source/components/SourceCard.tsx @@ -23,6 +23,7 @@ import { SpinnerImage } from '@/modules/core/components/SpinnerImage.tsx'; import { GetSourcesListQuery } from '@/lib/graphql/generated/graphql.ts'; import { MediaQuery } from '@/modules/core/utils/MediaQuery.tsx'; import { translateExtensionLanguage } from '@/modules/extension/Extensions.utils.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; interface IProps { source: GetSourcesListQuery['sources']['nodes'][number]; @@ -59,7 +60,7 @@ export const SourceCard: React.FC = (props: IProps) => { > = (props: IProps) => {