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/. */
|
|
|
|
|
|
2023-03-23 13:59:32 +01:00
|
|
|
import { t } from 'i18next';
|
2022-11-09 18:09:15 +01:00
|
|
|
import { useReducerLocalStorage } from 'util/useLocalStorage';
|
2023-03-23 13:59:32 +01:00
|
|
|
import {
|
|
|
|
|
ChapterListOptions,
|
|
|
|
|
ChapterOptionsReducerAction,
|
|
|
|
|
ChapterSortMode,
|
|
|
|
|
IChapter,
|
|
|
|
|
NullAndUndefined,
|
|
|
|
|
TranslationKey,
|
|
|
|
|
} from 'typings';
|
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
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function unreadFilter(unread: NullAndUndefined<boolean>, { read: isChapterRead }: IChapter) {
|
|
|
|
|
switch (unread) {
|
|
|
|
|
case true:
|
|
|
|
|
return !isChapterRead;
|
|
|
|
|
case false:
|
|
|
|
|
return isChapterRead;
|
|
|
|
|
default:
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-08 18:19:26 +01:00
|
|
|
function downloadFilter(downloaded: NullAndUndefined<boolean>, { downloaded: chapterDownload }: IChapter) {
|
2022-01-24 15:09:28 +05:30
|
|
|
switch (downloaded) {
|
|
|
|
|
case true:
|
|
|
|
|
return chapterDownload;
|
|
|
|
|
case false:
|
|
|
|
|
return !chapterDownload;
|
|
|
|
|
default:
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-08 18:19:26 +01:00
|
|
|
function bookmarkedFilter(bookmarked: NullAndUndefined<boolean>, { bookmarked: chapterBookmarked }: IChapter) {
|
2022-01-24 15:09:28 +05:30
|
|
|
switch (bookmarked) {
|
|
|
|
|
case true:
|
|
|
|
|
return chapterBookmarked;
|
|
|
|
|
case false:
|
|
|
|
|
return !chapterBookmarked;
|
|
|
|
|
default:
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-08 18:19:26 +01:00
|
|
|
export function filterAndSortChapters(chapters: IChapter[], options: ChapterListOptions): IChapter[] {
|
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-02-08 18:19:26 +01:00
|
|
|
const Sorted = options.sortBy === 'fetchedAt' ? filtered.sort((a, b) => a.fetchedAt - b.fetchedAt) : filtered;
|
2022-01-24 15:09:28 +05:30
|
|
|
if (options.reverse) {
|
|
|
|
|
Sorted.reverse();
|
|
|
|
|
}
|
|
|
|
|
return Sorted;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-06 10:06:33 +01:00
|
|
|
export const useChapterOptions = (mangaId: string) =>
|
|
|
|
|
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;
|
|
|
|
|
};
|