import { useCallback, useContext, useMemo, useRef, useState } from "preact/hooks"; import { MessageTools, type IMessage } from "../../tools/messages"; import { StateContext } from "../../contexts/state"; import { DOMTools } from "../../tools/dom"; import styles from './message.module.css'; import { AutoTextarea } from "../autoTextarea"; import { useInputState } from "@common/hooks/useInputState"; interface IProps { message: IMessage; index: number; isLastUser: boolean; isLastAssistant: boolean; } export const Message = ({ message, index, isLastUser, isLastAssistant }: IProps) => { const { messages, editMessage, editSummary, deleteMessage, setCurrentSwipe, setMessages, continueMessage } = useContext(StateContext); const [editing, setEditing] = useState(false); const [editedMessage, setEditedMessage] = useInputState(''); const textRef = useRef(null); const swipe = useMemo(() => MessageTools.getSwipe(message), [message]); const content = swipe?.content; const summary = swipe?.summary; const cost = swipe?.cost ?? 0; const htmlContent = useMemo(() => MessageTools.format(content ?? ''), [content]); const handleEnableEdit = useCallback(() => { setEditing(true); setEditedMessage(content ?? ''); }, [content]); const handleSaveEdit = useCallback(() => { editMessage(index, editedMessage.trim(), cost); editSummary(index, '', 0); setEditing(false); }, [editMessage, editSummary, index, editedMessage, cost]); const handleCancelEdit = useCallback(() => { setEditing(false); }, [editMessage, index]); const handleDeleteMessage = useCallback(() => { if (confirm('Delete message?')) { setEditing(false); deleteMessage(index); } }, [deleteMessage, index]); const handleStopHere = useCallback(() => { if (confirm('Delete all messages after that?')) { setMessages(messages.filter((_, i) => i <= index)); setEditing(false); } }, [messages, setMessages, index]); const handleSwipeLeft = useCallback(() => { setCurrentSwipe(index, message.currentSwipe - 1); DOMTools.animate(textRef.current, 'swipe-from-left'); }, [setCurrentSwipe, index, message]); const handleSwipeRight = useCallback(() => { setCurrentSwipe(index, message.currentSwipe + 1); DOMTools.animate(textRef.current, 'swipe-from-right'); }, [setCurrentSwipe, index, message]); const handleContinueMessage = useCallback(() => { continueMessage(true); }, [continueMessage]); return (
{editing ? : <>
{summary && {summary}} {cost > 0 && 💲 {cost}} }
{editing ? <> : <> {isLastAssistant && <>
{message.currentSwipe + 1}/{message.swipes.length}
} }
); };