diff options
| author | Adam Soltys <[email protected]> | 2026-09-04 11:23:24 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-04 11:23:24 -0700 |
| commit | 7c6838c5364f1cb8255b091b1f2fcae5dd4a4029 (patch) | |
| tree | ac82a815c972ab067c87a5caec097b59120f8d4b | |
| parent | a70d221ea6b4940b8511f16075f7b4850e465b2e (diff) | |
| download | coinosv3-7c6838c5364f1cb8255b091b1f2fcae5dd4a4029.tar.gz coinosv3-7c6838c5364f1cb8255b091b1f2fcae5dd4a4029.zip | |
An uploaded (or pasted) profile picture or cover previews at the top of the profile page immediately, not after Save: while the editor is open the DRAFT is the truth for the banner, the avatar, and the display name shown up top — clearing a field previews the removal too. The editor's text fields render per keystroke so pasted URLs track live (the morph never rewrites a focused field, so it can't fight the typing); uploads already rendered after filling the field. Verified headless: typing picture/cover URLs into the edit form updates the page-top avatar and banner backgrounds before any save
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01MGzU12QrAA4G6BYGzGVdXz
| -rw-r--r-- | src/features/messages.js | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index 2e6b295..9b61658 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -2116,7 +2116,10 @@ export function messagesFeature(ctx) { h(multi ? 'textarea' : 'input', { ...(multi ? { rows: '4', style: 'font-family:var(--sans);min-height:72px' } : { type: 'text' }), placeholder: ph, value: ui.profEdit[key], - onInput: (ev) => { ui.profEdit[key] = ev.target.value; }, + // render per keystroke so the page-top preview (name/picture/banner) + // tracks the draft live — the morph never rewrites a focused field, + // so this can't fight the typing + onInput: (ev) => { ui.profEdit[key] = ev.target.value; render(); }, })); // A lightning address worth showing: not an npub-shaped machine address // (npub1…@some.relay duplicates the npub below) and not the same string @@ -2134,17 +2137,25 @@ export function messagesFeature(ctx) { const showAbout = about.length > 1; // The cover photo: nostr's standard kind-0 `banner`. Legacy coinos.io // wore these proudly — migrated accounts bring theirs along, and anyone - // can set one in the editor below. - const bannerUrl = full && typeof full.banner === 'string' && /^https?:\/\//i.test(full.banner.trim()) - ? full.banner.trim() : null; + // can set one in the editor below. WHILE EDITING, the draft is the + // truth: an uploaded (or pasted) picture/banner previews immediately at + // the top of the page instead of waiting for Save — and clearing a field + // previews the removal too. + const draft = mine && ui.profEdit ? ui.profEdit : null; + const urlish = (s) => (typeof s === 'string' && /^https?:\/\//i.test(s.trim()) ? s.trim() : null); + const bannerUrl = draft ? urlish(draft.banner) + : (full && urlish(full.banner)) || null; + const draftPic = draft && urlish(draft.picture); return h('div', { class: 'col', style: 'gap:16px' }, ctx.brandHeader(false), h('div', { class: 'card col', style: 'gap:12px' }, bannerUrl ? h('div', { class: 'profile-banner', style: `background-image:url(${JSON.stringify(bannerUrl)})` }) : null, h('div', { class: 'row gap6', style: 'align-items:center' }, - avatar(pk, 'chat-avatar profile-avatar', false), + draftPic + ? h('div', { class: 'chat-avatar profile-avatar ava-img', style: `background-image:url(${JSON.stringify(draftPic)})` }) + : avatar(pk, 'chat-avatar profile-avatar', false), h('div', { class: 'col grow', style: 'min-width:0;gap:2px' }, - h('div', { class: 'chat-title' }, name), + h('div', { class: 'chat-title' }, draft && draft.name.trim() ? draft.name.trim() : name), nip05 ? h('div', { class: 'muted small break' }, nip05) : null, showLud ? h('div', { class: 'muted small break' }, '⚡ ' + lud16) : null, // the hat pitch lives beside the avatar it decorates |
