Add track action to manga action menu in library
This commit is contained in:
@@ -17,6 +17,8 @@ import Label from '@mui/icons-material/Label';
|
|||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import SyncAltIcon from '@mui/icons-material/SyncAlt';
|
import SyncAltIcon from '@mui/icons-material/SyncAlt';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
import SyncIcon from '@mui/icons-material/Sync';
|
||||||
|
import { Dialog } from '@mui/material';
|
||||||
import { TManga } from '@/typings.ts';
|
import { TManga } from '@/typings.ts';
|
||||||
import { actionToTranslationKey, MangaAction, MangaDownloadInfo, Mangas, MangaUnreadInfo } from '@/lib/data/Mangas.ts';
|
import { actionToTranslationKey, MangaAction, MangaDownloadInfo, Mangas, MangaUnreadInfo } from '@/lib/data/Mangas.ts';
|
||||||
import { SelectableCollectionReturnType } from '@/components/collection/useSelectableCollection.ts';
|
import { SelectableCollectionReturnType } from '@/components/collection/useSelectableCollection.ts';
|
||||||
@@ -24,13 +26,14 @@ import { CategorySelect } from '@/components/navbar/action/CategorySelect.tsx';
|
|||||||
import { MenuItem } from '@/components/menu/MenuItem.tsx';
|
import { MenuItem } from '@/components/menu/MenuItem.tsx';
|
||||||
import { createGetMenuItemTitle, createIsMenuItemDisabled, createShouldShowMenuItem } from '@/components/menu/util.ts';
|
import { createGetMenuItemTitle, createIsMenuItemDisabled, createShouldShowMenuItem } from '@/components/menu/util.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
|
||||||
|
import { TrackManga } from '@/components/tracker/TrackManga.tsx';
|
||||||
|
|
||||||
const ACTION_DISABLES_SELECTION_MODE: MangaAction[] = ['remove_from_library'] as const;
|
const ACTION_DISABLES_SELECTION_MODE: MangaAction[] = ['remove_from_library'] as const;
|
||||||
|
|
||||||
type BaseProps = { onClose: (selectionModeState: boolean) => void; setHideMenu: (hide: boolean) => void };
|
type BaseProps = { onClose: (selectionModeState: boolean) => void; setHideMenu: (hide: boolean) => void };
|
||||||
|
|
||||||
export type SingleModeProps = {
|
export type SingleModeProps = {
|
||||||
manga: Pick<TManga, 'id' | 'title' | 'source'> & MangaDownloadInfo & MangaUnreadInfo;
|
manga: Pick<TManga, 'id' | 'title' | 'source' | 'trackRecords'> & MangaDownloadInfo & MangaUnreadInfo;
|
||||||
handleSelection?: SelectableCollectionReturnType<TManga['id']>['handleSelection'];
|
handleSelection?: SelectableCollectionReturnType<TManga['id']>['handleSelection'];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -52,6 +55,7 @@ export const MangaActionMenuItems = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const [isCategorySelectOpen, setIsCategorySelectOpen] = useState(false);
|
const [isCategorySelectOpen, setIsCategorySelectOpen] = useState(false);
|
||||||
|
const [isTrackDialogOpen, setIsTrackDialogOpen] = useState(false);
|
||||||
|
|
||||||
const isSingleMode = !!manga;
|
const isSingleMode = !!manga;
|
||||||
const selectedMangas = passedSelectedMangas ?? [];
|
const selectedMangas = passedSelectedMangas ?? [];
|
||||||
@@ -140,6 +144,16 @@ export const MangaActionMenuItems = ({
|
|||||||
<MenuItem Icon={SyncAltIcon} title={getMenuItemTitle('migrate', selectedMangas.length)} />
|
<MenuItem Icon={SyncAltIcon} title={getMenuItemTitle('migrate', selectedMangas.length)} />
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
|
{isSingleMode && (
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
setIsTrackDialogOpen(true);
|
||||||
|
setHideMenu(true);
|
||||||
|
}}
|
||||||
|
Icon={SyncIcon}
|
||||||
|
title={getMenuItemTitle('track', selectedMangas.length)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsCategorySelectOpen(true);
|
setIsCategorySelectOpen(true);
|
||||||
@@ -164,6 +178,20 @@ export const MangaActionMenuItems = ({
|
|||||||
mangaIds={(passedSelectedMangas ? Mangas.getIds(selectedMangas) : undefined) as number[]}
|
mangaIds={(passedSelectedMangas ? Mangas.getIds(selectedMangas) : undefined) as number[]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{isTrackDialogOpen && (
|
||||||
|
<Dialog
|
||||||
|
open
|
||||||
|
maxWidth="md"
|
||||||
|
fullWidth
|
||||||
|
scroll="paper"
|
||||||
|
onClose={() => {
|
||||||
|
setIsTrackDialogOpen(false);
|
||||||
|
onClose(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TrackManga manga={manga!} />
|
||||||
|
</Dialog>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ const getTrackerMode = (id: number, trackersInUse: number[], searchModeForTracke
|
|||||||
return TrackerMode.UNTRACKED;
|
return TrackerMode.UNTRACKED;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TrackManga = ({ manga }: { manga: TManga }) => {
|
export const TrackManga = ({ manga }: { manga: Pick<TManga, 'id' | 'trackRecords'> }) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [searchModeForTracker, setSearchModeForTracker] = useState<number>();
|
const [searchModeForTracker, setSearchModeForTracker] = useState<number>();
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ export type MangaAction =
|
|||||||
| 'mark_as_unread'
|
| 'mark_as_unread'
|
||||||
| 'remove_from_library'
|
| 'remove_from_library'
|
||||||
| 'change_categories'
|
| 'change_categories'
|
||||||
| 'migrate';
|
| 'migrate'
|
||||||
|
| 'track';
|
||||||
|
|
||||||
export const actionToTranslationKey: {
|
export const actionToTranslationKey: {
|
||||||
[key in MangaAction]: {
|
[key in MangaAction]: {
|
||||||
@@ -95,6 +96,14 @@ export const actionToTranslationKey: {
|
|||||||
success: 'manga.action.migrate.label.success',
|
success: 'manga.action.migrate.label.success',
|
||||||
error: 'manga.action.migrate.label.error',
|
error: 'manga.action.migrate.label.error',
|
||||||
},
|
},
|
||||||
|
track: {
|
||||||
|
action: {
|
||||||
|
single: 'manga.action.track.add.label.action',
|
||||||
|
selected: 'manga.action.track.add.label.action', // not supported
|
||||||
|
},
|
||||||
|
success: 'manga.action.track.add.label.success',
|
||||||
|
error: 'manga.action.track.add.label.error',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MangaChapterCountInfo = { chapters: Pick<TManga['chapters'], 'totalCount'> };
|
export type MangaChapterCountInfo = { chapters: Pick<TManga['chapters'], 'totalCount'> };
|
||||||
|
|||||||
Reference in New Issue
Block a user