From b5432e3e5f2ce90b15955dde764cce9253b5bcc7 Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Wed, 12 Aug 2026 10:59:06 -0400 Subject: [PATCH] fix(download): sibling cover via curl + episode image fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The download wrote its sibling .jpg with Bun fetch — which hangs in compiled binaries, so shipped builds never produced offline cover art. Now curl (same flags as the cover cache). Also falls back to the episode's own image when the feed has no channel cover (URL-added feeds like The Fifth Column). mpv --cover-art-auto=exact picks up the same-basename .jpg (verified against mpv 0.41). --- src/stores/download.ts | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/stores/download.ts b/src/stores/download.ts index 83a3bf3..b997dcc 100644 --- a/src/stores/download.ts +++ b/src/stores/download.ts @@ -237,23 +237,36 @@ function createDownloadStore() { }); // Write the podcast cover beside the audio so mpv's - // --cover-art-auto=exact picks it up for Now Playing art. - const coverUrl = useFeedStore() - .feeds() - .find((f) => f.id === item.feedId)?.podcast.coverUrl; + // --cover-art-auto=exact picks it up for Now Playing art when the + // local file plays (same basename, .jpg extension — verified + // against mpv 0.41). curl, NOT fetch: Bun's fetch hangs in + // compiled binaries, so the shipped app never wrote this file. + // Falls back to the episode's own image when the feed has no + // channel cover (URL-added feeds). + const feedStore = useFeedStore(); + const episode = feedStore.findEpisode(item.episodeId); + const coverUrl = + feedStore + .feeds() + .find((f) => f.id === item.feedId)?.podcast.coverUrl ?? + episode?.imageUrl; if (coverUrl && result.filePath) { const dot = result.filePath.lastIndexOf("."); if (dot > 0) { const coverPath = result.filePath.slice(0, dot) + ".jpg"; - fetch(coverUrl) - .then(async (r) => { - if (!r.ok) return; - await Bun.write( - coverPath, - new Uint8Array(await r.arrayBuffer()), - ); - }) - .catch(() => {}); + Bun.spawn([ + "curl", + "-sS", + "--fail", + "-m", + "8", + "--max-filesize", + "2097152", + "-o", + coverPath, + coverUrl, + ]) + .exited.catch(() => {}); } } } else {