Sfoglia il codice sorgente

Add problems option to context menu

Saoud Rizwan 1 anno fa
parent
commit
7e91e7aecb

+ 18 - 3
webview-ui/src/components/ChatTextArea.tsx

@@ -87,6 +87,9 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
 					} else if (type === "file" || type === "folder") {
 						// For files and folders, we insert the path
 						insertValue = value
+					} else if (type === "problems") {
+						// For workspace problems, we insert @problems
+						insertValue = "problems"
 					}
 
 					const newValue = insertMention(textAreaRef.current.value, cursorPosition, insertValue)
@@ -105,6 +108,12 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
 		const handleKeyDown = useCallback(
 			(event: React.KeyboardEvent<HTMLTextAreaElement>) => {
 				if (showContextMenu) {
+					if (event.key === "Escape") {
+						// event.preventDefault()
+						setShowContextMenu(false)
+						return
+					}
+
 					if (event.key === "ArrowUp" || event.key === "ArrowDown") {
 						event.preventDefault()
 						setSelectedMenuIndex((prevIndex) => {
@@ -159,7 +168,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
 						charAfterCursor === " " || charAfterCursor === "\n" || charAfterCursor === "\r\n"
 					if (
 						charBeforeIsWhitespace &&
-						inputValue.slice(0, cursorPosition - 1).match(/@(\/|\w+:\/\/)[^\s]+$/)
+						inputValue.slice(0, cursorPosition - 1).match(/@((?:\/|\w+:\/\/)[^\s]+|problems)$/)
 					) {
 						const newCursorPosition = cursorPosition - 1
 						if (!charAfterIsWhitespace) {
@@ -220,7 +229,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
 					if (query.length > 0) {
 						setSelectedMenuIndex(0)
 					} else {
-						setSelectedMenuIndex(2) // Set to "File" option by default
+						setSelectedMenuIndex(3) // Set to "File" option by default
 					}
 				} else {
 					setSearchQuery("")
@@ -230,6 +239,12 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
 			[setInputValue]
 		)
 
+		useEffect(() => {
+			if (!showContextMenu) {
+				setSelectedType(null)
+			}
+		}, [showContextMenu])
+
 		const handleBlur = useCallback(() => {
 			// Only hide the context menu if the user didn't click on it
 			if (!isMouseDownOnMenu) {
@@ -299,7 +314,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
 			if (!textAreaRef.current || !highlightLayerRef.current) return
 
 			const text = textAreaRef.current.value
-			const mentionRegex = /@(\/|\w+:\/\/)[^\s]+/g
+			const mentionRegex = /@((?:\/|\w+:\/\/)[^\s]+|problems\b)/g
 
 			highlightLayerRef.current.innerHTML = text
 				.replace(/\n$/, "\n\n")

+ 8 - 5
webview-ui/src/components/ContextMenu.tsx

@@ -88,6 +88,8 @@ const ContextMenu: React.FC<ContextMenuProps> = ({
 								? "Add file"
 								: option.value === "Folder"
 								? "Add folder"
+								: option.value === "Problems"
+								? "Workspace Problems"
 								: option.value === "URL"
 								? "Paste URL to scrape"
 								: option.value}
@@ -95,11 +97,12 @@ const ContextMenu: React.FC<ContextMenuProps> = ({
 						{(option.value === "File" || option.value === "Folder") && (
 							<i className="codicon codicon-chevron-right" style={{ fontSize: "14px" }} />
 						)}
-						{(option.type === "file" || option.type === "folder") &&
-							option.value !== "File" &&
-							option.value !== "Folder" && (
-								<i className="codicon codicon-add" style={{ fontSize: "14px" }} />
-							)}
+						{(option.type === "problems" ||
+							((option.type === "file" || option.type === "folder") &&
+								option.value !== "File" &&
+								option.value !== "Folder")) && (
+							<i className="codicon codicon-add" style={{ fontSize: "14px" }} />
+						)}
 					</div>
 				))}
 			</div>

+ 16 - 2
webview-ui/src/utils/mention-context.ts

@@ -1,4 +1,5 @@
 export const mockPaths = [
+	{ type: "problems", path: "Problems" },
 	{ type: "file", path: "/src/components/Header.tsx" },
 	{ type: "file", path: "/src/components/Footer.tsx" },
 	{ type: "file", path: "/src/utils/helpers.ts" },
@@ -29,7 +30,7 @@ export function insertMention(text: string, position: number, value: string): st
 }
 
 export function removeMention(text: string, position: number): { newText: string; newPosition: number } {
-	const mentionRegex = /@(\/|\w+:\/\/)[^\s]+/
+	const mentionRegex = /@((?:\/|\w+:\/\/)[^\s]+|problems\b)/
 	const beforeCursor = text.slice(0, position)
 	const afterCursor = text.slice(position)
 
@@ -73,6 +74,11 @@ export function getContextMenuOptions(
 	if (query === "") {
 		return [
 			{ type: "url", value: "URL", icon: "link" },
+			{
+				type: "problems",
+				value: "Problems",
+				icon: "warning",
+			},
 			{ type: "folder", value: "Folder", icon: "folder" },
 			{ type: "file", value: "File", icon: "file" },
 		]
@@ -93,12 +99,17 @@ export function getContextMenuOptions(
 			return matchingPaths.map((item) => ({
 				type: item.type,
 				value: item.path,
-				icon: item.type === "file" ? "file" : "folder",
+				icon: item.type === "file" ? "file" : item.type === "problems" ? "warning" : "folder",
 			}))
 		} else {
 			// If no matches, show all options
 			return [
 				{ type: "url", value: "URL", icon: "link" },
+				{
+					type: "problems",
+					value: "Problems",
+					icon: "warning",
+				},
 				{ type: "folder", value: "Folder", icon: "folder" },
 				{ type: "file", value: "File", icon: "file" },
 			]
@@ -120,6 +131,9 @@ export function shouldShowContextMenu(text: string, position: number): boolean {
 	// Don't show the menu if it's a URL
 	if (textAfterAt.toLowerCase().startsWith("http")) return false
 
+	// Don't show the menu if it's a problems
+	if (textAfterAt.toLowerCase().startsWith("problems")) return false
+
 	// Show the menu if there's just '@' or '@' followed by some text (but not a URL)
 	return true
 }