feishin/src/renderer/components/virtual-grid/grid-card/default-card.tsx

165 lines
4 KiB
TypeScript
Raw Normal View History

2023-03-09 02:26:09 -08:00
import { generatePath, Link } from 'react-router-dom';
import { ListChildComponentProps } from 'react-window';
2022-12-19 15:59:14 -08:00
import styled from 'styled-components';
2023-01-05 21:59:07 -08:00
import { Album, AlbumArtist, Artist, LibraryItem } from '/@/renderer/api/types';
2022-12-24 13:44:52 -08:00
import { CardRows } from '/@/renderer/components/card';
2023-03-09 02:26:09 -08:00
import { Skeleton } from '/@/renderer/components/skeleton';
import { GridCardControls } from '/@/renderer/components/virtual-grid/grid-card/grid-card-controls';
import { CardRow, PlayQueueAddOptions, Play, CardRoute } from '/@/renderer/types';
interface BaseGridCardProps {
columnIndex: number;
controls: {
cardRows: CardRow<Album | AlbumArtist | Artist>[];
handleFavorite: (options: { id: string[]; isFavorite: boolean; itemType: LibraryItem }) => void;
handlePlayQueueAdd: (options: PlayQueueAddOptions) => void;
itemType: LibraryItem;
playButtonBehavior: Play;
route: CardRoute;
};
data: any;
isHidden?: boolean;
listChildProps: Omit<ListChildComponentProps, 'data' | 'style'>;
}
2022-12-19 15:59:14 -08:00
2023-03-09 02:26:09 -08:00
const DefaultCardContainer = styled.div<{ $isHidden?: boolean }>`
display: flex;
flex-direction: column;
width: 100%;
height: calc(100% - 2rem);
margin: 1rem;
overflow: hidden;
2022-12-19 15:59:14 -08:00
background: var(--card-default-bg);
border-radius: var(--card-default-radius);
2023-03-09 02:26:09 -08:00
opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)};
pointer-events: auto;
2022-12-19 15:59:14 -08:00
&:hover {
background: var(--card-default-bg-hover);
}
2023-03-09 02:26:09 -08:00
`;
const InnerCardContainer = styled.div`
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
padding: 1rem;
overflow: hidden;
.card-controls {
opacity: 0;
}
2022-12-19 15:59:14 -08:00
2023-03-09 02:26:09 -08:00
&:hover .card-controls {
2022-12-19 15:59:14 -08:00
opacity: 1;
}
&:hover * {
&::before {
opacity: 0.5;
}
}
`;
2023-03-09 02:26:09 -08:00
const ImageContainer = styled.div`
position: relative;
2022-12-19 15:59:14 -08:00
display: flex;
2023-03-09 02:26:09 -08:00
align-items: center;
2022-12-19 15:59:14 -08:00
height: 100%;
2023-03-09 02:26:09 -08:00
aspect-ratio: 1/1;
overflow: hidden;
background: var(--placeholder-bg);
2022-12-19 15:59:14 -08:00
border-radius: var(--card-default-radius);
&::before {
position: absolute;
top: 0;
left: 0;
z-index: 1;
width: 100%;
height: 100%;
background: linear-gradient(0deg, rgba(0, 0, 0, 100%) 35%, rgba(0, 0, 0, 0%) 100%);
opacity: 0;
transition: all 0.2s ease-in-out;
content: '';
user-select: none;
}
`;
const Image = styled.img`
2022-12-19 15:59:14 -08:00
width: 100%;
2023-03-09 02:26:09 -08:00
max-width: 100%;
height: auto;
object-fit: contain;
border: 0;
2022-12-19 15:59:14 -08:00
`;
2023-03-09 02:26:09 -08:00
const DetailContainer = styled.div`
margin-top: 0.5rem;
2022-12-19 15:59:14 -08:00
`;
export const DefaultCard = ({
listChildProps,
data,
columnIndex,
controls,
2023-03-09 02:26:09 -08:00
isHidden,
2022-12-19 15:59:14 -08:00
}: BaseGridCardProps) => {
if (data) {
return (
2023-03-09 02:26:09 -08:00
<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>
2022-12-19 15:59:14 -08:00
<Image
2023-03-09 02:26:09 -08:00
placeholder={data?.imagePlaceholderUrl || 'var(--placeholder-bg)'}
2022-12-19 15:59:14 -08:00
src={data?.imageUrl}
/>
<GridCardControls
2023-01-08 00:52:53 -08:00
handleFavorite={controls.handleFavorite}
2023-03-09 02:26:09 -08:00
handlePlayQueueAdd={controls.handlePlayQueueAdd}
2022-12-19 15:59:14 -08:00
itemData={data}
2023-03-09 02:26:09 -08:00
itemType={controls.itemType}
2022-12-19 15:59:14 -08:00
/>
2023-03-09 02:26:09 -08:00
</ImageContainer>
<DetailContainer>
<CardRows
data={data}
rows={controls.cardRows}
/>
</DetailContainer>
</InnerCardContainer>
</Link>
</DefaultCardContainer>
2022-12-19 15:59:14 -08:00
);
}
return (
2023-03-09 02:26:09 -08:00
<DefaultCardContainer
key={`card-${columnIndex}-${listChildProps.index}`}
$isHidden={isHidden}
2022-12-19 15:59:14 -08:00
>
2023-03-09 02:26:09 -08:00
<InnerCardContainer>
<ImageContainer>
<Skeleton
visible
radius="sm"
/>
</ImageContainer>
</InnerCardContainer>
</DefaultCardContainer>
2022-12-19 15:59:14 -08:00
);
};