Repository navigation
Replies and reactions, Signal-style (0.3.0, qc 0.2.0) - #279
Merged
Merged
Conversation
Reactions are messages of their own (message_type 'reaction') whose
END-TO-END ENCRYPTED body is { target, emoji, remove }: the server learns
that someone reacted, never to what or with which emoji. One reaction per
person per message; a new one replaces yours, tapping yours removes it.
Replies use the existing reply_to_id; the quote is drawn from the reader's
own decrypted copy, so quoted text is never stored twice.
- src/lib/chat/reactions.js: envelope + foldMessages (reactions into their
targets, reply quotes), shared by the web app and qc.
- MessageItem: quote block (jumps to the original), reaction chips with
OpenEmoji art and who-reacted titles, hover/tap action bar with six quick
reactions, the full picker and Reply. MessageList folds and only
auto-scrolls on new messages, not on a reaction.
- Composer: reply bar (Escape/x cancels), sends replyToId.
- Server: messageType allowlist; replyToId must be a message in the same
conversation. /api/messages/load returned a chat's OLDEST N messages
(ascending + limit); it now returns the newest N (default 200, max 500).
- Migration 20261006180000: message_type CHECK allows 'reaction' (applied
on dev2).
- qc: messages fold reactions/replies, TUI shows quotes and reaction
summaries, `qc react <chat> <id> <emoji> [--remove]`,
`qc send --reply <id>`, MCP react_to_message + send_message reply_to.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ThreatCrush Security Scan13 finding(s) MEDIUM: 9 | LOW: 4
Snippets are redacted; ThreatCrush never prints matched credential material. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Signal-style reply-to and reactions, in the web app and in
qc.Privacy model
Reactions are messages of their own:
message_type: 'reaction', with an end-to-end encrypted body of{ target, emoji, remove }.Replies use the existing
reply_to_id. The server could already see that link.Web
replyToId.Server
messageTypeis checked against an allow-list (text,image,file,reaction).replyToIdmust be a message in the same conversation. Before, it was stored unchecked./api/messages/loadreturned a chat's oldest N messages (it sorted ascending and then applied the limit), so in long chats the newest messages never showed. It now returns the newest N, default 200 and max 500, which also leaves room for reactions.20261006180000_message_type_reactionlets the CHECK constraint acceptreaction. It is already applied on dev2, and the schema cache is reloaded.qc (0.2.0)
foldMessagesthe web app uses.┃ quotelines and reaction summaries.qc readshows both, plus a short message id.qc react <chat> <id> <emoji> [--remove]andqc send <chat> <text> --reply <id>.react_to_messagetool,reply_toonsend_message, andread_chatnow returns ids, reactions and reply quotes.Not in this PR
Tests
MessageItem(4 tests)qcfolding a real ML-KEM-encrypted reaction and a replytest:ci: 636/636.next buildpasses.Messaging is Preshy's area. Anthony asked for this directly.
🤖 Generated with Claude Code