diff options
| author | Adam Soltys <[email protected]> | 2026-08-26 07:55:28 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-26 07:55:28 -0700 |
| commit | 5b92c9384074e0d94c784193be00f03a08bb9599 (patch) | |
| tree | 6ec1c12af97cde6cd4b8b92f67c67c7832257eae /src/features | |
| parent | 14817c69079cd4cf92b0e7a0e630e68d4c8211c0 (diff) | |
| download | coinosv3-5b92c9384074e0d94c784193be00f03a08bb9599.tar.gz coinosv3-5b92c9384074e0d94c784193be00f03a08bb9599.zip | |
The old address book habit carries over: v3.coinos.io/<username> opens that user's profile — the server already hands every stray path to the app, which now reads a lone name (or npub, or bare key) off the doormat, asks the registrar who lives there, and shows you in
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019eA8JRq9Wr7z2fRQk99HLi
Diffstat (limited to 'src/features')
| -rw-r--r-- | src/features/messages.js | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index 9336f7c..f563435 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -25,6 +25,7 @@ import { import { makeDMRumor, unwrapDM, wrapDM } from '../dm.js'; import { saveInbox } from '../dm-inbox.js'; import { makeSearcher, resultRows, fallbackAvatar } from '../recipient-search.js'; +import { getNetwork } from '../api.js'; import { hexToBytes, bytesToHex } from '@noble/hashes/utils'; import { t } from '../i18n.js'; @@ -607,6 +608,18 @@ export function messagesFeature(ctx) { const urlInvite = typeof location !== 'undefined' ? parseInviteLink(location.href) : null; if (urlInvite) { try { history.replaceState(null, '', '/'); } catch {} } + // coinos.io/<username> parity: a claimed name (or a raw npub / hex key) as + // the whole URL path deep-links to that profile. Real files never reach the + // app — the server tries them first — and gift/invite links carry their own + // multi-segment paths, which this single-segment shape can't match. The + // path is consumed immediately so a reload lands on the wallet as usual. + const urlProfile = (() => { + if (typeof location === 'undefined' || urlInvite) return null; + const m = location.pathname.match(/^\/([A-Za-z0-9._-]{1,64})\/?$/); + return m ? m[1] : null; + })(); + if (urlProfile) { try { history.replaceState(null, '', '/'); } catch {} } + // ---- push notifications ------------------------------------------------- // The nwcpush notifier watches relays for what it can see without keys: // kind-1059 wraps p-tagged at us (DMs, direct invites), zap receipts @@ -2380,6 +2393,22 @@ export function messagesFeature(ctx) { loadLinkInvite(urlInvite); setTimeout(() => { ui.chatOpen = true; ui.msgView = 'home'; render(); }, 0); } + if (urlProfile) { + (async () => { + let pk = parseNostrPubkey(urlProfile); + if (!pk && /^[a-z0-9._-]{1,30}$/i.test(urlProfile)) { + // same registrar + domain rule the names feature uses + const domain = getNetwork() === 'mutinynet' ? 'staging.coinos.io' : 'coinos.io'; + const name = urlProfile.toLowerCase(); + try { + const j = await fetch(`https://names.coinos.io/.well-known/nostr.json?name=${encodeURIComponent(name)}&domain=${domain}`) + .then((r) => r.json()); + pk = (j.names || {})[name] || null; + } catch {} + } + if (pk && /^[0-9a-f]{64}$/.test(pk)) openProfile(pk); + })(); + } window.addEventListener('resize', onViewportResize); window.visualViewport?.addEventListener('resize', onViewportResize); allUnsubs.push(() => { |
