diff options
Diffstat (limited to 'public')
| -rw-r--r-- | public/app.css | 17 | ||||
| -rw-r--r-- | public/app.js | 40 | ||||
| -rw-r--r-- | public/index.html | 9 |
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> |
