feat(gpt-runner-web): add use event emitter hook
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user