Options panels refactoring (#196)

* Refactor library options to match chapter options using shared component

* Disable some eslint rules

* Cleanup SourceOptions layout to use same components as other panels
This commit is contained in:
Valter Martinek
2022-11-24 09:41:03 +01:00
committed by GitHub
parent 3972d7757f
commit 154b357c40
35 changed files with 625 additions and 685 deletions

View File

@@ -239,7 +239,6 @@ const ChapterList: React.FC<IProps> = ({ mangaId }) => {
totalCount={visibleChapters.length}
itemContent={(index:number) => (
<ChapterCard
// eslint-disable-next-line react/jsx-props-no-spreading
{...chaptersWithMeta[index]}
showChapterNumber={options.showChapterNumber}
triggerChaptersUpdate={() => mutate()}

View File

@@ -5,110 +5,70 @@
* 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 { ArrowDownward, ArrowUpward } from '@mui/icons-material';
import {
Drawer, FormControlLabel, Radio, RadioGroup, Tab, Tabs,
} from '@mui/material';
import { Box } from '@mui/system';
import TabPanel from 'components/util/TabPanel';
import ThreeStateCheckbox from 'components/util/ThreeStateCheckbox';
import React, { useCallback, useState } from 'react';
import { RadioGroup } from '@mui/material';
import RadioInput from 'components/atoms/RadioInput';
import SortRadioInput from 'components/atoms/SortRadioInput';
import ThreeStateCheckboxInput from 'components/atoms/ThreeStateCheckboxInput';
import OptionsTabs from 'components/molecules/OptionsTabs';
import React from 'react';
import { SORT_OPTIONS } from './util';
interface IProps{
interface IProps {
open: boolean
onClose: () => void;
onClose: () => void
options: ChapterListOptions
optionsDispatch: React.Dispatch<ChapterOptionsReducerAction>
}
const TabContent: React.FC<{ children: React.ReactNode }> = ({ children }) => (
<Box sx={{
px: 3, py: 1, display: 'flex', flexDirection: 'column', minHeight: 150,
}}
>
{children}
</Box>
);
const TITLES = {
filter: 'Filter',
sort: 'Sort',
display: 'Display',
};
const ChapterOptions: React.FC<IProps> = ({
open, onClose, options, optionsDispatch,
}) => {
const [tabNum, setTabNum] = useState(0);
const handleFilterChange = useCallback(
(value: NullAndUndefined<boolean>, name: string) => {
optionsDispatch({ type: 'filter', filterType: name.toLowerCase(), filterValue: value });
}, [],
);
return (
<>
<Drawer
anchor="bottom"
open={open}
onClose={onClose}
PaperProps={{
style: {
maxWidth: 600,
marginLeft: 'auto',
marginRight: 'auto',
minHeight: '150px',
},
}}
>
<Box>
<Tabs
value={tabNum}
variant="fullWidth"
onChange={(e, newTab) => setTabNum(newTab)}
indicatorColor="primary"
textColor="primary"
>
<Tab value={0} label="Filter" />
<Tab value={1} label="Sort" />
<Tab value={2} label="Display" />
</Tabs>
<TabPanel index={0} currentIndex={tabNum}>
<TabContent>
<FormControlLabel control={<ThreeStateCheckbox name="Unread" checked={options.unread} onChange={handleFilterChange} />} label="Unread" />
<FormControlLabel control={<ThreeStateCheckbox name="Downloaded" checked={options.downloaded} onChange={handleFilterChange} />} label="Downloaded" />
<FormControlLabel control={<ThreeStateCheckbox name="Bookmarked" checked={options.bookmarked} onChange={handleFilterChange} />} label="Bookmarked" />
</TabContent>
</TabPanel>
<TabPanel index={1} currentIndex={tabNum}>
<TabContent>
{
SORT_OPTIONS.map(([mode, label]) => (
<FormControlLabel
key={mode}
control={(
<Radio
checked={options.sortBy === mode}
checkedIcon={options.reverse ? <ArrowUpward color="primary" /> : <ArrowDownward color="primary" />}
onClick={() => (mode !== options.sortBy
? optionsDispatch({ type: 'sortBy', sortBy: mode })
: optionsDispatch({ type: 'sortReverse' }))}
/>
)}
label={label}
/>
))
}
</TabContent>
</TabPanel>
<TabPanel index={2} currentIndex={tabNum}>
<TabContent>
<RadioGroup onChange={() => optionsDispatch({ type: 'showChapterNumber' })} value={options.showChapterNumber}>
<FormControlLabel label="Source Title" value="title" control={<Radio checked={!options.showChapterNumber} />} />
<FormControlLabel label="Chapter Number" value="chapterNumber" control={<Radio checked={options.showChapterNumber} />} />
</RadioGroup>
</TabContent>
</TabPanel>
</Box>
</Drawer>
</>
);
};
}) => (
<OptionsTabs<'filter' | 'sort' | 'display'>
open={open}
onClose={onClose}
minHeight={150}
tabs={['filter', 'sort', 'display']}
tabTitle={(key) => TITLES[key]}
tabContent={(key) => {
if (key === 'filter') {
return (
<>
<ThreeStateCheckboxInput label="Unread" checked={options.unread} onChange={(c) => optionsDispatch({ type: 'filter', filterType: 'unread', filterValue: c })} />
<ThreeStateCheckboxInput label="Downloaded" checked={options.downloaded} onChange={(c) => optionsDispatch({ type: 'filter', filterType: 'downloaded', filterValue: c })} />
<ThreeStateCheckboxInput label="Bookmarked" checked={options.bookmarked} onChange={(c) => optionsDispatch({ type: 'filter', filterType: 'bookmarked', filterValue: c })} />
</>
);
}
if (key === 'sort') {
return SORT_OPTIONS.map(([mode, label]) => (
<SortRadioInput
key={mode}
label={label}
checked={options.sortBy === mode}
sortDescending={options.reverse}
onClick={() => (mode !== options.sortBy
? optionsDispatch({ type: 'sortBy', sortBy: mode })
: optionsDispatch({ type: 'sortReverse' }))}
/>
));
}
if (key === 'display') {
return (
<RadioGroup onChange={() => optionsDispatch({ type: 'showChapterNumber' })} value={options.showChapterNumber}>
<RadioInput label="Source Title" value={false} />
<RadioInput label="Chapter Number" value />
</RadioGroup>
);
}
return null;
}}
/>
);
export default ChapterOptions;