Add emoji picker, reactions user_id & UI tweaks
Introduce client-side emoji picker and richer reaction UX, and propagate user IDs for reactions over the WS protocol. Backend: include user_id in reaction events. Frontend: add EmojiPicker component; update useChatSocket types to include user_id; handle "reaction" events in ChatRoomPage to update cached messages (add/remove/switch reactions). Message component: UI overhaul — action menu with slide-out actions, toggle button (⋮→✕), emoji picker trigger, grouped reaction buttons that show counts and indicate "mine" state, and various layout/cleanups. Media: defer video loading by setting preload="none" in ChatMediaGallery, MediaGallery and PostComposer to improve performance.
This commit is contained in:
@@ -148,7 +148,7 @@ export default function ChatRoomPage() {
|
||||
(event: ChatSocketEvent) => {
|
||||
if (event.type === "new_chat_message" || event.type === "new_reply_chat_message") {
|
||||
let replyTo: MessageModel["reply_to"] = null;
|
||||
if (event.type === "new_reply_chat_message" && event.reply_to_id != null) {
|
||||
if (event.reply_to_id != null) {
|
||||
const cached = queryClient.getQueryData<{ pages: CursorPaginated<MessageModel>[] }>(
|
||||
messagesQueryKey(chatId),
|
||||
);
|
||||
@@ -184,6 +184,31 @@ export default function ChatRoomPage() {
|
||||
);
|
||||
} else if (event.type === "stop_typing") {
|
||||
setTypingUsers((prev) => prev.filter((u) => u !== event.user));
|
||||
} else if (event.type === "reaction") {
|
||||
queryClient.setQueryData<{
|
||||
pages: CursorPaginated<MessageModel>[];
|
||||
pageParams: unknown[];
|
||||
}>(messagesQueryKey(chatId), (old) => {
|
||||
if (!old) return old as never;
|
||||
return {
|
||||
...old,
|
||||
pages: old.pages.map((p) => ({
|
||||
...p,
|
||||
results: p.results.map((m) => {
|
||||
if (m.id !== event.message_id) return m;
|
||||
let reactions = [...(m.reactions ?? [])] as typeof m.reactions;
|
||||
if (event.action === "added") {
|
||||
reactions = [...reactions, { id: -Date.now(), user: event.user_id, emoji: event.emoji, created_at: new Date().toISOString() } as never];
|
||||
} else if (event.action === "removed") {
|
||||
reactions = reactions.filter((r) => !((r.user as unknown as number) === event.user_id && r.emoji === event.emoji));
|
||||
} else if (event.action === "switched") {
|
||||
reactions = reactions.map((r) => (r.user as unknown as number) === event.user_id ? { ...r, emoji: event.emoji } : r);
|
||||
}
|
||||
return { ...m, reactions };
|
||||
}),
|
||||
})),
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
[appendMessage, removeMessage, chatId, user, queryClient],
|
||||
|
||||
Reference in New Issue
Block a user