From 41c4667eb4848aa8c8c8b7a459f1d3ba25869fc8 Mon Sep 17 00:00:00 2001 From: Masahiko AMANO Date: Mon, 6 Jul 2026 22:35:47 +0300 Subject: [PATCH] feat(frontend): enlarge viewer prev/next into full-height tap zones MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Paging previously required hitting a small arrow circle pinned near each edge. Replace them with full-height left/right tap zones (30%, capped at 220px) so a tap anywhere on that side pages. The arrow stays as a chip near the edge with a hover-only hint gradient; the zones sit above the image, and the "Replacing…" overlay is lifted above them so an in-flight content replace still blocks paging. Co-Authored-By: Claude Opus 4.8 --- .../src/lib/components/file/FileViewer.svelte | 107 +++++++++++------- 1 file changed, 68 insertions(+), 39 deletions(-) diff --git a/frontend/src/lib/components/file/FileViewer.svelte b/frontend/src/lib/components/file/FileViewer.svelte index abc5283..d49eec3 100644 --- a/frontend/src/lib/components/file/FileViewer.svelte +++ b/frontend/src/lib/components/file/FileViewer.svelte @@ -499,39 +499,43 @@ {/if} - + {#if prevId} {/if} {#if nextId} {/if} @@ -777,7 +781,7 @@ .preview-busy { position: absolute; inset: 0; - z-index: 2; + z-index: 4; /* above the nav zones — an in-flight replace blocks paging */ display: flex; flex-direction: column; align-items: center; @@ -818,33 +822,58 @@ background-color: #1a1010; } - /* ---- Nav buttons ---- */ - .nav-btn { + /* ---- Nav zones ---- + Each covers the full-height left/right portion of the preview so paging + only needs a tap on that side, not a precise hit on the arrow. They sit + above the image, so over a full-width image the sides page and the centre + still opens the original. The dark hint gradient shows on hover only, to + keep photos clean on touch where there is no hover. */ + .nav-zone { position: absolute; - top: 50%; - transform: translateY(-50%); - width: 40px; - height: 40px; - border-radius: 50%; + top: 0; + bottom: 0; + width: 30%; + max-width: 220px; border: none; - background-color: rgba(0, 0, 0, 0.55); - color: #fff; + background: none; + padding: 0 12px; display: flex; align-items: center; - justify-content: center; cursor: pointer; - transition: background-color 0.15s; - } - - .nav-btn:hover { - background-color: rgba(0, 0, 0, 0.8); + z-index: 3; + -webkit-tap-highlight-color: transparent; } .nav-prev { - left: 10px; + left: 0; + justify-content: flex-start; } .nav-next { - right: 10px; + right: 0; + justify-content: flex-end; + } + + .nav-prev:hover { + background: linear-gradient(to right, rgba(0, 0, 0, 0.3), transparent); + } + .nav-next:hover { + background: linear-gradient(to left, rgba(0, 0, 0, 0.3), transparent); + } + + .nav-chip { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 50%; + background-color: rgba(0, 0, 0, 0.55); + color: #fff; + transition: background-color 0.15s; + } + + .nav-zone:hover .nav-chip { + background-color: rgba(0, 0, 0, 0.8); } /* ---- Metadata panel ---- */