Faisal Amir 635435fbb8
Revert feat: temporary remove dark mode (#2221)
* Revert "feat: temporary remove dark mode :(  (#2168)"

This reverts commit 222b4ad897c275dab0eaec3c8a8472bf3df7afc4.

* fix: revert darkmode and fix darkmode for import model

* fix: prettier format import model

---------

Co-authored-by: Louis <louis@jan.ai>
2024-03-04 14:46:10 +07:00

122 lines
4.1 KiB
TypeScript

import { useCallback, useEffect } from 'react'
import { Thread } from '@janhq/core/'
import { motion as m } from 'framer-motion'
import { useAtomValue, useSetAtom } from 'jotai'
import { GalleryHorizontalEndIcon, MoreVerticalIcon } from 'lucide-react'
import { twMerge } from 'tailwind-merge'
import { useCreateNewThread } from '@/hooks/useCreateNewThread'
import useSetActiveThread from '@/hooks/useSetActiveThread'
import { displayDate } from '@/utils/datetime'
import CleanThreadModal from '../CleanThreadModal'
import DeleteThreadModal from '../DeleteThreadModal'
import { assistantsAtom } from '@/helpers/atoms/Assistant.atom'
import { editMessageAtom } from '@/helpers/atoms/ChatMessage.atom'
import {
getActiveThreadIdAtom,
threadDataReadyAtom,
threadStatesAtom,
threadsAtom,
} from '@/helpers/atoms/Thread.atom'
export default function ThreadList() {
const threadStates = useAtomValue(threadStatesAtom)
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 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) {
requestCreateNewThread(assistants[0])
} else if (threadDataReady && !activeThreadId) {
setActiveThread(threads[0])
}
}, [
assistants,
threads,
threadDataReady,
requestCreateNewThread,
activeThreadId,
setActiveThread,
])
return (
<div className="px-3 py-4">
{threads.length === 0 ? (
<div className="px-4 py-8 text-center">
<GalleryHorizontalEndIcon
size={26}
className="mx-auto mb-3 text-muted-foreground"
/>
<h2 className="font-semibold">No Thread History</h2>
</div>
) : (
threads.map((thread) => (
<div
key={thread.id}
className={twMerge(
`group/message relative mb-1 flex cursor-pointer flex-col transition-all hover:rounded-lg hover:bg-gray-100 hover:dark:bg-secondary/50`
)}
onClick={() => {
onThreadClick(thread)
}}
>
<div className="relative z-10 p-4 py-4">
<p className="line-clamp-1 text-xs leading-5 text-muted-foreground">
{thread.updated && displayDate(thread.updated)}
</p>
<h2 className="line-clamp-1 font-bold">{thread.title}</h2>
<p className="mt-1 line-clamp-1 text-xs text-gray-700 group-hover/message:max-w-[160px] dark:text-gray-300">
{threadStates[thread.id]?.lastMessage
? threadStates[thread.id]?.lastMessage
: 'No new message'}
</p>
</div>
<div
className={twMerge(
`group/icon invisible absolute bottom-2 right-2 z-20 rounded-lg p-1 text-muted-foreground hover:bg-gray-200 group-hover/message:visible hover:dark:bg-secondary`
)}
>
<MoreVerticalIcon />
<div className="invisible absolute right-0 z-20 w-40 overflow-hidden rounded-lg border border-border bg-background shadow-lg group-hover/icon:visible">
<CleanThreadModal threadId={thread.id} />
<DeleteThreadModal threadId={thread.id} />
</div>
</div>
{activeThreadId === thread.id && (
<m.div
className="absolute inset-0 left-0 h-full w-full rounded-lg bg-gray-100 p-4 dark:bg-secondary/50"
layoutId="active-thread"
/>
)}
</div>
))
)}
</div>
)
}