Files
cinny/src/app/utils/draft.test.ts
T
jaredandClaude Opus 4.8 c44ef8d795 feat(nav): draft indicator on room-nav items
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>
2026-07-10 11:37:21 -04:00

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);
});