fix(downloads): use the local poster as the Library thumbnail primary
The Library card used the source's remote thumbnail_url as the primary <img>
src and only fell back to our self-hosted poster on error. For Facebook
downloads (the bulk of a typical library) that URL is an fbcdn signed link that
expires within days, and is also blocked by ad-blockers / Brave Shields on the
facebook domain — so the thumbnail broke even though the local poster was
present on disk. Flip the priority: serve /api/downloads/{id}/poster.jpg first
(always present, never expires, same-origin) and keep the remote as the fallback
for the rare poster-less asset.
This commit is contained in:
@@ -84,10 +84,13 @@ function StatusPill({ job }: { job: DownloadJob }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Thumb({ job }: { job: DownloadJob }) {
|
function Thumb({ job }: { job: DownloadJob }) {
|
||||||
// Prefer the source thumbnail; fall back to our generated poster for thumbnail-less sources.
|
// Prefer OUR self-hosted poster: it's always present on disk, never expires, and is same-origin, so
|
||||||
const primary = job.asset?.thumbnail_url || job.poster_url;
|
// a source-CDN signature expiry (Facebook's fbcdn URLs expire within days) or an ad-blocker/Shields
|
||||||
// A remote i.ytimg.com thumbnail 404s once the source video is deleted/privated, leaving a
|
// rule on the source domain can't break it. The source's remote thumbnail_url is only a fallback for
|
||||||
// broken image. On load failure fall back to our always-present self-hosted poster.
|
// the rare poster-less asset (a thumbnail-less source whose ffmpeg frame-cut also failed).
|
||||||
|
const remote = job.asset?.thumbnail_url ?? null;
|
||||||
|
const primary = job.poster_url || remote;
|
||||||
|
// On load failure (a genuinely missing poster file) fall back to the remote source thumbnail.
|
||||||
const [src, setSrc] = useState(primary);
|
const [src, setSrc] = useState(primary);
|
||||||
useEffect(() => setSrc(primary), [primary]);
|
useEffect(() => setSrc(primary), [primary]);
|
||||||
return (
|
return (
|
||||||
@@ -99,7 +102,7 @@ function Thumb({ job }: { job: DownloadJob }) {
|
|||||||
loading="lazy"
|
loading="lazy"
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
onError={() => {
|
onError={() => {
|
||||||
if (job.poster_url && src !== job.poster_url) setSrc(job.poster_url);
|
if (remote && src !== remote) setSrc(remote);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
Reference in New Issue
Block a user