diff options
| author | Adam Soltys <[email protected]> | 2026-09-15 22:47:26 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-15 22:47:26 -0700 |
| commit | 398bb77165e3ff454f1401b3c114a976aae5216c (patch) | |
| tree | f362de76df685538e352b998a0839c64faf4448c /src | |
| parent | 3d706acd1edccb5c4eb0f781b52b3d302bdafa2b (diff) | |
| download | coinosv3-398bb77165e3ff454f1401b3c114a976aae5216c.tar.gz coinosv3-398bb77165e3ff454f1401b3c114a976aae5216c.zip | |
A bare @npub in a message resolves to the person's name.
Vector writes a mention as @npub1… with no nostr: prefix; ours only
resolved the prefixed form, so the raw key sat in the bubble. Bare npubs
and nprofiles, with or without the @, now render as @name and open the
profile, like the prefixed ones. Keys inside URLs are left alone.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
Diffstat (limited to 'src')
| -rw-r--r-- | src/features/messages.js | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index 0a87e15..3c48a17 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -3766,7 +3766,10 @@ export function messagesFeature(ctx) { // nip05 (a word character sits before those), and never inside a URL // (the URL token starts earlier and swallows it). const MENTION = '(?<![\\w.@/])@[A-Za-z0-9_]{2,32}(?![\\w@])'; - const NOTE_SPLIT = new RegExp('(' + MD_LINK + '|https?:\\/\\/[^\\s]+|nostr:(?:npub|nprofile|note|nevent|naddr)1[a-z0-9]+|' + MENTION + ')', 'gi'); + // A bare npub/nprofile — with or without an @ in front, no nostr: prefix — + // is how Vector (and people) write a mention; it resolves to the name too. + const BARE_KEY = '(?<![\\w/])@?(?:npub|nprofile)1[a-z0-9]{20,}(?![\\w])'; + const NOTE_SPLIT = new RegExp('(' + MD_LINK + '|https?:\\/\\/[^\\s]+|nostr:(?:npub|nprofile|note|nevent|naddr)1[a-z0-9]+|' + BARE_KEY + '|' + MENTION + ')', 'gi'); const MD_PARTS = new RegExp('^(!?)\\[([^\\]\\n]{0,300})\\]\\(\\s*<?(https?:\\/\\/[^\\s>)]+)>?[^)\\n]{0,300}\\)$', 'i'); // A YouTube link is a video, so show the video. All three shapes it comes @@ -4135,10 +4138,11 @@ export function messagesFeature(ctx) { } else if (/^https?:\/\//i.test(part)) { const pack = PACK_LINK_RE.exec(part); out.push(pack ? packLinkNode(part, pack[1]) : urlNode(part)); - } else if (/^nostr:(npub|nprofile)1/i.test(part)) { - const ref = parseNostrRef(part.slice(6)); + } else if (/^(nostr:|@?)(npub|nprofile)1/i.test(part)) { + const bare = part.replace(/^(nostr:|@)/i, ''); + const ref = parseNostrRef(bare); if (ref && ref.type === 'pubkey') out.push(h('a', { href: '#', onClick: (e) => { e.preventDefault(); openProfile(ref.pk); } }, '@' + displayName(ref.pk))); - else out.push(h('span', { class: 'faint' }, part.slice(6, 18) + '…')); + else out.push(h('span', { class: 'faint' }, bare.slice(0, 12) + '…')); } else if (/^nostr:(note|nevent)1/i.test(part)) { const ref = parseNostrRef(part.slice(6)); if (ref && ref.type === 'event') { |
