This repository was archived by the owner on Jul 15, 2026. It is now read-only.
Media: stat-gated image renderability + labeled placeholders for missing files - #26
Merged
Merged
Conversation
…ing files (#15, #4) Diagnosis of issue #15 (browser broken-image glyphs on Media -> Images): - Hypothesis 1 CONFIRMED (root cause): imgRenderable returned true for any web-native extension without checking that the file exists on disk (or that the source's archive root even resolves), so an attachment row whose file is absent rendered an <img> whose /media src answers 404 (400 on an unconfigured root) -- exactly the browser's broken-image glyph. - Hypothesis 2 (encoding round-trip) disproved: mediaURL PathEscapes per segment and the Go 1.22 mux decodes {path...}; spaces, unicode, '#', '%', '&', '+', ';' and subfolders all round-trip. Locked in as regression by TestMediaURLEncodingRoundTrip and the extended TestMediaURLEscaping. - Hypothesis 3 (transcode gap) disproved as stated: the HEIC/TIFF gate already stats the derived JPEG -- it never claims a derivative that does not exist. Full state matrix covered by TestImgTileState. - Hypothesis 4 ruled out by inspection: tiles are static HTML swapped in by htmx; no JS touches img src, and img-src 'self' admits /media. Fix: a three-state imgTileState (img / nopreview / missing) classifies each image with the same existence checks handleMedia applies at serve time. The gallery grid renders msgbrowse's own inert labeled "missing" placeholder for absent files (an <img> would 404; a download link would save an error page), and the transcript -- imgRenderable now delegates to the classifier -- falls back to its labeled attachment chip instead of a broken thumbnail. Files tab (issue #4 remnant): decorateFiles already stat'ed every row, so missing files now flag Missing and render an inert labeled card instead of a download anchor -- a native click on <a download> answering 404 surfaces as a silently failed download, i.e. "clicking does nothing" in a plain browser. Cost: one stat per rendered tile (plus one for the derivative on convertible formats) -- the same per-item price the Files tab already paid in decorateFiles, microseconds against the SPEC-0008 budgets. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…SS (#15, #4) The transcript fix for a DB-only image (file absent from the archive on this machine) was left as uncommitted working-tree edits, so the tree was in an inconsistent, un-mergeable state: partials.html rendered an inert attach-chip-missing <span>, but media_issue15_test.go still asserted a live <a class="attach-chip"> download anchor to ghost.jpg, and app.css was never regenerated for the new .attach-chip-missing rules — CI failed on the tree. Reconcile the deliverable into one self-consistent commit: - Finalize partials.html: a missing image/attachment renders the inert, labeled attach-chip-missing placeholder instead of a download anchor whose click fetches a 404 (the issue #4 "clicking does nothing" silently failed download). This matches the gallery's inert missing tile/card treatment, so graceful degradation is applied consistently across the transcript and the Media Images/Files tabs. - Update TestTranscriptMissingImageNoBrokenImg to codify the fix: assert the missing image is NOT a link (no <a ...ghost.jpg) and renders the labeled attach-chip-missing placeholder, mirroring the gallery's inert-element assertions — rather than green-lighting the dead download link. - Regenerate internal/web/static/app.css so the .attach-chip-missing rules ship; the embedded server serves static/app.css, so without this the chip would render unstyled. - gallery.html/input.css three-state imgTileState changes folded in. CGO_ENABLED=0 make check passes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…en-images # Conflicts: # internal/web/static/app.css
This was referenced Jul 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #15. Closes #15. Re-verifies #4.
Diagnosis (issue #15)
The
<img>renders (imgRenderablereturned true) but itssrc404s at request time. Worked through the ticket's hypotheses in tests:handleMedia404 → browser broken-image glyph. Confirmed the dominant cause.mediaURL↔handleMediaagree onRelPathwith spaces/unicode/#/subfolders (regression test).Fix
<img>; genuinely-missing files degrade to msgbrowse's own labeled placeholder instead of a raw broken image. No inline JS (CSP-safe).<img>.TestTranscriptMissingImageNoBrokenImg,TestGalleryMissingImagePlaceholder,TestGalleryFilesMissingInert, plus the path-encoding round-trip.Issue #4 re-verification
PR #18's
hx-boost="false"did not address the reported cause — confirmed:#main-contentsits inside the un-boosted.drawer-content; only the toolbar title/nav/search and the sidebar are boosted, so those file anchors were never htmx-intercepted (the attribute is harmless future-proofing, kept). Web-server evidence:Content-Disposition: attachment→ real download.Remaining for #4: desktop-webview (Wails) download interception is out of scope for the server and needs a
cmd/msgbrowse-desktopfollow-up. Recommend keeping #4 open for that.🤖 Generated with Claude Code
Generated by Claude Code