From e4574b026015636b7c4ee7b8cca7e9a5cf735c6c Mon Sep 17 00:00:00 2001 From: jeffvli Date: Fri, 26 Sep 2025 10:44:03 -0700 Subject: [PATCH] add item card skeleton --- .../components/item-card/item-card.module.css | 1 - .../components/item-card/item-card.tsx | 180 ++++++++++++------ 2 files changed, 124 insertions(+), 57 deletions(-) diff --git a/src/renderer/components/item-card/item-card.module.css b/src/renderer/components/item-card/item-card.module.css index 3f405df3a..45660de09 100644 --- a/src/renderer/components/item-card/item-card.module.css +++ b/src/renderer/components/item-card/item-card.module.css @@ -67,7 +67,6 @@ max-width: 100%; overflow: hidden; text-overflow: ellipsis; - line-height: 1.6; white-space: nowrap; a { diff --git a/src/renderer/components/item-card/item-card.tsx b/src/renderer/components/item-card/item-card.tsx index ea78154c8..0e1fc6b6d 100644 --- a/src/renderer/components/item-card/item-card.tsx +++ b/src/renderer/components/item-card/item-card.tsx @@ -8,6 +8,7 @@ import styles from './item-card.module.css'; import { AppRoute } from '/@/renderer/router/routes'; import { Image } from '/@/shared/components/image/image'; import { Separator } from '/@/shared/components/separator/separator'; +import { Skeleton } from '/@/shared/components/skeleton/skeleton'; import { Text } from '/@/shared/components/text/text'; import { Album, @@ -31,8 +32,9 @@ type DataRow = { }; interface ItemCardProps { - data: Album | AlbumArtist | Artist | Playlist | Song; + data: Album | AlbumArtist | Artist | Playlist | Song | undefined; isRound?: boolean; + itemType: LibraryItem; onClick?: () => void; onItemExpand?: () => void; onItemSelect?: () => void; @@ -43,17 +45,18 @@ interface ItemCardProps { export const ItemCard = ({ data, isRound, + itemType, onClick, onItemExpand, onItemSelect, type = 'poster', withControls, }: ItemCardProps) => { - const imageUrl = getImageUrl(data); - const rows = getDataRows(data); - const [showControls, setShowControls] = useState(false); + const imageUrl = getImageUrl(data); + const rows = getDataRows(itemType); + switch (type) { case 'compact': return ( @@ -61,6 +64,7 @@ export const ItemCard = ({ data={data} imageUrl={imageUrl} isRound={isRound} + itemType={itemType} onClick={onClick} onItemExpand={onItemExpand} onItemSelect={onItemSelect} @@ -76,6 +80,7 @@ export const ItemCard = ({ data={data} imageUrl={imageUrl} isRound={isRound} + itemType={itemType} onClick={onClick} onItemExpand={onItemExpand} onItemSelect={onItemSelect} @@ -92,6 +97,7 @@ export const ItemCard = ({ data={data} imageUrl={imageUrl} isRound={isRound} + itemType={itemType} onClick={onClick} onItemExpand={onItemExpand} onItemSelect={onItemSelect} @@ -123,24 +129,41 @@ const CompactItemCard = ({ showControls, withControls, }: ItemCardDerivativeProps) => { + if (data) { + return ( +
+
withControls && setShowControls(true)} + onMouseLeave={() => withControls && setShowControls(false)} + > + + + {withControls && showControls && } + +
+ {rows.map((row) => ( + + ))} +
+
+
+ ); + } + return (
-
withControls && setShowControls(true)} - onMouseLeave={() => withControls && setShowControls(false)} - > - - - {withControls && showControls && } - +
+
{rows.map((row) => ( - +
+   +
))}
@@ -160,28 +183,43 @@ const DefaultItemCard = ({ showControls, withControls, }: ItemCardDerivativeProps) => { + if (data) { + return ( +
+
withControls && setShowControls(true)} + onMouseLeave={() => withControls && setShowControls(false)} + > + + + {withControls && showControls && } + +
+
+ {rows.map((row) => ( + + ))} +
+
+ ); + } + return (
-
withControls && setShowControls(true)} - onMouseLeave={() => withControls && setShowControls(false)} - > - - - {withControls && showControls && } - +
+
{rows.map((row) => ( - - - +
+   +
))}
@@ -200,35 +238,48 @@ const PosterItemCard = ({ showControls, withControls, }: ItemCardDerivativeProps) => { + if (data) { + return ( +
+
withControls && setShowControls(true)} + onMouseLeave={() => withControls && setShowControls(false)} + > + + + {withControls && showControls && } + +
+
+ {rows.map((row) => ( + + ))} +
+
+ ); + } + return (
-
withControls && setShowControls(true)} - onMouseLeave={() => withControls && setShowControls(false)} - > - - - {withControls && showControls && } - +
+
{rows.map((row) => ( - - - + ))}
); }; -const getDataRows = (data: Album | AlbumArtist | Artist | Playlist | Song): DataRow[] => { - switch (data.itemType) { +const getDataRows = (itemType: LibraryItem): DataRow[] => { + switch (itemType) { case LibraryItem.ALBUM: return [ { @@ -274,11 +325,13 @@ const getDataRows = (data: Album | AlbumArtist | Artist | Playlist | Song): Data return [{ format: (data) => (data as Playlist).name, id: 'name' }]; case LibraryItem.SONG: return [{ format: (data) => (data as Song).name, id: 'name' }]; + default: + return []; } }; -const getImageUrl = (data: Album | AlbumArtist | Artist | Playlist | Song) => { - if ('imageUrl' in data) { +const getImageUrl = (data: Album | AlbumArtist | Artist | Playlist | Song | undefined) => { + if (data && 'imageUrl' in data) { return data.imageUrl || undefined; } @@ -290,10 +343,25 @@ const ItemCardRow = ({ row, type, }: { - data: Album | AlbumArtist | Artist | Playlist | Song; + data: Album | AlbumArtist | Artist | Playlist | Song | undefined; row: DataRow; type?: 'compact' | 'default' | 'poster'; }) => { + if (!data) { + return ( +
+   +
+ ); + } + return (