aboutsummaryrefslogtreecommitdiff
path: root/public/app.js
diff options
context:
space:
mode:
authordax <me@dax.ist>2026-08-05 09:19:53 +0100
committerdax <me@dax.ist>2026-08-05 09:19:53 +0100
commite0663c2f0681662fb599bbf0ac0d45ab8385aa79 (patch)
tree654fee764b20e9dbf985a87c80d539ffe27c217c /public/app.js
parent51847eceda8057c2e6daaf394cf337f231b750b2 (diff)
preview loading/blank state: hide old thumb instantly while new loads, 1s spinner fallback; keep preview hidden until scroll or mouse move, reset after click/keyboard navigation
Diffstat (limited to 'public/app.js')
-rw-r--r--public/app.js37
1 files changed, 33 insertions, 4 deletions
diff --git a/public/app.js b/public/app.js
index f323b22..4a55cb9 100644
--- a/public/app.js
+++ b/public/app.js
@@ -34,6 +34,7 @@ let panY = 0
let scale = 1
let userZoomed = false
let drag = null
+let previewsShown = false
const TOUCH = typeof window.matchMedia === "function" && window.matchMedia("(hover: none)").matches
@@ -323,6 +324,7 @@ function adjacentTile(id, dir) {
}
function traverseFrom(id, dir) {
+ previewsShown = false
followEnabled = false
const back = adjacentTile(id, dir)
if (back) {
@@ -377,18 +379,40 @@ function renderTileZones(id) {
if (!best) return
const els = []
const preview = document.createElement("div")
- preview.className = "preview"
+ preview.className = "preview hidden"
const previewImg = document.createElement("img")
previewImg.alt = ""
- previewImg.loading = "lazy"
preview.appendChild(previewImg)
+ const spinner = document.createElement("div")
+ spinner.className = "spinner"
+ preview.appendChild(spinner)
let hotDir = null
+ let loadTimer = 0
+ const doneLoading = () => {
+ clearTimeout(loadTimer)
+ preview.classList.remove("loading", "slow")
+ }
+ previewImg.onload = doneLoading
+ previewImg.onerror = doneLoading
const showAt = (x) => {
+ previewsShown = true
+ preview.classList.remove("hidden")
preview.style.left = x.p.rect.x + "px"
preview.style.top = x.p.rect.y + "px"
preview.style.width = x.p.rect.w + "px"
preview.style.height = x.p.rect.h + "px"
- previewImg.src = x.p.info.thumb
+ const next = new URL(x.p.info.thumb, location.href).href
+ if (previewImg.src === next && previewImg.complete) {
+ doneLoading()
+ return
+ }
+ clearTimeout(loadTimer)
+ preview.classList.add("loading")
+ preview.classList.remove("slow")
+ previewImg.src = next
+ loadTimer = setTimeout(() => {
+ if (preview.classList.contains("loading")) preview.classList.add("slow")
+ }, 1000)
}
const reset = () => {
hotDir = null
@@ -424,7 +448,7 @@ function renderTileZones(id) {
els.push(z)
}
world.appendChild(preview)
- showAt(best)
+ if (previewsShown && best) showAt(best)
zones.set(id, { els, key, preview, reset })
}
@@ -496,6 +520,10 @@ stage.addEventListener("pointerdown", (e) => {
})
stage.addEventListener("pointermove", (e) => {
+ if (!previewsShown) {
+ const entry = zones.get(cur && cur.id)
+ if (entry && entry.reset) entry.reset()
+ }
if (pointers.has(e.pointerId)) {
pointers.set(e.pointerId, { x: e.clientX, y: e.clientY })
if (pointers.size === 2 && pinchDist > 0) {
@@ -541,6 +569,7 @@ stage.addEventListener("pointerup", (e) => {
const id = Number(tile.dataset.id)
followEnabled = false
if (cur && cur.id === id) return
+ previewsShown = false
setCurrent(id, tiles.get(id).rect)
})