Matrix: read receipts and unread sync #71

Closed
opened 2026-09-02 00:04:15 -04:00 by Salastil · 1 comment
Owner

markBufferRead is an explicit no-op for Matrix (rpc/methods.rs:415-434, comment: "Matrix's receipts are their own piece of work"), and inbound ephemeral handling only looks at m.typing (mod.rs:421).

So reading a room in moho leaves it unread on your phone, and a room you read elsewhere is still bold here. Every other protocol in the project syncs read state in at least one direction.

Done looks like: send m.read/m.fully_read on markBufferRead, and honour inbound m.receipt for your own user to clear unread.

`markBufferRead` is an explicit no-op for Matrix (`rpc/methods.rs:415-434`, comment: "Matrix's receipts are their own piece of work"), and inbound `ephemeral` handling only looks at `m.typing` (`mod.rs:421`). So reading a room in moho leaves it unread on your phone, and a room you read elsewhere is still bold here. Every other protocol in the project syncs read state in at least one direction. **Done looks like:** send `m.read`/`m.fully_read` on `markBufferRead`, and honour inbound `m.receipt` for your own user to clear unread.
Author
Owner

Finished — https://git.salastil.com/Salastil/nobilis/commit/3ec9d34

markBufferRead was an explicit no-op for Matrix, so a room read in moho stayed bold on every other client, and one read elsewhere stayed bold here.

Both markers are now sent, because Matrix has two and they answer different questions. m.read is public — it is what puts your avatar against a message in somebody else's client — and m.fully_read is private, and is what your own other sessions use to stop showing a room as unread. Sent together through the one endpoint that takes both.

Pointed at the newest message this client actually holds, by its real event id: a marker is a claim about a specific message rather than about a time. A room with nothing in it says nothing at all, since a receipt pointing at no event is not a claim anybody can act on — and the id has to be one the server gave, not one generated locally, so it is checked for the $ an event id starts with.

Best-effort by design: failing to say a room has been read must not make reading it look like an error.

Verified against your three Matrix rooms — the server accepted the markers for both rooms that have messages, and the empty one correctly sent nothing.

Not included: reading other people's receipts back in, which would let moho show who else has read a message. That is a display feature rather than a sync one and wants its own ticket.

Finished — https://git.salastil.com/Salastil/nobilis/commit/3ec9d34 `markBufferRead` was an explicit no-op for Matrix, so a room read in moho stayed bold on every other client, and one read elsewhere stayed bold here. Both markers are now sent, because Matrix has two and they answer different questions. `m.read` is public — it is what puts your avatar against a message in somebody else's client — and `m.fully_read` is private, and is what your own other sessions use to stop showing a room as unread. Sent together through the one endpoint that takes both. Pointed at the newest message this client actually holds, by its real event id: a marker is a claim about a specific message rather than about a time. A room with nothing in it says nothing at all, since a receipt pointing at no event is not a claim anybody can act on — and the id has to be one the server gave, not one generated locally, so it is checked for the `$` an event id starts with. Best-effort by design: failing to say a room has been read must not make reading it look like an error. Verified against your three Matrix rooms — the server accepted the markers for both rooms that have messages, and the empty one correctly sent nothing. Not included: reading other people's receipts back in, which would let moho show who else has read a message. That is a display feature rather than a sync one and wants its own ticket.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Salastil/moho#71