Skip to content

feat(images): open image files as pictures, not binary refusals - #3

Open
letrquan wants to merge 1 commit into
mainfrom
feat/open-images
Open

feat(images): open image files as pictures, not binary refusals#3
letrquan wants to merge 1 commit into
mainfrom
feat/open-images

Conversation

@letrquan

Copy link
Copy Markdown
Owner

What

Opening an image file in Chapter used to hit a dead end — the changes list, the Ctrl+P palette and the commit panel all routed images into a diff or code view, which can only answer with a "Binary file" notice. Images rendered solely as assets inside markdown previews.

This adds a first-class image view: clicking an image file (png/jpg/jpeg/gif/webp/avif/bmp/ico/svg) now opens it as a picture in its own tab.

How

Frontend (Chapter.Web)

  • New image view mode alongside diff/code/preview. The image is fetched as a data URI through the existing getAsset bridge endpoint and rendered centred in a new #image-host pane, on a checkerboard background so PNG/SVG transparency reads as transparency rather than as the theme colour.
  • Images open straight into image view from every entry point (changes list default, palette navigation, markdown links, commit panel). The Diff/Code segmented control hides for image tabs — nothing to switch to — and the Ctrl+D toggle stands down. The hunk bar is dismissed when an image replaces a split diff, so it cannot stage against a file no longer on screen.
  • The extension predicate mirrors the backend allow-list, with comments pointing at each other.

Backend (Chapter.Core)

  • getAsset is now scope-aware, mirroring getFileContent: Branch/Uncommitted read from disk; Committed/LastCommit resolve where the comparison ends and serve the image as that revision has it — an edited picture can no longer leak into a review of older work.
  • New DiffService.GetBytesAtAsync returns raw bytes at a revision (git show rev:path, null when absent) for content that must not pass through a text decode — GetContentAtAsync classifies images as binary and would hand back an empty string.
  • Every failure is still reported as an AssetPayload reason ("not found", "too large to preview", …) rather than thrown, so the UI can show an honest refusal; the one new throw path (git failure on committed scopes) is caught by the existing per-call error handling, matching getFileContent behaviour.

Verification

  • dotnet test: 441 passed (2 asset tests updated for the instance API; new Opened_images_follow_the_scope_not_the_working_tree proves a Committed-scope image serves the committed bytes, not the working tree).
  • tsc --noEmit clean; npm run build clean.
  • Verified in the running app: image files open as pictures from the changes list, the mode switch hides for them, and text files are unaffected.

Notes for reviewers

  • Mode (main.ts) and ViewMode (editor.ts) are parallel unions; drift is caught at compile time at the showMode/revealPosition call sites.
  • Known cosmetic gap, shared with the pre-existing "Binary file" notice path: a refusal notice does not clear a stale banner from the previous text tab (banner is z-index 30, above the notice).

Clicking an image in the changes list, palette or commit panel landed on
a "Binary file" notice; images only ever rendered inside markdown
previews. They now open in their own view mode.

- New "image" view mode: the backend inlines the file as a data URI via
  the existing getAsset endpoint, and the pane renders it centred on a
  checkerboard so transparency reads as transparency.
- getAsset is scope-aware: Committed and Last views show the image as
  that comparison ends (raw bytes via git show), not whatever the
  working tree holds now. New DiffService.GetBytesAtAsync reads bytes
  at a revision without a text decode.
- The Diff/Code switch hides for images, and Ctrl+D and the hunk bar
  stand down, since neither has anything to act on.
@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
chapter Error Error Aug 25, 2026 4:33am

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant