Improve grid card components
- Dynamic placeholder depending on item type - Fix skeleton for default card
This commit is contained in:
parent
b5da8aeb55
commit
2100c1495d
2 changed files with 103 additions and 25 deletions
|
@ -1,4 +1,7 @@
|
||||||
|
import { Center, Stack } from '@mantine/core';
|
||||||
|
import { RiAlbumFill, RiUserVoiceFill, RiPlayListFill } from 'react-icons/ri';
|
||||||
import { generatePath, useNavigate } from 'react-router-dom';
|
import { generatePath, useNavigate } from 'react-router-dom';
|
||||||
|
import { SimpleImg } from 'react-simple-img';
|
||||||
import { ListChildComponentProps } from 'react-window';
|
import { ListChildComponentProps } from 'react-window';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Album, AlbumArtist, Artist, LibraryItem } from '/@/renderer/api/types';
|
import { Album, AlbumArtist, Artist, LibraryItem } from '/@/renderer/api/types';
|
||||||
|
@ -88,14 +91,6 @@ const ImageContainer = styled.div`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Image = styled.img`
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
object-fit: contain;
|
|
||||||
border: 0;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const DetailContainer = styled.div`
|
const DetailContainer = styled.div`
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
`;
|
`;
|
||||||
|
@ -120,6 +115,26 @@ export const DefaultCard = ({
|
||||||
}, {}),
|
}, {}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let Placeholder = RiAlbumFill;
|
||||||
|
|
||||||
|
switch (controls.itemType) {
|
||||||
|
case LibraryItem.ALBUM:
|
||||||
|
Placeholder = RiAlbumFill;
|
||||||
|
break;
|
||||||
|
case LibraryItem.ARTIST:
|
||||||
|
Placeholder = RiUserVoiceFill;
|
||||||
|
break;
|
||||||
|
case LibraryItem.ALBUM_ARTIST:
|
||||||
|
Placeholder = RiUserVoiceFill;
|
||||||
|
break;
|
||||||
|
case LibraryItem.PLAYLIST:
|
||||||
|
Placeholder = RiPlayListFill;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Placeholder = RiAlbumFill;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DefaultCardContainer
|
<DefaultCardContainer
|
||||||
key={`card-${columnIndex}-${listChildProps.index}`}
|
key={`card-${columnIndex}-${listChildProps.index}`}
|
||||||
|
@ -127,10 +142,29 @@ export const DefaultCard = ({
|
||||||
>
|
>
|
||||||
<InnerCardContainer>
|
<InnerCardContainer>
|
||||||
<ImageContainer>
|
<ImageContainer>
|
||||||
<Image
|
{data?.imageUrl ? (
|
||||||
placeholder={data?.imagePlaceholderUrl || 'var(--placeholder-bg)'}
|
<SimpleImg
|
||||||
src={data?.imageUrl}
|
imgStyle={{ objectFit: 'cover' }}
|
||||||
/>
|
importance="auto"
|
||||||
|
placeholder={data?.imagePlaceholderUrl || 'var(--placeholder-bg)'}
|
||||||
|
src={data?.imageUrl}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Center
|
||||||
|
sx={{
|
||||||
|
background: 'var(--placeholder-bg)',
|
||||||
|
borderRadius: 'var(--card-default-radius)',
|
||||||
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Placeholder
|
||||||
|
color="var(--placeholder-fg)"
|
||||||
|
size={35}
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
|
)}
|
||||||
|
|
||||||
<GridCardControls
|
<GridCardControls
|
||||||
handleFavorite={controls.handleFavorite}
|
handleFavorite={controls.handleFavorite}
|
||||||
handlePlayQueueAdd={controls.handlePlayQueueAdd}
|
handlePlayQueueAdd={controls.handlePlayQueueAdd}
|
||||||
|
@ -161,6 +195,18 @@ export const DefaultCard = ({
|
||||||
radius="sm"
|
radius="sm"
|
||||||
/>
|
/>
|
||||||
</ImageContainer>
|
</ImageContainer>
|
||||||
|
<DetailContainer>
|
||||||
|
<Stack spacing="sm">
|
||||||
|
{controls.cardRows.map((row) => (
|
||||||
|
<Skeleton
|
||||||
|
key={row.arrayProperty}
|
||||||
|
visible
|
||||||
|
height={14}
|
||||||
|
radius="sm"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
</DetailContainer>
|
||||||
</InnerCardContainer>
|
</InnerCardContainer>
|
||||||
</DefaultCardContainer>
|
</DefaultCardContainer>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { Stack } from '@mantine/core';
|
import { Center, Stack } from '@mantine/core';
|
||||||
|
import { RiAlbumFill, RiPlayListFill, RiUserVoiceFill } from 'react-icons/ri';
|
||||||
import { generatePath, useNavigate } from 'react-router-dom';
|
import { generatePath, useNavigate } from 'react-router-dom';
|
||||||
|
import { SimpleImg } from 'react-simple-img';
|
||||||
import { ListChildComponentProps } from 'react-window';
|
import { ListChildComponentProps } from 'react-window';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Album, AlbumArtist, Artist, LibraryItem } from '/@/renderer/api/types';
|
import { Album, AlbumArtist, Artist, LibraryItem } from '/@/renderer/api/types';
|
||||||
|
@ -77,14 +79,6 @@ const ImageContainer = styled.div`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Image = styled.img`
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
object-fit: cover;
|
|
||||||
border: 0;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const DetailContainer = styled.div`
|
const DetailContainer = styled.div`
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
`;
|
`;
|
||||||
|
@ -109,14 +103,52 @@ export const PosterCard = ({
|
||||||
}, {}),
|
}, {}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let Placeholder = RiAlbumFill;
|
||||||
|
|
||||||
|
switch (controls.itemType) {
|
||||||
|
case LibraryItem.ALBUM:
|
||||||
|
Placeholder = RiAlbumFill;
|
||||||
|
break;
|
||||||
|
case LibraryItem.ARTIST:
|
||||||
|
Placeholder = RiUserVoiceFill;
|
||||||
|
break;
|
||||||
|
case LibraryItem.ALBUM_ARTIST:
|
||||||
|
Placeholder = RiUserVoiceFill;
|
||||||
|
break;
|
||||||
|
case LibraryItem.PLAYLIST:
|
||||||
|
Placeholder = RiPlayListFill;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Placeholder = RiAlbumFill;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PosterCardContainer key={`card-${columnIndex}-${listChildProps.index}`}>
|
<PosterCardContainer key={`card-${columnIndex}-${listChildProps.index}`}>
|
||||||
<LinkContainer onClick={() => navigate(path)}>
|
<LinkContainer onClick={() => navigate(path)}>
|
||||||
<ImageContainer>
|
<ImageContainer>
|
||||||
<Image
|
{data?.imageUrl ? (
|
||||||
placeholder={data?.imagePlaceholderUrl || 'var(--card-default-bg)'}
|
<SimpleImg
|
||||||
src={data?.imageUrl}
|
imgStyle={{ objectFit: 'cover' }}
|
||||||
/>
|
importance="auto"
|
||||||
|
placeholder={data?.imagePlaceholderUrl || 'var(--card-default-bg)'}
|
||||||
|
src={data?.imageUrl}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Center
|
||||||
|
sx={{
|
||||||
|
background: 'var(--placeholder-bg)',
|
||||||
|
borderRadius: 'var(--card-default-radius)',
|
||||||
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Placeholder
|
||||||
|
color="var(--placeholder-fg)"
|
||||||
|
size={35}
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
|
)}
|
||||||
<GridCardControls
|
<GridCardControls
|
||||||
handleFavorite={controls.handleFavorite}
|
handleFavorite={controls.handleFavorite}
|
||||||
handlePlayQueueAdd={controls.handlePlayQueueAdd}
|
handlePlayQueueAdd={controls.handlePlayQueueAdd}
|
||||||
|
|
Reference in a new issue