# Room timeline — handoff ## Summary The room view is the core messaging experience: virtualized timeline, message rendering, composer input, threads, reactions, pins, members drawer, and room header. Includes Paarrot-specific embed filter integration and command autocomplete. ## User-facing behavior - Scrollable timeline with read markers, edits, redactions, reactions - Rich composer with mentions, emoji, attachments, slash commands - Thread side panel (`ThreadView`) - Members drawer, room header actions, typing indicators - Jump to time, pinned messages menu, reaction viewer - Following mode / tombstone for upgraded rooms ## Architecture ``` Room.tsx / RoomView.tsx → RoomTimeline.tsx (virtualized events) → RoomInput.tsx + Editor → Message.tsx / RenderMessageContent.tsx → ThreadView.tsx → RoomViewHeader.tsx, MembersDrawer Hooks: useVirtualPaginator, useRoomLatestRenderedEvent, useMarkAsRead ``` ## Key files | Path | Role | |------|------| | `cinny/src/app/features/room/Room.tsx` | Room entry | | `cinny/src/app/features/room/RoomView.tsx` | Main layout | | `cinny/src/app/features/room/RoomTimeline.tsx` | Timeline | | `cinny/src/app/features/room/RoomInput.tsx` | Composer | | `cinny/src/app/features/room/ThreadView.tsx` | Thread panel | | `cinny/src/app/features/room/RoomViewHeader.tsx` | Header bar | | `cinny/src/app/features/room/message/Message.tsx` | Single message | | `cinny/src/app/features/room/message/Reactions.tsx` | Reaction row | | `cinny/src/app/features/room/message/MessageEditor.tsx` | Edit message | | `cinny/src/app/features/room/CommandAutocomplete.tsx` | Slash commands | | `cinny/src/app/features/room/reaction-viewer/ReactionViewer.tsx` | Who reacted | | `cinny/src/app/features/room/jump-to-time/JumpToTime.tsx` | Time jump UI | | `cinny/src/app/features/room/room-pin-menu/RoomPinMenu.tsx` | Pinned messages | | `cinny/src/app/components/RenderMessageContent.tsx` | Content render + embeds | | `cinny/src/app/hooks/useVirtualPaginator.ts` | Timeline pagination | ## Data model | Source | Data | |--------|------| | Matrix sync | `m.room.message`, edits, reactions, pins | | Room account data | drafts (`roomInputDrafts`) | | `im.paarrot.embed_filters` | Personal embed blocks | | `im.paarrot.room.embed_filters` | Room-wide embed blocks | ## Dependencies - `matrix-js-sdk` timeline APIs - Slate editor (composer) - Embed filter hooks - Plugin button slots in header/composer/message actions ## Integration points - **editor-and-composer**: RoomInput uses Editor - **embed-filters**: timeline + thread embed gating - **message-rendering**: markdown/HTML parse pipeline - **media-and-url-preview**: attachments and link cards - **plugins**: message-actions, composer-actions slots - **voice-calls**: header call controls ## Testing ### Manual 1. Send text, image, reply, edit, delete. 2. Open thread; reply in thread. 3. Add reaction; open reaction viewer. 4. Pin message; open pin menu. 5. Block embed domain; verify no preview. 6. Slash command from plugin. ### Automated - None ## Known issues & gotchas - Virtual paginator complexity — scroll position bugs common regression area - Encrypted rooms: render path differs for `m.room.encrypted` - `RoomViewFollowing` auto-scroll behavior vs manual scroll - Large threads performance ## Future work - Timeline unit tests for edit/redaction grouping - Improved read receipt aggregation ## Related docs - [editor-and-composer HANDOFF](../editor-and-composer/HANDOFF.md) - [embed-filters HANDOFF](../embed-filters/HANDOFF.md) - [message-rendering HANDOFF](../message-rendering/HANDOFF.md) - [media-and-url-preview HANDOFF](../media-and-url-preview/HANDOFF.md) ## Add your extra things here - `msgContent.ts` — message content helpers - `useRoomNavigate` for permalink jumps