import { useCallback, useEffect } from 'react' import { Thread } from '@janhq/core' import { Button } from '@janhq/joi' import { motion as m } from 'framer-motion' import { useAtomValue, useSetAtom } from 'jotai' import { GalleryHorizontalEndIcon, MoreHorizontalIcon, PenSquareIcon, } from 'lucide-react' import { twMerge } from 'tailwind-merge' import LeftPanelContainer from '@/containers/LeftPanelContainer' import { toaster } from '@/containers/Toast' import { useCreateNewThread } from '@/hooks/useCreateNewThread' import useRecommendedModel from '@/hooks/useRecommendedModel' import useSetActiveThread from '@/hooks/useSetActiveThread' import ModalCleanThread from './ModalCleanThread' import ModalDeleteThread from './ModalDeleteThread' import ModalEditTitleThread from './ModalEditTitleThread' import { assistantsAtom } from '@/helpers/atoms/Assistant.atom' import { editMessageAtom } from '@/helpers/atoms/ChatMessage.atom' import { getActiveThreadIdAtom, threadDataReadyAtom, threadsAtom, } from '@/helpers/atoms/Thread.atom' const ThreadLeftPanel = () => { const threads = useAtomValue(threadsAtom) const activeThreadId = useAtomValue(getActiveThreadIdAtom) const { setActiveThread } = useSetActiveThread() const assistants = useAtomValue(assistantsAtom) const threadDataReady = useAtomValue(threadDataReadyAtom) const { requestCreateNewThread } = useCreateNewThread() const setEditMessage = useSetAtom(editMessageAtom) const { recommendedModel, downloadedModels } = useRecommendedModel() const onThreadClick = useCallback( (thread: Thread) => { setActiveThread(thread) setEditMessage('') }, [setActiveThread, setEditMessage] ) /** * Auto create thread * This will create a new thread if there are assistants available * and there are no threads available */ useEffect(() => { if ( threadDataReady && assistants.length > 0 && threads.length === 0 && (recommendedModel || downloadedModels[0]) ) { const model = recommendedModel || downloadedModels[0] requestCreateNewThread(assistants[0], model) } else if (threadDataReady && !activeThreadId) { setActiveThread(threads[0]) } }, [ assistants, threads, threadDataReady, requestCreateNewThread, activeThreadId, setActiveThread, recommendedModel, downloadedModels, ]) const onCreateConversationClick = async () => { if (assistants.length === 0) { toaster({ title: 'No assistant available.', description: `Could not create a new thread. Please add an assistant.`, type: 'error', }) } else { requestCreateNewThread(assistants[0]) } } return ( {threads.length === 0 ? (

No Thread History

) : (
{threads.map((thread) => (
{ onThreadClick(thread) }} >

{thread.title}

{activeThreadId === thread.id && ( )}
))}
)}
) } export default ThreadLeftPanel