refactor ChapterOptions (#126)

* Added a useLocalStorageReducer funtion
This is mostly  a refactor of ChapterOptions to simplify it with  a reducer function
Also moved a lot of function used in ChaperList to a utility file

* Added UseCallback where needed

* renamed utility folder to util to follow the convention throughout the app

* Refactor: Moved Resume FAB to seperate file

* Renamed  Types and Function for chapter filtering and sorting with the chapterOption prefix

* more renaming
This commit is contained in:
abhijeetChawla
2022-01-24 15:09:28 +05:30
committed by GitHub
parent f273b11a82
commit aaaadebfb3
7 changed files with 216 additions and 167 deletions

View File

@@ -5,10 +5,10 @@
* 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 React, { useState } from 'react';
import React, { useState, useCallback } from 'react';
import FilterListIcon from '@mui/icons-material/FilterList';
import {
Drawer, FormControlLabel, IconButton, Typography, Tab, Tabs, Radio, RadioGroup,
Drawer, FormControlLabel, IconButton, Typography, Tab, Tabs, Radio, RadioGroup, Stack,
} from '@mui/material';
import ThreeStateCheckbox from 'components/util/ThreeStateCheckbox';
import { Box } from '@mui/system';
@@ -17,51 +17,21 @@ import TabPanel from 'components/util/TabPanel';
interface IProps{
options: ChapterListOptions
setOptions: React.Dispatch<React.SetStateAction<ChapterListOptions>>
optionsDispatch: React.Dispatch<ChapterOptionsReducerAction>
}
const SortTab: [ChapterSortMode, string][] = [['source', 'By Source'], ['fetchedAt', 'By Fetch date']];
export default function ChapterOptions(props: IProps) {
const { options, setOptions } = props;
const { options, optionsDispatch } = props;
const [filtersOpen, setFiltersOpen] = useState(false);
const [tabNum, setTabNum] = useState(0);
const setUnread = (newUnread: NullAndUndefined<boolean>) => {
const active = options.unread !== false
&& options.downloaded !== false
&& options.bookmarked !== false;
setOptions({ ...options, active, unread: newUnread });
};
const setDownloaded = (newDownloaded: NullAndUndefined<boolean>) => {
const active = options.unread !== false
&& options.downloaded !== false
&& options.bookmarked !== false;
setOptions({ ...options, active, downloaded: newDownloaded });
};
const setBookmarked = (newBookmarked: NullAndUndefined<boolean>) => {
const active = options.unread !== false
&& options.downloaded !== false
&& options.bookmarked !== false;
setOptions({ ...options, active, bookmarked: newBookmarked });
};
const setSort = (newSort: ChapterSortMode) => {
if (newSort !== options.sortBy) {
setOptions({ ...options, sortBy: newSort });
} else {
setOptions({ ...options, reverse: !options.reverse });
}
};
const handleDisplay = (e: React.ChangeEvent<HTMLInputElement>) => {
const showChapterNumber = e.target.value === 'chapterNumber';
if (showChapterNumber !== options.showChapterNumber) {
setOptions({ ...options, showChapterNumber });
}
};
const filterOptions = useCallback(
(value: NullAndUndefined<boolean>, name: string) => {
optionsDispatch({ type: 'filter', filterType: name.toLowerCase(), filterValue: value });
}, [],
);
return (
<>
@@ -101,51 +71,45 @@ export default function ChapterOptions(props: IProps) {
</Tabs>
<TabPanel index={0} currentIndex={tabNum}>
<Box sx={{ display: 'flex', flexDirection: 'column', minHeight: '150px' }}>
<FormControlLabel control={<ThreeStateCheckbox name="Unread" checked={options.unread} onChange={setUnread} />} label="Unread" />
<FormControlLabel control={<ThreeStateCheckbox name="Downloaded" checked={options.downloaded} onChange={setDownloaded} />} label="Downloaded" />
<FormControlLabel control={<ThreeStateCheckbox name="Bookmarked" checked={options.bookmarked} onChange={setBookmarked} />} label="Bookmarked" />
<FormControlLabel control={<ThreeStateCheckbox name="Unread" checked={options.unread} onChange={filterOptions} />} label="Unread" />
<FormControlLabel control={<ThreeStateCheckbox name="Downloaded" checked={options.downloaded} onChange={filterOptions} />} label="Downloaded" />
<FormControlLabel control={<ThreeStateCheckbox name="Bookmarked" checked={options.bookmarked} onChange={filterOptions} />} label="Bookmarked" />
</Box>
</TabPanel>
<TabPanel index={1} currentIndex={tabNum}>
<Box sx={{ display: 'flex', flexDirection: 'column', minHeight: '150px' }}>
{
SortTab.map((item) => (
<Box
onClick={() => setSort(item[0])}
sx={{
display: 'flex',
alignItems: 'center',
gap: 1,
height: 42,
py: 1,
}}
<Stack
direction="row"
alignItems="center"
spacing="2"
sx={{ py: 1, height: 42 }}
onClick={() => (item[0] !== options.sortBy
? optionsDispatch({ type: 'sortBy', sortBy: item[0] })
: optionsDispatch({ type: 'sortReverse' }))}
>
<Box sx={{
height: 24,
width: 24,
}}
>
{options.sortBy === item[0]
&& (options.reverse ? (
<ArrowUpward color="primary" />
) : (
<ArrowDownward color="primary" />
))}
<Box sx={{ height: 24, width: 24 }}>
{
options.sortBy === item[0]
&& (options.reverse
? (<ArrowUpward color="primary" />) : (<ArrowDownward color="primary" />))
}
</Box>
<Typography>{item[1]}</Typography>
</Box>
</Stack>
))
}
</Box>
</TabPanel>
<TabPanel index={2} currentIndex={tabNum}>
<Box sx={{ display: 'flex', flexDirection: 'column', minHeight: '150px' }}>
<RadioGroup name="chapter-title-display" onChange={handleDisplay} value={options.showChapterNumber}>
<Stack flexDirection="column" sx={{ minHeight: '150px' }}>
<RadioGroup name="chapter-title-display" onChange={() => optionsDispatch({ type: 'showChapterNumber' })} value={options.showChapterNumber}>
<FormControlLabel label="By Source Title" value="title" control={<Radio checked={!options.showChapterNumber} />} />
<FormControlLabel label="By Chapter Number" value="chapterNumber" control={<Radio checked={options.showChapterNumber} />} />
</RadioGroup>
</Box>
</Stack>
</TabPanel>
</Box>
</Drawer>