Write rich messages in a new composer, with layer 229 buttons and folded quotes
The composer is a Tiptap 3 / ProseMirror document now, and it is the only formatting path: the chat input, captions, forward comments, fact checks, poll and checklist fields, the gift message and every InputFieldEmoji field mount the same engine, a plain field with a schema that simply has no blocks it cannot send. The old execCommand formatting and its markup bookkeeping are gone; helpers/dom/markdown.ts only dispatches into the editor. The engine and its rules are described in components/chat/inputEditor/README.md. Expanded, the composer writes native rich messages: headings, lists, tables, folds, quotes and pull quotes, code blocks with a detected language, math, photos and videos inside the text, a map, and buttons. It checks them against the app config limits before sending, follows rich_message_posting (Premium, or offering to send without formatting where it is not allowed), and edits a rich message back into the same document. Create with AI starts a rich message from a prompt. Layer 229, as the other clients have it: - Buttons in rich messages and Instant View pages (pageBlockButtonRow and inline textButton), with their styles and alignment, doing what a keyboard button of the same type does. The composer adds them through a dialog with a live preview; a button that needs a message is drawn but inert outside one. - The new keyboard button types: open a user's profile, share a location (asked first, then sent as a reply), create a poll or a quiz. Keyboard and page buttons share one handler. - Quotes can be sent collapsed; the composer offers the switch on a long quote, and a collapsed one opens with a disclosure button. Compact tables. - A welcome template's buttons fire only when they need no message, and a template can be rich: ephemeral sends and edits carry rich_message. Keyboard and screen readers: composer chips and quote switches are buttons reachable with Tab and pressed with Enter or Space, a toast no longer swallows a keyboard click, the markup tooltip keeps its focus inside a popup, and the in-app browser's header buttons have names. Checked with Axe in every theme and the focus-visibility sweep. In development CSS module class names are hashed from the file path alone, so an SCSS edit no longer renames every class under DOM built imperatively (ProseMirror node views). New Playwright suites: test:editor:e2e for the engine and test:popups on its own config, both on servers without hot reload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
E
Eduard Kuzmenko committed
36d1db91bc191acb9514e97876b9527f69e8ad2f
Parent: 1749a0d