From c115121aa79db4dd8f585fa3aa76d99e67a2fc8f Mon Sep 17 00:00:00 2001 From: ritual Date: Sat, 21 Feb 2026 21:28:33 +0000 Subject: [PATCH] Testing PWA install prompt --- index.html | 34 ++++++++++++++++++++++++++++++++ script.js | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++- style.css | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 8add3b0..bcbf4b2 100644 --- a/index.html +++ b/index.html @@ -49,6 +49,13 @@
+ +
+ 📲 + + +
+
+
+ +
+ + +
+
+
document.getElementById(id); @@ -20,7 +20,9 @@ const sApikey = $("s-apikey"); const eyeBtn = $("eye-btn"); const saveBtn = $("save-btn"); const themeToggle = $("theme-toggle"); +const mastodonVisToggle = $("mastodon-vis-toggle"); const mastodonToggle = $("mastodon-toggle"); +const mastodonRow = mastodonToggle.closest(".field"); // ── Settings ───────────────────────────────────────────────────────────────── function applyTheme(theme) { @@ -44,12 +46,25 @@ function updateThemeToggle(theme) { }); } +function applyMastodonVisibility(show) { + mastodonRow.style.display = show ? "" : "none"; +} + +function updateMastodonVisToggle(show) { + mastodonVisToggle.querySelectorAll(".theme-btn").forEach((btn) => { + const active = (btn.dataset.mastodonVis === "show") === show; + btn.classList.toggle("active", active); + btn.setAttribute("aria-pressed", active ? "true" : "false"); + }); +} + function loadSettings() { try { const raw = localStorage.getItem("spo-settings"); if (raw) settings = { ...settings, ...JSON.parse(raw) }; } catch {} applyTheme(settings.theme); + applyMastodonVisibility(settings.showMastodon ?? true); updateBadge(); mastodonToggle.checked = settings.mastodonPost ?? false; } @@ -80,6 +95,7 @@ function openModal() { sUsername.value = settings.username; sApikey.value = settings.apiKey; updateThemeToggle(settings.theme); + updateMastodonVisToggle(settings.showMastodon ?? true); overlay.classList.add("open"); document.body.style.overflow = "hidden"; // Focus first empty field @@ -121,6 +137,15 @@ mastodonToggle.addEventListener("change", () => { try { localStorage.setItem("spo-settings", JSON.stringify(settings)); } catch {} }); +mastodonVisToggle.addEventListener("click", (e) => { + const btn = e.target.closest(".theme-btn"); + if (!btn) return; + const show = btn.dataset.mastodonVis === "show"; + settings.showMastodon = show; + applyMastodonVisibility(show); + updateMastodonVisToggle(show); +}); + themeToggle.addEventListener("click", (e) => { const btn = e.target.closest(".theme-btn"); if (!btn) return; @@ -280,6 +305,36 @@ if ("serviceWorker" in navigator) { navigator.serviceWorker.register("sw.js").catch(() => {}); } +// ── Install banner ──────────────────────────────────────────────────────────── +(function () { + const isPWA = + window.matchMedia("(display-mode: standalone)").matches || + navigator.standalone === true; + if (isPWA) return; + + try { + if (localStorage.getItem("spo-install-dismissed")) return; + } catch {} + + const ua = navigator.userAgent; + let msg = null; + if (/iPad|iPhone|iPod/.test(ua)) { + msg = 'Tap Share ↑ at the bottom of Safari, then "Add to Home Screen" to install this app.'; + } else if (/Android/.test(ua)) { + msg = 'Tap the ⋮ menu in Chrome, then "Add to Home Screen" to install this app.'; + } + if (!msg) return; + + const banner = $("install-banner"); + $("install-banner-text").textContent = msg; + banner.classList.add("visible"); + + $("install-banner-close").addEventListener("click", () => { + banner.classList.remove("visible"); + try { localStorage.setItem("spo-install-dismissed", "1"); } catch {} + }); +})(); + // ── Init ────────────────────────────────────────────────────────────────────── loadSettings(); diff --git a/style.css b/style.css index 66d9e33..d644ea4 100644 --- a/style.css +++ b/style.css @@ -608,6 +608,43 @@ input::placeholder { opacity: 0.8; } +/* ── Install banner ────────────────────────────────────────────────────── */ +.install-banner { + display: none; + gap: 10px; + align-items: flex-start; + background: var(--accent-dim); + border: 1.5px solid color-mix(in srgb, var(--accent) 30%, transparent); + border-radius: var(--r); + padding: 12px 14px; + font-size: 0.875rem; + color: var(--text); + line-height: 1.5; +} + +.install-banner.visible { + display: flex; +} + +.install-banner-icon { + font-size: 1.1rem; + flex-shrink: 0; + margin-top: 1px; +} + +.install-banner-close { + background: none; + border: none; + cursor: pointer; + color: var(--muted); + font-size: 0.8rem; + padding: 2px 0 0; + margin-left: auto; + flex-shrink: 0; + line-height: 1; + -webkit-tap-highlight-color: transparent; +} + /* ── Theme segmented control ───────────────────────────────────────────── */ .theme-toggle { display: flex;