diff --git a/sparkle/src/components/ConversationMessage.tsx b/sparkle/src/components/ConversationMessage.tsx index 17bb85b58aac..a74569a80a5b 100644 --- a/sparkle/src/components/ConversationMessage.tsx +++ b/sparkle/src/components/ConversationMessage.tsx @@ -4,6 +4,7 @@ import { Button } from "@sparkle/components"; import { ConversationMessageActions, ConversationMessageEmojiSelectorProps, + ConversationMessageThumbSelectorProps, } from "@sparkle/components/ConversationMessageActions"; import { ConversationMessageContent } from "@sparkle/components/ConversationMessageContent"; import { ConversationMessageHeader } from "@sparkle/components/ConversationMessageHeader"; @@ -29,6 +30,7 @@ type ConversationMessageProps = { children?: React.ReactNode; citations?: React.ReactElement[]; messageEmoji?: ConversationMessageEmojiSelectorProps; + messageThumb?: ConversationMessageThumbSelectorProps; name: string | null; pictureUrl?: string | React.ReactNode | null; renderName?: (name: string | null) => React.ReactNode; @@ -46,6 +48,7 @@ export function ConversationMessage({ children, citations, messageEmoji, + messageThumb, name, pictureUrl, renderName = (name) => ( @@ -77,6 +80,7 @@ export function ConversationMessage({ ); diff --git a/sparkle/src/components/ConversationMessageActions.tsx b/sparkle/src/components/ConversationMessageActions.tsx index 3c1cbd59c123..31895691bb64 100644 --- a/sparkle/src/components/ConversationMessageActions.tsx +++ b/sparkle/src/components/ConversationMessageActions.tsx @@ -6,19 +6,42 @@ import { EmojiMartData, EmojiPicker, } from "@sparkle/components/EmojiPicker"; -import { Popover } from "@sparkle/components/Popover"; -import { ReactionIcon } from "@sparkle/icons/solid"; +import { Page } from "@sparkle/components/Page"; +import { + Popover, + PopoverContent, + PopoverRoot, + PopoverTrigger, +} from "@sparkle/components/Popover"; +import { TextArea } from "@sparkle/components/TextArea"; +import { + HandThumbDownIcon, + HandThumbUpIcon, + ReactionIcon, +} from "@sparkle/icons/solid"; import { cn } from "@sparkle/lib/utils"; type ConversationMessageActionsProps = { buttons?: React.ReactElement[]; messageEmoji?: ConversationMessageEmojiSelectorProps; + messageThumb?: ConversationMessageThumbSelectorProps; }; export function ConversationMessageActions({ buttons = [], messageEmoji, + messageThumb, }: ConversationMessageActionsProps) { + if (messageThumb) { + buttons.push( + + ); + } + if (messageEmoji) { buttons.push( Promise; + isSubmittingThumb: boolean; +} + function ConversationMessageEmojiSelector({ reactions, onSubmitEmoji, @@ -174,3 +207,104 @@ function EmojiSelector({ /> ); } + +function ConversationMessageThumbsSelector({ + onSubmitThumb, + isSubmittingThumb, +}: ConversationMessageThumbSelectorProps) { + return ( + + ); +} + +function ThumbsSelector({ + isSubmittingThumb = false, + onSubmitThumb, +}: ConversationMessageThumbSelectorProps) { + const [selectedThumb, setSelectedThumb] = + React.useState(null); + const [feedback, setFeedback] = React.useState(null); + const [isPopoverOpen, setIsPopoverOpen] = React.useState(false); + const containerRef = useRef(null); + + const selectThumb = async (thumb: ThumbReaction) => { + if (selectedThumb === thumb) { + setSelectedThumb(null); + setIsPopoverOpen(false); + await onSubmitThumb({ thumb, isToRemove: true }); + return; + } + setSelectedThumb(thumb); + setIsPopoverOpen(true); + await onSubmitThumb({ thumb, isToRemove: false }); + }; + + return ( +
+ + +
+
+
+ +
+ + {selectedThumb === "up" + ? "🎉 Glad you liked it! Tell us more?" + : "🫠 Help make the answers better!"} + +