Private
Public Access
Add emoji picker and message reactions (Gitea issue #11)
Composer gains an emoji picker (static curated unicode list, insert at cursor position) and messages gain Slack/Mattermost-style reactions: react with any emoji, toggle off by reacting again, see who reacted via a tooltip on each pill. Backend: MessageReaction model (unique on message_id+user_id+emoji backs toggle semantics), WS "reaction" envelope broadcasts the full recomputed reaction list per message (same approach as message edits), REST message list embeds reactions so a reload doesn't lose state that only arrived over WS. Frontend: shared EmojiPicker component (anchored popover, Escape/outside- click dismiss via new useEscapeKey hook) used by both the composer and a new hover-revealed reaction trigger on each message row.
This commit is contained in:
@@ -54,6 +54,13 @@ export function ChatPane({ room, members, isMobile, onBack, onToggleInfo, infoOp
|
||||
m.id === envelope.id ? { ...m, content: envelope.content, edited_at: envelope.edited_at } : m,
|
||||
),
|
||||
)
|
||||
} else if (envelope.type === 'reaction_update') {
|
||||
setHistory((prev) =>
|
||||
prev.map((m) => (m.id === envelope.id ? { ...m, reactions: envelope.reactions } : m)),
|
||||
)
|
||||
setLive((prev) =>
|
||||
prev.map((m) => (m.id === envelope.id ? { ...m, reactions: envelope.reactions } : m)),
|
||||
)
|
||||
} else if (envelope.type === 'error') {
|
||||
setWsError(envelope.detail)
|
||||
}
|
||||
@@ -61,7 +68,7 @@ export function ChatPane({ room, members, isMobile, onBack, onToggleInfo, infoOp
|
||||
|
||||
const onUnauthenticated = useCallback(() => navigate('/login'), [navigate])
|
||||
|
||||
const { connected, send, sendEdit } = useChatSocket({ roomId: room.id, onMessage, onUnauthenticated })
|
||||
const { connected, send, sendEdit, sendReaction } = useChatSocket({ roomId: room.id, onMessage, onUnauthenticated })
|
||||
|
||||
return (
|
||||
<section className="chat-pane">
|
||||
@@ -99,7 +106,13 @@ export function ChatPane({ room, members, isMobile, onBack, onToggleInfo, infoOp
|
||||
</p>
|
||||
)}
|
||||
|
||||
<MessageList roomId={room.id} messages={[...history, ...live]} members={members} onEdit={sendEdit} />
|
||||
<MessageList
|
||||
roomId={room.id}
|
||||
messages={[...history, ...live]}
|
||||
members={members}
|
||||
onEdit={sendEdit}
|
||||
onReact={sendReaction}
|
||||
/>
|
||||
<Composer roomId={room.id} roomName={room.name} disabled={!connected} onSend={send} />
|
||||
</section>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user