mirror of
https://github.com/gabehf/Koito.git
synced 2026-03-16 10:55:55 -07:00
feat: v0.0.8
This commit is contained in:
parent
00e7782be2
commit
80b6f4deaa
66 changed files with 1559 additions and 916 deletions
|
|
@ -35,92 +35,52 @@ export default function TopItemList<T extends Item>({ data, separators, type, cl
|
|||
|
||||
function ItemCard({ item, type }: { item: Item; type: "album" | "track" | "artist" }) {
|
||||
|
||||
const itemClasses = `flex items-center gap-2 hover:text-(--color-fg-secondary)`
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleItemClick = (type: string, id: number) => {
|
||||
navigate(`/${type.toLowerCase()}/${id}`);
|
||||
};
|
||||
|
||||
const handleArtistClick = (event: React.MouseEvent) => {
|
||||
// Stop the click from navigating to the album page
|
||||
event.stopPropagation();
|
||||
};
|
||||
|
||||
// Also stop keyboard events on the inner links from bubbling up
|
||||
const handleArtistKeyDown = (event: React.KeyboardEvent) => {
|
||||
event.stopPropagation();
|
||||
}
|
||||
const itemClasses = `flex items-center gap-2`
|
||||
|
||||
switch (type) {
|
||||
case "album": {
|
||||
const album = item as Album;
|
||||
|
||||
const handleKeyDown = (event: React.KeyboardEvent) => {
|
||||
if (event.key === 'Enter') {
|
||||
handleItemClick("album", album.id);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{fontSize: 12}}>
|
||||
<div
|
||||
className={itemClasses}
|
||||
onClick={() => handleItemClick("album", album.id)}
|
||||
onKeyDown={handleKeyDown}
|
||||
role="link"
|
||||
tabIndex={0}
|
||||
aria-label={`View album: ${album.title}`}
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
<img src={imageUrl(album.image, "small")} alt={album.title} />
|
||||
<div>
|
||||
<div style={{fontSize: 12}} className={itemClasses}>
|
||||
<Link to={`/album/${album.id}`}>
|
||||
<img loading="lazy" src={imageUrl(album.image, "small")} alt={album.title} className="min-w-[48px]" />
|
||||
</Link>
|
||||
<div>
|
||||
<Link to={`/album/${album.id}`} className="hover:text-(--color-fg-secondary)">
|
||||
<span style={{fontSize: 14}}>{album.title}</span>
|
||||
<br />
|
||||
{album.is_various_artists ?
|
||||
<span className="color-fg-secondary">Various Artists</span>
|
||||
:
|
||||
<div onClick={handleArtistClick} onKeyDown={handleArtistKeyDown}>
|
||||
<ArtistLinks artists={album.artists ? [album.artists[0]] : [{id: 0, name: 'Unknown Artist'}]}/>
|
||||
</div>
|
||||
}
|
||||
<div className="color-fg-secondary">{album.listen_count} plays</div>
|
||||
</Link>
|
||||
<br />
|
||||
{album.is_various_artists ?
|
||||
<span className="color-fg-secondary">Various Artists</span>
|
||||
:
|
||||
<div>
|
||||
<ArtistLinks artists={album.artists ? [album.artists[0]] : [{id: 0, name: 'Unknown Artist'}]}/>
|
||||
</div>
|
||||
}
|
||||
<div className="color-fg-secondary">{album.listen_count} plays</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
case "track": {
|
||||
const track = item as Track;
|
||||
|
||||
const handleKeyDown = (event: React.KeyboardEvent) => {
|
||||
if (event.key === 'Enter') {
|
||||
handleItemClick("track", track.id);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{fontSize: 12}}>
|
||||
<div
|
||||
className={itemClasses}
|
||||
onClick={() => handleItemClick("track", track.id)}
|
||||
onKeyDown={handleKeyDown}
|
||||
role="link"
|
||||
tabIndex={0}
|
||||
aria-label={`View track: ${track.title}`}
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
<img src={imageUrl(track.image, "small")} alt={track.title} />
|
||||
<div style={{fontSize: 12}} className={itemClasses}>
|
||||
<Link to={`/track/${track.id}`}>
|
||||
<img loading="lazy" src={imageUrl(track.image, "small")} alt={track.title} className="min-w-[48px]" />
|
||||
</Link>
|
||||
<div>
|
||||
<span style={{fontSize: 14}}>{track.title}</span>
|
||||
<Link to={`/track/${track.id}`} className="hover:text-(--color-fg-secondary)">
|
||||
<span style={{fontSize: 14}}>{track.title}</span>
|
||||
</Link>
|
||||
<br />
|
||||
<div onClick={handleArtistClick} onKeyDown={handleArtistKeyDown}>
|
||||
<div>
|
||||
<ArtistLinks artists={track.artists || [{id: 0, Name: 'Unknown Artist'}]}/>
|
||||
</div>
|
||||
<div className="color-fg-secondary">{track.listen_count} plays</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -128,12 +88,12 @@ function ItemCard({ item, type }: { item: Item; type: "album" | "track" | "artis
|
|||
const artist = item as Artist;
|
||||
return (
|
||||
<div style={{fontSize: 12}}>
|
||||
<Link className={itemClasses+' mt-1 mb-[6px]'} to={`/artist/${artist.id}`}>
|
||||
<img src={imageUrl(artist.image, "small")} alt={artist.name} />
|
||||
<div>
|
||||
<span style={{fontSize: 14}}>{artist.name}</span>
|
||||
<div className="color-fg-secondary">{artist.listen_count} plays</div>
|
||||
</div>
|
||||
<Link className={itemClasses+' mt-1 mb-[6px] hover:text-(--color-fg-secondary)'} to={`/artist/${artist.id}`}>
|
||||
<img loading="lazy" src={imageUrl(artist.image, "small")} alt={artist.name} className="min-w-[48px]" />
|
||||
<div>
|
||||
<span style={{fontSize: 14}}>{artist.name}</span>
|
||||
<div className="color-fg-secondary">{artist.listen_count} plays</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue