Skip to content

Commit

Permalink
add comfortable grid
Browse files Browse the repository at this point in the history
and all the stuff needed to make it easy to add more
  • Loading branch information
Robonau committed Mar 5, 2022
1 parent 837e55a commit d699955
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 45 deletions.
109 changes: 67 additions & 42 deletions src/components/MangaCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Link } from 'react-router-dom';
import { Grid } from '@mui/material';
import useLocalStorage from 'util/useLocalStorage';
import SpinnerImage from 'components/util/SpinnerImage';
import { styled } from '@mui/system';
import { Box, styled } from '@mui/system';
import { useLibraryOptionsContext } from 'components/context/LibraryOptionsContext';

const BottomGradient = styled('div')({
Expand Down Expand Up @@ -70,12 +70,14 @@ const truncateText = (str: string, maxLength: number) => {

interface IProps {
manga: IMangaCard
gridLayout: number | undefined
}
const MangaCard = React.forwardRef<HTMLDivElement, IProps>((props: IProps, ref) => {
const {
manga: {
id, title, thumbnailUrl, downloadCount, unreadCount: unread,
},
gridLayout,
} = props;
const { options: { showUnreadBadge, showDownloadBadge } } = useLibraryOptionsContext();

Expand All @@ -84,60 +86,83 @@ const MangaCard = React.forwardRef<HTMLDivElement, IProps>((props: IProps, ref)

return (
<Grid item xs={6} sm={4} md={3} lg={2}>
<Link to={`/manga/${id}/`}>
<Card
<Link to={`/manga/${id}/`} style={(gridLayout === 1) ? { textDecoration: 'none' } : {}}>
<Box
sx={{
// force standard aspect ratio of manga covers
aspectRatio: '225/350',
display: 'flex',
flexDirection: 'column',
}}
ref={ref}
>
<CardActionArea
<Card
sx={{
position: 'relative',
height: '100%',
// force standard aspect ratio of manga covers
aspectRatio: '225/350',
display: 'flex',
}}
ref={ref}
>
<CardActionArea
sx={{
position: 'relative',
height: '100%',
}}
>

<BadgeContainer>
{ showUnreadBadge && unread! > 0 && (
<Typography
sx={{ backgroundColor: 'primary.dark' }}
>
{unread}
</Typography>
)}
{ showDownloadBadge && downloadCount! > 0 && (
<Typography sx={{
backgroundColor: 'success.dark',
<BadgeContainer>
{ showUnreadBadge && unread! > 0 && (
<Typography
sx={{ backgroundColor: 'primary.dark' }}
>
{unread}
</Typography>
)}
{ showDownloadBadge && downloadCount! > 0 && (
<Typography sx={{
backgroundColor: 'success.dark',
}}
>
{downloadCount}
</Typography>
)}
</BadgeContainer>
<SpinnerImage
alt={title}
src={`${serverAddress}${thumbnailUrl}?useCache=${useCache}`}
imgStyle={{
height: '100%',
width: '100%',
objectFit: 'cover',
}}
>
{downloadCount}
</Typography>
spinnerStyle={{
display: 'grid',
placeItems: 'center',
}}
/>
{(gridLayout === 1) ? (<></>) : (
<>
<BottomGradient />
<BottomGradientDoubledDown />
</>
)}
</BadgeContainer>
<SpinnerImage
alt={title}
src={`${serverAddress}${thumbnailUrl}?useCache=${useCache}`}
imgStyle={{
height: '100%',
width: '100%',
objectFit: 'cover',
}}
spinnerStyle={{
display: 'grid',
placeItems: 'center',
{(gridLayout === 1) ? (
<></>
) : (
<MangaTitle>
{truncateText(title, 61)}
</MangaTitle>
)}
</CardActionArea>
</Card>
{(gridLayout === 1) ? (
<MangaTitle
sx={{
position: 'relative',
}}
/>
<BottomGradient />
<BottomGradientDoubledDown />

<MangaTitle>
>
{truncateText(title, 61)}
</MangaTitle>
</CardActionArea>
</Card>
) : (<></>)}
</Box>
</Link>
</Grid>
);
Expand Down
6 changes: 5 additions & 1 deletion src/components/MangaGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ export interface IMangaGridProps{
hasNextPage: boolean
lastPageNum: number
setLastPageNum: (lastPageNum: number) => void
gridLayout?: number | undefined
}

export default function MangaGrid(props: IMangaGridProps) {
const {
mangas, isLoading, message, messageExtra, hasNextPage, lastPageNum, setLastPageNum,
mangas, isLoading, message, messageExtra,
hasNextPage, lastPageNum, setLastPageNum, gridLayout,
} = props;
let mapped;
const lastManga = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -61,13 +63,15 @@ export default function MangaGrid(props: IMangaGridProps) {
key={it.id}
manga={it}
ref={lastManga}
gridLayout={gridLayout}
/>
);
}
return (
<MangaCard
key={it.id}
manga={it}
gridLayout={gridLayout}
/>
);
});
Expand Down
3 changes: 2 additions & 1 deletion src/components/context/LibraryOptionsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
import React, { useContext } from 'react';

type ContextType = {
// display options
options: LibraryDisplayOptions;
setOptions: React.Dispatch<React.SetStateAction<LibraryDisplayOptions>>;
};

const LibraryOptionsContext = React.createContext<ContextType>({
options: { showDownloadBadge: false, showUnreadBadge: false },
options: { showDownloadBadge: false, showUnreadBadge: false, gridLayout: 0 },
setOptions: () => {},
});

Expand Down
3 changes: 3 additions & 0 deletions src/components/library/LibraryMangaGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import React from 'react';
import MangaGrid, { IMangaGridProps } from 'components/MangaGrid';
import useLibraryOptions from 'util/useLibraryOptions';
import { useLibraryOptionsContext } from 'components/context/LibraryOptionsContext';

const FILTERED_OUT_MESSAGE = 'There are no Manga matching this filter';

Expand Down Expand Up @@ -79,6 +80,7 @@ export default function LibraryMangaGrid(props: IMangaGridProps) {
mangas, isLoading, hasNextPage, lastPageNum, setLastPageNum, message,
} = props;

const { options } = useLibraryOptionsContext();
const { active, query } = useLibraryOptions();
const filteredManga = filterManga(mangas);
const sortedManga = sortManga(filteredManga);
Expand All @@ -93,6 +95,7 @@ export default function LibraryMangaGrid(props: IMangaGridProps) {
lastPageNum={lastPageNum}
setLastPageNum={setLastPageNum}
message={showFilteredOutMessage ? FILTERED_OUT_MESSAGE : message}
gridLayout={options.gridLayout}
/>
);
}
33 changes: 33 additions & 0 deletions src/components/library/LibraryOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
ListItemButton,
ListItemIcon,
ListItemText,
Radio,
} from '@mui/material';
import useLibraryOptions from 'util/useLibraryOptions';
import ThreeStateCheckbox from 'components/util/ThreeStateCheckbox';
Expand Down Expand Up @@ -111,9 +112,41 @@ function dispalyTab(currentTab: number) {
) {
setOptions((prev) => ({ ...prev, [e.target.name]: checked }));
}

function setGridContextOptions(
e: React.ChangeEvent<HTMLInputElement>,
checked: boolean,
) {
if (checked) {
setOptions((prev) => ({ ...prev, gridLayout: parseInt(e.target.name, 10) }));
}
}

return (
<TabPanel index={2} currentIndex={currentTab}>
<Stack direction="column">
DISPLAY MODE
<FormControlLabel
label="Compact grid"
control={(
<Radio
name="0"
checked={options.gridLayout === 0 || options.gridLayout === undefined}
onChange={setGridContextOptions}
/>
)}
/>
<FormControlLabel
label="Comfortable grid"
control={(
<Radio
name="1"
checked={options.gridLayout === 1}
onChange={setGridContextOptions}
/>
)}
/>
BADGES
<FormControlLabel
label="Unread Badges"
control={(
Expand Down
2 changes: 1 addition & 1 deletion src/components/library/LibraryOptionsProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface IProps {

export default function LibraryOptionsContextProvider({ children }: IProps) {
const [options, setOptions] = useLocalStorage<LibraryDisplayOptions>('libraryOptions',
{ showDownloadBadge: false, showUnreadBadge: false });
{ showDownloadBadge: false, showUnreadBadge: false, gridLayout: 0 });

return (
<LibraryOptionsContext.Provider value={{ options, setOptions }}>
Expand Down
1 change: 1 addition & 0 deletions src/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,4 +264,5 @@ type ChapterOptionsReducerAction =
interface LibraryDisplayOptions {
showDownloadBadge: boolean
showUnreadBadge: boolean
gridLayout: number
}

0 comments on commit d699955

Please sign in to comment.