Composer drafts persist per room, but nothing in the room list showed which OTHER rooms had an unsent draft. Add a subtle chat-bubble icon on a room's nav item when it has a message draft (and isn't the open room), so half-written messages elsewhere are visible at a glance. - Shared pure helper hasMsgDraft (utils/draft.ts, unit-tested) replaces the inline emptiness check; the composer DraftIndicator now reuses it. - RoomNavItem reads a memoized selectAtom(draftAtom, hasMsgDraft) so a row re-renders only when its draft flag flips (the draft atom is written on room-leave, not per keystroke). Uses Icons.Message (pencil is reserved for the custom-name marker), muted, aria-label "Unsent draft". - useHydrateMsgDrafts (mounted in ClientNonUIFeatures) pre-fills the per-room draft atoms from draft-msg-* localStorage on startup, so indicators are correct after a page reload, not only after revisiting a room. Thread drafts (key contains ::) are skipped; room-level only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
28 lines
910 B
TypeScript
28 lines
910 B
TypeScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { Descendant } from 'slate';
|
|
import { hasMsgDraft } from './draft';
|
|
|
|
const paragraph = (text: string): Descendant =>
|
|
({ type: 'paragraph', children: [{ text }] }) as unknown as Descendant;
|
|
|
|
test('hasMsgDraft is false for an empty array', () => {
|
|
assert.equal(hasMsgDraft([]), false);
|
|
});
|
|
|
|
test('hasMsgDraft is false for an empty paragraph (empty editor)', () => {
|
|
assert.equal(hasMsgDraft([paragraph('')]), false);
|
|
});
|
|
|
|
test('hasMsgDraft is false for whitespace-only content', () => {
|
|
assert.equal(hasMsgDraft([paragraph(' \n ')]), false);
|
|
});
|
|
|
|
test('hasMsgDraft is true when there is real text', () => {
|
|
assert.equal(hasMsgDraft([paragraph('hello')]), true);
|
|
});
|
|
|
|
test('hasMsgDraft is true across multiple paragraphs with text', () => {
|
|
assert.equal(hasMsgDraft([paragraph(''), paragraph(' hi ')]), true);
|
|
});
|