Move chapter files into new folder
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
yarn lint-staged
|
|
||||||
@@ -37,7 +37,7 @@ import {
|
|||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { TrackManga } from '@/components/tracker/TrackManga.tsx';
|
import { TrackManga } from '@/components/tracker/TrackManga.tsx';
|
||||||
import { useCategorySelect } from '@/components/navbar/action/useCategorySelect.tsx';
|
import { useCategorySelect } from '@/components/navbar/action/useCategorySelect.tsx';
|
||||||
import { ChaptersDownloadActionMenuItems } from '@/components/chapter/ChaptersDownloadActionMenuItems.tsx';
|
import { ChaptersDownloadActionMenuItems } from '@/modules/chapter/components/actions/ChaptersDownloadActionMenuItems.tsx';
|
||||||
import { NestedMenuItem } from '@/modules/core/components/menu/NestedMenuItem.tsx';
|
import { NestedMenuItem } from '@/modules/core/components/menu/NestedMenuItem.tsx';
|
||||||
import { MangaChapterStatFieldsFragment, MangaType } from '@/lib/graphql/generated/graphql.ts';
|
import { MangaChapterStatFieldsFragment, MangaType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import {
|
|||||||
TrackRecordType,
|
TrackRecordType,
|
||||||
UpdateMangaCategoriesPatchInput,
|
UpdateMangaCategoriesPatchInput,
|
||||||
} from '@/lib/graphql/generated/graphql.ts';
|
} from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { Chapters } from '@/lib/data/Chapters.ts';
|
import { Chapters } from '@/modules/chapter/services/Chapters.ts';
|
||||||
import { makeToast } from '@/lib/ui/Toast.ts';
|
import { makeToast } from '@/lib/ui/Toast.ts';
|
||||||
import { getMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
|
import { getMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
|
||||||
import { GET_MANGAS_BASE } from '@/lib/graphql/queries/MangaQuery.ts';
|
import { GET_MANGAS_BASE } from '@/lib/graphql/queries/MangaQuery.ts';
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { requestManager } from '@/lib/requests/requests/RequestManager.ts';
|
|||||||
import { MetaType, SourceType } from '@/lib/graphql/generated/graphql.ts';
|
import { MetaType, SourceType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { DEFAULT_DEVICE, getActiveDevice } from '@/util/device.ts';
|
import { DEFAULT_DEVICE, getActiveDevice } from '@/util/device.ts';
|
||||||
import { CategoryIdInfo } from '@/lib/data/Categories.ts';
|
import { CategoryIdInfo } from '@/lib/data/Categories.ts';
|
||||||
import { ChapterIdInfo } from '@/lib/data/Chapters.ts';
|
import { ChapterIdInfo } from '@/modules/chapter/services/Chapters.ts';
|
||||||
import { MangaIdInfo } from '@/lib/data/Mangas.ts';
|
import { MangaIdInfo } from '@/lib/data/Mangas.ts';
|
||||||
|
|
||||||
const APP_METADATA_KEY_PREFIX = 'webUI_';
|
const APP_METADATA_KEY_PREFIX = 'webUI_';
|
||||||
|
|||||||
27
src/modules/chapter/Chapter.constants.ts
Normal file
27
src/modules/chapter/Chapter.constants.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { TranslationKey } from '@/Base.types.ts';
|
||||||
|
import { ChapterListOptions, ChapterSortMode } from '@/modules/chapter/Chapter.types.ts';
|
||||||
|
|
||||||
|
export const DEFAULT_CHAPTER_OPTIONS: ChapterListOptions = {
|
||||||
|
active: false,
|
||||||
|
unread: undefined,
|
||||||
|
downloaded: undefined,
|
||||||
|
bookmarked: undefined,
|
||||||
|
reverse: true,
|
||||||
|
sortBy: 'source',
|
||||||
|
showChapterNumber: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CHAPTER_SORT_OPTIONS_TO_TRANSLATION_KEY: Record<ChapterSortMode, TranslationKey> = {
|
||||||
|
source: 'global.sort.label.by_source',
|
||||||
|
chapterNumber: 'global.sort.label.by_chapter_number',
|
||||||
|
uploadedAt: 'global.sort.label.by_upload_date',
|
||||||
|
fetchedAt: 'global.sort.label.by_fetch_date',
|
||||||
|
};
|
||||||
27
src/modules/chapter/Chapter.types.ts
Normal file
27
src/modules/chapter/Chapter.types.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NullAndUndefined } from '@/Base.types.ts';
|
||||||
|
|
||||||
|
export type ChapterSortMode = 'fetchedAt' | 'source' | 'chapterNumber' | 'uploadedAt';
|
||||||
|
|
||||||
|
export interface ChapterListOptions {
|
||||||
|
active: boolean;
|
||||||
|
unread: NullAndUndefined<boolean>;
|
||||||
|
downloaded: NullAndUndefined<boolean>;
|
||||||
|
bookmarked: NullAndUndefined<boolean>;
|
||||||
|
reverse: boolean;
|
||||||
|
sortBy: ChapterSortMode;
|
||||||
|
showChapterNumber: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ChapterOptionsReducerAction =
|
||||||
|
| { type: 'filter'; filterType: string; filterValue: NullAndUndefined<boolean> }
|
||||||
|
| { type: 'sortBy'; sortBy: ChapterSortMode }
|
||||||
|
| { type: 'sortReverse' }
|
||||||
|
| { type: 'showChapterNumber' };
|
||||||
@@ -20,11 +20,11 @@ import DoneAllIcon from '@mui/icons-material/DoneAll';
|
|||||||
import PopupState, { bindMenu, bindTrigger } from 'material-ui-popup-state';
|
import PopupState, { bindMenu, bindTrigger } from 'material-ui-popup-state';
|
||||||
import Menu from '@mui/material/Menu';
|
import Menu from '@mui/material/Menu';
|
||||||
import { requestManager } from '@/lib/requests/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/requests/RequestManager.ts';
|
||||||
import { ChapterCard } from '@/components/chapter/ChapterCard.tsx';
|
import { ChapterCard } from '@/modules/chapter/components/cards/ChapterCard.tsx';
|
||||||
import { ResumeFab } from '@/components/manga/ResumeFAB.tsx';
|
import { ResumeFab } from '@/components/manga/ResumeFAB.tsx';
|
||||||
import { filterAndSortChapters, useChapterOptions } from '@/components/chapter/util.tsx';
|
import { filterAndSortChapters } from '@/modules/chapter/utils/ChapterList.util.tsx';
|
||||||
import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder/EmptyViewAbsoluteCentered.tsx';
|
import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder/EmptyViewAbsoluteCentered.tsx';
|
||||||
import { ChaptersToolbarMenu } from '@/components/chapter/ChaptersToolbarMenu.tsx';
|
import { ChaptersToolbarMenu } from '@/modules/chapter/components/ChaptersToolbarMenu.tsx';
|
||||||
import { SelectionFAB } from '@/components/collection/SelectionFAB.tsx';
|
import { SelectionFAB } from '@/components/collection/SelectionFAB.tsx';
|
||||||
import { DEFAULT_FULL_FAB_HEIGHT } from '@/modules/core/components/buttons/StyledFab.tsx';
|
import { DEFAULT_FULL_FAB_HEIGHT } from '@/modules/core/components/buttons/StyledFab.tsx';
|
||||||
import {
|
import {
|
||||||
@@ -34,18 +34,19 @@ import {
|
|||||||
} from '@/lib/graphql/generated/graphql.ts';
|
} from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { useSelectableCollection } from '@/components/collection/useSelectableCollection.ts';
|
import { useSelectableCollection } from '@/components/collection/useSelectableCollection.ts';
|
||||||
import { SelectableCollectionSelectAll } from '@/components/collection/SelectableCollectionSelectAll.tsx';
|
import { SelectableCollectionSelectAll } from '@/components/collection/SelectableCollectionSelectAll.tsx';
|
||||||
import { Chapters } from '@/lib/data/Chapters.ts';
|
import { Chapters } from '@/modules/chapter/services/Chapters.ts';
|
||||||
import { ChaptersWithMeta, ChapterWithMetaType } from '@/lib/data/ChaptersWithMeta.ts';
|
import { ChaptersWithMeta, ChapterWithMetaType } from '@/modules/chapter/services/ChaptersWithMeta.ts';
|
||||||
import { ChapterActionMenuItems } from '@/components/chapter/ChapterActionMenuItems.tsx';
|
import { ChapterActionMenuItems } from '@/modules/chapter/components/actions/ChapterActionMenuItems.tsx';
|
||||||
import { ChaptersDownloadActionMenuItems } from '@/components/chapter/ChaptersDownloadActionMenuItems.tsx';
|
import { ChaptersDownloadActionMenuItems } from '@/modules/chapter/components/actions/ChaptersDownloadActionMenuItems.tsx';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { LoadingPlaceholder } from '@/modules/core/components/placeholder/LoadingPlaceholder.tsx';
|
import { LoadingPlaceholder } from '@/modules/core/components/placeholder/LoadingPlaceholder.tsx';
|
||||||
import { GET_CHAPTERS_MANGA } from '@/lib/graphql/queries/ChapterQuery.ts';
|
import { GET_CHAPTERS_MANGA } from '@/lib/graphql/queries/ChapterQuery.ts';
|
||||||
import { Mangas } from '@/lib/data/Mangas';
|
import { Mangas } from '@/lib/data/Mangas.ts';
|
||||||
import { useNavBarContext } from '@/components/context/NavbarContext.tsx';
|
import { useNavBarContext } from '@/components/context/NavbarContext.tsx';
|
||||||
import { useResizeObserver } from '@/modules/core/hooks/useResizeObserver.tsx';
|
import { useResizeObserver } from '@/modules/core/hooks/useResizeObserver.tsx';
|
||||||
import { MediaQuery } from '@/lib/ui/MediaQuery.tsx';
|
import { MediaQuery } from '@/lib/ui/MediaQuery.tsx';
|
||||||
import { shouldForwardProp } from '@/modules/core/utils/ShouldForwardProp.ts';
|
import { shouldForwardProp } from '@/modules/core/utils/ShouldForwardProp.ts';
|
||||||
|
import { useChapterOptions } from '@/modules/chapter/hooks/useChapterOptions.tsx';
|
||||||
|
|
||||||
type ChapterListHeaderProps = {
|
type ChapterListHeaderProps = {
|
||||||
scrollbarWidth: number;
|
scrollbarWidth: number;
|
||||||
@@ -9,13 +9,13 @@
|
|||||||
import RadioGroup from '@mui/material/RadioGroup';
|
import RadioGroup from '@mui/material/RadioGroup';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ChapterListOptions, ChapterOptionsReducerAction } from '@/typings.ts';
|
|
||||||
import { RadioInput } from '@/modules/core/components/inputs/RadioInput.tsx';
|
import { RadioInput } from '@/modules/core/components/inputs/RadioInput.tsx';
|
||||||
import { SortRadioInput } from '@/modules/core/components/inputs/SortRadioInput.tsx';
|
import { SortRadioInput } from '@/modules/core/components/inputs/SortRadioInput.tsx';
|
||||||
import { ThreeStateCheckboxInput } from '@/modules/core/components/inputs/ThreeStateCheckboxInput.tsx';
|
import { ThreeStateCheckboxInput } from '@/modules/core/components/inputs/ThreeStateCheckboxInput.tsx';
|
||||||
import { OptionsTabs } from '@/modules/core/components/OptionsTabs.tsx';
|
import { OptionsTabs } from '@/modules/core/components/OptionsTabs.tsx';
|
||||||
import { SORT_OPTIONS } from '@/components/chapter/util.tsx';
|
import { CHAPTER_SORT_OPTIONS_TO_TRANSLATION_KEY } from '@/modules/chapter/Chapter.constants.ts';
|
||||||
import { TranslationKey } from '@/Base.types.ts';
|
import { TranslationKey } from '@/Base.types.ts';
|
||||||
|
import { ChapterListOptions, ChapterOptionsReducerAction } from '@/modules/chapter/Chapter.types.ts';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -81,7 +81,7 @@ export const ChapterOptions: React.FC<IProps> = ({ open, onClose, options, optio
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (key === 'sort') {
|
if (key === 'sort') {
|
||||||
return Object.entries(SORT_OPTIONS).map(([mode, label]) => (
|
return Object.entries(CHAPTER_SORT_OPTIONS_TO_TRANSLATION_KEY).map(([mode, label]) => (
|
||||||
<SortRadioInput
|
<SortRadioInput
|
||||||
key={mode}
|
key={mode}
|
||||||
label={t(label)}
|
label={t(label)}
|
||||||
@@ -89,7 +89,10 @@ export const ChapterOptions: React.FC<IProps> = ({ open, onClose, options, optio
|
|||||||
sortDescending={options.reverse}
|
sortDescending={options.reverse}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
mode !== options.sortBy
|
mode !== options.sortBy
|
||||||
? optionsDispatch({ type: 'sortBy', sortBy: mode as keyof typeof SORT_OPTIONS })
|
? optionsDispatch({
|
||||||
|
type: 'sortBy',
|
||||||
|
sortBy: mode as keyof typeof CHAPTER_SORT_OPTIONS_TO_TRANSLATION_KEY,
|
||||||
|
})
|
||||||
: optionsDispatch({ type: 'sortReverse' })
|
: optionsDispatch({ type: 'sortReverse' })
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@@ -11,9 +11,9 @@ import IconButton from '@mui/material/IconButton';
|
|||||||
import Tooltip from '@mui/material/Tooltip';
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ChapterListOptions, ChapterOptionsReducerAction } from '@/typings.ts';
|
import { ChapterOptions } from '@/modules/chapter/components/ChapterOptions.tsx';
|
||||||
import { ChapterOptions } from '@/components/chapter/ChapterOptions.tsx';
|
import { isFilterActive } from '@/modules/chapter/utils/ChapterList.util.tsx';
|
||||||
import { isFilterActive } from '@/components/chapter/util.tsx';
|
import { ChapterListOptions, ChapterOptionsReducerAction } from '@/modules/chapter/Chapter.types.ts';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
options: ChapterListOptions;
|
options: ChapterListOptions;
|
||||||
@@ -28,10 +28,10 @@ import {
|
|||||||
ChapterReadInfo,
|
ChapterReadInfo,
|
||||||
ChapterRealUrlInfo,
|
ChapterRealUrlInfo,
|
||||||
Chapters,
|
Chapters,
|
||||||
} from '@/lib/data/Chapters.ts';
|
} from '@/modules/chapter/services/Chapters.ts';
|
||||||
import { MenuItem } from '@/modules/core/components/menu/MenuItem.tsx';
|
import { MenuItem } from '@/modules/core/components/menu/MenuItem.tsx';
|
||||||
import { IChapterWithMeta } from '@/components/chapter/ChapterList.tsx';
|
import { IChapterWithMeta } from '@/modules/chapter/components/ChapterList.tsx';
|
||||||
import { ChaptersWithMeta } from '@/lib/data/ChaptersWithMeta.ts';
|
import { ChaptersWithMeta } from '@/modules/chapter/services/ChaptersWithMeta.ts';
|
||||||
import {
|
import {
|
||||||
createGetMenuItemTitle,
|
createGetMenuItemTitle,
|
||||||
createIsMenuItemDisabled,
|
createIsMenuItemDisabled,
|
||||||
@@ -25,7 +25,7 @@ import { useLongPress } from 'use-long-press';
|
|||||||
import { getDateString } from '@/util/DateHelper.ts';
|
import { getDateString } from '@/util/DateHelper.ts';
|
||||||
import { DownloadStateIndicator } from '@/modules/core/components/DownloadStateIndicator.tsx';
|
import { DownloadStateIndicator } from '@/modules/core/components/DownloadStateIndicator.tsx';
|
||||||
import { ChapterType } from '@/lib/graphql/generated/graphql.ts';
|
import { ChapterType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { ChapterActionMenuItems } from '@/components/chapter/ChapterActionMenuItems.tsx';
|
import { ChapterActionMenuItems } from '@/modules/chapter/components/actions/ChapterActionMenuItems.tsx';
|
||||||
import { Menu } from '@/modules/core/components/menu/Menu.tsx';
|
import { Menu } from '@/modules/core/components/menu/Menu.tsx';
|
||||||
import { TypographyMaxLines } from '@/modules/core/components/TypographyMaxLines.tsx';
|
import { TypographyMaxLines } from '@/modules/core/components/TypographyMaxLines.tsx';
|
||||||
import {
|
import {
|
||||||
@@ -37,8 +37,8 @@ import {
|
|||||||
ChapterNumberInfo,
|
ChapterNumberInfo,
|
||||||
ChapterReadInfo,
|
ChapterReadInfo,
|
||||||
ChapterScanlatorInfo,
|
ChapterScanlatorInfo,
|
||||||
} from '@/lib/data/Chapters.ts';
|
} from '@/modules/chapter/services/Chapters.ts';
|
||||||
import { ChaptersWithMeta } from '@/lib/data/ChaptersWithMeta.ts';
|
import { ChaptersWithMeta } from '@/modules/chapter/services/ChaptersWithMeta.ts';
|
||||||
|
|
||||||
type TChapter = ChapterIdInfo &
|
type TChapter = ChapterIdInfo &
|
||||||
ChapterMangaInfo &
|
ChapterMangaInfo &
|
||||||
38
src/modules/chapter/hooks/useChapterOptions.tsx
Normal file
38
src/modules/chapter/hooks/useChapterOptions.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { t } from 'i18next';
|
||||||
|
import { useReducerLocalStorage } from '@/modules/core/hooks/useStorage.tsx';
|
||||||
|
import { DEFAULT_CHAPTER_OPTIONS } from '@/modules/chapter/Chapter.constants.ts';
|
||||||
|
import { ChapterListOptions, ChapterOptionsReducerAction } from '@/modules/chapter/Chapter.types.ts';
|
||||||
|
|
||||||
|
function chapterOptionsReducer(state: ChapterListOptions, actions: ChapterOptionsReducerAction): ChapterListOptions {
|
||||||
|
switch (actions.type) {
|
||||||
|
case 'filter':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
active: state.unread !== false && state.downloaded !== false && state.bookmarked !== false,
|
||||||
|
[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:
|
||||||
|
throw Error(t('global.error.label.invalid_action'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useChapterOptions = (mangaId: number) =>
|
||||||
|
useReducerLocalStorage<ChapterListOptions, ChapterOptionsReducerAction>(
|
||||||
|
chapterOptionsReducer,
|
||||||
|
`${mangaId}filterOptions`,
|
||||||
|
DEFAULT_CHAPTER_OPTIONS,
|
||||||
|
);
|
||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
ChapterDownloadStatus,
|
ChapterDownloadStatus,
|
||||||
ChapterReadInfo,
|
ChapterReadInfo,
|
||||||
Chapters,
|
Chapters,
|
||||||
} from '@/lib/data/Chapters.ts';
|
} from '@/modules/chapter/services/Chapters.ts';
|
||||||
import { DownloadState } from '@/lib/graphql/generated/graphql.ts';
|
import { DownloadState } from '@/lib/graphql/generated/graphql.ts';
|
||||||
|
|
||||||
export type ChapterWithMetaType<
|
export type ChapterWithMetaType<
|
||||||
@@ -6,41 +6,10 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { t } from 'i18next';
|
import { ChapterBookmarkInfo, ChapterDownloadInfo, ChapterReadInfo } from '@/modules/chapter/services/Chapters.ts';
|
||||||
import { ChapterListOptions, ChapterOptionsReducerAction, ChapterSortMode } from '@/typings.ts';
|
|
||||||
import { useReducerLocalStorage } from '@/modules/core/hooks/useStorage.tsx';
|
|
||||||
import { ChapterBookmarkInfo, ChapterDownloadInfo, ChapterReadInfo } from '@/lib/data/Chapters.ts';
|
|
||||||
import { ChapterType } from '@/lib/graphql/generated/graphql.ts';
|
import { ChapterType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { NullAndUndefined, TranslationKey } from '@/Base.types.ts';
|
import { NullAndUndefined } from '@/Base.types.ts';
|
||||||
|
import { ChapterListOptions } from '@/modules/chapter/Chapter.types.ts';
|
||||||
const defaultChapterOptions: ChapterListOptions = {
|
|
||||||
active: false,
|
|
||||||
unread: undefined,
|
|
||||||
downloaded: undefined,
|
|
||||||
bookmarked: undefined,
|
|
||||||
reverse: true,
|
|
||||||
sortBy: 'source',
|
|
||||||
showChapterNumber: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
function chapterOptionsReducer(state: ChapterListOptions, actions: ChapterOptionsReducerAction): ChapterListOptions {
|
|
||||||
switch (actions.type) {
|
|
||||||
case 'filter':
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
active: state.unread !== false && state.downloaded !== false && state.bookmarked !== false,
|
|
||||||
[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:
|
|
||||||
throw Error(t('global.error.label.invalid_action'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function unreadFilter(unread: NullAndUndefined<boolean>, { isRead: isChapterRead }: ChapterReadInfo) {
|
export function unreadFilter(unread: NullAndUndefined<boolean>, { isRead: isChapterRead }: ChapterReadInfo) {
|
||||||
switch (unread) {
|
switch (unread) {
|
||||||
@@ -126,20 +95,6 @@ export function filterAndSortChapters<Chapters extends TChapterFilter>(
|
|||||||
return sortChapters(filtered, options);
|
return sortChapters(filtered, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useChapterOptions = (mangaId: number) =>
|
|
||||||
useReducerLocalStorage<ChapterListOptions, ChapterOptionsReducerAction>(
|
|
||||||
chapterOptionsReducer,
|
|
||||||
`${mangaId}filterOptions`,
|
|
||||||
defaultChapterOptions,
|
|
||||||
);
|
|
||||||
|
|
||||||
export const SORT_OPTIONS: Record<ChapterSortMode, TranslationKey> = {
|
|
||||||
source: 'global.sort.label.by_source',
|
|
||||||
chapterNumber: 'global.sort.label.by_chapter_number',
|
|
||||||
uploadedAt: 'global.sort.label.by_upload_date',
|
|
||||||
fetchedAt: 'global.sort.label.by_fetch_date',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const isFilterActive = (options: ChapterListOptions) => {
|
export const isFilterActive = (options: ChapterListOptions) => {
|
||||||
const { unread, downloaded, bookmarked } = options;
|
const { unread, downloaded, bookmarked } = options;
|
||||||
return unread != null || downloaded != null || bookmarked != null;
|
return unread != null || downloaded != null || bookmarked != null;
|
||||||
@@ -11,7 +11,7 @@ import Box from '@mui/material/Box';
|
|||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { DownloadState } from '@/lib/graphql/generated/graphql.ts';
|
import { DownloadState } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { ChapterDownloadStatus } from '@/lib/data/Chapters.ts';
|
import { ChapterDownloadStatus } from '@/modules/chapter/services/Chapters.ts';
|
||||||
import { TranslationKey } from '@/Base.types.ts';
|
import { TranslationKey } from '@/Base.types.ts';
|
||||||
|
|
||||||
const DOWNLOAD_STATE_TO_TRANSLATION_KEY_MAP: { [state in DownloadState]: TranslationKey } = {
|
const DOWNLOAD_STATE_TO_TRANSLATION_KEY_MAP: { [state in DownloadState]: TranslationKey } = {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder
|
|||||||
import { NavBarContext } from '@/components/context/NavbarContext.tsx';
|
import { NavBarContext } from '@/components/context/NavbarContext.tsx';
|
||||||
import { LoadingPlaceholder } from '@/modules/core/components/placeholder/LoadingPlaceholder.tsx';
|
import { LoadingPlaceholder } from '@/modules/core/components/placeholder/LoadingPlaceholder.tsx';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { ChapterDownloadStatus, ChapterIdInfo } from '@/lib/data/Chapters.ts';
|
import { ChapterDownloadStatus, ChapterIdInfo } from '@/modules/chapter/services/Chapters.ts';
|
||||||
import { DownloadState } from '@/lib/graphql/generated/graphql.ts';
|
import { DownloadState } from '@/lib/graphql/generated/graphql.ts';
|
||||||
|
|
||||||
const HeightPreservingItem = ({ children, ...props }: BoxProps) => (
|
const HeightPreservingItem = ({ children, ...props }: BoxProps) => (
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { useParams } from 'react-router-dom';
|
|||||||
import { isNetworkRequestInFlight } from '@apollo/client/core/networkStatus';
|
import { isNetworkRequestInFlight } from '@apollo/client/core/networkStatus';
|
||||||
import { requestManager } from '@/lib/requests/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/requests/RequestManager.ts';
|
||||||
import { NavBarContext } from '@/components/context/NavbarContext';
|
import { NavBarContext } from '@/components/context/NavbarContext';
|
||||||
import { ChapterList } from '@/components/chapter/ChapterList.tsx';
|
import { ChapterList } from '@/modules/chapter/components/ChapterList.tsx';
|
||||||
import { useRefreshManga } from '@/components/manga/useRefreshManga.ts';
|
import { useRefreshManga } from '@/components/manga/useRefreshManga.ts';
|
||||||
import { MangaDetails } from '@/components/manga/MangaDetails';
|
import { MangaDetails } from '@/components/manga/MangaDetails';
|
||||||
import { MangaToolbarMenu } from '@/components/manga/MangaToolbarMenu';
|
import { MangaToolbarMenu } from '@/components/manga/MangaToolbarMenu';
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import {
|
|||||||
} from '@/lib/graphql/generated/graphql.ts';
|
} from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { useMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
|
import { useMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { ChapterIdInfo, Chapters } from '@/lib/data/Chapters.ts';
|
import { ChapterIdInfo, Chapters } from '@/modules/chapter/services/Chapters.ts';
|
||||||
import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder/EmptyViewAbsoluteCentered.tsx';
|
import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder/EmptyViewAbsoluteCentered.tsx';
|
||||||
import { GET_CHAPTERS_READER } from '@/lib/graphql/queries/ChapterQuery.ts';
|
import { GET_CHAPTERS_READER } from '@/lib/graphql/queries/ChapterQuery.ts';
|
||||||
import { GET_MANGA_READER } from '@/lib/graphql/queries/MangaQuery.ts';
|
import { GET_MANGA_READER } from '@/lib/graphql/queries/MangaQuery.ts';
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import { SpinnerImage } from '@/modules/core/components/SpinnerImage.tsx';
|
|||||||
import { dateTimeFormatter, epochToDate, getDateString } from '@/util/DateHelper.ts';
|
import { dateTimeFormatter, epochToDate, getDateString } from '@/util/DateHelper.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { TypographyMaxLines } from '@/modules/core/components/TypographyMaxLines.tsx';
|
import { TypographyMaxLines } from '@/modules/core/components/TypographyMaxLines.tsx';
|
||||||
import { ChapterIdInfo, ChapterMangaInfo } from '@/lib/data/Chapters.ts';
|
import { ChapterIdInfo, ChapterMangaInfo } from '@/modules/chapter/services/Chapters.ts';
|
||||||
import { makeToast } from '@/lib/ui/Toast.ts';
|
import { makeToast } from '@/lib/ui/Toast.ts';
|
||||||
|
|
||||||
const groupByDate = (updates: Pick<ChapterType, 'fetchedAt'>[]): [date: string, items: number][] => {
|
const groupByDate = (updates: Pick<ChapterType, 'fetchedAt'>[]): [date: string, items: number][] => {
|
||||||
|
|||||||
@@ -227,24 +227,6 @@ export interface NavbarItem {
|
|||||||
show: 'mobile' | 'desktop' | 'both';
|
show: 'mobile' | 'desktop' | 'both';
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ChapterSortMode = 'fetchedAt' | 'source' | 'chapterNumber' | 'uploadedAt';
|
|
||||||
|
|
||||||
export interface ChapterListOptions {
|
|
||||||
active: boolean;
|
|
||||||
unread: NullAndUndefined<boolean>;
|
|
||||||
downloaded: NullAndUndefined<boolean>;
|
|
||||||
bookmarked: NullAndUndefined<boolean>;
|
|
||||||
reverse: boolean;
|
|
||||||
sortBy: ChapterSortMode;
|
|
||||||
showChapterNumber: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ChapterOptionsReducerAction =
|
|
||||||
| { type: 'filter'; filterType: string; filterValue: NullAndUndefined<boolean> }
|
|
||||||
| { type: 'sortBy'; sortBy: ChapterSortMode }
|
|
||||||
| { type: 'sortReverse' }
|
|
||||||
| { type: 'showChapterNumber' };
|
|
||||||
|
|
||||||
export type LibrarySortMode =
|
export type LibrarySortMode =
|
||||||
| 'unreadChapters'
|
| 'unreadChapters'
|
||||||
| 'totalChapters'
|
| 'totalChapters'
|
||||||
|
|||||||
Reference in New Issue
Block a user