Feature/make selection logic reusable (#515)
* Introduce "selectable collection" hook * Extract "select all" button into component * Make "SelectionFABActionItem" reusable Was to tightly coupled to chapters * Make "SelectionFAB" reusable Was to tightly coupled to chapters
This commit is contained in:
@@ -10,32 +10,22 @@ import MoreHoriz from '@mui/icons-material/MoreHoriz';
|
||||
import { Fab, Menu, Box } from '@mui/material';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import type { IChapterWithMeta } from '@/components/manga/ChapterList';
|
||||
import { SelectionFABActionItem } from '@/components/manga/SelectionFABActionItem';
|
||||
import { DEFAULT_FAB_STYLE } from '@/components/util/StyledFab';
|
||||
|
||||
export type SelectionAction = 'download' | 'delete' | 'bookmark' | 'unbookmark' | 'mark_as_read' | 'mark_as_unread';
|
||||
import { TranslationKey } from '@/typings.ts';
|
||||
|
||||
interface SelectionFABProps {
|
||||
selectedChapters: IChapterWithMeta[];
|
||||
onAction: (action: SelectionAction, chapters: IChapterWithMeta[]) => void;
|
||||
children: (handleClose: () => void) => React.ReactNode;
|
||||
selectedItemsCount: number;
|
||||
title: TranslationKey;
|
||||
}
|
||||
|
||||
export const SelectionFAB: React.FC<SelectionFABProps> = (props) => {
|
||||
export const SelectionFAB: React.FC<SelectionFABProps> = ({ children, selectedItemsCount, title }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { selectedChapters, onAction } = props;
|
||||
const count = selectedChapters.length;
|
||||
|
||||
const anchorEl = useRef<HTMLElement>();
|
||||
const [open, setOpen] = useState(false);
|
||||
const handleClose = () => setOpen(false);
|
||||
|
||||
const handleAction = (action: SelectionAction, chapters: IChapterWithMeta[]) => {
|
||||
onAction(action, chapters);
|
||||
handleClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@@ -47,7 +37,7 @@ export const SelectionFAB: React.FC<SelectionFABProps> = (props) => {
|
||||
ref={anchorEl}
|
||||
>
|
||||
<Fab variant="extended" color="primary" id="selectionMenuButton" onClick={() => setOpen(true)}>
|
||||
{`${count} ${t('chapter.title', { count })}`}
|
||||
{`${selectedItemsCount} ${t(title, { count: selectedItemsCount })}`}
|
||||
<MoreHoriz sx={{ ml: 1 }} />
|
||||
</Fab>
|
||||
<Menu
|
||||
@@ -61,44 +51,7 @@ export const SelectionFAB: React.FC<SelectionFABProps> = (props) => {
|
||||
'aria-labelledby': 'selectionMenuButton',
|
||||
}}
|
||||
>
|
||||
<SelectionFABActionItem
|
||||
action="download"
|
||||
matchingChapters={selectedChapters.filter(
|
||||
({ chapter: c, downloadChapter: dc }) => !c.isDownloaded && dc === undefined,
|
||||
)}
|
||||
onClick={handleAction}
|
||||
title={t('chapter.action.download.add.button.selected')}
|
||||
/>
|
||||
<SelectionFABActionItem
|
||||
action="delete"
|
||||
matchingChapters={selectedChapters.filter(({ chapter }) => chapter.isDownloaded)}
|
||||
onClick={handleAction}
|
||||
title={t('chapter.action.download.delete.button.selected')}
|
||||
/>
|
||||
<SelectionFABActionItem
|
||||
action="bookmark"
|
||||
matchingChapters={selectedChapters.filter(({ chapter }) => !chapter.isBookmarked)}
|
||||
onClick={handleAction}
|
||||
title={t('chapter.action.bookmark.add.button.selected')}
|
||||
/>
|
||||
<SelectionFABActionItem
|
||||
action="unbookmark"
|
||||
matchingChapters={selectedChapters.filter(({ chapter }) => chapter.isBookmarked)}
|
||||
onClick={handleAction}
|
||||
title={t('chapter.action.bookmark.remove.button.selected')}
|
||||
/>
|
||||
<SelectionFABActionItem
|
||||
action="mark_as_read"
|
||||
matchingChapters={selectedChapters.filter(({ chapter }) => !chapter.isRead)}
|
||||
onClick={handleAction}
|
||||
title={t('chapter.action.mark_as_read.add.button.selected')}
|
||||
/>
|
||||
<SelectionFABActionItem
|
||||
action="mark_as_unread"
|
||||
matchingChapters={selectedChapters.filter(({ chapter }) => chapter.isRead)}
|
||||
onClick={handleAction}
|
||||
title={t('chapter.action.mark_as_read.remove.button.selected')}
|
||||
/>
|
||||
{children(handleClose)}
|
||||
</Menu>
|
||||
</Box>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user