diff options
| author | Adam Soltys <[email protected]> | 2026-08-18 12:11:39 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-18 12:11:39 -0700 |
| commit | 1731b035ebdb4e09b2578300345ac2c3480b5735 (patch) | |
| tree | d4bd9bf7b4cb692ef1dfead07fbfdee6b90bbee5 | |
| parent | a0374566a5c69d87e5a156f5fabecf5b9b45d6f9 (diff) | |
| download | coinosv3-1731b035ebdb4e09b2578300345ac2c3480b5735.tar.gz coinosv3-1731b035ebdb4e09b2578300345ac2c3480b5735.zip | |
The tick bows out: delivery speaks through the dimming alone — faint in flight, full strength once a relay has it
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_012u4oe1KPx9faCsDBLfZYqi
| -rw-r--r-- | src/features/messages.js | 12 | ||||
| -rw-r--r-- | src/style.css | 3 |
2 files changed, 6 insertions, 9 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index 366bbbc..20b2b03 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -395,7 +395,7 @@ export function messagesFeature(ctx) { if (!id) { noIdToast(); return; } // The rumor id is a plain hash, so the message can be on screen before // any signing, encryption or network runs. The pending flag renders as a - // dimmed bubble; a relay accepting the wrap clears it and shows the tick. + // dimmed bubble; a relay accepting the wrap brings it to full strength. const { created_at, ms } = msTags(Date.now()); const rumor = rumorWithId({ kind: 9, pubkey: id.pubkey, content: text, @@ -411,7 +411,7 @@ export function messagesFeature(ctx) { const wrap = await wrapRumor(rumor, id.signer, room.chStream(chId)); seenWraps.add(wrap.id); // our own echo has nothing to add const ok = await publishOn(room.relays, wrap); - if (!ok) { toast(t('msgSendFailed')); return; } // stays dimmed, no tick + if (!ok) { toast(t('msgSendFailed')); return; } // stays dimmed delete entry.pending; render(); ensureJoined(room, id).catch(() => {}); @@ -1013,7 +1013,7 @@ export function messagesFeature(ctx) { if (!id) { noIdToast(); return; } if (!(id.signer instanceof Uint8Array) && !id.signer.encryptTo) { toast(t('msgSignerNoDm')); return; } // Same optimistic shape as channel sends: the rumor is synchronous, the - // bubble shows dimmed at once, and the tick lands when a relay takes the + // bubble shows dimmed at once, and undims when a relay takes the // recipient's wrap. Wrapping the same rumor keeps the id, so the sent-copy // echo folds into this entry instead of duplicating it. const rumor = makeDMRumor(id.pubkey, peer, text); @@ -1029,7 +1029,7 @@ export function messagesFeature(ctx) { const inbox = (await fetchInboxRelays(peer)).slice(0, 4); const ok = await publishOn([...new Set([...inbox, ...DM_RELAYS])], toPeer); publishOn(DM_RELAYS, toSelf); - if (!ok) { toast(t('msgSendFailed')); return; } // stays dimmed, no tick + if (!ok) { toast(t('msgSendFailed')); return; } // stays dimmed delete entry.pending; render(); persistDms(); @@ -2091,7 +2091,6 @@ export function messagesFeature(ctx) { h('div', { class: 'chat-bubble' }, text, edit ? h('span', { class: 'chat-edited' }, ' ', t('msgEdited')) : null, - mine && !m.pending ? h('span', { class: 'chat-tick' }, '✓') : null, mine ? h('button', { class: 'chat-del', title: t('msgDelete'), onClick: () => deleteMessage(room, chId, m) }, '×') : null), @@ -2276,8 +2275,7 @@ export function messagesFeature(ctx) { ? msgs.map((m) => h('div', { class: 'chat-row dm' + (m.mine ? ' mine' : '') + (m.pending ? ' pending' : '') }, h('div', { class: 'chat-body' }, - h('div', { class: 'chat-bubble' + (m.mine ? ' me' : '') }, m.rumor.content, - m.mine && !m.pending ? h('span', { class: 'chat-tick' }, '✓') : null), + h('div', { class: 'chat-bubble' + (m.mine ? ' me' : '') }, m.rumor.content), h('div', { class: 'chat-time' }, timeLabel(m.rumor.created_at * 1000))))) : [h('div', { class: 'muted small', style: 'text-align:center;padding:24px 0' }, t('msgNoDmsYet'))])), composer(t('msgDmPlaceholder'), () => sendDM(peer))); diff --git a/src/style.css b/src/style.css index e9f0466..1b059f3 100644 --- a/src/style.css +++ b/src/style.css @@ -386,9 +386,8 @@ hr.divider { margin: 16px 0; } overflow-wrap: break-word; white-space: pre-wrap; } .chat-edited { font-size: 11px; color: var(--faint); } -/* Optimistic sends: dimmed while in flight, a small tick once a relay has it. */ +/* Optimistic sends: dimmed while in flight, full strength once a relay has it. */ .chat-row.pending .chat-bubble { opacity: 0.55; } -.chat-tick { font-size: 10px; margin-left: 6px; opacity: 0.6; user-select: none; } .chat-del { position: absolute; top: -7px; right: -7px; width: 18px; height: 18px; display: none; align-items: center; justify-content: center; |
