From 5984d392535450c571a7f012dd4ae0b0333675cd Mon Sep 17 00:00:00 2001 From: Local Dev Date: Thu, 22 Oct 2026 03:08:40 +0300 Subject: [PATCH] hermes signin: one Sign in button + two chips, nav + mobile dark bg Signin screen (both the Theseus addon panel and hermes.x/messenger): - Open with Theseus ID and Create a new account stay as top-level actions (unchanged). - Beneath them, a 'Sign in' divider + two chips [Name + password] [Seed phrase] drive one unified Sign in button. Toggle swaps the input area between the password form and the mnemonic textarea. The old 'Sign in with name + password' and 'Open an existing account' secondary buttons are gone. Site nav restructure (site-hermes-x/): - Header now: Hermes.X brand + Overview + Sign in icon (opens /messenger). Messenger tab, Branding tab, and Get Theseus pill are all removed from the header. - Footer carries Branding + Open Messenger + Get Theseus links as secondary nav. Branding is 'here' on the brand kit page. Mobile dark bg fix (shared.css): - color-scheme: dark on :root so mobile browsers don't flip the page into a light theme that makes the sky-blue mark unreadable. - html { background: var(--bg) } so the pre-body paint is dark too (Safari / Firefox mobile briefly show the html bg before body css loads). --- bundled-addons/hermes/panel.html | 107 +++++++++++++++++++------------ 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/bundled-addons/hermes/panel.html b/bundled-addons/hermes/panel.html index 9e7bdd1e..3acdb1b1 100644 --- a/bundled-addons/hermes/panel.html +++ b/bundled-addons/hermes/panel.html @@ -243,8 +243,6 @@
- -
@@ -253,16 +251,30 @@
You'll get a handle like alice.erm. We'll generate a seed phrase — back it up in Settings.
-
+ +
+ + Sign in + +
+ + + +
-
Only works on this device. From a new device, use seed phrase.
-
- - + + + +
You'll stay signed in. Sign out from the ⋯ menu.
@@ -687,36 +699,6 @@ $("toggleCreateBtn").addEventListener("click", () => { $("createBox").classList.toggle("show"); if ($("createBox").classList.contains("show")) $("createHandle").focus(); }); -$("toggleNamePwBtn").addEventListener("click", () => { - $("createBox").classList.remove("show"); - $("mnemonicBox").classList.remove("show"); - $("namePwBox").classList.toggle("show"); - if ($("namePwBox").classList.contains("show")) $("signinHandle").focus(); -}); -$("useNamePwBtn").addEventListener("click", async () => { - const handle = $("signinHandle").value.trim(); - const password = $("signinPassword").value; - if (!handle) { err($("signinErr"), "enter your name"); return; } - if (!password) { err($("signinErr"), "enter your password"); return; } - err($("signinErr"), ""); - const btn = $("useNamePwBtn"); const prev = btn.textContent; - btn.disabled = true; btn.textContent = "Signing in…"; - try { - const r = await bridge.invoke("getBackup", { password }); - if (!r || !r.ok) throw new Error((r && r.err) || "wrong password or no local account"); - const r2 = await bridge.invoke("init", { mnemonic: r.mnemonic, handle: handle, remember: true }); - if (!r2 || !r2.ok) throw new Error((r2 && r2.err) || "sign-in failed"); - showApp({ pkHex: r2.pkHex, npub: r2.npub, handle: r2.handle || (handle + ".erm") }); - } catch (e) { - err($("signinErr"), (e && e.message) || String(e)); - } finally { btn.disabled = false; btn.textContent = prev; } -}); -$("toggleMnemonicBtn").addEventListener("click", () => { - $("createBox").classList.remove("show"); - $("namePwBox").classList.remove("show"); - $("mnemonicBox").classList.toggle("show"); - if ($("mnemonicBox").classList.contains("show")) $("mnemonicInput").focus(); -}); $("useCreateBtn").addEventListener("click", () => { const handle = $("createHandle").value.trim(); const p1 = $("createPassword").value; @@ -726,10 +708,55 @@ $("useCreateBtn").addEventListener("click", () => { if (p1 !== p2) { err($("signinErr"), "passwords don't match"); return; } initWithOpts({ create: true, handle, password: p1 }); }); -$("useMnemonicBtn").addEventListener("click", () => { - const mnemonic = $("mnemonicInput").value; - initWithOpts({ useVault: false, mnemonic }); + +// --- unified Sign in button + chip switcher --- +function switchMethod(name) { + for (const c of document.querySelectorAll(".signin-chips .chip")) { + const active = c.dataset.method === name; + c.classList.toggle("chip-active", active); + c.style.background = active ? "var(--sky)" : "var(--panel)"; + c.style.color = active ? "#06111a" : "var(--ink)"; + c.style.borderColor = active ? "var(--sky)" : "var(--line)"; + c.style.fontWeight = active ? "600" : "400"; + } + $("methodNamepw").style.display = name === "namepw" ? "flex" : "none"; + $("methodSeed").style.display = name === "seed" ? "flex" : "none"; + state._signinMethod = name; + const focusEl = name === "namepw" ? $("signinHandle") : $("mnemonicInput"); + setTimeout(() => focusEl && focusEl.focus(), 50); +} +state._signinMethod = "namepw"; +for (const c of document.querySelectorAll(".signin-chips .chip")) { + c.addEventListener("click", () => switchMethod(c.dataset.method)); +} +$("signinBtn").addEventListener("click", async () => { + const m = state._signinMethod || "namepw"; + err($("signinErr"), ""); + if (m === "namepw") { + const handle = $("signinHandle").value.trim(); + const password = $("signinPassword").value; + if (!handle) { err($("signinErr"), "enter your name"); return; } + if (!password) { err($("signinErr"), "enter your password"); return; } + const btn = $("signinBtn"); const prev = btn.textContent; + btn.disabled = true; btn.textContent = "Signing in\u2026"; + try { + const r = await bridge.invoke("getBackup", { password }); + if (!r || !r.ok) throw new Error((r && r.err) || "wrong password or no local account"); + const r2 = await bridge.invoke("init", { mnemonic: r.mnemonic, handle, remember: true }); + if (!r2 || !r2.ok) throw new Error((r2 && r2.err) || "sign-in failed"); + showApp({ pkHex: r2.pkHex, npub: r2.npub, handle: r2.handle || handle }); + } catch (e) { + err($("signinErr"), (e && e.message) || String(e)); + } finally { btn.disabled = false; btn.textContent = prev; } + } else { + const mnemonic = $("mnemonicInput").value.trim(); + if (!mnemonic || mnemonic.split(/\s+/).length < 12) { + err($("signinErr"), "paste a 12- or 24-word mnemonic"); return; + } + initWithOpts({ useVault: false, mnemonic }); + } }); + $("popOutBtn").addEventListener("click", () => bridge.invoke("open-messages")); $("menuBtn").addEventListener("click", (e) => { e.stopPropagation();