forked from
chadtmiller.com/slices-teal-relay
Teal.fm frontend powered by slices.network
tealfm-slices.wisp.place
tealfm
slices
1import { useState } from "react";
2
3interface AlbumArtProps {
4 releaseMbId: string | null | undefined;
5 alt: string;
6}
7
8export default function AlbumArt({ releaseMbId, alt }: AlbumArtProps) {
9 const [hasError, setHasError] = useState(false);
10 const [isLoading, setIsLoading] = useState(true);
11
12 if (!releaseMbId || hasError) {
13 return (
14 <div className="w-10 h-10 bg-zinc-800 flex items-center justify-center">
15 <svg className="w-5 h-5 text-zinc-600" fill="currentColor" viewBox="0 0 20 20">
16 <path d="M18 3a1 1 0 00-1.196-.98l-10 2A1 1 0 006 5v9.114A4.369 4.369 0 005 14c-1.657 0-3 .895-3 2s1.343 2 3 2 3-.895 3-2V7.82l8-1.6v5.894A4.37 4.37 0 0015 12c-1.657 0-3 .895-3 2s1.343 2 3 2 3-.895 3-2V3z" />
17 </svg>
18 </div>
19 );
20 }
21
22 return (
23 <>
24 {isLoading && <div className="w-10 h-10 bg-zinc-800 animate-pulse" />}
25 <img
26 src={`https://coverartarchive.org/release/${releaseMbId}/front-250`}
27 alt={alt}
28 className={`w-10 h-10 object-cover ${isLoading ? 'hidden' : ''}`}
29 onLoad={() => setIsLoading(false)}
30 onError={() => {
31 setIsLoading(false);
32 setHasError(true);
33 }}
34 />
35 </>
36 );
37}