From 105cdca432362f4ded67c77ca3e692074fcedd58 Mon Sep 17 00:00:00 2001 From: nl_0 Date: Tue, 6 Aug 2024 14:57:33 +0200 Subject: [PATCH] discard messages --- .../app/components/Assistant/UI/Chat/Chat.tsx | 212 +++++++++++------- 1 file changed, 129 insertions(+), 83 deletions(-) diff --git a/catalog/app/components/Assistant/UI/Chat/Chat.tsx b/catalog/app/components/Assistant/UI/Chat/Chat.tsx index f545da321b6..93570eeaf13 100644 --- a/catalog/app/components/Assistant/UI/Chat/Chat.tsx +++ b/catalog/app/components/Assistant/UI/Chat/Chat.tsx @@ -11,6 +11,124 @@ import * as Model from '../../Model' import Input from './Input' import backgroundPattern from './bg.svg' +const USER_BG = M.colors.cyan[100] + +const useMessageContainerStyles = M.makeStyles((t) => ({ + role_user: {}, + role_assistant: {}, + messageContainer: { + alignItems: 'flex-end', + display: 'flex', + gap: `${t.spacing(1)}px`, + '&$role_user': { + alignSelf: 'flex-end', + flexFlow: 'row-reverse', + }, + '&$role_assistant': { + alignSelf: 'flex-start', + }, + }, + avatar: { + color: t.palette.text.primary, + height: `${t.spacing(4)}px`, + width: `${t.spacing(4)}px`, + '$role_user &': { + background: USER_BG, + }, + '$role_assistant &': { + background: t.palette.background.paper, + }, + }, + contentArea: { + borderRadius: `${t.spacing(1)}px`, + '$role_user &': { + background: USER_BG, + borderBottomRightRadius: 0, + }, + '$role_assistant &': { + background: t.palette.background.paper, + borderBottomLeftRadius: 0, + }, + }, + contents: { + ...t.typography.body2, + color: t.palette.text.primary, + padding: `${t.spacing(1.5)}px`, + }, + footer: { + ...t.typography.caption, + color: t.palette.text.hint, + display: 'flex', + gap: t.spacing(1), + justifyContent: 'flex-end', + padding: t.spacing(0, 1.5, 1, 1.5), + marginTop: t.spacing(-1.5), + }, + actions: { + opacity: 0.5, + '$messageContainer:hover &': { + opacity: 1, + }, + }, + spacer: { + flexShrink: 0, + width: `${t.spacing(4)}px`, + }, +})) + +interface MessageContainerProps { + role: 'user' | 'assistant' + children: React.ReactNode + actions?: React.ReactNode + timestamp?: Date +} + +function MessageContainer({ role, children, actions, timestamp }: MessageContainerProps) { + const classes = useMessageContainerStyles() + return ( +
+ + {role === 'user' ? 'person' : 'assistant'} + +
+
{children}
+ {!!(actions || timestamp) && ( +
+ {!!actions &&
{actions}
} + {timestamp && {timestamp.toLocaleTimeString()}} +
+ )} +
+
+
+ ) +} + +const useMessageActionStyles = M.makeStyles({ + action: { + cursor: 'pointer', + opacity: 0.5, + '&:hover': { + opacity: 1, + }, + }, +}) + +interface MessageActionProps { + children: React.ReactNode + className?: string + onClick?: () => void +} + +function MessageAction({ children, onClick }: MessageActionProps) { + const classes = useMessageActionStyles() + return ( + + {children} + + ) +} + type ConversationDispatch = (action: Model.Conversation.Action) => void interface MessageSharedProps { @@ -19,28 +137,23 @@ interface MessageSharedProps { } function Message({ - // state, - // id, - // timestamp, - // dispatch, + state, + id, + timestamp, + dispatch, role, content, }: MessageSharedProps & ReturnType) { - // const discard = React.useCallback(() => { - // if (state !== 'Idle') return - // dispatch(Model.Conversation.Action.Discard({ id })) - // }, [dispatch, id, state]) - // TODO: only show action on hover? + const discard = React.useMemo( + () => + state === 'Idle' ? () => dispatch(Model.Conversation.Action.Discard({ id })) : null, + [dispatch, id, state], + ) return ( - // - // close - // - // - // } + actions={<>{discard && discard}} + timestamp={timestamp} > {Model.Content.MessageContentBlock.$match(content, { Text: ({ text }) => , @@ -125,73 +238,6 @@ function ToolUse({ // }, // })) -const USER_BG = M.colors.cyan[100] - -const useMessageContainerStyles = M.makeStyles((t) => ({ - role_user: {}, - role_assistant: {}, - messageContainer: { - alignItems: 'flex-end', - display: 'flex', - gap: `${t.spacing(1)}px`, - '&$role_user': { - alignSelf: 'flex-end', - flexFlow: 'row-reverse', - }, - '&$role_assistant': { - alignSelf: 'flex-start', - }, - }, - avatar: { - color: t.palette.text.primary, - height: `${t.spacing(4)}px`, - width: `${t.spacing(4)}px`, - '$role_user &': { - background: USER_BG, - }, - '$role_assistant &': { - background: t.palette.background.paper, - }, - }, - contents: { - borderRadius: `${t.spacing(1)}px`, - color: t.palette.text.primary, - padding: `${t.spacing(1.5)}px`, - ...t.typography.body2, - '$role_user &': { - background: USER_BG, - borderBottomRightRadius: 0, - }, - '$role_assistant &': { - background: t.palette.background.paper, - borderBottomLeftRadius: 0, - }, - }, - action: { - flexShrink: 0, - width: `${t.spacing(4)}px`, - }, -})) - -interface MessageContainerProps { - role: 'user' | 'assistant' - children: React.ReactNode - action?: React.ReactNode -} - -function MessageContainer({ role, children, action }: MessageContainerProps) { - const classes = useMessageContainerStyles() - return ( -
- - {role === 'user' ? 'person' : 'assistant'} - -
{children}
-
{!!action && action}
-
- ) -} - const useChatStyles = M.makeStyles((t) => ({ chat: { display: 'flex',