aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-10 11:23:06 -0700
committerAdam Soltys <[email protected]>2026-09-10 11:23:06 -0700
commitfaa20f7380a517f04395b2395616d75e24007fdd (patch)
tree5b077caa22dc6673710bec038e1033ffb1c5027c
parent84628442c8c4f2cf30e79f84fbbcc872ea8fe818 (diff)
downloadcoinosv3-faa20f7380a517f04395b2395616d75e24007fdd.tar.gz
coinosv3-faa20f7380a517f04395b2395616d75e24007fdd.zip
Profile posts: a missing signer opens the reconnect screen (with the nsec field), not a toast.
A pasted-nsec login is never stored, so a reload leaves the link without a signer. The post, reply and profile-edit paths checked for an identity by THROWING the "signer isn't connected" message, which the composer then caught and toasted — bypassing noIdToast, whose whole job is to open the reconnect screen where the nsec (or extension / bunker) can be re-entered. Those paths now go through requireIdentity(): it opens the screen (or toasts, when there's no link to reconnect) and throws a silent error the callers don't repeat. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Nw1Dijik1tLVKRM1WkU7xE
-rw-r--r--src/features/messages.js23
1 files changed, 15 insertions, 8 deletions
diff --git a/src/features/messages.js b/src/features/messages.js
index 0a828bb..a57ec8e 100644
--- a/src/features/messages.js
+++ b/src/features/messages.js
@@ -233,6 +233,16 @@ export function messagesFeature(ctx) {
if (!wallet.watchOnly && hook('nostrReconnectPrompt')) return;
toast(t(wallet.watchOnly ? 'msgLockedChat' : 'msgNoIdentity'));
};
+ // Thrown by the publish paths after noIdToast already did the talking
+ // (opened the reconnect screen, or toasted): callers must not toast it
+ // again — a pasted-nsec login that lost its signer on reload used to get
+ // the toast INSTEAD of the screen with the nsec field this way.
+ class NoIdentity extends Error { constructor() { super(t('msgNoIdentity')); this.silent = true; } }
+ const requireIdentity = async () => {
+ const id = await identity();
+ if (!id) { noIdToast(); throw new NoIdentity(); }
+ return id;
+ };
// ---- shared runtime -----------------------------------------------------
@@ -2065,8 +2075,7 @@ export function messagesFeature(ctx) {
// signer alone can take seconds), swapped for the signed event on success
// and withdrawn on failure.
async function publishPost(text) {
- const id = await identity();
- if (!id) throw new Error(t('msgNoIdentity'));
+ const id = await requireIdentity();
const temp = {
id: 'pending:' + Math.random().toString(36).slice(2),
pubkey: id.pubkey, content: text, created_at: Math.floor(Date.now() / 1000),
@@ -2093,8 +2102,7 @@ export function messagesFeature(ctx) {
}
async function publishReply(c, s, text) {
- const id = await identity();
- if (!id) throw new Error(t('msgNoIdentity'));
+ const id = await requireIdentity();
const target = c.replies.find((e) => e.id === s.focusId) || c.root || s.seed;
const rootId = c.rootId;
const pTags = [...new Set([
@@ -2148,7 +2156,7 @@ export function messagesFeature(ctx) {
const inp = document.querySelector('.thread-reply-input');
if (inp) inp.value = '';
toast(t('threadReplied'));
- } catch (e) { toast(e.message); }
+ } catch (e) { if (!e.silent) toast(e.message); }
s.sending = false; render();
},
}, s.sending ? h('span', { class: 'spinner sm' }) : t('threadReplySend')));
@@ -2182,8 +2190,7 @@ export function messagesFeature(ctx) {
}
async function publishProfileFields(fields, opts = {}) {
- const id = await identity();
- if (!id) throw new Error(t('msgNoIdentity'));
+ const id = await requireIdentity();
const evs = await queryOn([...new Set([...PROFILE_RELAYS, ...DM_RELAYS])], { kinds: [0], authors: [id.pubkey] }, 3000);
const newest = evs.sort((a, b) => b.created_at - a.created_at)[0];
let base = {};
@@ -2493,7 +2500,7 @@ export function messagesFeature(ctx) {
try { await publishPost(text); toast(t('profPosted')); }
catch (e) {
ui.profCompose = text;
- toast(e.message || String(e));
+ if (!e.silent) toast(e.message || String(e));
render();
}
} }, t('profPostBtn')),