Reduce code duplication for Library filtering and sorting

This commit is contained in:
schroda
2024-05-03 17:01:04 +02:00
parent 3efb2662de
commit c29173681f

View File

@@ -13,38 +13,27 @@ import { useLibraryOptionsContext } from '@/components/context/LibraryOptionsCon
import { useMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts'; import { useMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
import { Trackers } from '@/lib/data/Trackers.ts'; import { Trackers } from '@/lib/data/Trackers.ts';
const unreadFilter = (unread: NullAndUndefined<boolean>, { unreadCount }: TManga): boolean => { const triStateFilter = (
switch (unread) { triState: NullAndUndefined<boolean>,
enabledFilter: () => boolean,
disabledFilter: () => boolean,
): boolean => {
switch (triState) {
case true: case true:
return !!unreadCount && unreadCount >= 1; return enabledFilter();
case false: case false:
return unreadCount === 0; return disabledFilter();
default: default:
return true; return true;
} }
}; };
const downloadedFilter = (downloaded: NullAndUndefined<boolean>, { downloadCount }: TManga): boolean => { const triStateFilterNumber = (triState: NullAndUndefined<boolean>, count?: number): boolean =>
switch (downloaded) { triStateFilter(
case true: triState,
return !!downloadCount && downloadCount >= 1; () => !!count && count >= 1,
case false: () => count === 0,
return downloadCount === 0; );
default:
return true;
}
};
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;
@@ -63,14 +52,11 @@ const trackerFilter = (trackFilters: LibraryOptions['tracker'], manga: TManga):
const mangaTrackers = Trackers.getTrackers(manga.trackRecords.nodes); const mangaTrackers = Trackers.getTrackers(manga.trackRecords.nodes);
const isTrackerBound = mangaTrackers.some((tracker) => tracker.id === Number(trackFilterId)); const isTrackerBound = mangaTrackers.some((tracker) => tracker.id === Number(trackFilterId));
switch (trackFilterState) { return triStateFilter(
case true: trackFilterState,
return isTrackerBound; () => isTrackerBound,
case false: () => !isTrackerBound,
return !isTrackerBound; );
default:
return true;
}
}) })
.every((matchesFilter) => matchesFilter); .every((matchesFilter) => matchesFilter);
@@ -88,28 +74,17 @@ 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) && (triStateFilterNumber(downloaded, manga.downloadCount) &&
unreadFilter(unread, manga) && triStateFilterNumber(unread, manga.unreadCount) &&
bookmarkedFilter(bookmarked, manga) && triStateFilterNumber(bookmarked, manga.bookmarkCount) &&
trackerFilter(tracker, manga)); trackerFilter(tracker, manga));
return matchesSearch && matchesFilters; return matchesSearch && matchesFilters;
}); });
const sortByUnread = (a: TManga, b: TManga): number => (a.unreadCount ?? 0) - (b.unreadCount ?? 0); const sortByNumber = (a: number | string = 0, b: number | string = 0) => Number(a) - Number(b);
const sortByTitle = (a: TManga, b: TManga): number => a.title.localeCompare(b.title); const sortByString = (a: string, b: string): number => a.localeCompare(b);
const sortByDateAdded = (a: TManga, b: TManga): number => Number(a.inLibraryAt) - Number(b.inLibraryAt);
const sortByLastRead = (a: TManga, b: TManga): number =>
Number(b.lastReadChapter?.lastReadAt ?? 0) - Number(a.lastReadChapter?.lastReadAt ?? 0);
const sortByLatestUploadedChapter = (a: TManga, b: TManga): number =>
Number(a.latestUploadedChapter?.uploadDate ?? 0) - Number(b.latestUploadedChapter?.uploadDate ?? 0);
const sortByLatestFetchedChapter = (a: TManga, b: TManga): number =>
Number(a.latestFetchedChapter?.fetchedAt ?? 0) - Number(b.latestFetchedChapter?.fetchedAt ?? 0);
const sortManga = ( const sortManga = (
manga: TManga[], manga: TManga[],
@@ -120,28 +95,30 @@ const sortManga = (
switch (sort) { switch (sort) {
case 'sortAlph': case 'sortAlph':
result.sort(sortByTitle); result.sort((a, b) => sortByString(a.title, b.title));
break; break;
case 'sortDateAdded': case 'sortDateAdded':
result.sort(sortByDateAdded); result.sort((a, b) => sortByNumber(a.inLibraryAt, b.inLibraryAt));
break; break;
case 'sortToRead': case 'sortToRead':
result.sort(sortByUnread); result.sort((a, b) => sortByNumber(a.unreadCount, b.unreadCount));
break; break;
case 'sortLastRead': case 'sortLastRead':
result.sort(sortByLastRead); result.sort((a, b) => sortByNumber(a.lastReadChapter?.lastReadAt, b.lastReadChapter?.lastReadAt));
break; break;
case 'sortLatestUploadedChapter': case 'sortLatestUploadedChapter':
result.sort(sortByLatestUploadedChapter); result.sort((a, b) =>
sortByNumber(a.latestUploadedChapter?.uploadDate, b.latestUploadedChapter?.uploadDate),
);
break; break;
case 'sortLatestFetchedChapter': case 'sortLatestFetchedChapter':
result.sort(sortByLatestFetchedChapter); result.sort((a, b) => sortByNumber(a.latestFetchedChapter?.fetchedAt, b.latestFetchedChapter?.fetchedAt));
break; break;
default: default:
break; break;
} }
if (desc === true) { if (desc) {
result.reverse(); result.reverse();
} }