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>
This commit is contained in:
@@ -129,7 +129,7 @@ const MainApp = () => {
|
||||
<ErrorBoundary>
|
||||
<Routes>
|
||||
{/* General Routes */}
|
||||
<Route path={AppRoutes.root.match} element={<Navigate to={AppRoutes.library.path} replace />} />
|
||||
<Route path={AppRoutes.root.match} element={<Navigate to={AppRoutes.library.path()} replace />} />
|
||||
<Route path={AppRoutes.matchAll.match} element={<Navigate to={AppRoutes.root.path} replace />} />
|
||||
{isMobileWidth && <Route path={AppRoutes.more.match} element={<More />} />}
|
||||
<Route path={AppRoutes.about.match} element={<About />} />
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -29,6 +29,6 @@ export const useBackButton = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
navigate(AppRoutes.library.path);
|
||||
navigate(AppRoutes.library.path());
|
||||
}, [history, location.pathname]);
|
||||
};
|
||||
|
||||
@@ -42,6 +42,8 @@ export type MangaTrackRecordInfo = MangaIdInfo & {
|
||||
export type MangaGenreInfo = Pick<MangaTypeGql, 'genre'>;
|
||||
export type MangaSourceNameInfo = { source?: Maybe<Pick<SourceType, 'name'>> };
|
||||
export type MangaSourceLngInfo = { source?: Maybe<Pick<SourceType, 'lang'>> };
|
||||
export type MangaArtistInfo = Pick<MangaTypeGql, 'artist'>;
|
||||
export type MangaAuthorInfo = Pick<MangaTypeGql, 'author'>;
|
||||
|
||||
export type MigrateMode = 'copy' | 'migrate';
|
||||
|
||||
|
||||
@@ -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<SourceType, 'id' | 'displayName'> | null):
|
||||
return source.displayName ?? source.id;
|
||||
}
|
||||
|
||||
function getValueOrUnknown(val?: string | null) {
|
||||
function getValueOrUnknown<T>(val?: T | null): T | string {
|
||||
return val ?? translate('global.label.unknown');
|
||||
}
|
||||
|
||||
const LibrarySearchLink = ({ query }: { query: string }) => (
|
||||
<Link
|
||||
component={RouterLink}
|
||||
to={AppRoutes.library.path(undefined, query)}
|
||||
sx={{ textDecoration: 'none', color: 'inherit' }}
|
||||
>
|
||||
{query}
|
||||
</Link>
|
||||
);
|
||||
|
||||
const valuesToJoinedLibrarySearchLinks = (values: string[] | undefined) =>
|
||||
values
|
||||
?.map((value) => <LibrarySearchLink query={value} />)
|
||||
.reduce((acc, valueLink) => (
|
||||
<>
|
||||
{acc}, {valueLink}
|
||||
</>
|
||||
));
|
||||
|
||||
const Thumbnail = ({
|
||||
manga,
|
||||
mangaDynamicColorSchemes,
|
||||
@@ -416,8 +437,14 @@ export const MangaDetails = ({
|
||||
</IconButton>
|
||||
</CustomTooltip>
|
||||
</Stack>
|
||||
<Metadata title={t('manga.label.author')} value={getValueOrUnknown(manga.author)} />
|
||||
<Metadata title={t('manga.label.artist')} value={getValueOrUnknown(manga.artist)} />
|
||||
<Metadata
|
||||
title={t('manga.label.author')}
|
||||
value={getValueOrUnknown(valuesToJoinedLibrarySearchLinks(Mangas.getAuthors(manga)))}
|
||||
/>
|
||||
<Metadata
|
||||
title={t('manga.label.author')}
|
||||
value={getValueOrUnknown(valuesToJoinedLibrarySearchLinks(Mangas.getArtists(manga)))}
|
||||
/>
|
||||
<Metadata
|
||||
title={t('manga.label.status')}
|
||||
value={t(MANGA_STATUS_TO_TRANSLATION[manga.status])}
|
||||
|
||||
@@ -27,6 +27,8 @@ import { MANGA_BASE_FIELDS } from '@/lib/graphql/fragments/MangaFragments.ts';
|
||||
import { MetadataMigrationSettings } from '@/modules/migration/Migration.types.ts';
|
||||
import {
|
||||
MangaAction,
|
||||
MangaArtistInfo,
|
||||
MangaAuthorInfo,
|
||||
MangaDownloadInfo,
|
||||
MangaGenreInfo,
|
||||
MangaIdInfo,
|
||||
@@ -92,6 +94,8 @@ type PerformActionOptions<Action extends MangaAction> = Action extends 'mark_as_
|
||||
|
||||
type MigrateFuncReturn = { copy: () => Promise<unknown>[]; cleanup: () => Promise<unknown>[] };
|
||||
|
||||
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 extends MangaArtistInfo>(manga: Manga): string[] | undefined {
|
||||
return manga.artist?.split(ARTIST_AUTHOR_SEPARATOR_REGEX);
|
||||
}
|
||||
|
||||
static getAuthors<Manga extends MangaAuthorInfo>(manga: Manga): string[] | undefined {
|
||||
return manga.author?.split(ARTIST_AUTHOR_SEPARATOR_REGEX);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ type RestrictedNavBarItem<Show extends NavbarItem['show']> = Omit<NavbarItem, 's
|
||||
|
||||
const NAVIGATION_BAR_BASE_ITEMS = [
|
||||
{
|
||||
path: AppRoutes.library.path,
|
||||
path: AppRoutes.library.path() as RestrictedNavBarItem<'both'>['path'],
|
||||
title: 'library.title',
|
||||
SelectedIconComponent: CollectionsBookmarkIcon,
|
||||
IconComponent: CollectionsOutlinedBookmarkIcon,
|
||||
|
||||
Reference in New Issue
Block a user