Skip to content

Commit

Permalink
rm context menu provider + chat context + move chat state to provider
Browse files Browse the repository at this point in the history
  • Loading branch information
samlhuillier committed Oct 16, 2024
1 parent e8f1748 commit 27c4d58
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 215 deletions.
46 changes: 18 additions & 28 deletions src/components/Chat/ChatSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,44 @@
import React, { useState } from 'react'

import { RiChatNewFill, RiArrowDownSLine } from 'react-icons/ri'
import { IoChatbubbles } from 'react-icons/io5'
import posthog from 'posthog-js'
import { RiChatNewFill, RiArrowDownSLine } from 'react-icons/ri'
import { useChatContext } from '@/contexts/ChatContext'
import { useContentContext } from '@/contexts/ContentContext'
import { ChatMetadata } from '../../lib/llm/types'
import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from '@/components/ui/context-menu'

export interface ChatItemProps {
chatMetadata: ChatMetadata
}

export const ChatItem: React.FC<ChatItemProps> = ({ chatMetadata }) => {
const { currentOpenChatID } = useChatContext()
const { openContent, showContextMenu } = useContentContext()
const { currentChat, deleteChat } = useChatContext()
const { openContent } = useContentContext()

const itemClasses = `
flex items-center cursor-pointer py-2 px-3 rounded-md
transition-colors duration-150 ease-in-out
${chatMetadata.id === currentOpenChatID ? 'bg-neutral-700 text-white' : 'text-gray-300 hover:bg-neutral-800'}
${chatMetadata.id === currentChat?.id ? 'bg-neutral-700 text-white' : 'text-gray-300 hover:bg-neutral-800'}
`
return (
<div>
<div
onClick={async () => {
openContent(chatMetadata.id)
}}
className={itemClasses}
onContextMenu={(e) => {
e.stopPropagation()
showContextMenu(e, 'ChatItem', { chatMetadata })
}}
>
<IoChatbubbles />
<span className="ml-2 flex-1 truncate text-[11px] font-medium">{chatMetadata.displayName}</span>
</div>
</div>
<ContextMenu>
<ContextMenuTrigger>
<div onClick={() => openContent(chatMetadata.id)} className={itemClasses}>
<IoChatbubbles />
<span className="ml-2 flex-1 truncate text-[11px] font-medium">{chatMetadata.displayName}</span>
</div>
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem onClick={() => deleteChat(chatMetadata.id)}>Delete Chat</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
)
}

