mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-27 21:33:41 +02:00
The comment card exposed two identical add-reaction affordances: a QuickEmojiPicker in the header's top-right actions and the add button inside the bottom ReactionBar. Keep only the bottom one. - Drop QuickEmojiPicker from the root header and reply-row headers - Always show the ReactionBar add button (it is the only entry point now), removing the isLongContent gating - Remove the now-unused hideAddButton prop from ReactionBar MUL-3262 Co-authored-by: Lambda <lambda@multica.ai> Co-authored-by: multica-agent <github@multica.ai>
85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
"use client";
|
|
|
|
import { Tooltip, TooltipTrigger, TooltipContent } from "@multica/ui/components/ui/tooltip";
|
|
import { QuickEmojiPicker } from "./quick-emoji-picker";
|
|
|
|
interface ReactionItem {
|
|
id: string;
|
|
actor_type: string;
|
|
actor_id: string;
|
|
emoji: string;
|
|
}
|
|
|
|
interface GroupedReaction {
|
|
emoji: string;
|
|
count: number;
|
|
reacted: boolean;
|
|
actors: { type: string; id: string }[];
|
|
}
|
|
|
|
function groupReactions(reactions: ReactionItem[], currentUserId?: string): GroupedReaction[] {
|
|
const map = new Map<string, GroupedReaction>();
|
|
for (const r of reactions) {
|
|
let group = map.get(r.emoji);
|
|
if (!group) {
|
|
group = { emoji: r.emoji, count: 0, reacted: false, actors: [] };
|
|
map.set(r.emoji, group);
|
|
}
|
|
group.count++;
|
|
group.actors.push({ type: r.actor_type, id: r.actor_id });
|
|
if (r.actor_type === "member" && r.actor_id === currentUserId) {
|
|
group.reacted = true;
|
|
}
|
|
}
|
|
return Array.from(map.values());
|
|
}
|
|
|
|
interface ReactionBarProps {
|
|
reactions: ReactionItem[];
|
|
currentUserId?: string;
|
|
onToggle: (emoji: string) => void;
|
|
getActorName: (type: string, id: string) => string;
|
|
className?: string;
|
|
}
|
|
|
|
function ReactionBar({
|
|
reactions,
|
|
currentUserId,
|
|
onToggle,
|
|
getActorName,
|
|
className,
|
|
}: ReactionBarProps) {
|
|
const grouped = groupReactions(reactions, currentUserId);
|
|
|
|
return (
|
|
<div className={`flex flex-wrap items-center gap-1.5 ${className ?? ""}`}>
|
|
{grouped.map((g) => (
|
|
<Tooltip key={g.emoji}>
|
|
<TooltipTrigger
|
|
render={
|
|
<button
|
|
type="button"
|
|
onClick={() => onToggle(g.emoji)}
|
|
className={`inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs transition-colors hover:bg-brand/15 ${
|
|
g.reacted
|
|
? "border-brand/30 bg-brand/8 text-brand"
|
|
: "border-brand/10 bg-brand/4 text-muted-foreground"
|
|
}`}
|
|
>
|
|
<span>{g.emoji}</span>
|
|
<span>{g.count}</span>
|
|
</button>
|
|
}
|
|
/>
|
|
<TooltipContent side="top">
|
|
{g.actors.map((a) => getActorName(a.type, a.id)).join(", ")}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
))}
|
|
<QuickEmojiPicker onSelect={onToggle} />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export { ReactionBar, type ReactionBarProps, type ReactionItem };
|