diff --git a/packages/iios-kernel-client/package.json b/packages/iios-kernel-client/package.json index a9ecafe..436b673 100644 --- a/packages/iios-kernel-client/package.json +++ b/packages/iios-kernel-client/package.json @@ -1,6 +1,6 @@ { "name": "@insignia/iios-kernel-client", - "version": "0.1.4", + "version": "0.1.6", "type": "module", "main": "dist/index.js", "module": "dist/index.js", diff --git a/packages/iios-kernel-client/src/types.ts b/packages/iios-kernel-client/src/types.ts index d1b74dd..e8f8a01 100644 --- a/packages/iios-kernel-client/src/types.ts +++ b/packages/iios-kernel-client/src/types.ts @@ -37,7 +37,11 @@ export interface OpenThreadResult { export interface ReceiptEvent { interactionId: string; + /** The reader's IIOS actor UUID — an internal id, NOT comparable to a caller's userId. */ actorId: string; + /** The reader's userId — the same id space clients hold, so they can ignore their own receipt. + * Optional: absent from servers older than the change that added it. */ + userId?: string; kind: 'READ' | 'DELIVERED'; } diff --git a/packages/iios-messaging-ui/package.json b/packages/iios-messaging-ui/package.json index 78d31d1..5ff7d63 100644 --- a/packages/iios-messaging-ui/package.json +++ b/packages/iios-messaging-ui/package.json @@ -1,6 +1,6 @@ { "name": "@insignia/iios-messaging-ui", - "version": "0.1.9", + "version": "0.1.14", "type": "module", "main": "dist/index.js", "module": "dist/index.js", diff --git a/packages/iios-messaging-ui/src/adapters/mock.ts b/packages/iios-messaging-ui/src/adapters/mock.ts index 5514657..b442234 100644 --- a/packages/iios-messaging-ui/src/adapters/mock.ts +++ b/packages/iios-messaging-ui/src/adapters/mock.ts @@ -270,8 +270,9 @@ export class MockAdapter implements MessagingAdapter { // No-op: nobody is typing back in a mock. } - async markRead(): Promise { - // No-op: the mock has no second party to report a read. + /** Echo a receipt the way a real server does, so the "ignore my own read" path is exercised. */ + async markRead(threadId: string, messageId: string): Promise { + this.emit(threadId, { kind: 'receipt', messageId, actorId: ME }); } isConnected(): boolean { diff --git a/packages/iios-messaging-ui/src/components/composer.test.tsx b/packages/iios-messaging-ui/src/components/composer.test.tsx index c6947f8..3896a32 100644 --- a/packages/iios-messaging-ui/src/components/composer.test.tsx +++ b/packages/iios-messaging-ui/src/components/composer.test.tsx @@ -16,6 +16,14 @@ describe(' formatting + native text services', () => { expect(box.getAttribute('autocorrect')).toBe('on'); }); + it('does NOT reuse .miu-textarea — that class belongs to the inbox mail composer', () => { + // Regression: sharing it let the mail rule (resize: vertical; min-height: 90px), which is + // declared later in the stylesheet, win at equal specificity and inflate the chat composer. + const { box } = mount(); + expect(box.classList.contains('miu-composer-box')).toBe(true); + expect(box.classList.contains('miu-textarea')).toBe(false); + }); + it('Enter sends, Shift+Enter does not (it makes a newline)', async () => { const { onSend, box } = mount(); fireEvent.change(box, { target: { value: 'hello' } }); diff --git a/packages/iios-messaging-ui/src/components/composer.tsx b/packages/iios-messaging-ui/src/components/composer.tsx index 20ecc33..c7a45c9 100644 --- a/packages/iios-messaging-ui/src/components/composer.tsx +++ b/packages/iios-messaging-ui/src/components/composer.tsx @@ -54,11 +54,14 @@ export function Composer({ const inputRef = useRef(null); // Grow with the content up to the CSS max-height, then scroll — a chat box, not a fixed field. + // The box is border-box, but scrollHeight excludes the border, so add it back or every measure + // lands a couple of pixels short and the textarea shows a scrollbar it doesn't need. useEffect(() => { const el = inputRef.current; if (!el) return; el.style.height = 'auto'; - el.style.height = `${el.scrollHeight}px`; + const border = el.offsetHeight - el.clientHeight; + el.style.height = `${el.scrollHeight + border}px`; }, [draft]); /** @@ -200,7 +203,7 @@ export function Composer({ ) : null}