export const ChatSidebar: React.FC = () => {
const [isRecentsOpen, setIsRecentsOpen] = useState(true)
const dropdownAnimationDelay = 0.02

const { setShowChatbot, allChatsMetadata, setCurrentOpenChatID } = useChatContext()
const { allChatsMetadata, openNewChat } = useChatContext()

const toggleRecents = () => setIsRecentsOpen((prev) => !prev)

Expand All @@ -58,18 +53,13 @@ export const ChatSidebar: React.FC = () => {
shadow-md transition-colors duration-200 hover:bg-blue-400 hover:text-gray-200
hover:shadow-lg"
type="button"
onClick={() => {
posthog.capture('create_new_chat')
setShowChatbot(true)
setCurrentOpenChatID(undefined)
}}
onClick={() => openNewChat()}
>
<RiChatNewFill className="text-xl" />
<span className="text-xs font-bold">Start New Chat</span>
</button>
</div>

{/* Recents Section */}
<div className="flex-1">
<div className="flex cursor-pointer items-center justify-between" onClick={toggleRecents}>
<h4 className="mb-0 mt-1 text-xs font-medium tracking-wider text-gray-200">Recents</h4>
Expand Down
17 changes: 3 additions & 14 deletions src/components/Chat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ import { appendToolCallsAndAutoExecuteTools, convertToolConfigToZodSchema } from
const ChatComponent: React.FC = () => {
const [loadingState, setLoadingState] = useState<LoadingState>('idle')
const [defaultModelName, setDefaultLLMName] = useState<string>('')
const [currentChat, setCurrentChat] = useState<Chat | undefined>(undefined)
const { saveChat, currentOpenChatID, setCurrentOpenChatID } = useChatContext()
const { currentChat, setCurrentChat, saveChat } = useChatContext()
const abortControllerRef = useRef<AbortController | null>(null)

useEffect(() => {
Expand All @@ -36,18 +35,10 @@ const ChatComponent: React.FC = () => {
if (abortControllerRef.current) {
abortControllerRef.current.abort()
}

const chat = await window.electronStore.getChat(currentOpenChatID)
setCurrentChat((oldChat) => {
if (oldChat && oldChat.id !== currentOpenChatID) {
saveChat(oldChat)
}
return chat
})
setLoadingState('idle')
}
fetchChat()
}, [currentOpenChatID, saveChat])
}, [currentChat?.id, saveChat])

const handleNewChatMessage = useCallback(
async (chat: Chat | undefined, userTextFieldInput?: string, agentConfig?: AgentConfig) => {
Expand All @@ -65,11 +56,9 @@ const ChatComponent: React.FC = () => {
}

setCurrentChat(outputChat)
setCurrentOpenChatID(outputChat.id)
await saveChat(outputChat)

const llmClient = await resolveLLMClient(defaultLLMName)

abortControllerRef.current = new AbortController()
const toolsZodSchema = Object.assign({}, ...outputChat.toolDefinitions.map(convertToolConfigToZodSchema))
const { textStream, toolCalls } = await streamText({
Expand Down Expand Up @@ -140,7 +129,7 @@ const ChatComponent: React.FC = () => {
abortControllerRef.current = null
}
},
[setCurrentOpenChatID, saveChat],
[saveChat, setCurrentChat],
)

return (
Expand Down
107 changes: 0 additions & 107 deletions src/components/Common/CustomContextMenu.tsx

This file was deleted.

2 changes: 0 additions & 2 deletions src/components/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import WritingAssistant from './WritingAssistant/WritingAssistant'
import { ChatProvider, useChatContext } from '@/contexts/ChatContext'
import { FileProvider, useFileContext } from '@/contexts/FileContext'
import ModalProvider from '@/contexts/ModalContext'
import CustomContextMenu from './Common/CustomContextMenu'
import CommonModals from './Common/CommonModals'

const MainPageContent: React.FC = () => {
Expand All @@ -32,7 +31,6 @@ const MainPageContent: React.FC = () => {
setShowSimilarFiles(!showSimilarFiles)
}}
/>
<CustomContextMenu />
<div className="flex h-below-titlebar">
<div className="border-y-0 border-l-0 border-r-[0.001px] border-solid border-neutral-700 pt-2.5">
<IconsSidebar />
Expand Down
51 changes: 30 additions & 21 deletions src/contexts/ChatContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@ import React, { createContext, useContext, useState, useCallback, useEffect } fr
import { SidebarAbleToShow } from '@/components/Sidebars/MainSidebar'
import { Chat, ChatMetadata } from '@/lib/llm/types'

export const UNINITIALIZED_STATE = 'UNINITIALIZED_STATE'

interface ChatContextType {
currentChat: Chat | undefined
setCurrentChat: React.Dispatch<React.SetStateAction<Chat | undefined>>
sidebarShowing: SidebarAbleToShow
setSidebarShowing: (option: SidebarAbleToShow) => void
showChatbot: boolean
setShowChatbot: (show: boolean) => void
currentOpenChatID: string | undefined
setCurrentOpenChatID: (chatID: string | undefined) => void
allChatsMetadata: ChatMetadata[]
deleteChat: (chatID: string | undefined) => Promise<boolean>
deleteChat: (chatID: string | undefined) => Promise<void>
saveChat: (updatedChat: Chat) => Promise<void>
openNewChat: (chatID?: string) => Promise<void>
}

const ChatContext = createContext<ChatContextType | undefined>(undefined)

export const ChatProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [currentChat, setCurrentChat] = useState<Chat | undefined>(undefined)
const [showChatbot, setShowChatbot] = useState<boolean>(false)
const [sidebarShowing, setSidebarShowing] = useState<SidebarAbleToShow>('files')
const [currentOpenChatID, setCurrentOpenChatID] = useState<string | undefined>(undefined)
const [allChatsMetadata, setAllChatsMetadata] = useState<ChatMetadata[]>([])

useEffect(() => {
Expand All @@ -39,42 +38,52 @@ export const ChatProvider: React.FC<{ children: React.ReactNode }> = ({ children
setAllChatsMetadata(retrievedChatsMetadata)
}, [])

const deleteChat = useCallback(
async (chatID: string | undefined) => {
if (!chatID) return false
await window.electronStore.deleteChat(chatID)
const retrievedChatsMetadata = await window.electronStore.getAllChatsMetadata()
setAllChatsMetadata(retrievedChatsMetadata)
if (currentOpenChatID === chatID) {
setCurrentOpenChatID(undefined)
}
return true
const deleteChat = useCallback(async (chatID: string | undefined) => {
if (!chatID) return
await window.electronStore.deleteChat(chatID)
const retrievedChatsMetadata = await window.electronStore.getAllChatsMetadata()
setAllChatsMetadata(retrievedChatsMetadata)
setCurrentChat(undefined)
}, [])

const openNewChat = useCallback(
async (chatID?: string) => {
const chat = await window.electronStore.getChat(chatID)
setCurrentChat((oldChat) => {
if (oldChat && oldChat.id !== chatID) {
saveChat(oldChat)
}
return chat
})
setShowChatbot(true)
},
[currentOpenChatID],
[setShowChatbot, saveChat],
)

const value = React.useMemo(
() => ({
currentChat,
setCurrentChat,
allChatsMetadata,
sidebarShowing,
setSidebarShowing,
showChatbot,
setShowChatbot,
currentOpenChatID,
setCurrentOpenChatID,
deleteChat,
saveChat,
openNewChat,
}),
[
currentChat,
setCurrentChat,
allChatsMetadata,
sidebarShowing,
setSidebarShowing,
showChatbot,
setShowChatbot,
currentOpenChatID,
setCurrentOpenChatID,
deleteChat,
saveChat,
openNewChat,
],
)

Expand Down
Loading

0 comments on commit 27c4d58

Please sign in to comment.