Feature: Message Reactions #19
Labels
No labels
area:api
area:core
area:docs
area:infra
area:ux
dependencies
documentation
duplicate
good first issue
help wanted
invalid
question
rust
status:complete
status:partial
status:planned
type:bug
type:design
type:feature
type:infra
type:refactor
type:research
type:ux
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
icub3d/decentcom#19
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Migrated from GitHub issue icub3d/decentcom#19
Original Author: @icub3d
Original Date: 2026-04-15T14:15:44Z
Feature: Message Reactions
Overview
Allow users to add and remove emoji reactions on messages. Reactions are lightweight social signals that reduce the need for short reply messages. Each reaction shows the emoji, the count of users who reacted, and whether the current user has reacted. Reaction changes are broadcast in real time via the gateway.
Background
The server model (
docs/design/server-model.md) definesemoji_reactionsas a feature flag (enabled by default). Reactions are a core UX feature in Discord-style platforms. The gateway (docs/design/architecture.md) already handles real-time event delivery, so reaction events follow the same event envelope pattern.Requirements
emoji_reactionsfeature flag gates reactions; when disabled, reaction endpoints return 403ADD_REACTIONSpermission to add reactions (removing own reactions is always allowed)MANAGE_MESSAGESpermission can remove any user's reactionDesign
API / Interface Changes
New REST endpoints:
PUT /api/v1/channels/{channel_id}/messages/{message_id}/reactions/{emoji}emojiis a URL-encoded Unicode emoji.ADD_REACTIONSpermission,emoji_reactionsfeature flag.200 OKDELETE /api/v1/channels/{channel_id}/messages/{message_id}/reactions204 No ContentDELETE /api/v1/channels/{channel_id}/messages/{message_id}/reactions/{user_id}MANAGE_MESSAGESpermission.204 No ContentGET /api/v1/channels/{channel_id}/messages/{message_id}/reactions/{emoji}200 OKwith{ users: [{ id, display_name }], total: N }Modified endpoint:
GET /api/v1/channels/{channel_id}/messages— Message objects in the response now include areactionsarray:New gateway events:
Data Model Changes
New table:
reactionsThe composite primary key (message_id, user_id) enforces one reaction per user per message. When a user adds a new emoji, use INSERT OR REPLACE to replace their previous reaction.
Component Changes
Server (
server/):server/src/models/reaction.rs— New module:Reactionstruct, DB operations (add, remove, list by message, counts withmeflag)server/src/routes/reactions.rs— New module: PUT, DELETE, GET endpointsserver/src/routes/messages.rs— Modify message serialization to include aggregated reaction dataserver/src/gateway/events.rs— AddREACTION_ADDandREACTION_REMOVEevent typesserver/src/gateway/handler.rs— Broadcast reaction events to channel subscribersClient (
client/):client/src/components/ReactionBar.tsx— New component: horizontal row of reaction pills below a message, each showing emoji + count, highlighted if the current user reactedclient/src/components/ReactionPicker.tsx— New component: emoji picker popover for adding/changing reactions (can reuse a lightweight emoji picker library or a curated grid of common emoji)client/src/components/Message.tsx— IntegrateReactionBarbelow message contentclient/src/api/reactions.ts— API client functions for add/remove/list reactionsclient/src/stores/messageStore.ts— Update message reaction state onREACTION_ADD/REACTION_REMOVEeventsclient/src/gateway/handlers.ts— Add handlers for reaction gateway eventsTask List
Server
reactionstable to SQLite migrations (server/migrations/008_reactions.sql)ReactionStoretrait and SQLite impl inserver/src/storage/sqlite/reactions.rsREACTION_ADDandREACTION_REMOVEadded to gateway Op enum inshared/src/lib.rsPUT /api/v1/channels/{channel_id}/messages/{message_id}/reactions/{emoji}with permission and feature flag checksDELETEendpoint for self-removal and admin removal (server/src/reactions/handlers.rs)GETendpoint to list users who reacted with a given emojireactionsarray withmefield viaenrich_messagesREACTION_ADD/REACTION_REMOVEevents broadcast via gateway on reaction changesADD_REACTIONSpermission flag addedClient
client/src/api/reactions.tsREACTION_ADD/REACTION_REMOVEhandlers inclient/src/gateway/handlers.tsReactionBar.tsxcomponent: render reaction pills, toggle own reaction on clickReactionPicker.tsxcomponent: emoji selection popover triggered by a "+" button on message hoverReactionBarintoMessage.tsxTest List
storage/sqlite/reactions.rs)meflag per emojiroutes/reaction_tests.rs)emoji_reactionsfeature flag is disabledREACTION_ADDgateway event to other subscribersMANAGE_MESSAGEScan remove another user's reactionOpen Questions
emoji-mart) or a minimal curated set for the initial release?