From 036c3b134daaeb1aa9780629ae3e84d3881dbc62 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 27 Aug 2026 23:17:24 -0700 Subject: Steady hands at the door: during sign-in the button's icon becomes the spinner and the label stays put — same size, no column reflow — and the passkey button now shows the same quiet work instead of just dimming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_019eA8JRq9Wr7z2fRQk99HLi --- src/features/nostrlogin.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/features/nostrlogin.js b/src/features/nostrlogin.js index 687a389..911358a 100644 --- a/src/features/nostrlogin.js +++ b/src/features/nostrlogin.js @@ -247,6 +247,8 @@ export function nostrLoginFeature(ctx) { // ours would just be a second question. async function passkeyLogin(run) { ui.nostrLoginError = ''; + ui.nostrLoginVia = 'passkey'; + render(); const pass = await import('../passkey.js'); try { const sk = await pass.passkeySignIn(); @@ -261,6 +263,9 @@ export function nostrLoginFeature(ctx) { if (!/NotAllowed|abort/i.test(String(e2.name || '') + e2.message)) ui.nostrLoginError = e2.message; render(); } + } finally { + ui.nostrLoginVia = null; + render(); } } @@ -269,9 +274,13 @@ export function nostrLoginFeature(ctx) { // Person + key, stroke style matching the app's other line icons. const PASSKEY_MARK = ''; - const markedLabel = (mark, label) => + // `spinning` swaps the ICON for a same-sized spinner and keeps the label — + // the button must not change size mid-login, or the whole column shifts. + const markedLabel = (mark, label, spinning) => h('span', { style: 'display:flex;align-items:center;justify-content:center;gap:8px' }, - h('span', { style: 'display:flex;flex-shrink:0', html: mark }), + spinning + ? h('span', { class: 'spinner sm', style: 'flex-shrink:0' }) + : h('span', { style: 'display:flex;flex-shrink:0', html: mark }), label); // Google + passkey, with their transient status rows — shared between the @@ -282,10 +291,10 @@ export function nostrLoginFeature(ctx) { return [ h('button', { class: 'btn-block', style: pad, disabled: ui.nostrLoginBusy, onClick: () => googleLogin(run) }, - ui.nostrLoginVia === 'google' ? h('span', { class: 'spinner sm' }) : markedLabel(GOOGLE_MARK, t('nlGoogle'))), + markedLabel(GOOGLE_MARK, t('nlGoogle'), ui.nostrLoginVia === 'google')), hasPasskey ? h('button', { class: 'btn-block', style: pad, disabled: ui.nostrLoginBusy, - onClick: () => passkeyLogin(run) }, markedLabel(PASSKEY_MARK, t('nlPasskey'))) + onClick: () => passkeyLogin(run) }, markedLabel(PASSKEY_MARK, t('nlPasskey'), ui.nostrLoginVia === 'passkey')) : null, ]; } -- cgit v1.2.3