aboutsummaryrefslogtreecommitdiff
path: root/public
diff options
context:
space:
mode:
authordax <me@dax.ist>2026-08-05 10:31:32 +0100
committerdax <me@dax.ist>2026-08-05 10:31:32 +0100
commitf2e2648e702333ea63ab480f6e1ff4050e2880da (patch)
treeef06d1cd33d0a5345f617c4323af811c077faedf /public
parent94b4f4c2012da7714e97fc6a14cd165e456b569f (diff)
restore splash overlay
Diffstat (limited to 'public')
-rw-r--r--public/app.css17
-rw-r--r--public/app.js40
-rw-r--r--public/index.html9
3 files changed, 61 insertions, 5 deletions
diff --git a/public/app.css b/public/app.css
index acfa24a..111ae65 100644
--- a/public/app.css
+++ b/public/app.css
@@ -139,6 +139,23 @@ html, body {
}
}
+#splash {
+ position: fixed;
+ inset: 0;
+ z-index: 10;
+ display: grid;
+ place-content: center;
+ justify-items: center;
+ gap: 14px;
+ text-align: center;
+ background: var(--bg);
+ transition: opacity .4s, visibility .4s;
+}
+#splash.hide { opacity: 0; visibility: hidden; pointer-events: none; }
+#splash h1 { margin: 0; font-size: 44px; font-weight: 300; letter-spacing: .18em; }
+#splash h1 .dot { color: var(--ring); }
+#splash p { max-width: 34ch; color: var(--muted); margin: 0; font-size: 15px; line-height: 1.6; }
+
#import-state {
position: fixed;
inset: 0;
diff --git a/public/app.js b/public/app.js
index 6e2b36e..993b40b 100644
--- a/public/app.js
+++ b/public/app.js
@@ -11,6 +11,8 @@ const toastEl = $("#toast")
const progressEl = $("#progress")
const progressFill = $("#progress-fill")
const progressText = $("#progress-text")
+const splash = $("#splash")
+const startBtn = $("#start")
addEventListener("error", (e) => {
toast(`error: ${e.message || "script failed"}`, true)
@@ -674,18 +676,50 @@ async function beginWalk() {
} catch { /* ignore */ }
}
+let hasPhotos = false
+
;(async () => {
try {
const r = await fetch("/api/paths")
const data = await r.json()
- if (data.total) await beginWalk()
- else showImportState()
- } catch {
+ hasPhotos = !!data.total
+ } catch { /* assume empty library */ }
+ if (!hasPhotos) {
+ splash.hidden = true
showImportState()
}
initDirectHint()
})()
+const MIN_READ = 1500
+const splashShownAt = Date.now()
+let splashTimer = 0
+
+function launch() {
+ if (started) return
+ clearTimeout(splashTimer)
+ splash.classList.add("hide")
+ if (hasPhotos) beginWalk()
+ else { started = true; showImportState() }
+}
+
+function noteActivity() {
+ if (started) return
+ const left = MIN_READ - (Date.now() - splashShownAt)
+ if (left <= 0) launch()
+ else {
+ clearTimeout(splashTimer)
+ splashTimer = setTimeout(launch, left)
+ }
+}
+
+startBtn.addEventListener("click", launch)
+addEventListener("pointermove", noteActivity)
+addEventListener("pointerdown", noteActivity)
+addEventListener("keydown", noteActivity)
+addEventListener("wheel", noteActivity)
+addEventListener("touchstart", noteActivity)
+
let toastTimer = 0
function toast(msg, isError = false) {
diff --git a/public/index.html b/public/index.html
index 9bda073..bee7574 100644
--- a/public/index.html
+++ b/public/index.html
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="dark">
<title>pathways</title>
- <link rel="stylesheet" href="/app.css?v=60">
+ <link rel="stylesheet" href="/app.css?v=61">
</head>
<body>
<main id="stage">
@@ -22,6 +22,11 @@
<p id="direct-hint" class="direct-hint" hidden>upload slow? use the direct link <a id="direct-link" href="#"></a></p>
</div>
</main>
+ <div id="splash">
+ <h1>pathways<span class="dot">.</span></h1>
+ <p>four paths, one per direction. walk them.</p>
+ <button id="start">start</button>
+ </div>
<input id="file" type="file" accept="image/jpeg,image/png,image/webp" multiple>
<div id="drop"><span>drop photos to import</span></div>
<div id="progress" hidden>
@@ -29,6 +34,6 @@
<span id="progress-text"></span>
</div>
<div id="toast" role="status" aria-live="polite"></div>
- <script src="/app.js?v=60"></script>
+ <script src="/app.js?v=61"></script>
</body>
</html>