import { useEffect, useState } from "react"; import type { MediaParticleData, StreamParticle } from "@/api/types"; import { apiClient } from "@/api/client"; import { usePlaybackStore } from "@/stores/playback-store"; import { Skeleton } from "@/components/ui/skeleton"; interface MediaParticleViewProps { particle: StreamParticle; onEnded: () => void; } export function MediaParticleView({ particle, onEnded, }: MediaParticleViewProps) { const cachedUrl = usePlaybackStore( (s) => s.downloadUrlCache[particle.id], ); const cacheDownloadUrl = usePlaybackStore((s) => s.cacheDownloadUrl); const [url, setUrl] = useState(cachedUrl ?? null); const [error, setError] = useState(null); useEffect(() => { if (cachedUrl) { setUrl(cachedUrl); return; } let cancelled = false; apiClient .getParticleDownloadUrl(particle.id) .then((downloadUrl) => { if (cancelled) return; cacheDownloadUrl(particle.id, downloadUrl); setUrl(downloadUrl); }) .catch(() => { if (!cancelled) setError("Failed to load media"); }); return () => { cancelled = true; }; }, [particle.id, cachedUrl, cacheDownloadUrl]); if (error) { return (
{error}
); } if (!url) { return ; } const data = particle.data as MediaParticleData; const isAudio = data.mime_type?.startsWith("audio/"); if (isAudio) { return (
); } return (