# 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
