Skip to content

feat(images): zoom into the full resolution of a picture - #88

Merged
skjnldsv merged 1 commit into
mainfrom
feat/zoom-native-resolution
Oct 2, 2026
Merged

skjnldsv merged 1 commit into
mainfrom
feat/zoom-native-resolution

Conversation

@skjnldsv

@skjnldsv skjnldsv commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Tall pictures like comics could not be zoomed into far enough to read them.

Fixes nextcloud/viewer#2391

The zoom stopped at 5x, but raising that alone would not have helped: the viewer shows a preview sized to the screen (previewSize in previewUtils.ts), so past 1x it only enlarges the preview's pixels. For a tall picture that preview is tiny. An 800×10000 comic fitted to a 900 px high viewer comes as a preview about 72 px wide.

The first zoom (wheel, pinch or double click) now fetches the largest preview the server renders, asking for 8192 px. The server never renders past the original nor past its own preview_max_x/preview_max_y (4096 by default), so what comes back is as much detail as there is. Zooming goes on while it loads, up to the old 5x. It is loaded and decoded in the background (image.decode()), so a large picture does not stall a frame or two when it is swapped in, then swapped in place: same zoom, same pan, at the size the picture is already drawn at (refitting from its own size could round it a pixel off), and without a second loaded for the viewer. The zoom limit then follows that preview: up to 4 screen pixels per pixel of it, and never less than the 5x it always allowed. A preview no sharper than the one shown is not swapped in.

Choices worth a look:

  • Fetched on the first zoom, not with the picture. Rendering a large preview is real work for the server, and most pictures are looked at without zooming. Fetching it eagerly is a one-line change if we want that instead.
  • A share that forbids downloading gets it through the x-nc-preview header, like its first preview (fix(preview): show previews on shares that forbid downloading #51).
  • A file shown from its own bytes (no preview, a gif, an svg) or from a preview an app chose (previewUrl) fetches nothing more; its zoom limit follows its own resolution.
  • 4 screen pixels per image pixel is a guess at what is still useful for small text; easy to change.

Unit tests cover the fetch on the first zoom only, the swap keeping the drawn size, preloadImage answering only once decoded, the limit following the detail (16x for 4000 px shown 1000 wide), 5x for a picture already shown in full, a failed fetch keeping the picture, the restricted share path and no fetch for a file shown as is; the three behaviour ones fail on main. Not tried in a browser against a real server: the playground has no preview endpoint that renders sizes.

👾 This pull request was assisted by Claude Code, commits carry an Assisted-by trailer.

@skjnldsv skjnldsv added AI assisted status: review Waiting for reviews type: enhancement 🚀 New feature or request labels Oct 2, 2026
@codecov

codecov Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.73585% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.74%. Comparing base (76f651a) to head (2bc70a3).

Files with missing lines Patch % Lines
lib/components/Images.vue 83.95% 12 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #88      +/-   ##
==========================================
+ Coverage   89.59%   89.74%   +0.14%     
==========================================
  Files          39       39              
  Lines        2855     2954      +99     
  Branches      599      635      +36     
==========================================
+ Hits         2558     2651      +93     
- Misses        290      295       +5     
- Partials        7        8       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The viewer shows a preview sized to the screen, and capped the zoom at
five times it, so zooming in only ever enlarged its pixels: a tall comic
fitted to the viewer could not be read at all. The first zoom now fetches
the largest preview the server renders, decodes it in the background and
swaps it in at the size the picture is drawn at, and lets the zoom go
until one of its pixels is four on screen, never less than the five
times it always allowed. Zooming goes on while it loads.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: John Molakvoæ <14975046+skjnldsv@users.noreply.github.com>
@skjnldsv
skjnldsv force-pushed the feat/zoom-native-resolution branch from 0309bf9 to 2bc70a3 Compare October 2, 2026 05:53
@skjnldsv
skjnldsv merged commit 5dd32e5 into main Oct 2, 2026
19 of 20 checks passed
@skjnldsv
skjnldsv deleted the feat/zoom-native-resolution branch October 2, 2026 05:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI assisted status: review Waiting for reviews type: enhancement 🚀 New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Increase Maximum Zoom in Viewer

1 participant