Files
suwayomi-material-you-webui/src/components/library/LibraryMangaGrid.tsx
Daniel 4e0a860dfd add prettier for auto formatting (#231)
* [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
2023-02-06 12:36:33 +03:30

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;