From f9573d3d62b4caa2235be0abcf95f01cc0b4a1c0 Mon Sep 17 00:00:00 2001 From: marwin Date: Tue, 4 Aug 2026 14:09:02 +0200 Subject: [PATCH] =?UTF-8?q?Reader:=20lange=20Notizen=20wurden=20im=20Rand?= =?UTF-8?q?=20zu=20fr=C3=BCh=20ausgeblendet=20(SW=20v28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _repositionMarginMarkers() filterte Einträge anhand eines festen ±60px- Fensters um den reinen Ankerpunkt, bevor die tatsächliche Kartenhöhe bekannt war. Für Notizen mit mehr Text als eine "Standard"-Karte reichte das nicht: die Karte hätte teilweise schon sichtbar sein müssen, obwohl ihr Anker noch weiter außerhalb lag — sie blieb beim Scrollen also länger verschwunden als erwartet. Vorfilter jetzt großzügig (mind. 400px bzw. die Höhe des sichtbaren Bereichs), danach ein zweiter Cull-Durchgang mit den tatsächlich gemessenen Kartenhöhen nach dem Stapeln — dadurch werden nur Einträge entfernt, die wirklich komplett außerhalb liegen. Co-Authored-By: Claude Sonnet 5 --- static/js/app.js | 18 +++++++++++++++++- static/js/sw.js | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/static/js/app.js b/static/js/app.js index 39b8ae7..b74fd8d 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -5386,6 +5386,13 @@ function _repositionMarginMarkers() { if (!readerAnnotationsMarginOpen || currentPdfDoc) return; const areaRect = markersEl.getBoundingClientRect(); + // A generous pre-filter band: a note card can be considerably taller than + // its own anchor point, so a card whose anchor is somewhat outside the + // strictly-visible area can still be partially (or fully) on-screen once + // rendered. A tight band here excluded it before it ever got a chance to + // be measured — the exact bug reported ("tall notes stay hidden until + // scrolled much further than expected"). + const band = Math.max(areaRect.height, 400); const entries = []; for (const h of currentHighlights) { let range; @@ -5394,13 +5401,14 @@ function _repositionMarginMarkers() { const rect = range.getBoundingClientRect(); if (!rect.width && !rect.height) continue; // detached/invalid const y = rect.top + rect.height / 2 - areaRect.top; - if (y < -60 || y > areaRect.height + 60) continue; // off-screen band + if (y < -band || y > areaRect.height + band) continue; entries.push({h, y}); } entries.sort((a, b) => a.y - b.y); let nextTop = -Infinity; const GAP = 4; + const rendered = []; for (const {h, y} of entries) { const hasText = !!h.note; const el = document.createElement('div'); @@ -5420,6 +5428,14 @@ function _repositionMarginMarkers() { const measured = el.getBoundingClientRect().height || (hasText ? 20 : 12); nextTop = top + measured + GAP; + rendered.push({el, top, measured}); + } + + // Now that actual card heights are known, do the real cull: drop anything + // that ended up entirely outside the visible band after stacking (e.g. + // pushed down by a very tall card above it). + for (const {el, top, measured} of rendered) { + if (top + measured < -40 || top > areaRect.height + 40) el.remove(); } } diff --git a/static/js/sw.js b/static/js/sw.js index 615ac52..08b05a4 100644 --- a/static/js/sw.js +++ b/static/js/sw.js @@ -2,7 +2,7 @@ * diora service worker — caches the app shell for offline use. */ -const CACHE = 'diora-v27'; +const CACHE = 'diora-v28'; const PODCAST_CACHE = 'diora-podcast-v1'; const SHELL = [ '/static/css/app.css',