feat(messages): add support for message editing, deletion, and reactions#71
Open
feat(messages): add support for message editing, deletion, and reactions#71
Conversation
Implements the foundation for message actions as described in issue #67: - Add new RoomMessageBody variants: Edit, Delete, Reaction, RemoveReaction - Actions are stored as signed messages in the timeline - Delta processing applies actions to build computed state (edited content, deleted flags, reaction counts) - Authorization enforced: only authors can edit/delete their messages - UI displays "(edited)" indicator and reaction badges - Add message_actions.rs component for future context menu/emoji picker Breaking change: New enum variants will cause deserialization errors for older clients. This is acceptable during alpha. Test plan: - 7 new unit tests covering all action types - Tests verify authorization (edit by non-author is ignored) - Tests verify action on deleted message is no-op - Tests verify display_messages filters actions Closes #67 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…uttons - Add hover action bar that appears when hovering over messages - React button (👍) adds thumbs-up reaction to any message - Delete button removes user's own messages - Edit button shown but disabled (coming soon) - Wire up handlers to create and apply action messages Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Clicking the delete button now shows a confirmation modal asking 'Delete Message?' before actually deleting. Users can cancel or confirm. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace single thumbs-up button with an expandable emoji picker: - Click 😊 to open picker with 8 curated emojis (👍❤️😂😮😢😡🎉🤔) - Visual hierarchy separates reactions from actions (edit/delete) - Warm amber hover for reaction trigger, red hover for delete - Picker closes after selecting an emoji - Divider visually separates reaction zone from action zone Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…lick-outside dismiss - Change from horizontal row to 2-column vertical grid - Raise z-index to z-50 so picker appears above room list - Add invisible backdrop to catch outside clicks and close picker - Keep action bar visible while picker is open (override hover behavior) - Larger emoji buttons (text-xl, more padding) for easier clicking Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes #72 - Remove overflow-y-auto from aside, add to member list only - Add flex-shrink-0 to header, invite button, and status sections - Member list now scrolls independently while footer stays visible Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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.
Problem
Users cannot edit or delete their own messages, nor can they react to messages with emoji. This limits the expressiveness and usability of the chat experience. (Issue #67)
Approach
Implements message actions (edit, delete, reactions) as special message types that flow through the normal message timeline:
RoomMessageBodyvariants (Edit,Delete,Reaction,RemoveReaction) are stored as signed messages in the timelineMessagesV1::actions_statetracks the effective state (edited content, deleted messages, reactions) - rebuilt from action messages on each deltaThis approach preserves the append-only, signed message model while enabling interactive features.
Why this design over alternatives?
#[serde(skip)]avoids signature invalidation issues - the signed message content is never mutatedrebuild_actions_state()means invalid actions (e.g., editing someone else's message) are simply ignored, not rejectedTesting
New unit tests added (7 tests):
test_edit_action- Verify edit applies andeditedflag is settest_edit_by_non_author_ignored- Verify unauthorized edits don't applytest_delete_action- Verify deleted messages are marked and filtered from displaytest_reaction_action- Verify reactions from multiple users aggregate correctlytest_remove_reaction_action- Verify users can remove their own reactionstest_action_on_deleted_message_ignored- Verify actions on deleted targets are no-optest_display_messages_filters_actions- Verify action messages are not shown directlyLocal validation:
cargo test -p river-core- All 94 tests passcargo clippy -p river-core- No errors (some pre-existing warnings)cargo fmt- All code formattedWhat still needs testing:
Breaking Change
This adds new
RoomMessageBodyenum variants, which will cause deserialization errors for older clients. This is acceptable during alpha. Before production, consider adding#[serde(other)]fallback variant.Critical Files
common/src/room_state/message.rsui/src/components/conversation.rsui/src/components/conversation/message_actions.rsui/src/components/app/notifications.rsFuture Work (not in this PR)
Closes #67
[AI-assisted - Claude]