# Rich Messaging

quicproquo supports rich messaging features beyond basic text: reactions, read
receipts, typing indicators, message editing, and message deletion. All
message types are end-to-end encrypted inside MLS ciphertext — the server
only sees opaque bytes.

## Reactions

React to any message with an emoji:

```
/react 👍        # react to the latest message
/react 🎉 3     # react to message at history index 3
```

Reactions are displayed inline with the sender's name. Each reaction
references the target message by its 16-byte message ID.

## Read receipts

Read receipts are sent **automatically** when you receive a Chat or Reply
message. The sender sees a `✓ read` indicator in their message history.

Receipts only trigger on Chat and Reply messages (not on other receipts,
typing indicators, or reactions) to prevent infinite loops.

## Typing indicators

Send a typing indicator to let others know you're composing:

```
/typing
```

Typing indicators timeout after 10 seconds of inactivity. Toggle display of
others' typing with:

```
/typing-notify on
/typing-notify off
```

The session tracks `typing_indicators` state per conversation.

## Editing messages

Edit one of your own messages by history index:

```
/edit 5 Updated text here
```

Only your own messages can be edited. The edit is sent as an `Edit` message
type referencing the original message ID, and the local database is updated on
receipt.

## Deleting messages

Delete one of your own messages:

```
/delete 5
```

Only your own messages can be deleted. A `Delete` message is broadcast to the
group, and the message is removed from the local database on receipt.

## Wire format

All rich message types use the same binary envelope inside the MLS ciphertext:

```
[version: 1 byte][type: 1 byte][payload...]
```

| Type | Code | Payload |
|---|---|---|
| Chat | `0x01` | `[msg_id: 16][body_len: 2 BE][body]` |
| Reply | `0x02` | `[ref_msg_id: 16][body_len: 2 BE][body]` |
| Reaction | `0x03` | `[ref_msg_id: 16][emoji_len: 1][emoji UTF-8]` |
| ReadReceipt | `0x04` | `[msg_id: 16]` |
| Typing | `0x05` | `[active: 1]` (0 = stopped, 1 = typing) |
| Edit | `0x06` | `[ref_msg_id: 16][body_len: 2 BE][body]` |
| Delete | `0x07` | `[ref_msg_id: 16]` |

## Implementation

- **Core serialisation:** `crates/quicproquo-core/src/app_message.rs` — the
  `AppMessage` enum with `serialize()` / `deserialize()` methods
- **REPL commands:** `crates/quicproquo-client/src/client/repl.rs` — slash
  command handlers
- **Display:** `crates/quicproquo-client/src/client/display.rs` — typing
  indicator rendering
