From 4126bea113e3d2cae7fba0ed0865a6c765a51a3e Mon Sep 17 00:00:00 2001 From: John W <93501228+JGW3@users.noreply.github.com> Date: Mon, 2 Nov 2026 09:44:29 -0600 Subject: [PATCH] fix(gallery): drop the second scrollbar on the photo detail view (#6597) * fix(gallery): drop the second scrollbar on the photo detail view With a photo open on desktop, the modal body, the images container and the detail view are each height: 100%, so the container fills the body exactly. The container's inline 2px top margin (grid-view spacing) then overflows the body by 2px, and the body shows its own scrollbar next to the inspector's. Zero that margin while the detail view is open. Bumps the shared stylesheet/app cache token and the service worker cache name, since a stylesheet changed. Co-Authored-By: Claude Opus 5.5 * chore(static): leave admin.js's cache tag unchanged Co-Authored-By: Claude Opus 5.5 * fix(cache): keep upstream's service worker cache name format dev's editor tests require CACHE_NAME to match odysseus-v-pr40-editor-precache, so keep the version bump and use that suffix. Co-Authored-By: Claude Opus 5.5 --------- Co-authored-by: Claude Opus 5.5 Co-authored-by: Alexandre Teixeira --- static/css/documents-gallery-editor.css | 7 ++++ static/index.html | 46 ++++++++++++------------- static/sw.js | 46 ++++++++++++------------- tests/test_gallery_visual_static.py | 14 ++++++++ 4 files changed, 67 insertions(+), 46 deletions(-) diff --git a/static/css/documents-gallery-editor.css b/static/css/documents-gallery-editor.css index 348401983..19c7f5adb 100644 --- a/static/css/documents-gallery-editor.css +++ b/static/css/documents-gallery-editor.css @@ -339,6 +339,13 @@ mark.doc-find-mark { height: 100%; min-height: 0; } + /* The container now fills the body exactly, so its inline 2px top margin + (spacing for the grid view) would push it 2px past the body and add a + second, outer scrollbar beside the inspector's own. !important is needed + to beat the inline style. */ + .gallery-images-container:has(> #gallery-detail[style*="flex"]) { + margin-top: 0 !important; + } } .gallery-detail-image:hover .gallery-detail-rotate { opacity: 0.85; } .gallery-detail-nav-disabled { diff --git a/static/index.html b/static/index.html index b1d2031df..93b6895e2 100644 --- a/static/index.html +++ b/static/index.html @@ -247,32 +247,32 @@ real request is discarded and the font fetched a second time. --> - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - + + + + @@ -2709,7 +2709,7 @@ - + diff --git a/static/sw.js b/static/sw.js index a4f448c8f..628b0d872 100644 --- a/static/sw.js +++ b/static/sw.js @@ -7,7 +7,7 @@ // - Other static assets (images/fonts/libs): cache-first with bg refresh. // - API / non-GET: never cached. // Bump CACHE_NAME whenever the precache list or SW logic changes. -const CACHE_NAME = 'odysseus-v1134-pr40-editor-precache'; +const CACHE_NAME = 'odysseus-v1135-pr40-editor-precache'; // KaTeX resolves these from its own stylesheet, so caching the CSS without them // gives offline math fallback glyphs instead of proper typesetting. @@ -40,28 +40,28 @@ const KATEX_FONTS = [ const PRECACHE = [ '/static/js/compare/sse.js', '/', - '/static/css/00-tokens.css?v=20260929csssplit', - '/static/css/01-agent-chat.css?v=20260929csssplit', - '/static/css/02-compare.css?v=20260929csssplit', - '/static/css/03-agent-chat.css?v=20260929csssplit', - '/static/css/04-memory.css?v=20260929csssplit', - '/static/css/05-documents.css?v=20260929csssplit', - '/static/css/06-admin-settings.css?v=20260929csssplit', - '/static/css/07-documents.css?v=20260929csssplit', - '/static/css/08-skills.css?v=20260929csssplit', - '/static/css/09-gallery.css?v=20260929csssplit', - '/static/css/10-cookbook.css?v=20260929csssplit', - '/static/css/11-tasks.css?v=20260929csssplit', - '/static/css/12-gallery.css?v=20260929csssplit', - '/static/css/13-image-editor.css?v=20260929csssplit', - '/static/css/14-email.css?v=20260929csssplit', - '/static/css/15-notes.css?v=20260929csssplit', - '/static/css/16-calendar.css?v=20260929csssplit', - '/static/css/17-research.css?v=20260929csssplit', - '/static/css/documents-gallery-editor.css?v=20260929csssplit', - '/static/css/email-calendar-notes-tasks.css?v=20260929csssplit', - '/static/css/cookbook-research-memory-settings.css?v=20260929csssplit', - '/static/app.js?v=20260929csssplit', + '/static/css/00-tokens.css?v=20261007detailscroll1', + '/static/css/01-agent-chat.css?v=20261007detailscroll1', + '/static/css/02-compare.css?v=20261007detailscroll1', + '/static/css/03-agent-chat.css?v=20261007detailscroll1', + '/static/css/04-memory.css?v=20261007detailscroll1', + '/static/css/05-documents.css?v=20261007detailscroll1', + '/static/css/06-admin-settings.css?v=20261007detailscroll1', + '/static/css/07-documents.css?v=20261007detailscroll1', + '/static/css/08-skills.css?v=20261007detailscroll1', + '/static/css/09-gallery.css?v=20261007detailscroll1', + '/static/css/10-cookbook.css?v=20261007detailscroll1', + '/static/css/11-tasks.css?v=20261007detailscroll1', + '/static/css/12-gallery.css?v=20261007detailscroll1', + '/static/css/13-image-editor.css?v=20261007detailscroll1', + '/static/css/14-email.css?v=20261007detailscroll1', + '/static/css/15-notes.css?v=20261007detailscroll1', + '/static/css/16-calendar.css?v=20261007detailscroll1', + '/static/css/17-research.css?v=20261007detailscroll1', + '/static/css/documents-gallery-editor.css?v=20261007detailscroll1', + '/static/css/email-calendar-notes-tasks.css?v=20261007detailscroll1', + '/static/css/cookbook-research-memory-settings.css?v=20261007detailscroll1', + '/static/app.js?v=20261007detailscroll1', '/static/js/storage.js', '/static/js/appConfig.js', '/static/js/ui.js?v=20260916largetoolscroll1', diff --git a/tests/test_gallery_visual_static.py b/tests/test_gallery_visual_static.py index 3e6cebe9a..2e0c74e92 100644 --- a/tests/test_gallery_visual_static.py +++ b/tests/test_gallery_visual_static.py @@ -162,6 +162,20 @@ def test_gallery_body_uses_available_window_height_without_grid_crop(): assert "max-height: 60vh;" not in grid_rule +def test_gallery_detail_container_drops_grid_margin_so_body_does_not_scroll(): + # With a photo open on desktop, the modal body, the images container and + # the detail view are each `height: 100%`. The container's inline 2px top + # margin (grid-view spacing) would then overflow the body by 2px, which + # shows a second, outer scrollbar next to the inspector's own. + js = _read("static/js/gallery.js") + css = app_css() + + assert 'id="gallery-images-container" style="margin-top:2px"' in js + rule = '.gallery-images-container:has(> #gallery-detail[style*="flex"]) {' + idx = css.index(rule) + assert "margin-top: 0 !important;" in css[idx:idx + 120] + + def test_gallery_photo_search_is_not_vertically_offset(): css = app_css()