From caad353bfac8ca668049c9a94141f3d036aea388 Mon Sep 17 00:00:00 2001 From: Well404 <40534114+Well2333@users.noreply.github.com> Date: Sun, 18 May 2025 01:04:16 +0800 Subject: [PATCH] Trigger library search on artist/author click (#939) * add search func * Fix lint issues and clean up --------- Co-authored-by: schroda <50052685+schroda@users.noreply.github.com> --- src/App.tsx | 2 +- src/modules/core/AppRoute.constants.ts | 9 ++++- .../core/components/texts/Metadata.tsx | 3 +- src/modules/core/hooks/useBackButton.ts | 2 +- src/modules/manga/Manga.types.ts | 2 ++ src/modules/manga/components/MangaDetails.tsx | 33 +++++++++++++++++-- src/modules/manga/services/Mangas.ts | 12 +++++++ .../navigation-bar/NavigationBar.constants.ts | 2 +- 8 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index b441d3ea..569b939c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -129,7 +129,7 @@ const MainApp = () => { {/* General Routes */} - } /> + } /> } /> {isMobileWidth && } />} } /> diff --git a/src/modules/core/AppRoute.constants.ts b/src/modules/core/AppRoute.constants.ts index 3a3559fd..7daef3ba 100644 --- a/src/modules/core/AppRoute.constants.ts +++ b/src/modules/core/AppRoute.constants.ts @@ -128,7 +128,14 @@ export const AppRoutes = { }, library: { match: 'library', - path: '/library', + path: (tab?: string, search?: string) => { + const tabParam = tab ? `tab=${tab}` : ''; + const searchParam = search ? `query=${encodeURIComponent(search)}` : ''; + + const params = [tabParam, searchParam].filter(Boolean).join('&'); + + return `/library${params ? `?${params}` : ''}`; + }, }, updates: { match: 'updates', diff --git a/src/modules/core/components/texts/Metadata.tsx b/src/modules/core/components/texts/Metadata.tsx index c02456ac..3b54e212 100644 --- a/src/modules/core/components/texts/Metadata.tsx +++ b/src/modules/core/components/texts/Metadata.tsx @@ -8,6 +8,7 @@ import Stack, { StackProps } from '@mui/material/Stack'; import Typography, { TypographyProps } from '@mui/material/Typography'; +import { ReactNode } from 'react'; export const Metadata = ({ title, @@ -17,7 +18,7 @@ export const Metadata = ({ valueProps, }: { title: string; - value: string; + value: ReactNode; stackProps?: StackProps; titleProps?: TypographyProps; valueProps?: TypographyProps; diff --git a/src/modules/core/hooks/useBackButton.ts b/src/modules/core/hooks/useBackButton.ts index d87e4f13..bc670368 100644 --- a/src/modules/core/hooks/useBackButton.ts +++ b/src/modules/core/hooks/useBackButton.ts @@ -29,6 +29,6 @@ export const useBackButton = () => { return; } - navigate(AppRoutes.library.path); + navigate(AppRoutes.library.path()); }, [history, location.pathname]); }; diff --git a/src/modules/manga/Manga.types.ts b/src/modules/manga/Manga.types.ts index f8def3fa..cbbc30f6 100644 --- a/src/modules/manga/Manga.types.ts +++ b/src/modules/manga/Manga.types.ts @@ -42,6 +42,8 @@ export type MangaTrackRecordInfo = MangaIdInfo & { export type MangaGenreInfo = Pick; export type MangaSourceNameInfo = { source?: Maybe> }; export type MangaSourceLngInfo = { source?: Maybe> }; +export type MangaArtistInfo = Pick; +export type MangaAuthorInfo = Pick; export type MigrateMode = 'copy' | 'migrate'; diff --git a/src/modules/manga/components/MangaDetails.tsx b/src/modules/manga/components/MangaDetails.tsx index b6787a1e..c34961b4 100644 --- a/src/modules/manga/components/MangaDetails.tsx +++ b/src/modules/manga/components/MangaDetails.tsx @@ -29,6 +29,7 @@ import { Vibrant } from 'node-vibrant/browser'; import { FastAverageColor } from 'fast-average-color'; import parseHtml from 'html-react-parser'; import sanitizeHtml from 'sanitize-html'; +import { Link as RouterLink } from 'react-router-dom'; import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx'; import { makeToast } from '@/modules/core/utils/Toast.ts'; import { Mangas } from '@/modules/manga/services/Mangas.ts'; @@ -48,6 +49,7 @@ import { TAppThemeContext, useAppThemeContext } from '@/modules/theme/contexts/A import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts'; import { CustomButtonIcon } from '@/modules/core/components/buttons/CustomButtonIcon.tsx'; import { Sources } from '@/modules/source/services/Sources.ts'; +import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; const DetailsWrapper = styled('div')(({ theme }) => ({ display: 'flex', @@ -161,10 +163,29 @@ function getSourceName(source?: Pick | null): return source.displayName ?? source.id; } -function getValueOrUnknown(val?: string | null) { +function getValueOrUnknown(val?: T | null): T | string { return val ?? translate('global.label.unknown'); } +const LibrarySearchLink = ({ query }: { query: string }) => ( + + {query} + +); + +const valuesToJoinedLibrarySearchLinks = (values: string[] | undefined) => + values + ?.map((value) => ) + .reduce((acc, valueLink) => ( + <> + {acc}, {valueLink} + + )); + const Thumbnail = ({ manga, mangaDynamicColorSchemes, @@ -416,8 +437,14 @@ export const MangaDetails = ({ - - + + = Action extends 'mark_as_ type MigrateFuncReturn = { copy: () => Promise[]; cleanup: () => Promise[] }; +const ARTIST_AUTHOR_SEPARATOR_REGEX = /\s*[,|、]\s*/; + export class Mangas { static getIds(mangas: MangaIdInfo[]): number[] { return mangas.map((manga) => manga.id); @@ -592,4 +596,12 @@ export class Mangas { Mangas.isType(manga, MangaType.MANHUA) ); } + + static getArtists(manga: Manga): string[] | undefined { + return manga.artist?.split(ARTIST_AUTHOR_SEPARATOR_REGEX); + } + + static getAuthors(manga: Manga): string[] | undefined { + return manga.author?.split(ARTIST_AUTHOR_SEPARATOR_REGEX); + } } diff --git a/src/modules/navigation-bar/NavigationBar.constants.ts b/src/modules/navigation-bar/NavigationBar.constants.ts index e906ec38..46c3ff76 100644 --- a/src/modules/navigation-bar/NavigationBar.constants.ts +++ b/src/modules/navigation-bar/NavigationBar.constants.ts @@ -26,7 +26,7 @@ type RestrictedNavBarItem = Omit['path'], title: 'library.title', SelectedIconComponent: CollectionsBookmarkIcon, IconComponent: CollectionsOutlinedBookmarkIcon,