Skip to content

Commit 680ab86

Browse files
committed
refactor(textarea): simplify event listeners
1 parent 92a04f5 commit 680ab86

File tree

3 files changed

+266
-114
lines changed

3 files changed

+266
-114
lines changed

pnpm-lock.yaml

Lines changed: 14 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/components/chat/ChatLexicalTextArea.tsx

Lines changed: 17 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ import { MentionNode } from "./lexical/MentionNode"
3434
import { LexicalMentionPlugin, type MentionInfo, type LexicalMentionPluginRef } from "./lexical/LexicalMentionPlugin"
3535
import { LexicalSelectAllPlugin } from "./lexical/LexicalSelectAllPlugin"
3636
import { LexicalPromptHistoryPlugin } from "./lexical/LexicalPromptHistoryPlugin"
37+
import { LexicalContextMenuPlugin } from "./lexical/LexicalContextMenuPlugin"
3738
import ContextMenu from "./ContextMenu"
38-
import { ContextMenuOptionType, getContextMenuOptions, SearchResult } from "@/utils/context-mentions"
39+
import { ContextMenuOptionType, SearchResult } from "@/utils/context-mentions"
3940
import { MAX_IMAGES_PER_MESSAGE } from "./ChatView"
4041
import { CloudAccountSwitcher } from "../cloud/CloudAccountSwitcher"
4142
import { ChatContextBar } from "./ChatContextBar"
@@ -112,7 +113,6 @@ export const ChatLexicalTextArea = forwardRef<LexicalEditor, ChatTextAreaProps>(
112113
const [searchLoading, setSearchLoading] = useState(false)
113114
const [searchRequestId, setSearchRequestId] = useState<string>("")
114115
const [gitCommits, setGitCommits] = useState<any[]>([])
115-
const contextMenuContainerRef = useRef<HTMLDivElement>(null)
116116
const searchTimeoutRef = useRef<NodeJS.Timeout | null>(null)
117117
const [isEnhancingPrompt, setIsEnhancingPrompt] = useState(false)
118118
const [isMouseDownOnMenu, setIsMouseDownOnMenu] = useState(false)
@@ -530,102 +530,10 @@ export const ChatLexicalTextArea = forwardRef<LexicalEditor, ChatTextAreaProps>(
530530
[searchQuery, setMode, setInputValue, mentionPluginRef],
531531
)
532532

533-
// Handle keyboard navigation for context menu
534-
useEffect(() => {
535-
const handleKeyDown = (event: KeyboardEvent) => {
536-
if (!showContextMenu) return
537-
538-
if (event.key === "Escape") {
539-
setSelectedType(null)
540-
setSelectedMenuIndex(3) // File by default
541-
return
542-
}
543-
544-
if (event.key === "ArrowUp" || event.key === "ArrowDown") {
545-
event.preventDefault()
546-
setSelectedMenuIndex((prevIndex) => {
547-
const direction = event.key === "ArrowUp" ? -1 : 1
548-
const options = getContextMenuOptions(
549-
searchQuery,
550-
selectedType,
551-
queryItems,
552-
fileSearchResults,
553-
customModes,
554-
commands,
555-
)
556-
const optionsLength = options.length
557-
558-
if (optionsLength === 0) return prevIndex
559-
560-
// Find selectable options (non-URL types)
561-
const selectableOptions = options.filter(
562-
(option) =>
563-
option.type !== ContextMenuOptionType.URL &&
564-
option.type !== ContextMenuOptionType.NoResults &&
565-
option.type !== ContextMenuOptionType.SectionHeader,
566-
)
567-
568-
if (selectableOptions.length === 0) return -1 // No selectable options
569-
570-
// Find the index of the next selectable option
571-
const currentSelectableIndex = selectableOptions.findIndex(
572-
(option) => option === options[prevIndex],
573-
)
574-
575-
const newSelectableIndex =
576-
(currentSelectableIndex + direction + selectableOptions.length) % selectableOptions.length
577-
578-
// Find the index of the selected option in the original options array
579-
return options.findIndex((option) => option === selectableOptions[newSelectableIndex])
580-
})
581-
return
582-
}
583-
584-
if ((event.key === "Enter" || event.key === "Tab") && selectedMenuIndex !== -1) {
585-
event.preventDefault()
586-
event.stopPropagation()
587-
const selectedOption = getContextMenuOptions(
588-
searchQuery,
589-
selectedType,
590-
queryItems,
591-
fileSearchResults,
592-
customModes,
593-
commands,
594-
)[selectedMenuIndex]
595-
if (
596-
selectedOption &&
597-
selectedOption.type !== ContextMenuOptionType.URL &&
598-
selectedOption.type !== ContextMenuOptionType.NoResults &&
599-
selectedOption.type !== ContextMenuOptionType.SectionHeader
600-
) {
601-
handleMentionSelect(selectedOption.type, selectedOption.value)
602-
}
603-
return
604-
}
605-
}
606-
607-
document.addEventListener("keydown", handleKeyDown, { capture: true })
608-
return () => document.removeEventListener("keydown", handleKeyDown, { capture: true })
609-
}, [
610-
showContextMenu,
611-
searchQuery,
612-
selectedMenuIndex,
613-
selectedType,
614-
queryItems,
615-
fileSearchResults,
616-
customModes,
617-
commands,
618-
handleMentionSelect,
619-
])
620-
621533
// Effect to handle clicks outside the context menu to close it
622534
useEffect(() => {
623-
const handleClickOutside = (event: MouseEvent) => {
624-
if (
625-
contextMenuContainerRef.current &&
626-
!contextMenuContainerRef.current.contains(event.target as Node) &&
627-
!isMouseDownOnMenu
628-
) {
535+
const handleClickOutside = () => {
536+
if (!isMouseDownOnMenu) {
629537
setShowContextMenu(false)
630538
}
631539
}
@@ -708,7 +616,6 @@ export const ChatLexicalTextArea = forwardRef<LexicalEditor, ChatTextAreaProps>(
708616
}}>
709617
{showContextMenu && (
710618
<div
711-
ref={contextMenuContainerRef}
712619
onMouseDown={handleMenuMouseDown}
713620
className={cn(
714621
"absolute",
@@ -837,6 +744,19 @@ export const ChatLexicalTextArea = forwardRef<LexicalEditor, ChatTextAreaProps>(
837744
promptHistory={promptHistory}
838745
showContextMenu={showContextMenu}
839746
/>
747+
<LexicalContextMenuPlugin
748+
showContextMenu={showContextMenu}
749+
searchQuery={searchQuery}
750+
selectedMenuIndex={selectedMenuIndex}
751+
setSelectedMenuIndex={setSelectedMenuIndex}
752+
selectedType={selectedType}
753+
setSelectedType={setSelectedType}
754+
queryItems={queryItems}
755+
fileSearchResults={fileSearchResults}
756+
customModes={customModes}
757+
commands={commands}
758+
onMentionSelect={handleMentionSelect}
759+
/>
840760
<LexicalSelectAllPlugin />
841761
</LexicalComposer>
842762

0 commit comments

Comments
 (0)