import { useCallback, useEffect, useRef } from 'react' import { Button } from '@janhq/joi' import { AnimatePresence } from 'framer-motion' import { useAtomValue } from 'jotai' import { PenSquareIcon } from 'lucide-react' import { twMerge } from 'tailwind-merge' import LeftPanelContainer from '@/containers/LeftPanelContainer' import { toaster } from '@/containers/Toast' import useAssistantQuery from '@/hooks/useAssistantQuery' import useThreads from '@/hooks/useThreads' import ThreadItem from './ThreadItem' import { downloadedModelsAtom, getSelectedModelAtom, } from '@/helpers/atoms/Model.atom' import { reduceTransparentAtom } from '@/helpers/atoms/Setting.atom' import { getActiveThreadIdAtom, threadsAtom } from '@/helpers/atoms/Thread.atom' const ThreadLeftPanel: React.FC = () => { const { createThread, setActiveThread } = useThreads() const reduceTransparent = useAtomValue(reduceTransparentAtom) const downloadedModels = useAtomValue(downloadedModelsAtom) const selectedModel = useAtomValue(getSelectedModelAtom) const threads = useAtomValue(threadsAtom) const activeThreadId = useAtomValue(getActiveThreadIdAtom) const { data: assistants } = useAssistantQuery() const isCreatingThread = useRef(false) useEffect(() => { // if user does not have any threads, we should create one const createThreadIfEmpty = async () => { if (!assistants || assistants.length === 0) return if (downloadedModels.length === 0) return if (threads.length > 0) return if (isCreatingThread.current) return isCreatingThread.current = true // user have models but does not have any thread. Let's create one await createThread(downloadedModels[0].model, assistants[0]) isCreatingThread.current = false } createThreadIfEmpty() }, [threads, assistants, downloadedModels, createThread]) useEffect(() => { const setActiveThreadIfNone = () => { if (activeThreadId) return if (threads.length === 0) return setActiveThread(threads[0].id) } setActiveThreadIfNone() }, [activeThreadId, setActiveThread, threads]) const onCreateThreadClicked = useCallback(async () => { if (!assistants || assistants.length === 0) { toaster({ title: 'No assistant available.', description: `Could not create a new thread. Please add an assistant.`, type: 'error', }) return } if (!selectedModel) return createThread(selectedModel.model, assistants[0]) }, [createThread, selectedModel, assistants]) return (
{threads.map((thread) => ( ))}
) } export default ThreadLeftPanel