Files
suwayomi-material-you-webui/src/components/manga/util.tsx
T

117 lines
3.6 KiB
TypeScript
Raw Normal View History

2022-01-24 15:09:28 +05:30
/*
* 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/.
*/
2022-01-24 15:09:28 +05:30
2023-03-23 13:59:32 +01:00
import { t } from 'i18next';
import {
ChapterListOptions,
ChapterOptionsReducerAction,
ChapterSortMode,
NullAndUndefined,
TranslationKey,
2023-06-05 01:42:39 +02:00
} from '@/typings';
import { useReducerLocalStorage } from '@/util/useLocalStorage';
2023-09-30 16:55:35 +02:00
import { ChapterType } from '@/lib/graphql/generated/graphql.ts';
2022-11-09 18:09:15 +01:00
const defaultChapterOptions: ChapterListOptions = {
2022-01-24 15:09:28 +05:30
active: false,
unread: undefined,
downloaded: undefined,
bookmarked: undefined,
reverse: false,
sortBy: 'source',
showChapterNumber: false,
};
2023-02-08 18:19:26 +01:00
function chapterOptionsReducer(state: ChapterListOptions, actions: ChapterOptionsReducerAction): ChapterListOptions {
2022-01-24 15:09:28 +05:30
switch (actions.type) {
case 'filter':
return {
...state,
2023-05-11 18:00:37 +02:00
active: state.unread !== false && state.downloaded !== false && state.bookmarked !== false,
2022-01-24 15:09:28 +05:30
[actions.filterType!]: actions.filterValue,
};
case 'sortBy':
return { ...state, sortBy: actions.sortBy };
case 'sortReverse':
return { ...state, reverse: !state.reverse };
case 'showChapterNumber':
return { ...state, showChapterNumber: !state.showChapterNumber };
default:
2023-03-23 13:59:32 +01:00
throw Error(t('global.error.label.invalid_action'));
2022-01-24 15:09:28 +05:30
}
}
2023-09-30 16:55:35 +02:00
export function unreadFilter(unread: NullAndUndefined<boolean>, { isRead: isChapterRead }: ChapterType) {
2022-01-24 15:09:28 +05:30
switch (unread) {
case true:
return !isChapterRead;
case false:
return isChapterRead;
default:
return true;
}
}
2023-09-30 16:55:35 +02:00
function downloadFilter(downloaded: NullAndUndefined<boolean>, { isDownloaded: chapterDownload }: ChapterType) {
2022-01-24 15:09:28 +05:30
switch (downloaded) {
case true:
return chapterDownload;
case false:
return !chapterDownload;
default:
return true;
}
}
2023-09-30 16:55:35 +02:00
function bookmarkedFilter(bookmarked: NullAndUndefined<boolean>, { isBookmarked: chapterBookmarked }: ChapterType) {
2022-01-24 15:09:28 +05:30
switch (bookmarked) {
case true:
return chapterBookmarked;
case false:
return !chapterBookmarked;
default:
return true;
}
}
2023-09-30 16:55:35 +02:00
export function filterAndSortChapters(chapters: ChapterType[], options: ChapterListOptions): ChapterType[] {
2022-01-24 15:09:28 +05:30
const filtered = options.active
2023-02-06 10:06:33 +01:00
? chapters.filter(
(chp) =>
unreadFilter(options.unread, chp) &&
downloadFilter(options.downloaded, chp) &&
bookmarkedFilter(options.bookmarked, chp),
)
2022-01-24 15:09:28 +05:30
: [...chapters];
2023-09-30 16:55:35 +02:00
const Sorted =
options.sortBy === 'fetchedAt'
? filtered.sort((a, b) => Number(a.fetchedAt ?? 0) - Number(b.fetchedAt ?? 0))
: filtered;
2022-01-24 15:09:28 +05:30
if (options.reverse) {
Sorted.reverse();
}
return Sorted;
}
2023-09-30 16:55:35 +02:00
export const useChapterOptions = (mangaId: number) =>
2023-02-06 10:06:33 +01:00
useReducerLocalStorage<ChapterListOptions, ChapterOptionsReducerAction>(
chapterOptionsReducer,
`${mangaId}filterOptions`,
defaultChapterOptions,
);
2022-11-09 18:09:15 +01:00
2023-03-23 13:59:32 +01:00
export const SORT_OPTIONS: [ChapterSortMode, TranslationKey][] = [
['source', 'global.sort.label.by_source'],
['fetchedAt', 'global.sort.label.by_fetch_date'],
2022-11-09 18:09:15 +01:00
];
export const isFilterActive = (options: ChapterListOptions) => {
const { unread, downloaded, bookmarked } = options;
return unread != null || downloaded != null || bookmarked != null;
};