From dc8f4b841ff57f4ef74597c2f80b6f90b352db13 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 3 Aug 2026 21:04:09 -0700 Subject: Messages in the header, and a room you can tell is alive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The header carries a message button again, left of the wallet selector, with a red dot when a conversation is waiting. Unread is a per-thread watermark on the newest message from someone else, kept in the rumor's own created_at so it means the same thing on every device it syncs to. Rooms subscribe at startup now, or the dot could not speak for a community nobody was listening to. Communities no longer buzz a phone by default: push registration only carries the stream keys of communities you have opted in, per community, from a bell in the room header. DMs and payments are unchanged. Presence and typing ride the channel stream as 21059 wraps, so who is around stays inside the community's encryption rather than becoming a public status. Measured against relay.coinos.io and nos.lol, neither actually drops NIP-01 ephemeral kinds, so beats carry a NIP-40 expiration and relay.coinos.io sweeps kind 21059 hourly — and presence is dated by the beat, never by arrival, or a replayed beat would light up the whole member list. The member list follows Telegram: online, then last seen in minutes and hours, then a vague 'recently' rather than advertising how long someone has been gone. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi --- src/app.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/app.js') diff --git a/src/app.js b/src/app.js index fdbe8f4..f2f9ee3 100644 --- a/src/app.js +++ b/src/app.js @@ -1448,6 +1448,23 @@ function avatarMenu() { : null; })()); } +// Messages sit one tap away, left of the wallet selector. The dot is presence, +// not a count — it says "someone's waiting", and the chat list says who. +function messagesBtn() { + const me = (featureHook('nostrLoginIdentity') || {}).pubkey || (wallet.nostrPubkey && wallet.nostrPubkey()); + if (!me) return null; + const unread = featureHook('unreadMessages') || 0; + return h('button', { + class: 'header-msgs' + (unread ? ' unread' : ''), + title: t('msgDmsTitle'), + 'aria-label': t('msgDmsTitle'), + onClick: () => { ui.profilePk = null; ui.chatOpen = true; ui.msgView = 'home'; render(); }, + }, h('span', { + class: 'hm-ico', + html: '', + })); +} + function brandHeader(withLock) { const acc = activeAccount(); return h( @@ -1460,6 +1477,7 @@ function brandHeader(withLock) { ), withLock ? h('div', { class: 'row gap6', style: 'align-items:center' }, + messagesBtn(), h('button', { class: 'btn-sm', onClick: () => { ui.screen = 'accounts'; render(); } }, acc ? acc.label : t('accounts')), avatarMenu()) -- cgit v1.2.3