clone

a self-hosted multitenant nostr relay with sites, file storage, git hosting, and inbox and outbox delivery

offer a quiet install link in the footer when the browser allows it

Dami committed 143080a
commit
143080a91f7fced491a8d2d4ef75f25da1d08937
parent
d215c469a86aa922ef945f65fb96412fdfb774ca
author
Dami <dami.etoile@gmail.com>
4 files changed, +32 -1
Minternal/webui/bridge.js27+++++++++++++++++++++++++++
Minternal/webui/page.html2+-
Minternal/webui/style.css3+++
Mscripts/signer.test.mjs1+
M internal/webui/bridge.js +27 -0
@@ -74,6 +74,21 @@
7474 };7575 paintChrome();7676 matchMedia("(prefers-color-scheme: dark)").addEventListener("change", paintChrome);77+ // Browsers that can install the app announce it; the footer then offers78+ // a quiet link and nothing else changes until it is pressed.79+ let installPrompt = null;80+ const installButton = () => document.getElementById("install");81+ window.addEventListener("beforeinstallprompt", event => {82+ event.preventDefault();83+ installPrompt = event;84+ const button = installButton();85+ if (button) button.hidden = false;86+ });87+ window.addEventListener("appinstalled", () => {88+ installPrompt = null;89+ const button = installButton();90+ if (button) button.hidden = true;91+ });7792 const setMenu = open => {7893 const menu = document.getElementById("nav-menu");7994 if (menu) menu.open = open;
@@ -86,6 +101,18 @@
86101 shellBindings.add(rail);87102 rail.addEventListener("click", event => { if (event.target.closest("a")) setMenu(false); });88103 }104+ const install = installButton();105+ if (install && !shellBindings.has(install)) {106+ shellBindings.add(install);107+ install.hidden = !installPrompt;108+ install.addEventListener("click", async () => {109+ if (!installPrompt) return;110+ const prompt = installPrompt;111+ installPrompt = null;112+ install.hidden = true;113+ try { await prompt.prompt(); } catch {}114+ });115+ }89116 if (themeButton && !shellBindings.has(themeButton)) {90117 shellBindings.add(themeButton);91118 const label = () => { themeButton.textContent = currentTheme() === "dark" ? "light" : "dark"; };
M internal/webui/page.html +1 -1
M internal/webui/style.css +3 -0
@@ -38,6 +38,8 @@ img{max-width:100%}
3838 #who button{border:0;background:none;padding:0;color:var(--accent);font:inherit}#who button:hover{text-decoration:underline}3939 #railbox{box-sizing:border-box;padding-bottom:44px}4040 #rail-tools{position:absolute;right:0;bottom:0;margin:0;padding:10px 2ch 10px 2.5ch}41+/* The install hint sits on the footer's centre line so it never moves the prompt or the session. */42+#install{position:absolute;left:50%;top:0;transform:translateX(-50%);border:0;background:none;padding:0;color:var(--muted);font:12px var(--mono);line-height:27px;cursor:pointer}#install:hover{color:var(--ink);text-decoration:underline}#install[hidden]{display:none}4143 share-link{display:inline-block}share-link:empty{display:none}4244 #theme{border:0;background:none;padding:0;color:var(--muted);font:12px var(--mono)}#theme:hover{color:var(--ink);text-decoration:underline}4345
@@ -210,6 +212,7 @@ html,body{overflow:auto}
210212 #content>section{padding:14px 2.5ch 20px}211213 #prompt{display:none}#footer td:last-child{text-align:left;white-space:nowrap}212214 #footer{padding:0 12px}#who{font-size:11px}215+#install{left:auto;right:12px;transform:none}213216 #navigation-status:not(:empty),#session-status:not(:empty){position:absolute;bottom:100%;left:0;right:0;padding:6px 12px;background:var(--rail);border-top:1px solid var(--line);white-space:normal}214217 #split,#split>tbody,#split>tbody>tr,#split>tbody>tr>td{display:block;width:auto}215218 #tree{border-right:0;border-bottom:1px solid var(--line)}
M scripts/signer.test.mjs +1 -0