From 5473d14eaeb8d21aea36f90f2f28833c0cd2817e Mon Sep 17 00:00:00 2001 From: akabhirav <108609220+akabhirav@users.noreply.github.com> Date: Thu, 16 Feb 2023 11:26:09 +0530 Subject: [PATCH] Adds search by genre to WebUI (#238) * add pagination to library and fix some prettier issues * add genre search support like tachiyomi android app * Search by genre like you do in tachiyomi mobile app --------- Co-authored-by: akxer <> --- src/components/library/LibraryMangaGrid.tsx | 33 ++++++++++++++++----- src/screens/Reader.tsx | 1 + src/screens/SourceMangas.tsx | 1 + src/typings.d.ts | 1 + 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/components/library/LibraryMangaGrid.tsx b/src/components/library/LibraryMangaGrid.tsx index b951e2fa..e43f88da 100644 --- a/src/components/library/LibraryMangaGrid.tsx +++ b/src/components/library/LibraryMangaGrid.tsx @@ -41,19 +41,36 @@ const queryFilter = (query: NullAndUndefined, { title }: IMangaCard): bo return title.toLowerCase().includes(query.toLowerCase()); }; +const queryGenreFilter = (query: NullAndUndefined, { genre }: IMangaCard): boolean => { + if (!query) return true; + const queries = query.split(',').map((str) => str.toLowerCase().trim()); + return queries.every((element) => genre.map((el) => el.toLowerCase()).includes(element)); +}; + const filterManga = ( manga: IMangaCard[], query: NullAndUndefined, unread: NullAndUndefined, downloaded: NullAndUndefined, -): IMangaCard[] => - manga.filter((m) => { - if (query) { - return queryFilter(query, m); - } - - return downloadedFilter(downloaded, m) && unreadFilter(unread, m); - }); +): IMangaCard[] => { + let filteredManga: IMangaCard[] = []; + if (query) { + const titleFilteredManga = manga.filter((m) => queryFilter(query, m)); + const genreFilteredManga = manga.filter((m) => queryGenreFilter(query, m)); + const unique = titleFilteredManga.concat(genreFilteredManga).reduce((acc: Record, obj) => { + const { id } = obj; + if (!acc[id]) { + acc[id] = obj; + } + return acc; + }, {}); + filteredManga = Object.values(unique); + } + filteredManga = (filteredManga.length ? filteredManga : manga).filter( + (m) => downloadedFilter(downloaded, m) && unreadFilter(unread, m), + ); + return filteredManga; +}; const sortByUnread = (a: IMangaCard, b: IMangaCard): number => // eslint-disable-next-line implicit-arrow-linebreak diff --git a/src/screens/Reader.tsx b/src/screens/Reader.tsx index a4d2ad03..3ed165a9 100644 --- a/src/screens/Reader.tsx +++ b/src/screens/Reader.tsx @@ -70,6 +70,7 @@ export default function Reader() { id: +mangaId, title: '', thumbnailUrl: '', + genre: [], }); const [chapter, setChapter] = useState(initialChapter()); const [curPage, setCurPage] = useState(0); diff --git a/src/screens/SourceMangas.tsx b/src/screens/SourceMangas.tsx index 2e96e87e..91e9089e 100644 --- a/src/screens/SourceMangas.tsx +++ b/src/screens/SourceMangas.tsx @@ -202,6 +202,7 @@ export default function SourceMangas(props: { popular: boolean }) { thumbnailUrl: it.thumbnailUrl, id: it.id, inLibrary: it.inLibrary, + genre: it.genre, })), ]); setHasNextPage(data.hasNextPage); diff --git a/src/typings.d.ts b/src/typings.d.ts index 442560bd..23079a6b 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -78,6 +78,7 @@ type MetadataKeyValuePair = [AppMetadataKeys, AllowedMetadataValueTypes]; interface IMangaCard { id: number; title: string; + genre: string[]; thumbnailUrl: string; unreadCount?: number; downloadCount?: number;