feat(gpt-runner-web): add use event emitter hook

This commit is contained in:
JinmingYang
2023-06-30 13:15:33 +08:00
parent 56fc24c534
commit 9924952d96
4 changed files with 58 additions and 13 deletions

View File

@@ -0,0 +1,52 @@
import { useEffect, useRef } from 'react'
import { emitter } from '../helpers/emitter'
export interface UseEventEmitterReturns {
emit: typeof emitter.emit
on: typeof emitter.on
once: typeof emitter.once
off: typeof emitter.off
}
export function useEventEmitter(): UseEventEmitterReturns {
const listenersRef = useRef<Record<string, (...args: any[]) => void>>({})
const on = (
eventName: string,
listener: (...args: any[]) => void,
) => {
listenersRef.current[eventName] = listener
emitter.on(eventName as any, listener)
}
const once = (
eventName: string,
listener: (...args: any[]) => void,
) => {
listenersRef.current[eventName] = listener
emitter.once(eventName as any, listener)
}
const off = (
eventName: string,
listener: (...args: any[]) => void,
) => {
delete listenersRef.current[eventName]
emitter.off(eventName as any, listener)
}
const emit = (eventName: string, ...args: any[]) => {
emitter.emit(eventName as any, ...args)
}
useEffect(() => {
return () => {
Object.entries(listenersRef.current).forEach(([eventName, listener]) => {
if (listener)
emitter.off(eventName as any, listener)
})
}
}, [])
return { on, once, off, emit } as UseEventEmitterReturns
}

View File

@@ -13,7 +13,6 @@ import type { MessageItemProps } from '../../../../components/chat-message-item'
import { ErrorView } from '../../../../components/error-view'
import { useGlobalStore } from '../../../../store/zustand/global'
import type { GptFileTreeItem } from '../../../../store/zustand/global/sidebar-tree.slice'
import { emitter } from '../../../../helpers/emitter'
import { getGlobalConfig } from '../../../../helpers/global-config'
import { PopoverMenu } from '../../../../components/popover-menu'
import { useKeyboard } from '../../../../hooks/use-keyboard.hook'
@@ -22,6 +21,7 @@ import { useElementSizeRealTime } from '../../../../hooks/use-element-size-real-
import { useTempStore } from '../../../../store/zustand/temp'
import type { MessageCodeBlockTheme } from '../../../../components/chat-message-code-block'
import { isDarkTheme } from '../../../../styles/themes'
import { useEventEmitter } from '../../../../hooks/use-event-emitter.hook'
import { ChatPanelPopoverTreeWrapper, ChatPanelWrapper } from './chat-panel.styles'
import { createRemarkOpenEditorPlugin } from './remark-plugin'
@@ -61,6 +61,7 @@ export const ChatPanel: FC<ChatPanelProps> = memo((props) => {
const [gptFileTreeItem, setGptFileTreeItem] = useState<GptFileTreeItem>()
const [chatPanelRef, { width: chatPanelWidth }] = useElementSizeRealTime<HTMLDivElement>()
const { filesRelativePaths } = useTempStore()
const emitter = useEventEmitter()
const filesPathsAllPartsInfo = useMemo(() => {
// not good, but fast

View File

@@ -12,7 +12,7 @@ import { IconButton } from '../../../../components/icon-button'
import { ErrorView } from '../../../../components/error-view'
import { useGlobalStore } from '../../../../store/zustand/global'
import { useChatInstance } from '../../../../hooks/use-chat-instance.hook'
import { emitter } from '../../../../helpers/emitter'
import { useEventEmitter } from '../../../../hooks/use-event-emitter.hook'
export interface ChatSidebarProps {
rootPath: string
@@ -36,6 +36,7 @@ export const ChatSidebar: FC<ChatSidebarProps> = memo((props) => {
} = useGlobalStore()
const [isLoading, setIsLoading] = useState(false)
const emitter = useEventEmitter()
const { removeChatInstance } = useChatInstance({
chatId,
@@ -61,11 +62,6 @@ export const ChatSidebar: FC<ChatSidebarProps> = memo((props) => {
emitter.on(ClientEventName.RefreshTree, refreshSidebarTree)
emitter.on(ClientEventName.RefreshChatTree, refreshSidebarTree)
return () => {
emitter.off(ClientEventName.RefreshTree, refreshSidebarTree)
emitter.off(ClientEventName.RefreshChatTree, refreshSidebarTree)
}
}, [rootPath])
const handleCreateChat = useCallback((gptFileId: string) => {

View File

@@ -16,7 +16,7 @@ import { useGlobalStore } from '../../../../store/zustand/global'
import type { FileInfoSidebarTreeItem, FileSidebarTreeItem } from '../../../../store/zustand/global/file-tree.slice'
import { PopoverMenu } from '../../../../components/popover-menu'
import { useTempStore } from '../../../../store/zustand/temp'
import { emitter } from '../../../../helpers/emitter'
import { useEventEmitter } from '../../../../hooks/use-event-emitter.hook'
import { FileTreeItemRightWrapper, FileTreeSidebarHighlight, FileTreeSidebarUnderSearchWrapper, FilterWrapper } from './file-tree.styles'
export interface FileTreeProps {
@@ -28,6 +28,7 @@ export const FileTree: FC<FileTreeProps> = memo((props: FileTreeProps) => {
const { rootPath, reverseTreeUi } = props
const { t } = useTranslation()
const emitter = useEventEmitter()
const [filesTree, _setFilesTree] = useState<FileSidebarTreeItem[]>([])
const fullPathFileMapRef = useRef<Record<string, FileSidebarTreeItem>>({})
const {
@@ -89,11 +90,6 @@ export const FileTree: FC<FileTreeProps> = memo((props: FileTreeProps) => {
emitter.on(ClientEventName.RefreshTree, refresh)
emitter.on(ClientEventName.RefreshFileTree, refresh)
return () => {
emitter.off(ClientEventName.RefreshTree, refresh)
emitter.off(ClientEventName.RefreshFileTree, refresh)
}
}, [rootPath])
// sync checked state