mirror of
https://github.com/antebudimir/feishin.git
synced 2025-12-31 18:13:31 +00:00
Change grid size to items per row
This commit is contained in:
parent
e47fcfc62e
commit
219a9ed613
8 changed files with 125 additions and 97 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { generatePath, Link } from 'react-router-dom';
|
||||
import { generatePath, useNavigate } from 'react-router-dom';
|
||||
import { ListChildComponentProps } from 'react-window';
|
||||
import styled from 'styled-components';
|
||||
import { Album, AlbumArtist, Artist, LibraryItem } from '/@/renderer/api/types';
|
||||
|
|
@ -31,6 +31,7 @@ const DefaultCardContainer = styled.div<{ $isHidden?: boolean }>`
|
|||
overflow: hidden;
|
||||
background: var(--card-default-bg);
|
||||
border-radius: var(--card-default-radius);
|
||||
cursor: pointer;
|
||||
opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)};
|
||||
pointer-events: auto;
|
||||
|
||||
|
|
@ -106,42 +107,44 @@ export const DefaultCard = ({
|
|||
controls,
|
||||
isHidden,
|
||||
}: BaseGridCardProps) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
if (data) {
|
||||
const path = generatePath(
|
||||
controls.route.route,
|
||||
controls.route.slugs?.reduce((acc, slug) => {
|
||||
return {
|
||||
...acc,
|
||||
[slug.slugProperty]: data[slug.idProperty],
|
||||
};
|
||||
}, {}),
|
||||
);
|
||||
|
||||
return (
|
||||
<DefaultCardContainer>
|
||||
<Link
|
||||
tabIndex={0}
|
||||
to={generatePath(
|
||||
controls.route.route,
|
||||
controls.route.slugs?.reduce((acc, slug) => {
|
||||
return {
|
||||
...acc,
|
||||
[slug.slugProperty]: data[slug.idProperty],
|
||||
};
|
||||
}, {}),
|
||||
)}
|
||||
>
|
||||
<InnerCardContainer key={`card-${columnIndex}-${listChildProps.index}`}>
|
||||
<ImageContainer>
|
||||
<Image
|
||||
placeholder={data?.imagePlaceholderUrl || 'var(--placeholder-bg)'}
|
||||
src={data?.imageUrl}
|
||||
/>
|
||||
<GridCardControls
|
||||
handleFavorite={controls.handleFavorite}
|
||||
handlePlayQueueAdd={controls.handlePlayQueueAdd}
|
||||
itemData={data}
|
||||
itemType={controls.itemType}
|
||||
/>
|
||||
</ImageContainer>
|
||||
<DetailContainer>
|
||||
<CardRows
|
||||
data={data}
|
||||
rows={controls.cardRows}
|
||||
/>
|
||||
</DetailContainer>
|
||||
</InnerCardContainer>
|
||||
</Link>
|
||||
<DefaultCardContainer
|
||||
key={`card-${columnIndex}-${listChildProps.index}`}
|
||||
onClick={() => navigate(path)}
|
||||
>
|
||||
<InnerCardContainer>
|
||||
<ImageContainer>
|
||||
<Image
|
||||
placeholder={data?.imagePlaceholderUrl || 'var(--placeholder-bg)'}
|
||||
src={data?.imageUrl}
|
||||
/>
|
||||
<GridCardControls
|
||||
handleFavorite={controls.handleFavorite}
|
||||
handlePlayQueueAdd={controls.handlePlayQueueAdd}
|
||||
itemData={data}
|
||||
itemType={controls.itemType}
|
||||
/>
|
||||
</ImageContainer>
|
||||
<DetailContainer>
|
||||
<CardRows
|
||||
data={data}
|
||||
rows={controls.cardRows}
|
||||
/>
|
||||
</DetailContainer>
|
||||
</InnerCardContainer>
|
||||
</DefaultCardContainer>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { generatePath, Link } from 'react-router-dom';
|
||||
import { Stack } from '@mantine/core';
|
||||
import { generatePath, useNavigate } from 'react-router-dom';
|
||||
import { ListChildComponentProps } from 'react-window';
|
||||
import styled from 'styled-components';
|
||||
import { Album, AlbumArtist, Artist, LibraryItem } from '/@/renderer/api/types';
|
||||
|
|
@ -27,7 +28,7 @@ const PosterCardContainer = styled.div<{ $isHidden?: boolean }>`
|
|||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0.5rem;
|
||||
margin: 1rem;
|
||||
overflow: hidden;
|
||||
opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)};
|
||||
pointer-events: auto;
|
||||
|
|
@ -35,16 +36,10 @@ const PosterCardContainer = styled.div<{ $isHidden?: boolean }>`
|
|||
.card-controls {
|
||||
opacity: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
&:hover .card-controls {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:hover * {
|
||||
&::before {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
const LinkContainer = styled.div`
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
const ImageContainer = styled.div`
|
||||
|
|
@ -70,6 +65,16 @@ const ImageContainer = styled.div`
|
|||
content: '';
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::before {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .card-controls {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
const Image = styled.img`
|
||||
|
|
@ -91,21 +96,22 @@ export const PosterCard = ({
|
|||
controls,
|
||||
isHidden,
|
||||
}: BaseGridCardProps) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
if (data) {
|
||||
const path = generatePath(
|
||||
controls.route.route,
|
||||
controls.route.slugs?.reduce((acc, slug) => {
|
||||
return {
|
||||
...acc,
|
||||
[slug.slugProperty]: data[slug.idProperty],
|
||||
};
|
||||
}, {}),
|
||||
);
|
||||
|
||||
return (
|
||||
<PosterCardContainer key={`card-${columnIndex}-${listChildProps.index}`}>
|
||||
<Link
|
||||
tabIndex={0}
|
||||
to={generatePath(
|
||||
controls.route.route,
|
||||
controls.route.slugs?.reduce((acc, slug) => {
|
||||
return {
|
||||
...acc,
|
||||
[slug.slugProperty]: data[slug.idProperty],
|
||||
};
|
||||
}, {}),
|
||||
)}
|
||||
>
|
||||
<LinkContainer onClick={() => navigate(path)}>
|
||||
<ImageContainer>
|
||||
<Image
|
||||
placeholder={data?.imagePlaceholderUrl || 'var(--card-default-bg)'}
|
||||
|
|
@ -118,7 +124,7 @@ export const PosterCard = ({
|
|||
itemType={controls.itemType}
|
||||
/>
|
||||
</ImageContainer>
|
||||
</Link>
|
||||
</LinkContainer>
|
||||
<DetailContainer>
|
||||
<CardRows
|
||||
data={data}
|
||||
|
|
@ -134,13 +140,24 @@ export const PosterCard = ({
|
|||
key={`card-${columnIndex}-${listChildProps.index}`}
|
||||
$isHidden={isHidden}
|
||||
>
|
||||
<ImageContainer>
|
||||
<Skeleton
|
||||
visible
|
||||
radius="sm"
|
||||
/>
|
||||
</ImageContainer>
|
||||
<DetailContainer />
|
||||
<Skeleton
|
||||
visible
|
||||
radius="sm"
|
||||
>
|
||||
<ImageContainer />
|
||||
</Skeleton>
|
||||
<DetailContainer>
|
||||
<Stack spacing="sm">
|
||||
{controls.cardRows.map((row) => (
|
||||
<Skeleton
|
||||
key={row.arrayProperty}
|
||||
visible
|
||||
height={14}
|
||||
radius="sm"
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
</DetailContainer>
|
||||
</PosterCardContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -56,20 +56,17 @@ export const VirtualInfiniteGrid = forwardRef(
|
|||
const listRef = useRef<any>(null);
|
||||
const loader = useRef<InfiniteLoader>(null);
|
||||
|
||||
const sz = itemSize / 2;
|
||||
|
||||
const { itemHeight, rowCount, columnCount } = useMemo(() => {
|
||||
const itemsPerRow = Math.floor(Number(width) / sz!) - 1;
|
||||
const widthPerItem = Number(width) / itemsPerRow - 10;
|
||||
const itemsPerRow = itemSize;
|
||||
const widthPerItem = Number(width) / itemsPerRow;
|
||||
const itemHeight = widthPerItem + cardRows.length * 26;
|
||||
|
||||
return {
|
||||
columnCount: itemsPerRow,
|
||||
itemHeight,
|
||||
itemWidth: sz,
|
||||
rowCount: Math.ceil(itemCount / itemsPerRow),
|
||||
};
|
||||
}, [cardRows.length, itemCount, sz, width]);
|
||||
}, [cardRows.length, itemCount, itemSize, width]);
|
||||
|
||||
const isItemLoaded = useCallback(
|
||||
(index: number) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue