From ccced4634115777fcbedd221f1324612e00b61d5 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 3 Aug 2026 22:31:48 -0700 Subject: Offer the signer back where you'd notice it's missing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A remote signer dropped by a reload now says so above the composer, with a button that reconnects in place — rather than letting someone write a message and only then be told it can't be sent as them. Failing that it opens the nostr settings, where logging in again is the fallback. Every remote-signer login made before sessions were persisted lands in exactly this state once. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi --- src/features/messages.js | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src/features') diff --git a/src/features/messages.js b/src/features/messages.js index 74abdd8..7f21d53 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -1226,7 +1226,31 @@ export function messagesFeature(ctx) { }); }; + // A remote signer that a reload dropped: say so where the typing happens, + // rather than letting someone write a message and only then be told. The + // identity itself is still known — it's the ability to sign as it that's + // missing — so this offers to fetch it back rather than to log in again. + function signerNotice() { + const id = hook('nostrLoginIdentity'); + if (!id || id.signer || ui.msgReconnected) return null; + return h('div', { class: 'row gap6 chat-signer-off', style: 'align-items:center' }, + h('span', { class: 'small muted grow' }, t('msgSignerOff')), + h('button', { + class: 'btn-sm', disabled: !!ui.msgReconnecting, + onClick: async () => { + ui.msgReconnecting = true; render(); + const s = await hook('nostrLoginResume'); + ui.msgReconnecting = false; + if (s) { ui.msgReconnected = true; toast(t('msgSignerBack')); } + else { ui.chatOpen = false; ui.screen = 'wallet'; ui.tab = 'settings'; ui.settingsPage = 'nostr'; } + render(); + }, + }, ui.msgReconnecting ? h('span', { class: 'spinner sm' }) : t('msgReconnect'))); + } + const composer = (placeholder, onSend, onType) => + h('div', { class: 'col', style: 'gap:6px' }, + signerNotice(), h('div', { class: 'chat-compose' }, h('input', { class: 'grow', type: 'text', id: 'msg-draft', placeholder, @@ -1235,7 +1259,7 @@ export function messagesFeature(ctx) { onKeydown: (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); onSend(); } }, }), h('button', { class: 'btn-primary btn-sm', disabled: ui.msgSending, onClick: onSend }, - ui.msgSending ? h('span', { class: 'spinner sm' }) : t('msgSend'))); + ui.msgSending ? h('span', { class: 'spinner sm' }) : t('msgSend')))); // ---- home --------------------------------------------------------------- -- cgit v1.2.3