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).
This commit is contained in:
parent
975edba88f
commit
5984d39253
1 changed files with 67 additions and 40 deletions
|
|
@ -243,8 +243,6 @@
|
|||
<div class="actions">
|
||||
<button class="primary" id="useVaultBtn" disabled>Open with Theseus ID</button>
|
||||
<button class="secondary" id="toggleCreateBtn">Create a new account</button>
|
||||
<button class="secondary" id="toggleNamePwBtn">Sign in with name + password</button>
|
||||
<button class="secondary" id="toggleMnemonicBtn">Open an existing account</button>
|
||||
</div>
|
||||
<div class="mnemonic" id="createBox">
|
||||
<input id="createHandle" type="text" placeholder="alice" autocomplete="off" spellcheck="false" style="font-family:inherit;font-size:13px;background:var(--panel);color:var(--ink);border:1px solid var(--line);border-radius:8px;padding:9px 10px;width:100%">
|
||||
|
|
@ -253,16 +251,30 @@
|
|||
<button class="primary" id="useCreateBtn">Create account</button>
|
||||
<div class="hint">You'll get a handle like <code>alice.erm</code>. We'll generate a seed phrase — back it up in Settings.</div>
|
||||
</div>
|
||||
<div class="mnemonic" id="namePwBox">
|
||||
|
||||
<div style="display:flex;align-items:center;gap:10px;width:100%;max-width:300px;margin-top:8px">
|
||||
<span style="flex:1;height:1px;background:var(--line)"></span>
|
||||
<span style="color:var(--mut);font-size:11.5px;letter-spacing:.4px;text-transform:uppercase">Sign in</span>
|
||||
<span style="flex:1;height:1px;background:var(--line)"></span>
|
||||
</div>
|
||||
|
||||
<div class="signin-chips" style="display:flex;gap:6px;width:100%;max-width:300px">
|
||||
<button class="chip chip-active" data-method="namepw" style="flex:1;font:inherit;font-size:12px;padding:7px 8px;background:var(--sky);color:#06111a;border:1px solid var(--sky);border-radius:6px;cursor:pointer;font-weight:600">Name + password</button>
|
||||
<button class="chip" data-method="seed" style="flex:1;font:inherit;font-size:12px;padding:7px 8px;background:var(--panel);color:var(--ink);border:1px solid var(--line);border-radius:6px;cursor:pointer">Seed phrase</button>
|
||||
</div>
|
||||
|
||||
<div id="methodNamepw" class="method" style="width:100%;max-width:300px;display:flex;flex-direction:column;gap:8px">
|
||||
<input id="signinHandle" type="text" placeholder="alice" autocomplete="username" spellcheck="false" style="font-family:inherit;font-size:13px;background:var(--panel);color:var(--ink);border:1px solid var(--line);border-radius:8px;padding:9px 10px;width:100%">
|
||||
<input id="signinPassword" type="password" placeholder="password" autocomplete="current-password" style="font-family:inherit;font-size:13px;background:var(--panel);color:var(--ink);border:1px solid var(--line);border-radius:8px;padding:9px 10px;width:100%">
|
||||
<button class="primary" id="useNamePwBtn">Sign in</button>
|
||||
<div class="hint">Only works on this device. From a new device, use seed phrase.</div>
|
||||
</div>
|
||||
<div class="mnemonic" id="mnemonicBox">
|
||||
<textarea id="mnemonicInput" placeholder="12 or 24 words, separated by spaces" autocomplete="off" spellcheck="false"></textarea>
|
||||
<button class="primary" id="useMnemonicBtn">Open</button>
|
||||
|
||||
<div id="methodSeed" class="method" style="width:100%;max-width:300px;display:none;flex-direction:column;gap:8px">
|
||||
<textarea id="mnemonicInput" placeholder="nsec1… or 12/24-word mnemonic — stays in this tab, never sent to the server" autocomplete="off" spellcheck="false" style="font-family:ui-monospace,Menlo,Consolas,monospace;font-size:12.5px;background:var(--panel);color:var(--ink);border:1px solid var(--line);border-radius:8px;padding:10px;width:100%;min-height:86px;resize:vertical"></textarea>
|
||||
<div class="hint">Paste your 12 or 24 words.</div>
|
||||
</div>
|
||||
|
||||
<button class="primary" id="signinBtn" style="width:100%;max-width:300px;margin-top:4px">Sign in</button>
|
||||
<div class="err" id="signinErr"></div>
|
||||
<div class="hint" id="vaultHint"></div>
|
||||
<div class="hint" style="margin-top:4px;max-width:300px">You'll stay signed in. Sign out from the ⋯ menu.</div>
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue