Add bookmarked filter in library (#687)

This commit is contained in:
schroda
2024-04-01 01:12:26 +02:00
committed by GitHub
parent fe2cb682b6
commit 4f7a05f6fe
7 changed files with 48 additions and 14 deletions

View File

@@ -28,6 +28,7 @@ export const DefaultLibraryOptions: LibraryOptions = {
SourcegridLayout: GridLayout.Compact, SourcegridLayout: GridLayout.Compact,
downloaded: undefined, downloaded: undefined,
bookmarked: undefined,
sortDesc: undefined, sortDesc: undefined,
sorts: undefined, sorts: undefined,
unread: undefined, unread: undefined,

View File

@@ -70,6 +70,11 @@ export const LibraryOptionsPanel: React.FC<IProps> = ({ open, onClose }) => {
checked={options.downloaded} checked={options.downloaded}
onChange={(c) => handleFilterChange('downloaded', c)} onChange={(c) => handleFilterChange('downloaded', c)}
/> />
<ThreeStateCheckboxInput
label={t('global.filter.label.bookmarked')}
checked={options.bookmarked}
onChange={(c) => handleFilterChange('bookmarked', c)}
/>
<FormLabel sx={{ mt: 2 }}>{t('global.filter.label.tracked')}</FormLabel> <FormLabel sx={{ mt: 2 }}>{t('global.filter.label.tracked')}</FormLabel>
{loggedInTrackers.map((tracker) => ( {loggedInTrackers.map((tracker) => (
<ThreeStateCheckboxInput <ThreeStateCheckboxInput

View File

@@ -35,6 +35,17 @@ const downloadedFilter = (downloaded: NullAndUndefined<boolean>, { downloadCount
} }
}; };
const bookmarkedFilter = (bookmarked: NullAndUndefined<boolean>, { bookmarkCount }: TManga): boolean => {
switch (bookmarked) {
case true:
return !!bookmarkCount && bookmarkCount >= 1;
case false:
return bookmarkCount === 0;
default:
return true;
}
};
const queryFilter = (query: NullAndUndefined<string>, { title }: TManga): boolean => { const queryFilter = (query: NullAndUndefined<string>, { title }: TManga): boolean => {
if (!query) return true; if (!query) return true;
return title.toLowerCase().includes(query.toLowerCase()); return title.toLowerCase().includes(query.toLowerCase());
@@ -68,6 +79,7 @@ const filterManga = (
query: NullAndUndefined<string>, query: NullAndUndefined<string>,
unread: NullAndUndefined<boolean>, unread: NullAndUndefined<boolean>,
downloaded: NullAndUndefined<boolean>, downloaded: NullAndUndefined<boolean>,
bookmarked: NullAndUndefined<boolean>,
tracker: LibraryOptions['tracker'], tracker: LibraryOptions['tracker'],
ignoreFilters: boolean, ignoreFilters: boolean,
): TManga[] => ): TManga[] =>
@@ -76,7 +88,10 @@ const filterManga = (
const matchesSearch = queryFilter(query, manga) || queryGenreFilter(query, manga); const matchesSearch = queryFilter(query, manga) || queryGenreFilter(query, manga);
const matchesFilters = const matchesFilters =
ignoreFiltersWhileSearching || ignoreFiltersWhileSearching ||
(downloadedFilter(downloaded, manga) && unreadFilter(unread, manga) && trackerFilter(tracker, manga)); (downloadedFilter(downloaded, manga) &&
unreadFilter(unread, manga) &&
bookmarkedFilter(bookmarked, manga) &&
trackerFilter(tracker, manga));
return matchesSearch && matchesFilters; return matchesSearch && matchesFilters;
}); });
@@ -136,12 +151,12 @@ const sortManga = (
export const useGetVisibleLibraryMangas = (mangas: TManga[]) => { export const useGetVisibleLibraryMangas = (mangas: TManga[]) => {
const [query] = useQueryParam('query', StringParam); const [query] = useQueryParam('query', StringParam);
const { options } = useLibraryOptionsContext(); const { options } = useLibraryOptionsContext();
const { unread, downloaded, tracker } = options; const { unread, downloaded, bookmarked, tracker } = options;
const { settings } = useMetadataServerSettings(); const { settings } = useMetadataServerSettings();
const filteredMangas = useMemo( const filteredMangas = useMemo(
() => filterManga(mangas, query, unread, downloaded, tracker, settings.ignoreFilters), () => filterManga(mangas, query, unread, downloaded, bookmarked, tracker, settings.ignoreFilters),
[mangas, query, unread, downloaded, tracker, settings.ignoreFilters], [mangas, query, unread, downloaded, bookmarked, tracker, settings.ignoreFilters],
); );
const sortedMangas = useMemo( const sortedMangas = useMemo(
() => sortManga(filteredMangas, options.sorts, options.sortDesc), () => sortManga(filteredMangas, options.sorts, options.sortDesc),
@@ -150,7 +165,7 @@ export const useGetVisibleLibraryMangas = (mangas: TManga[]) => {
const isATrackFilterActive = Object.values(options.tracker).some((trackFilterState) => trackFilterState != null); const isATrackFilterActive = Object.values(options.tracker).some((trackFilterState) => trackFilterState != null);
const showFilteredOutMessage = const showFilteredOutMessage =
(unread != null || downloaded != null || !!query || isATrackFilterActive) && (unread != null || downloaded != null || bookmarked != null || !!query || isATrackFilterActive) &&
filteredMangas.length === 0 && filteredMangas.length === 0 &&
mangas.length > 0; mangas.length > 0;

View File

@@ -291,6 +291,7 @@ export const PARTIAL_MANGA_FIELDS = gql`
...BASE_MANGA_FIELDS ...BASE_MANGA_FIELDS
unreadCount unreadCount
downloadCount downloadCount
bookmarkCount
categories { categories {
nodes { nodes {
...FULL_CATEGORY_FIELDS ...FULL_CATEGORY_FIELDS

File diff suppressed because one or more lines are too long

View File

@@ -117,6 +117,10 @@ export const UPDATE_CHAPTER = gql`
id id
} }
} }
manga @include(if: $getBookmarked) {
id
bookmarkCount
}
} }
} }
deleteDownloadedChapter(input: { id: $chapterIdToDelete }) @include(if: $deleteChapter) { deleteDownloadedChapter(input: { id: $chapterIdToDelete }) @include(if: $deleteChapter) {
@@ -163,6 +167,10 @@ export const UPDATE_CHAPTERS = gql`
id id
} }
} }
manga @include(if: $getBookmarked) {
id
bookmarkCount
}
} }
} }
deleteDownloadedChapters(input: { ids: $chapterIdsToDelete }) @include(if: $deleteChapters) { deleteDownloadedChapters(input: { ids: $chapterIdsToDelete }) @include(if: $deleteChapters) {

View File

@@ -101,7 +101,10 @@ export interface IMangaCard {
export type TManga = GetMangaQuery['manga']; export type TManga = GetMangaQuery['manga'];
export type TPartialManga = OptionalProperty<TManga, 'unreadCount' | 'downloadCount' | 'categories' | 'chapters'>; export type TPartialManga = OptionalProperty<
TManga,
'unreadCount' | 'downloadCount' | 'bookmarkCount' | 'categories' | 'chapters'
>;
export interface IManga { export interface IManga {
id: number; id: number;
@@ -388,6 +391,7 @@ export interface LibraryOptions {
// filter options // filter options
downloaded: NullAndUndefined<boolean>; downloaded: NullAndUndefined<boolean>;
bookmarked: NullAndUndefined<boolean>;
unread: NullAndUndefined<boolean>; unread: NullAndUndefined<boolean>;
sorts: NullAndUndefined<LibrarySortMode>; sorts: NullAndUndefined<LibrarySortMode>;
sortDesc: NullAndUndefined<boolean>; sortDesc: NullAndUndefined<boolean>;