diff options
| author | Adam Soltys <[email protected]> | 2026-08-02 19:39:00 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-02 19:39:00 -0700 |
| commit | 78ab79e7527bdab08c59e5ee8ee5dd701c0856e0 (patch) | |
| tree | a93a405f8c23e7158d47375127a2be68dd4b28c2 /src/recipient-search.js | |
| parent | 0f47a16fd81091f03ab1f4e4e8143fedf94d1f68 (diff) | |
| download | coinosv3-78ab79e7527bdab08c59e5ee8ee5dd701c0856e0.tar.gz coinosv3-78ab79e7527bdab08c59e5ee8ee5dd701c0856e0.zip | |
Punk default avatars, header profile button, owner channel creation
Everyone gets a face: profiles without a picture fall back to a coinos
punk, picked deterministically by the pubkey's last byte — the same 64
webps and formula the coinos app uses (initials show through if the
image can't load). Your own avatar moves from the chat home to the app
header next to the wallet selector, opening your editable profile from
anywhere.
Community owners can add channels from the room's + panel: one
owner-signed ChannelMetadata edition (CORD-03), and every member's
channel switcher grows when the fold lands.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
Diffstat (limited to 'src/recipient-search.js')
| -rw-r--r-- | src/recipient-search.js | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/src/recipient-search.js b/src/recipient-search.js index d3e69eb..5cc8315 100644 --- a/src/recipient-search.js +++ b/src/recipient-search.js @@ -10,6 +10,17 @@ import { queryOn, parseNostrPubkey, npubOf, PROFILE_RELAYS } from './nostr.js'; +// coinos punks: the deterministic default avatar — same formula the coinos +// app uses (last byte of the pubkey picks one of 64). Initials show through +// if the image can't load (offline). +export const punkUrl = (pk) => + `https://coinos.io/api/public/punks/${Math.floor((parseInt(pk.slice(-2), 16) / 256) * 64) + 1}.webp`; + +export const fallbackAvatar = (h, pk, name, cls) => + h('div', { class: cls + ' fallback' }, + h('img', { class: 'punk', src: punkUrl(pk), alt: '', onError: (e) => { e.target.style.display = 'none'; } }), + (name || npubOf(pk) || '??').slice(0, 2)); + const REGISTRAR = 'https://names.coinos.io'; const SEARCH_RELAYS = ['wss://search.nos.today', 'wss://relay.nostr.band']; const PRIMAL_CACHE = 'wss://cache2.primal.net/v1'; @@ -144,7 +155,7 @@ export function resultRows(h, rows, onPick) { h('div', { class: 'item chat-thread-row', onClick: () => onPick(r) }, r.picture ? h('img', { class: 'chat-avatar', src: r.picture, alt: '' }) - : h('div', { class: 'chat-avatar fallback' }, (r.name || npubOf(r.pk) || '??').slice(0, 2)), + : fallbackAvatar(h, r.pk, r.name, 'chat-avatar'), h('div', { class: 'col grow', style: 'min-width:0;gap:1px' }, h('div', { class: 'chat-name' }, r.name || (npubOf(r.pk) || '').slice(0, 14) + '…'), h('div', { class: 'muted small chat-preview' }, r.address || r.nip05 || (npubOf(r.pk) || '').slice(0, 24) + '…')))); |
