Files
suwayomi-material-you-webui/src/components/MangaGrid.tsx
T

145 lines
4.2 KiB
TypeScript
Raw Normal View History

/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
2021-01-26 23:32:12 +03:30
* 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/. */
2023-02-06 10:06:33 +01:00
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
2021-09-09 17:51:22 +04:30
import Grid from '@mui/material/Grid';
2021-10-30 16:10:34 +03:30
import EmptyView from 'components/util/EmptyView';
import LoadingPlaceholder from 'components/util/LoadingPlaceholder';
2022-03-12 04:46:55 +00:00
import { Typography } from '@mui/material';
import { Box } from '@mui/system';
2023-02-05 16:15:20 +01:00
import MangaCard from 'components/MangaCard';
import { GridLayout } from 'components/context/LibraryOptionsContext';
import { IMangaCard } from 'typings';
2021-01-20 15:26:52 +03:30
2023-02-06 10:06:33 +01:00
export interface IMangaGridProps {
mangas: IMangaCard[];
isLoading: boolean;
message?: string;
messageExtra?: JSX.Element;
hasNextPage: boolean;
lastPageNum: number;
setLastPageNum: (lastPageNum: number) => void;
gridLayout?: GridLayout;
horizontal?: boolean | undefined;
2023-02-06 10:06:33 +01:00
noFaces?: boolean | undefined;
inLibraryIndicator?: boolean;
2021-01-20 15:26:52 +03:30
}
2022-11-24 21:04:30 +01:00
const MangaGrid: React.FC<IMangaGridProps> = (props) => {
2021-01-22 21:11:00 +03:30
const {
2023-02-06 10:06:33 +01:00
mangas,
isLoading,
message,
messageExtra,
hasNextPage,
lastPageNum,
setLastPageNum,
gridLayout,
horizontal,
2023-02-06 10:06:33 +01:00
noFaces,
2022-11-24 21:04:30 +01:00
inLibraryIndicator,
2021-01-22 21:11:00 +03:30
} = props;
2021-01-20 15:26:52 +03:30
let mapped;
const lastManga = useRef<HTMLDivElement>(null);
2021-01-22 21:11:00 +03:30
const scrollHandler = () => {
if (lastManga.current) {
const rect = lastManga.current.getBoundingClientRect();
2023-02-06 10:06:33 +01:00
if ((rect.y + rect.height) / window.innerHeight < 2 && hasNextPage) {
2021-01-22 21:11:00 +03:30
setLastPageNum(lastPageNum + 1);
}
}
};
useEffect(() => {
window.addEventListener('scroll', scrollHandler, true);
return () => {
window.removeEventListener('scroll', scrollHandler, true);
};
}, [hasNextPage, mangas]);
2021-01-20 15:26:52 +03:30
2022-04-02 01:34:10 +01:00
const [dimensions, setDimensions] = useState(1);
const gridRef = useRef<HTMLDivElement>(null);
const TestDimensions = () => {
setDimensions(gridRef.current ? gridRef.current.offsetWidth : 0);
};
useLayoutEffect(TestDimensions, []);
let movementTimer: NodeJS.Timeout;
window.addEventListener('resize', () => {
clearInterval(movementTimer);
movementTimer = setTimeout(TestDimensions, 100);
});
2021-01-20 15:26:52 +03:30
if (mangas.length === 0) {
2021-10-24 22:56:10 +03:30
if (isLoading) {
2023-02-06 10:06:33 +01:00
mapped = <LoadingPlaceholder />;
2021-10-24 22:56:10 +03:30
} else {
2022-03-12 04:46:55 +00:00
mapped = noFaces ? (
<Box
sx={{
margin: 'auto',
}}
>
2023-02-06 10:06:33 +01:00
<Typography variant="h5">{message}</Typography>
2022-03-12 04:46:55 +00:00
{messageExtra}
</Box>
) : (
2021-10-24 22:56:10 +03:30
<EmptyView message={message!} messageExtra={messageExtra} />
);
}
2021-01-20 15:26:52 +03:30
} else {
2022-11-24 21:04:30 +01:00
mapped = mangas.map((it, idx) => (
<MangaCard
key={it.id}
manga={it}
ref={idx === mangas.length - 1 ? lastManga : undefined}
gridLayout={gridLayout}
dimensions={dimensions}
inLibraryIndicator={inLibraryIndicator}
/>
));
2021-01-20 15:26:52 +03:30
}
2021-01-22 21:11:00 +03:30
return (
2022-04-02 01:34:10 +01:00
<div ref={gridRef}>
<Grid
container
spacing={1}
2023-02-06 10:06:33 +01:00
style={
horizontal
2023-02-06 10:06:33 +01:00
? {
margin: 0,
width: '100%',
padding: '5px',
overflowX: 'scroll',
display: '-webkit-inline-box',
flexWrap: 'nowrap',
}
: {
margin: 0,
width: '100%',
padding: '5px',
}
}
2022-04-02 01:34:10 +01:00
>
{mapped}
</Grid>
</div>
2021-01-22 21:11:00 +03:30
);
2022-11-24 21:04:30 +01:00
};
2021-01-22 21:11:00 +03:30
MangaGrid.defaultProps = {
2021-10-24 22:56:10 +03:30
message: '',
2021-09-19 17:30:34 +04:30
messageExtra: undefined,
2021-01-22 21:11:00 +03:30
};
2022-11-24 21:04:30 +01:00
export default MangaGrid;