/* eslint-disable @typescript-eslint/no-explicit-any */ import { useEffect, useRef, useState } from 'react' import { ConversationalExtension, ExtensionTypeEnum, MessageStatus, ThreadMessage, } from '@janhq/core' import { TextArea, Button, Modal, ModalClose } from '@janhq/joi' import { useAtom, useAtomValue, useSetAtom } from 'jotai' import { twMerge } from 'tailwind-merge' import { editPromptAtom } from '@/containers/Providers/Jotai' import { useActiveModel } from '@/hooks/useActiveModel' import useSendChatMessage from '@/hooks/useSendChatMessage' import { extensionManager } from '@/extension' import { editMessageAtom, getCurrentChatMessagesAtom, setConvoMessagesAtom, } from '@/helpers/atoms/ChatMessage.atom' import { spellCheckAtom } from '@/helpers/atoms/Setting.atom' import { activeThreadAtom, getActiveThreadIdAtom, } from '@/helpers/atoms/Thread.atom' type Props = { message: ThreadMessage } const EditChatInput: React.FC = ({ message }) => { const activeThread = useAtomValue(activeThreadAtom) const { stateModel, stopInference } = useActiveModel() const messages = useAtomValue(getCurrentChatMessagesAtom) const [editPrompt, setEditPrompt] = useAtom(editPromptAtom) const { sendChatMessage } = useSendChatMessage() const setMessages = useSetAtom(setConvoMessagesAtom) const activeThreadId = useAtomValue(getActiveThreadIdAtom) const spellCheck = useAtomValue(spellCheckAtom) const textareaRef = useRef(null) const setEditMessage = useSetAtom(editMessageAtom) const [showDialog, setshowDialog] = useState(false) const onPromptChange = (e: React.ChangeEvent) => { setEditPrompt(e.target.value) } useEffect(() => { if (textareaRef.current) { textareaRef.current.focus() const length = textareaRef.current.value.length textareaRef.current.setSelectionRange(length, length) } }, [activeThreadId]) useEffect(() => { if (textareaRef.current) { textareaRef.current.style.height = '40px' textareaRef.current.style.height = textareaRef.current.scrollHeight + 'px' textareaRef.current.style.overflow = textareaRef.current.clientHeight >= 390 ? 'auto' : 'hidden' } }, [editPrompt]) useEffect(() => { if (message.content?.[0]?.text?.value) setEditPrompt(message.content[0].text.value) // eslint-disable-next-line react-hooks/exhaustive-deps }, []) const sendEditMessage = async () => { setEditMessage('') const messageIdx = messages.findIndex((msg) => msg.id === message.id) const newMessages = messages.slice(0, messageIdx) const toDeleteMessages = messages.slice(messageIdx) const threadId = messages[0].thread_id await Promise.all( toDeleteMessages.map(async (message) => extensionManager .get(ExtensionTypeEnum.Conversational) ?.deleteMessage(message.thread_id, message.id) ) ).catch(console.error) setMessages(threadId, newMessages) sendChatMessage(editPrompt, false, newMessages) } const onKeyDown = async (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault() if (messages[messages.length - 1]?.status !== MessageStatus.Pending) sendEditMessage() else onStopInferenceClick() } } const onStopInferenceClick = async () => { stopInference() } return (