import { SmilePlusIcon } from "lucide-react"; import { observer } from "mobx-react-lite"; import { useRef, useState } from "react"; import useClickAway from "react-use/lib/useClickAway"; import { memoServiceClient } from "@/grpcweb"; import useCurrentUser from "@/hooks/useCurrentUser"; import { cn } from "@/lib/utils"; import { instanceStore, memoStore } from "@/store"; import { Memo } from "@/types/proto/api/v1/memo_service"; import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover"; interface Props { memo: Memo; className?: string; onOpenChange?: (open: boolean) => void; } const ReactionSelector = observer((props: Props) => { const { memo, className, onOpenChange } = props; const currentUser = useCurrentUser(); const [open, setOpen] = useState(false); const containerRef = useRef(null); const instanceMemoRelatedSetting = instanceStore.state.memoRelatedSetting; useClickAway(containerRef, () => { setOpen(false); onOpenChange?.(false); }); const handleOpenChange = (newOpen: boolean) => { setOpen(newOpen); onOpenChange?.(newOpen); }; const hasReacted = (reactionType: string) => { return memo.reactions.some((r) => r.reactionType === reactionType && r.creator === currentUser?.name); }; const handleReactionClick = async (reactionType: string) => { try { if (hasReacted(reactionType)) { const reactions = memo.reactions.filter( (reaction) => reaction.reactionType === reactionType && reaction.creator === currentUser.name, ); for (const reaction of reactions) { await memoServiceClient.deleteMemoReaction({ name: reaction.name }); } } else { await memoServiceClient.upsertMemoReaction({ name: memo.name, reaction: { contentId: memo.name, reactionType: reactionType, }, }); } await memoStore.getOrFetchMemoByName(memo.name, { skipCache: true }); } catch { // skip error. } handleOpenChange(false); }; return (
{instanceMemoRelatedSetting.reactions.map((reactionType) => { return ( handleReactionClick(reactionType)} > {reactionType} ); })}
); }); export default ReactionSelector;