Reactions: names in the tooltip, animated custom reactions, who reacted #303

Closed
opened 2026-10-07 20:43:14 -04:00 by Salastil · 1 comment
Owner
  • Tooltip is title={r.emoji} (MessageRow.tsx:983) - raw <:name:id> for custom emoji.
  • ReactionEmoji accepts animated but ignores it (1147-1151).
  • Who reacted isn't available: Reaction has no reactor list (wire.ts:410-417). Discord's tooltip reads "X, Y and Z reacted with :name:".

Fix: resolve custom emoji names; animate animated reactions; daemon: a listReactors RPC fetched on hover (Discord GET /channels/{c}/messages/{m}/reactions/{emoji}, Matrix annotation senders).

Part of the v1.0 UI pass.

- Tooltip is `title={r.emoji}` (MessageRow.tsx:983) - raw `<:name:id>` for custom emoji. - `ReactionEmoji` accepts `animated` but ignores it (1147-1151). - Who reacted isn't available: `Reaction` has no reactor list (wire.ts:410-417). Discord's tooltip reads "X, Y and Z reacted with :name:". **Fix:** resolve custom emoji names; animate animated reactions; **daemon:** a `listReactors` RPC fetched on hover (Discord `GET /channels/{c}/messages/{m}/reactions/{emoji}`, Matrix annotation senders). _Part of the v1.0 UI pass._
Salastil added this to the v1.0 milestone 2026-10-07 20:43:14 -04:00
Salastil added the feature label 2026-10-07 20:43:14 -04:00
Author
Owner

Finished: 506140d.

Pointing at a reaction now tells you what it is and who gave it.

  • Names: the tooltip was the raw token (<:name:id> for a custom emoji). It is now Discord's sentence - "Ann, Bob and Cat reacted with :name:", "Ann, Bob, Cat and 4 others…", or "5 people reacted with :name:" while the names haven't arrived or the service can't say. Custom emoji are named from their own token, Unicode ones from the picker's table (the bare emoji where there is no name).
  • Who reacted (daemon): new listReactors RPC (nobilis 1da3ad8). Discord: GET /channels/{c}/messages/{m}/reactions/{emoji}?limit=10. Matrix: the senders the session has seen for that message and emoji - matrix_reaction_targets now records the sender (as a ReactionEvent), a redaction removes just that person, names come from the room roster. Every other service answers an empty list (the count is all there is). Asked once the pointer has stayed 250 ms, never per message, and kept 30 s per (message, emoji, count).
  • Animated: nothing was being ignored - the CDN address already asks for the WebP with animated=true, which animates the ones that move; the dead animated prop is gone and the comment says so.
  • Tests: reactions.test.ts (names and sentences), reactor_tests in nobilis (who is seen, a redaction loses only that person). Clippy and the daemon suite pass.
  • Not exercised live: the Discord request, since the test account is receive-only and not to be used for this. The picture is the staged state, so it shows the fallback sentence; the names fill the same slot.

Before (top: only the pointer, with no tooltip a screenshot can capture), after (bottom):

tip

Finished: [506140d](https://git.salastil.com/Salastil/moho/commit/506140db866ee707da289f4b02e4055a6b0cb9f1). Pointing at a reaction now tells you what it is and who gave it. - **Names:** the tooltip was the raw token (`<:name:id>` for a custom emoji). It is now Discord's sentence - "Ann, Bob and Cat reacted with :name:", "Ann, Bob, Cat and 4 others…", or "5 people reacted with :name:" while the names haven't arrived or the service can't say. Custom emoji are named from their own token, Unicode ones from the picker's table (the bare emoji where there is no name). - **Who reacted (daemon):** new `listReactors` RPC (nobilis 1da3ad8). Discord: `GET /channels/{c}/messages/{m}/reactions/{emoji}?limit=10`. Matrix: the senders the session has seen for that message and emoji - `matrix_reaction_targets` now records the sender (as a `ReactionEvent`), a redaction removes just that person, names come from the room roster. Every other service answers an empty list (the count is all there is). Asked once the pointer has stayed 250 ms, never per message, and kept 30 s per (message, emoji, count). - **Animated:** nothing was being ignored - the CDN address already asks for the WebP with `animated=true`, which animates the ones that move; the dead `animated` prop is gone and the comment says so. - Tests: `reactions.test.ts` (names and sentences), `reactor_tests` in nobilis (who is seen, a redaction loses only that person). Clippy and the daemon suite pass. - Not exercised live: the Discord request, since the test account is receive-only and not to be used for this. The picture is the staged state, so it shows the fallback sentence; the names fill the same slot. Before (top: only the pointer, with no tooltip a screenshot can capture), after (bottom): ![tip](https://git.salastil.com/attachments/4bfd996d-e52d-41f0-8632-3724f1c4a279)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Salastil/moho#303