- Shipped
- September 24, 2026 at 11:32 PM UTC
- Author
- Kamo
- Commit
- 593585d
A chat image is drawn at most 240x240 CSS px and the bubble downloaded the whole original to do it — 3-8 MB per phone photo, per viewer. AttachmentChip now draws **************** MediaService's 480px WebP (tens of KB), made the first time anyone asks and answered with the original whenever an image has none (an animation, a vector). The lightbox, downloads, video and audio keep reading the original. Fallback: if the preview fails the bubble tries the original at the same URL generation, and only the ORIGINAL's failure enters useAttachmentSource's recovery (cookie re-plant, then the HEAD verdict) — a broken preview is never reported as a missing file. The chip remembers which url the preview failed at, so a recovery that changes the url (the re-plant, Retry) tries the preview again instead of leaving the whole original in the bubble. /api/media/* is not a proxied prefix, so the preview has its own route file. Both routes now share app/lib/imagingProxyRelay.ts (same OTK forward, same pass-through of MediaService's CSP/nosniff/disposition, plus x-attachment-rendition), and refuse an id that is not a UUID before building the upstream URL. Deploy AFTER MediaService (the /preview endpoint). If this lands first the preview request 404s upstream and every bubble falls back to the original — today's behaviour, one extra small request.
