thermograph/frontend/static/ios-install.js
Emi Griffith d6df04eab2 Subtree-merge thermograph-frontend (origin/main) into frontend/
git-subtree-dir: frontend
git-subtree-mainline: a4be7066e5
git-subtree-split: 3a98146da4
2026-07-22 22:01:11 -07:00

73 lines
3 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// A small, dismissible "Add to Home Screen" hint for iPhone/iPad visitors.
//
// iOS only grants Web Push to a site the user has added to the Home Screen via
// Safari's Share sheet (iOS 16.4+). There is no beforeinstallprompt on iOS, so
// the only nudge available is telling people where the control is. This module
// shows that nudge — and only when it can actually help: real iOS Safari, not
// already installed, not previously dismissed. Everything degrades to nothing.
// Not the "tg:" prefix — cache.js sweeps that namespace on every load. The
// durable app prefer­ences ("thermograph:unit", "thermograph:loc") use this one.
const KEY = "thermograph:ios-a2hs";
function isIOS() {
const ua = navigator.userAgent || "";
// iPadOS 13+ reports as "Macintosh"; a touch point count disambiguates it.
return /iphone|ipad|ipod/i.test(ua) ||
(/Macintosh/.test(ua) && (navigator.maxTouchPoints || 0) > 1);
}
function isStandalone() {
return window.navigator.standalone === true ||
(window.matchMedia && window.matchMedia("(display-mode: standalone)").matches);
}
function isSafari() {
// Add to Home Screen only works from Safari proper — not Chrome (CriOS),
// Firefox (FxiOS), Edge (EdgiOS), Opera (OPiOS), or most in-app webviews.
const ua = navigator.userAgent || "";
if (/crios|fxios|edgios|opios/i.test(ua)) return false;
return /safari/i.test(ua);
}
function dismissed() {
try { return localStorage.getItem(KEY) === "off"; } catch (e) { return false; }
}
function remember() {
try { localStorage.setItem(KEY, "off"); } catch (e) {}
}
function build() {
const el = document.createElement("div");
el.className = "ios-a2hs";
el.setAttribute("role", "note");
el.setAttribute("aria-label", "Install Thermograph on your Home Screen");
// The share glyph mirrors iOS's own Share icon so the instruction is scannable.
el.innerHTML =
'<svg class="ios-a2hs-share" viewBox="0 0 24 24" aria-hidden="true" fill="none" ' +
'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' +
'<path d="M12 3v12"/><path d="M8 7l4-4 4 4"/>' +
'<path d="M5 12v7a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-7"/></svg>' +
'<div class="ios-a2hs-text"><b>Add Thermograph to your Home Screen</b>' +
'<span>Tap Share, then <b>Add to Home Screen</b>. Its how to get weather alerts on iPhone.</span></div>' +
'<button type="button" class="ios-a2hs-x" aria-label="Dismiss">×</button>';
el.querySelector(".ios-a2hs-x").addEventListener("click", () => {
remember();
el.remove();
});
return el;
}
function maybeShow() {
if (!isIOS() || isStandalone() || !isSafari() || dismissed()) return;
if (document.querySelector(".ios-a2hs")) return;
document.body.appendChild(build());
}
// Wait a beat so the hint never competes with first paint, and only on an
// interactive document.
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => setTimeout(maybeShow, 1200));
} else {
setTimeout(maybeShow, 1200);
}