sorting (#136)
* sorting add menu add sort by left to Read add sort alphabetical add sort by ID add Asc/Desc * woops * woops * Camel case
This commit is contained in:
@@ -48,6 +48,32 @@ function filterManga(mangas: IMangaCard[]): IMangaCard[] {
|
|||||||
&& queryFilter(query, manga));
|
&& queryFilter(query, manga));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toReadSort(a: IMangaCard, b: IMangaCard): number {
|
||||||
|
if (!a.unreadCount) return -1;
|
||||||
|
if (!b.unreadCount) return 1;
|
||||||
|
return a.unreadCount > b.unreadCount ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toSortAlph(a: IMangaCard, b: IMangaCard): number {
|
||||||
|
return a.title < b.title ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toSortID(a: IMangaCard, b: IMangaCard): number {
|
||||||
|
return a.id > b.id ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortManga(mangas: IMangaCard[]): IMangaCard[] {
|
||||||
|
const { sorts, sortDesc } = useLibraryOptions();
|
||||||
|
return (sorts === 'sortID' || sorts === undefined) && !sortDesc ? mangas : mangas.sort((a, b) => {
|
||||||
|
const c = sortDesc === true ? b : a;
|
||||||
|
const d = sortDesc === true ? a : b;
|
||||||
|
if (sorts === 'sortToRead') { return toReadSort(c, d); }
|
||||||
|
if (sorts === 'sortAlph') { return toSortAlph(c, d); }
|
||||||
|
if (sorts === 'sortID' || sorts === undefined) { return toSortID(c, d); }
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export default function LibraryMangaGrid(props: IMangaGridProps) {
|
export default function LibraryMangaGrid(props: IMangaGridProps) {
|
||||||
const {
|
const {
|
||||||
mangas, isLoading, hasNextPage, lastPageNum, setLastPageNum, message,
|
mangas, isLoading, hasNextPage, lastPageNum, setLastPageNum, message,
|
||||||
@@ -55,12 +81,13 @@ export default function LibraryMangaGrid(props: IMangaGridProps) {
|
|||||||
|
|
||||||
const { active, query } = useLibraryOptions();
|
const { active, query } = useLibraryOptions();
|
||||||
const filteredManga = filterManga(mangas);
|
const filteredManga = filterManga(mangas);
|
||||||
|
const sortedManga = sortManga(filteredManga);
|
||||||
const showFilteredOutMessage = (active || query)
|
const showFilteredOutMessage = (active || query)
|
||||||
&& filteredManga.length === 0 && mangas.length > 0;
|
&& filteredManga.length === 0 && mangas.length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MangaGrid
|
<MangaGrid
|
||||||
mangas={filteredManga}
|
mangas={sortedManga}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
hasNextPage={hasNextPage}
|
hasNextPage={hasNextPage}
|
||||||
lastPageNum={lastPageNum}
|
lastPageNum={lastPageNum}
|
||||||
|
|||||||
@@ -8,9 +8,12 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import FilterListIcon from '@mui/icons-material/FilterList';
|
import FilterListIcon from '@mui/icons-material/FilterList';
|
||||||
|
import SortIcon from '@mui/icons-material/Sort';
|
||||||
import { Drawer, FormControlLabel, IconButton } from '@mui/material';
|
import { Drawer, FormControlLabel, IconButton } from '@mui/material';
|
||||||
import useLibraryOptions from 'util/useLibraryOptions';
|
import useLibraryOptions from 'util/useLibraryOptions';
|
||||||
import ThreeStateCheckbox from 'components/util/ThreeStateCheckbox';
|
import ThreeStateCheckbox from 'components/util/ThreeStateCheckbox';
|
||||||
|
import Switch from '@mui/material/Switch';
|
||||||
|
import Radio from '@mui/material/Radio';
|
||||||
import { Box } from '@mui/system';
|
import { Box } from '@mui/system';
|
||||||
|
|
||||||
function Options() {
|
function Options() {
|
||||||
@@ -25,8 +28,32 @@ function Options() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SortOptions() {
|
||||||
|
const {
|
||||||
|
sorts, setSorts, sortDesc, setSortDesc,
|
||||||
|
} = useLibraryOptions();
|
||||||
|
|
||||||
|
const handleSortChange = (name: string) => (event: { target: { checked: boolean; }; }) => {
|
||||||
|
setSorts(event.target.checked ? name : undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOrderChange = () => (event: { target: { checked: boolean; }; }) => {
|
||||||
|
setSortDesc(event.target.checked);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
|
<FormControlLabel control={<Switch name="sortDesc" checked={sortDesc === true} onChange={handleOrderChange()} color="default" />} label="Asc/Desc" />
|
||||||
|
<FormControlLabel control={<Radio name="sortToRead" checked={sorts === 'sortToRead'} onChange={handleSortChange('sortToRead')} />} label="Sort by left to read" />
|
||||||
|
<FormControlLabel control={<Radio name="sortAlph" checked={sorts === 'sortAlph'} onChange={handleSortChange('sortAlph')} />} label="Sort alphbetical" />
|
||||||
|
<FormControlLabel control={<Radio name="sortID" checked={sorts === 'sortID' || sorts === undefined} onChange={handleSortChange('sortID')} />} label="Sort by ID" />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function LibraryOptions() {
|
export default function LibraryOptions() {
|
||||||
const [filtersOpen, setFiltersOpen] = React.useState(false);
|
const [filtersOpen, setFiltersOpen] = React.useState(false);
|
||||||
|
const [sortsOpen, setSortsOpen] = React.useState(false);
|
||||||
const { active } = useLibraryOptions();
|
const { active } = useLibraryOptions();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -50,6 +77,26 @@ export default function LibraryOptions() {
|
|||||||
<Options />
|
<Options />
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
||||||
|
<IconButton
|
||||||
|
onClick={() => setSortsOpen(!filtersOpen)}
|
||||||
|
color={active ? 'warning' : 'default'}
|
||||||
|
>
|
||||||
|
<SortIcon />
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
<Drawer
|
||||||
|
anchor="bottom"
|
||||||
|
open={sortsOpen}
|
||||||
|
onClose={() => setSortsOpen(false)}
|
||||||
|
PaperProps={{
|
||||||
|
style: {
|
||||||
|
maxWidth: 600, padding: '1em', marginLeft: 'auto', marginRight: 'auto',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SortOptions />
|
||||||
|
</Drawer>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,22 +10,38 @@ import { BooleanParam, useQueryParam, StringParam } from 'use-query-params';
|
|||||||
|
|
||||||
interface IUseLibraryOptions {
|
interface IUseLibraryOptions {
|
||||||
downloaded: NullAndUndefined<boolean>
|
downloaded: NullAndUndefined<boolean>
|
||||||
setDownloaded: (downloaded: NullAndUndefined<boolean>)=>void
|
setDownloaded: (downloaded: NullAndUndefined<boolean>) => void
|
||||||
unread: NullAndUndefined<boolean>
|
unread: NullAndUndefined<boolean>
|
||||||
setUnread: (unread: NullAndUndefined<boolean>) => void
|
setUnread: (unread: NullAndUndefined<boolean>) => void
|
||||||
query: NullAndUndefined<string>
|
query: NullAndUndefined<string>
|
||||||
setQuery: (query: NullAndUndefined<string>) => void
|
setQuery: (query: NullAndUndefined<string>) => void
|
||||||
active: boolean
|
active: boolean
|
||||||
|
sorts: NullAndUndefined<string>
|
||||||
|
setSorts: (sorts: NullAndUndefined<string>) => void
|
||||||
|
sortDesc: NullAndUndefined<boolean>
|
||||||
|
setSortDesc: (sortDesc: NullAndUndefined<boolean>) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function useLibraryOptions(): IUseLibraryOptions {
|
export default function useLibraryOptions(): IUseLibraryOptions {
|
||||||
const [downloaded, setDownloaded] = useQueryParam('downloaded', BooleanParam);
|
const [downloaded, setDownloaded] = useQueryParam('downloaded', BooleanParam);
|
||||||
const [unread, setUnread] = useQueryParam('unread', BooleanParam);
|
const [unread, setUnread] = useQueryParam('unread', BooleanParam);
|
||||||
const [query, setQuery] = useQueryParam('query', StringParam);
|
const [query, setQuery] = useQueryParam('query', StringParam);
|
||||||
|
const [sorts, setSorts] = useQueryParam('sorts', StringParam);
|
||||||
|
const [sortDesc, setSortDesc] = useQueryParam('sortDesc', BooleanParam);
|
||||||
|
|
||||||
// eslint-disable-next-line eqeqeq
|
// eslint-disable-next-line eqeqeq
|
||||||
const active = !(unread == undefined) || !(downloaded == undefined);
|
const active = !(unread == undefined) || !(downloaded == undefined);
|
||||||
return {
|
return {
|
||||||
downloaded, setDownloaded, unread, setUnread, query, setQuery, active,
|
downloaded,
|
||||||
|
setDownloaded,
|
||||||
|
unread,
|
||||||
|
setUnread,
|
||||||
|
query,
|
||||||
|
setQuery,
|
||||||
|
active,
|
||||||
|
sorts,
|
||||||
|
setSorts,
|
||||||
|
sortDesc,
|
||||||
|
setSortDesc,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user