From 0fa2ea40ce21b642552d2d64e31bd80461cfa7ef Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 10 Nov 2026 11:44:52 -0700 Subject: The public chat page's button opens the chat for someone who has a wallet here, and stops telling them to sign in. "andy's having some trouble with the public chat … I can see the feed etc fine, so I am logged in" (Adam relaying Andy, 2026-11-10): /chat read "sign in to join the conversation" to a signed-in reader, and its "Open coinos" button went to the wallet, leaving him to find the chat. With an account on the device the line now reads "open the chat in Coinos to join the conversation" and the button "Join the chat", which goes to /?chat: the app takes the marker off the address and, once the wallet is open, opens the coinos community's room. A saved wallet counts as an account too (a tab opened from a link has no session yet). And /chat, /pos and /feed no longer paint the static profile shell (a card named "chat") while they load. tools/public-chat-join-test.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.2 --- src/features/messages.js | 14 ++++++++++++++ src/i18n.js | 3 ++- src/locales/it.json | 3 ++- src/public-chat.js | 9 ++++++--- 4 files changed, 24 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/features/messages.js b/src/features/messages.js index b491a5c..592c5dc 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -2332,6 +2332,13 @@ export function messagesFeature(ctx) { // An invite link opened in the browser lands here before the wallet exists. const urlInvite = typeof location !== 'undefined' ? parseInviteLink(location.href) : null; if (urlInvite) { try { history.replaceState(null, '', '/'); } catch {} } + // /?chat: the public chat page's button on a device that has an account. + // It opens the coinos community's room itself once the wallet is open + // (init below), where "Open coinos" used to leave a signed-in reader on + // the wallet to find the chat (Andy, 2026-11-10). + let urlChat = typeof location !== 'undefined' && !urlInvite && location.pathname === '/' + && /(?:^|&)chat(?:=|&|$)/.test((location.search || '').slice(1)); + if (urlChat) { try { history.replaceState(null, '', '/'); } catch {} } // coinos's own pack share link, /emojis/pack/ — the Android app // owns every v3.coinos.io path, so one tapped on a phone lands here, not // in a browser; added once a wallet is open (init below). @@ -19130,6 +19137,13 @@ export function messagesFeature(ctx) { loadLinkInvite(urlInvite); setTimeout(() => { ui.chatOpen = true; ui.msgView = 'home'; render(); }, 0); } + if (urlChat) { + urlChat = false; // once: init runs again for every wallet born in this tab + setTimeout(() => { + ui.chatOpen = true; ui.msgView = 'room'; ui.msgCommunity = COMMUNITY.community_id; + ui.msgChannel = null; ui.msgStick = true; render(); + }, 0); + } if (urlPack) { addPack(urlPack).catch(() => {}); setTimeout(() => { ui.chatOpen = true; ui.msgView = 'home'; render(); }, 0); diff --git a/src/i18n.js b/src/i18n.js index af0bdfb..06afc11 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -709,7 +709,8 @@ const STR = { publicChatTitle: '{name} community', publicChatDesc: 'Live chat: read along, sign in to join the conversation', publicChatSignIn: 'Sign in to chat', - publicChatOpenApp: 'Open coinos', + publicChatDescMember: 'Live chat: open the chat in Coinos to join the conversation', + publicChatOpenApp: 'Join the chat', publicChatLoading: 'Loading messages…', msgDelete: 'Delete message', msgNoIdentity: "Your nostr signer isn't connected. Reconnect it to send as yourself", diff --git a/src/locales/it.json b/src/locales/it.json index a9998c1..30b05a8 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -486,7 +486,8 @@ "publicChatTitle": "Community {name}", "publicChatDesc": "Chat dal vivo: leggi, accedi per partecipare alla conversazione", "publicChatSignIn": "Accedi per chattare", - "publicChatOpenApp": "Apri coinos", + "publicChatDescMember": "Chat dal vivo: apri la chat in Coinos per partecipare alla conversazione", + "publicChatOpenApp": "Partecipa alla chat", "publicChatLoading": "Caricamento messaggi…", "msgDelete": "Elimina messaggio", "msgNoIdentity": "Il tuo signer nostr non è connesso. Riconnettilo per inviare a tuo nome", diff --git a/src/public-chat.js b/src/public-chat.js index 9cce6f5..dd54342 100644 --- a/src/public-chat.js +++ b/src/public-chat.js @@ -213,7 +213,9 @@ export function mountPublicChat() { const hasAccount = (() => { try { - return !!(sessionStorage.getItem('btc-wallet-accounts') || (JSON.parse(localStorage.getItem('btc-wallet-watch') || '[]')).length); + // a session in this tab, a saved wallet (a tab opened from a link has no session yet), or a watch-only one + return !!(sessionStorage.getItem('btc-wallet-accounts') || localStorage.getItem('btc-wallet-vault') + || (JSON.parse(localStorage.getItem('btc-wallet-watch') || '[]')).length); } catch { return false; } })(); @@ -306,8 +308,9 @@ export function mountPublicChat() { h('div', { class: 'row between', style: 'align-items:center;gap:10px' }, h('div', { class: 'col', style: 'gap:2px;min-width:0' }, h('div', { class: 'chat-title' }, t('publicChatTitle', { name: COMMUNITY.name })), - h('div', { class: 'small muted' }, t('publicChatDesc'))), - h('button', { class: 'btn-primary btn-sm', style: 'flex-shrink:0', onClick: () => { location.href = '/'; } }, + h('div', { class: 'small muted' }, t(hasAccount ? 'publicChatDescMember' : 'publicChatDesc'))), + // with an account on the device the button opens the room itself (/?chat) + h('button', { class: 'btn-primary btn-sm', style: 'flex-shrink:0', onClick: () => { location.href = hasAccount ? '/?chat' : '/'; } }, hasAccount ? t('publicChatOpenApp') : t('publicChatSignIn'))), tabs), log)); -- cgit v1.2.3