Add bookmarked filter in library (#687)
This commit is contained in:
@@ -28,6 +28,7 @@ export const DefaultLibraryOptions: LibraryOptions = {
|
||||
SourcegridLayout: GridLayout.Compact,
|
||||
|
||||
downloaded: undefined,
|
||||
bookmarked: undefined,
|
||||
sortDesc: undefined,
|
||||
sorts: undefined,
|
||||
unread: undefined,
|
||||
|
||||
@@ -70,6 +70,11 @@ export const LibraryOptionsPanel: React.FC<IProps> = ({ open, onClose }) => {
|
||||
checked={options.downloaded}
|
||||
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>
|
||||
{loggedInTrackers.map((tracker) => (
|
||||
<ThreeStateCheckboxInput
|
||||
|
||||
@@ -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 => {
|
||||
if (!query) return true;
|
||||
return title.toLowerCase().includes(query.toLowerCase());
|
||||
@@ -68,6 +79,7 @@ const filterManga = (
|
||||
query: NullAndUndefined<string>,
|
||||
unread: NullAndUndefined<boolean>,
|
||||
downloaded: NullAndUndefined<boolean>,
|
||||
bookmarked: NullAndUndefined<boolean>,
|
||||
tracker: LibraryOptions['tracker'],
|
||||
ignoreFilters: boolean,
|
||||
): TManga[] =>
|
||||
@@ -76,7 +88,10 @@ const filterManga = (
|
||||
const matchesSearch = queryFilter(query, manga) || queryGenreFilter(query, manga);
|
||||
const matchesFilters =
|
||||
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;
|
||||
});
|
||||
@@ -136,12 +151,12 @@ const sortManga = (
|
||||
export const useGetVisibleLibraryMangas = (mangas: TManga[]) => {
|
||||
const [query] = useQueryParam('query', StringParam);
|
||||
const { options } = useLibraryOptionsContext();
|
||||
const { unread, downloaded, tracker } = options;
|
||||
const { unread, downloaded, bookmarked, tracker } = options;
|
||||
const { settings } = useMetadataServerSettings();
|
||||
|
||||
const filteredMangas = useMemo(
|
||||
() => filterManga(mangas, query, unread, downloaded, tracker, settings.ignoreFilters),
|
||||
[mangas, query, unread, downloaded, tracker, settings.ignoreFilters],
|
||||
() => filterManga(mangas, query, unread, downloaded, bookmarked, tracker, settings.ignoreFilters),
|
||||
[mangas, query, unread, downloaded, bookmarked, tracker, settings.ignoreFilters],
|
||||
);
|
||||
const sortedMangas = useMemo(
|
||||
() => 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 showFilteredOutMessage =
|
||||
(unread != null || downloaded != null || !!query || isATrackFilterActive) &&
|
||||
(unread != null || downloaded != null || bookmarked != null || !!query || isATrackFilterActive) &&
|
||||
filteredMangas.length === 0 &&
|
||||
mangas.length > 0;
|
||||
|
||||
|
||||
@@ -291,6 +291,7 @@ export const PARTIAL_MANGA_FIELDS = gql`
|
||||
...BASE_MANGA_FIELDS
|
||||
unreadCount
|
||||
downloadCount
|
||||
bookmarkCount
|
||||
categories {
|
||||
nodes {
|
||||
...FULL_CATEGORY_FIELDS
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -117,6 +117,10 @@ export const UPDATE_CHAPTER = gql`
|
||||
id
|
||||
}
|
||||
}
|
||||
manga @include(if: $getBookmarked) {
|
||||
id
|
||||
bookmarkCount
|
||||
}
|
||||
}
|
||||
}
|
||||
deleteDownloadedChapter(input: { id: $chapterIdToDelete }) @include(if: $deleteChapter) {
|
||||
@@ -163,6 +167,10 @@ export const UPDATE_CHAPTERS = gql`
|
||||
id
|
||||
}
|
||||
}
|
||||
manga @include(if: $getBookmarked) {
|
||||
id
|
||||
bookmarkCount
|
||||
}
|
||||
}
|
||||
}
|
||||
deleteDownloadedChapters(input: { ids: $chapterIdsToDelete }) @include(if: $deleteChapters) {
|
||||
|
||||
@@ -101,7 +101,10 @@ export interface IMangaCard {
|
||||
|
||||
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 {
|
||||
id: number;
|
||||
@@ -388,6 +391,7 @@ export interface LibraryOptions {
|
||||
|
||||
// filter options
|
||||
downloaded: NullAndUndefined<boolean>;
|
||||
bookmarked: NullAndUndefined<boolean>;
|
||||
unread: NullAndUndefined<boolean>;
|
||||
sorts: NullAndUndefined<LibrarySortMode>;
|
||||
sortDesc: NullAndUndefined<boolean>;
|
||||
|
||||
Reference in New Issue
Block a user