import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "preact/hooks"; import { MessageTools, type IMessage } from "../../messages"; import { StateContext } from "../../contexts/state"; import { DOMTools } from "../../dom"; import styles from './message.module.css'; import { AutoTextarea } from "../autoTextarea"; interface IProps { message: IMessage; index: number; isLastUser: boolean; isLastAssistant: boolean; } export const Message = ({ message, index, isLastUser, isLastAssistant }: IProps) => { const { messages, editMessage, deleteMessage, setCurrentSwipe, setMessages } = useContext(StateContext); const [editing, setEditing] = useState(false); const [savedMessage, setSavedMessage] = useState(''); const textRef = useRef(null); const content = useMemo(() => MessageTools.getSwipe(message)?.content, [message]); const htmlContent = useMemo(() => MessageTools.format(content ?? ''), [content]); const handleToggleEdit = useCallback(() => { setEditing(!editing); if (!editing) { setSavedMessage(content ?? ''); } }, [editing, content]); const handleCancelEdit = useCallback(() => { setEditing(false); editMessage(index, savedMessage); }, [editMessage, index, savedMessage]); 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 handleEdit = useCallback((e: InputEvent) => { if (e.target instanceof HTMLTextAreaElement) { const newContent = e.target.value; editMessage(index, newContent); } }, [editMessage, 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]); return (
{editing ? :
} {(isLastUser || message.role === 'assistant') &&
{editing ? <> : <> {isLastAssistant &&
{message.currentSwipe + 1}/{message.swipes.length}
} }
}
); };