import { Avatar, Box, HStack, Menu, MenuButton, MenuDivider, MenuGroup, MenuItem, MenuList, SimpleGrid, useBreakpointValue, useColorModeValue, useDisclosure, } from "@chakra-ui/react"; import { boolean } from "boolean"; import { ClipboardList, Flag, MessageSquare, MoreHorizontal } from "lucide-react"; import { useRouter } from "next/router"; import { useTranslation } from "next-i18next"; import { useCallback, useEffect, useMemo, useState } from "react"; import { LabelMessagePopup } from "src/components/Messages/LabelPopup"; import { getEmojiIcon, MessageEmojiButton } from "src/components/Messages/MessageEmojiButton"; import { ReportPopup } from "src/components/Messages/ReportPopup"; import { post } from "src/lib/api"; import { Message, MessageEmojis } from "src/types/Conversation"; import { colors } from "styles/Theme/colors"; import useSWRMutation from "swr/mutation"; interface MessageTableEntryProps { message: Message; enabled?: boolean; highlight?: boolean; } export function MessageTableEntry({ message, enabled, highlight }: MessageTableEntryProps) { const router = useRouter(); const [emojiState, setEmojis] = useState({ emojis: {}, user_emojis: [] }); useEffect(() => { setEmojis({ emojis: message.emojis || {}, user_emojis: message.user_emojis || [] }); }, [message.emojis, message.user_emojis]); const goToMessage = useCallback(() => router.push(`/messages/${message.id}`), [router, message.id]); const { isOpen: reportPopupOpen, onOpen: showReportPopup, onClose: closeReportPopup } = useDisclosure(); const { isOpen: labelPopupOpen, onOpen: showLabelPopup, onClose: closeLabelPopup } = useDisclosure(); const backgroundColor = useColorModeValue("gray.100", "gray.700"); const backgroundColor2 = useColorModeValue("#DFE8F1", "#42536B"); const borderColor = useColorModeValue("blackAlpha.200", "whiteAlpha.200"); const inlineAvatar = useBreakpointValue({ base: true, sm: false }); const avatar = useMemo( () => ( ), [borderColor, inlineAvatar, message.is_assistant] ); const highlightColor = useColorModeValue(colors.light.highlight, colors.dark.highlight); const { trigger: sendEmojiChange } = useSWRMutation(`/api/messages/${message.id}/emoji`, post, { onSuccess: setEmojis, }); const react = (emoji: string, state: boolean) => { sendEmojiChange({ op: state ? "add" : "remove", emoji }); }; return ( {!inlineAvatar && avatar} {inlineAvatar && avatar} {message.text} e.stopPropagation()} > {Object.entries(emojiState.emojis).map(([emoji, count]) => ( react(emoji, !emojiState.user_emojis.includes(emoji))} /> ))} ); } const EmojiMenuItem = ({ emoji, checked, react, }: { emoji: string; checked?: boolean; react: (emoji: string, state: boolean) => void; }) => { const activeColor = useColorModeValue(colors.light.active, colors.dark.active); return ( react(emoji, !checked)} justifyContent="center" color={checked ? activeColor : undefined}> {getEmojiIcon(emoji, "NORMAL")} ); }; const MessageActions = ({ react, userEmoji, onLabel, onReport, messageId, }: { react: (emoji: string, state: boolean) => void; userEmoji: string[]; onLabel: () => void; onReport: () => void; messageId: string; }) => { const { t } = useTranslation("message"); return ( {["+1", "-1"].map((emoji) => ( ))} }> {t("label_action")} }> {t("report_action")} }> {t("open_new_tab_action")} ); };