aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-04 11:23:24 -0700
committerAdam Soltys <[email protected]>2026-09-04 11:23:24 -0700
commit7c6838c5364f1cb8255b091b1f2fcae5dd4a4029 (patch)
treeac82a815c972ab067c87a5caec097b59120f8d4b /src
parenta70d221ea6b4940b8511f16075f7b4850e465b2e (diff)
downloadcoinosv3-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
Diffstat (limited to 'src')
-rw-r--r--src/features/messages.js23
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