* [Prettier] Add "prettier" Makes the formatting of the code consistent. By using the eslint-plugin-prettier formatting issues will be highlighted as a lint error. These errors will be auto fixed by running "lint --fix" (which can be done automatically on file save) * [Prettier] Add "prettier" - Fix formatting
138 lines
3.9 KiB
TypeScript
138 lines
3.9 KiB
TypeScript
/*
|
|
* 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 React, { useMemo } from 'react';
|
|
import MangaGrid, { IMangaGridProps } from 'components/MangaGrid';
|
|
import { useLibraryOptionsContext } from 'components/context/LibraryOptionsContext';
|
|
import { StringParam, useQueryParam } from 'use-query-params';
|
|
|
|
const FILTERED_OUT_MESSAGE = 'There are no Manga matching this filter';
|
|
|
|
const unreadFilter = (unread: NullAndUndefined<boolean>, { unreadCount }: IMangaCard): boolean => {
|
|
switch (unread) {
|
|
case true:
|
|
return !!unreadCount && unreadCount >= 1;
|
|
case false:
|
|
return unreadCount === 0;
|
|
default:
|
|
return true;
|
|
}
|
|
};
|
|
|
|
const downloadedFilter = (
|
|
downloaded: NullAndUndefined<boolean>,
|
|
{ downloadCount }: IMangaCard,
|
|
): boolean => {
|
|
switch (downloaded) {
|
|
case true:
|
|
return !!downloadCount && downloadCount >= 1;
|
|
case false:
|
|
return downloadCount === 0;
|
|
default:
|
|
return true;
|
|
}
|
|
};
|
|
|
|
const queryFilter = (query: NullAndUndefined<string>, { title }: IMangaCard): boolean => {
|
|
if (!query) return true;
|
|
return title.toLowerCase().includes(query.toLowerCase());
|
|
};
|
|
|
|
const filterManga = (
|
|
manga: IMangaCard[],
|
|
query: NullAndUndefined<string>,
|
|
unread: NullAndUndefined<boolean>,
|
|
downloaded: NullAndUndefined<boolean>,
|
|
): IMangaCard[] =>
|
|
manga.filter((m) => {
|
|
if (query) {
|
|
return queryFilter(query, m);
|
|
}
|
|
|
|
return downloadedFilter(downloaded, m) && unreadFilter(unread, m);
|
|
});
|
|
|
|
const sortByUnread = (a: IMangaCard, b: IMangaCard): number =>
|
|
// eslint-disable-next-line implicit-arrow-linebreak
|
|
(a.unreadCount ?? 0) - (b.unreadCount ?? 0);
|
|
|
|
const sortByTitle = (a: IMangaCard, b: IMangaCard): number => a.title.localeCompare(b.title);
|
|
|
|
const sortById = (a: IMangaCard, b: IMangaCard): number => a.id - b.id;
|
|
|
|
const sortManga = (
|
|
manga: IMangaCard[],
|
|
sort: NullAndUndefined<LibrarySortMode>,
|
|
desc: NullAndUndefined<boolean>,
|
|
): IMangaCard[] => {
|
|
const result = [...manga];
|
|
|
|
switch (sort) {
|
|
case 'sortAlph':
|
|
result.sort(sortByTitle);
|
|
break;
|
|
case 'sortID':
|
|
result.sort(sortById);
|
|
break;
|
|
case 'sortToRead':
|
|
result.sort(sortByUnread);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (desc === true) {
|
|
result.reverse();
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
const LibraryMangaGrid: React.FC<IMangaGridProps & { lastLibraryUpdate: number }> = ({
|
|
mangas,
|
|
isLoading,
|
|
hasNextPage,
|
|
lastPageNum,
|
|
setLastPageNum,
|
|
message,
|
|
lastLibraryUpdate,
|
|
}) => {
|
|
const [query] = useQueryParam('query', StringParam);
|
|
const { options } = useLibraryOptionsContext();
|
|
const { unread, downloaded } = options;
|
|
|
|
const sortedManga = useMemo(
|
|
() => sortManga(mangas, options.sorts, options.sortDesc),
|
|
[mangas, lastLibraryUpdate, options.sorts, options.sortDesc],
|
|
);
|
|
|
|
const filteredManga = useMemo(
|
|
() => filterManga(sortedManga, query, unread, downloaded),
|
|
[sortedManga, lastLibraryUpdate, query, unread, downloaded],
|
|
);
|
|
|
|
const showFilteredOutMessage =
|
|
(unread != null || downloaded != null || query) &&
|
|
filteredManga.length === 0 &&
|
|
mangas.length > 0;
|
|
|
|
return (
|
|
<MangaGrid
|
|
mangas={filteredManga}
|
|
isLoading={isLoading}
|
|
hasNextPage={hasNextPage}
|
|
lastPageNum={lastPageNum}
|
|
setLastPageNum={setLastPageNum}
|
|
message={showFilteredOutMessage ? FILTERED_OUT_MESSAGE : message}
|
|
gridLayout={options.gridLayout}
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default LibraryMangaGrid;
|