From 9fc039dd6b2b8168056d7118cab29d58a303f282 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sun, 2 Aug 2026 22:51:04 -0700 Subject: Header menu survives watch-only wallets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A watch-only wallet has no nostr identity, and the whole avatar menu — including Settings and Logout — vanished with it. The menu now shows a neutral face and keeps the keyless items; Edit profile and Messages appear only when an identity exists. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi --- src/app.js | 13 +++++++++---- src/style.css | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/app.js b/src/app.js index f2955da..c7e488e 100644 --- a/src/app.js +++ b/src/app.js @@ -1344,8 +1344,13 @@ function lock() { // cache + punk fallback); without that feature there's no menu. function avatarMenu() { const me = (featureHook('nostrLoginIdentity') || {}).pubkey || (wallet.nostrPubkey && wallet.nostrPubkey()); - const node = me && featureHook('headerAvatar', me); - if (!node) return null; + // No identity (watch-only wallet): the menu still exists — Settings and + // Logout don't need keys — behind a neutral face. + const node = (me && featureHook('headerAvatar', me)) + || h('span', { + class: 'chat-avatar header-ava fallback', + html: '', + }); const item = (label, fn) => h('button', { class: 'icon-select-item', onClick: () => { ui.avatarMenu = false; fn(); render(); }, @@ -1356,9 +1361,9 @@ function avatarMenu() { ? h('span', {}, h('div', { class: 'menu-backdrop', onClick: () => { ui.avatarMenu = false; render(); } }), h('div', { class: 'icon-select-menu avatar-menu' }, - item(t('profEdit'), () => featureHook('showProfile', me)), + me ? item(t('profEdit'), () => featureHook('showProfile', me)) : null, item(t('tabSettings'), () => { ui.chatOpen = false; ui.profilePk = null; ui.screen = 'wallet'; ui.tab = 'settings'; ui.settingsPage = null; }), - item(t('msgDmsTitle'), () => { ui.profilePk = null; ui.chatOpen = true; }), + me ? item(t('msgDmsTitle'), () => { ui.profilePk = null; ui.chatOpen = true; }) : null, item(t('logout'), () => lock()))) : null); } diff --git a/src/style.css b/src/style.css index 2a2cf4c..ca85a8c 100644 --- a/src/style.css +++ b/src/style.css @@ -405,3 +405,4 @@ hr.divider { margin: 16px 0; } .avatar-menu { position: absolute; right: 0; top: calc(100% + 8px); z-index: 41; min-width: 170px; } .chat-avatar.fallback.loading { background: var(--surface2); } .wallet-row-btn { font-size: 19px; line-height: 1; padding: 8px 12px; } +.chat-avatar.header-ava.fallback { align-items: center; justify-content: center; display: flex; color: var(--muted); } -- cgit v1.2.3