Files
cinny/docs/handoff/features/editor-and-composer/HANDOFF.md
Max Litruv Boonzaayer e058165830 feat: upgrade toolchain and soften sync recovery after network blips
Bump Vite 8, matrix-js-sdk, and related deps; fix immer/vanilla-extract imports for new majors. Replace blocking sync error dialog with background recovery on wake/offline, and disable Vite auto-open in dev. Add feature handoff documentation index.
2026-07-09 01:55:09 +10:00

93 lines
2.8 KiB
Markdown

# Editor & composer — handoff
## Summary
The message composer is a **Slate**-based rich text editor with autocomplete for users, rooms, and emoticons. Converts between editor state and Matrix HTML/plaintext. Supports toolbar formatting, intents, and file paste/drop integration.
## User-facing behavior
- Type messages with bold/italic/code etc. (toolbar)
- `@user` and `#room` mentions with autocomplete popup
- `:emoji` emoticon autocomplete
- Paste images/files into composer
- Draft persistence per room
## Architecture
```
Editor.tsx (Slate)
→ Elements.tsx, Toolbar.tsx
→ autocomplete/ (User, Room, Emoticon)
→ input.ts / output.ts — Matrix format conversion
RoomInput.tsx wires Editor to send pipeline + uploads
text-area plugin (legacy/plain areas in some UI)
```
## Key files
| Path | Role |
|------|------|
| `cinny/src/app/components/editor/Editor.tsx` | Main Slate editor |
| `cinny/src/app/components/editor/Toolbar.tsx` | Formatting toolbar |
| `cinny/src/app/components/editor/input.ts` | Parse into editor |
| `cinny/src/app/components/editor/output.ts` | Serialize to Matrix |
| `cinny/src/app/components/editor/autocomplete/` | Mention/emoji menus |
| `cinny/src/app/features/room/RoomInput.tsx` | Room composer wrapper |
| `cinny/src/app/plugins/text-area/` | Plain text area utilities |
| `cinny/src/app/hooks/useFilePasteHandler.ts` | Paste files |
| `cinny/src/app/hooks/useFileDrop.ts` | Drag-drop files |
| `cinny/src/app/state/room/roomInputDrafts.ts` | Draft persistence |
## Data model
| Key | Storage |
|-----|---------|
| `roomIdToMsgDraftAtomFamily` | localStorage per room |
| `roomIdToUploadItemsAtomFamily` | pending uploads |
## Dependencies
- `slate`, `slate-react`
- `folds` UI primitives
## Integration points
- **room-timeline**: send on submit
- **emoji-stickers**: emoticon autocomplete + custom packs
- **plugins**: `text-composer-toolbar`, `composer-actions` slots
- **media-and-url-preview**: upload before send
## Testing
### Manual
1. Mention user and room; verify pill rendering in sent message.
2. Format bold/italic; verify HTML in `formatted_body`.
3. Reload mid-compose; draft restores.
4. Paste image; upload card appears.
### Automated
- `Editor.preview.tsx` exists for dev preview
## Known issues & gotchas
- `useCompositionEndTracking` in App.tsx for IME composition
- Slate types in `slate.d.ts` — keep custom elements typed
- Plain text vs HTML fallback for clients without HTML support
## Future work
- WYSIWYG markdown mode
- Draft sync across devices via account data
## Related docs
- [room-timeline HANDOFF](../room-timeline/HANDOFF.md)
- [emoji-stickers HANDOFF](../emoji-stickers/HANDOFF.md)
## Add your extra things here
- `plainToEditorInput`, `toPlainText` helpers exported from editor index
- Forum has separate composers: `ForumReplyComposer`, `ForumChatComposer`