mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Refactor to use ContextMenuOptionType and ContextMenuQueryItem
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { forwardRef, useCallback, useEffect, useLayoutEffect, useRef, useState } from "react"
|
import React, { forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"
|
||||||
import DynamicTextArea from "react-textarea-autosize"
|
import DynamicTextArea from "react-textarea-autosize"
|
||||||
import { useExtensionState } from "../context/ExtensionStateContext"
|
import { useExtensionState } from "../context/ExtensionStateContext"
|
||||||
import {
|
import {
|
||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
mentionRegexGlobal,
|
mentionRegexGlobal,
|
||||||
removeMention,
|
removeMention,
|
||||||
shouldShowContextMenu,
|
shouldShowContextMenu,
|
||||||
|
ContextMenuOptionType,
|
||||||
} from "../utils/mention-context"
|
} from "../utils/mention-context"
|
||||||
import { MAX_IMAGES_PER_MESSAGE } from "./ChatView"
|
import { MAX_IMAGES_PER_MESSAGE } from "./ChatView"
|
||||||
import ContextMenu from "./ContextMenu"
|
import ContextMenu from "./ContextMenu"
|
||||||
@@ -42,6 +43,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
|
const { filePaths } = useExtensionState()
|
||||||
const [isTextAreaFocused, setIsTextAreaFocused] = useState(false)
|
const [isTextAreaFocused, setIsTextAreaFocused] = useState(false)
|
||||||
const [thumbnailsHeight, setThumbnailsHeight] = useState(0)
|
const [thumbnailsHeight, setThumbnailsHeight] = useState(0)
|
||||||
const [textAreaBaseHeight, setTextAreaBaseHeight] = useState<number | undefined>(undefined)
|
const [textAreaBaseHeight, setTextAreaBaseHeight] = useState<number | undefined>(undefined)
|
||||||
@@ -52,21 +54,19 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||||||
const [isMouseDownOnMenu, setIsMouseDownOnMenu] = useState(false)
|
const [isMouseDownOnMenu, setIsMouseDownOnMenu] = useState(false)
|
||||||
const highlightLayerRef = useRef<HTMLDivElement>(null)
|
const highlightLayerRef = useRef<HTMLDivElement>(null)
|
||||||
const [selectedMenuIndex, setSelectedMenuIndex] = useState(-1)
|
const [selectedMenuIndex, setSelectedMenuIndex] = useState(-1)
|
||||||
const [selectedType, setSelectedType] = useState<string | null>(null)
|
const [selectedType, setSelectedType] = useState<ContextMenuOptionType | null>(null)
|
||||||
const [justDeletedSpaceAfterMention, setJustDeletedSpaceAfterMention] = useState(false)
|
const [justDeletedSpaceAfterMention, setJustDeletedSpaceAfterMention] = useState(false)
|
||||||
const [intendedCursorPosition, setIntendedCursorPosition] = useState<number | null>(null)
|
const [intendedCursorPosition, setIntendedCursorPosition] = useState<number | null>(null)
|
||||||
const contextMenuContainerRef = useRef<HTMLDivElement>(null)
|
const contextMenuContainerRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
const { filePaths } = useExtensionState()
|
const queryItems = useMemo(() => {
|
||||||
|
|
||||||
const searchPaths = React.useMemo(() => {
|
|
||||||
return [
|
return [
|
||||||
{ type: "problems", path: "problems" },
|
{ type: ContextMenuOptionType.Problems, value: "problems" },
|
||||||
...filePaths
|
...filePaths
|
||||||
.map((file) => "/" + file)
|
.map((file) => "/" + file)
|
||||||
.map((path) => ({
|
.map((path) => ({
|
||||||
type: path.endsWith("/") ? "folder" : "file",
|
type: path.endsWith("/") ? ContextMenuOptionType.Folder : ContextMenuOptionType.File,
|
||||||
path: path,
|
value: path,
|
||||||
})),
|
})),
|
||||||
]
|
]
|
||||||
}, [filePaths])
|
}, [filePaths])
|
||||||
@@ -91,30 +91,29 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||||||
}, [showContextMenu, setShowContextMenu])
|
}, [showContextMenu, setShowContextMenu])
|
||||||
|
|
||||||
const handleMentionSelect = useCallback(
|
const handleMentionSelect = useCallback(
|
||||||
(type: string, value: string) => {
|
(type: ContextMenuOptionType, value?: string) => {
|
||||||
if (type === "noResults") {
|
if (type === ContextMenuOptionType.NoResults) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === "file" || value === "folder") {
|
if (type === ContextMenuOptionType.File || type === ContextMenuOptionType.Folder) {
|
||||||
setSelectedType(type.toLowerCase())
|
if (!value) {
|
||||||
setSearchQuery("")
|
setSelectedType(type)
|
||||||
setSelectedMenuIndex(0)
|
setSearchQuery("")
|
||||||
return
|
setSelectedMenuIndex(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setShowContextMenu(false)
|
setShowContextMenu(false)
|
||||||
setSelectedType(null)
|
setSelectedType(null)
|
||||||
if (textAreaRef.current) {
|
if (textAreaRef.current) {
|
||||||
let insertValue = value
|
let insertValue = value || ""
|
||||||
if (type === "url") {
|
if (type === ContextMenuOptionType.URL) {
|
||||||
// For URLs, we insert the value as is
|
insertValue = value || ""
|
||||||
insertValue = value
|
} else if (type === ContextMenuOptionType.File || type === ContextMenuOptionType.Folder) {
|
||||||
} else if (type === "file" || type === "folder") {
|
insertValue = value || ""
|
||||||
// For files and folders, we insert the path
|
} else if (type === ContextMenuOptionType.Problems) {
|
||||||
insertValue = value
|
|
||||||
} else if (type === "problems") {
|
|
||||||
// For workspace problems, we insert @problems
|
|
||||||
insertValue = "problems"
|
insertValue = "problems"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,10 +121,8 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||||||
setInputValue(newValue)
|
setInputValue(newValue)
|
||||||
const newCursorPosition = newValue.indexOf(" ", newValue.lastIndexOf("@")) + 1
|
const newCursorPosition = newValue.indexOf(" ", newValue.lastIndexOf("@")) + 1
|
||||||
setCursorPosition(newCursorPosition)
|
setCursorPosition(newCursorPosition)
|
||||||
setIntendedCursorPosition(newCursorPosition) // Update intended cursor position
|
setIntendedCursorPosition(newCursorPosition)
|
||||||
textAreaRef.current.focus()
|
textAreaRef.current.focus()
|
||||||
// Remove the direct setSelectionRange call
|
|
||||||
// textAreaRef.current.setSelectionRange(newCursorPosition, newCursorPosition)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[setInputValue, cursorPosition]
|
[setInputValue, cursorPosition]
|
||||||
@@ -145,14 +142,16 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
setSelectedMenuIndex((prevIndex) => {
|
setSelectedMenuIndex((prevIndex) => {
|
||||||
const direction = event.key === "ArrowUp" ? -1 : 1
|
const direction = event.key === "ArrowUp" ? -1 : 1
|
||||||
const options = getContextMenuOptions(searchQuery, selectedType, searchPaths)
|
const options = getContextMenuOptions(searchQuery, selectedType, queryItems)
|
||||||
const optionsLength = options.length
|
const optionsLength = options.length
|
||||||
|
|
||||||
if (optionsLength === 0) return prevIndex
|
if (optionsLength === 0) return prevIndex
|
||||||
|
|
||||||
// Find selectable options (non-URL types)
|
// Find selectable options (non-URL types)
|
||||||
const selectableOptions = options.filter(
|
const selectableOptions = options.filter(
|
||||||
(option) => option.type !== "url" && option.type !== "noResults"
|
(option) =>
|
||||||
|
option.type !== ContextMenuOptionType.URL &&
|
||||||
|
option.type !== ContextMenuOptionType.NoResults
|
||||||
)
|
)
|
||||||
|
|
||||||
if (selectableOptions.length === 0) return -1 // No selectable options
|
if (selectableOptions.length === 0) return -1 // No selectable options
|
||||||
@@ -173,10 +172,14 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||||||
}
|
}
|
||||||
if (event.key === "Enter" && selectedMenuIndex !== -1) {
|
if (event.key === "Enter" && selectedMenuIndex !== -1) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
const selectedOption = getContextMenuOptions(searchQuery, selectedType, searchPaths)[
|
const selectedOption = getContextMenuOptions(searchQuery, selectedType, queryItems)[
|
||||||
selectedMenuIndex
|
selectedMenuIndex
|
||||||
]
|
]
|
||||||
if (selectedOption && selectedOption.type !== "url" && selectedOption.type !== "noResults") {
|
if (
|
||||||
|
selectedOption &&
|
||||||
|
selectedOption.type !== ContextMenuOptionType.URL &&
|
||||||
|
selectedOption.type !== ContextMenuOptionType.NoResults
|
||||||
|
) {
|
||||||
handleMentionSelect(selectedOption.type, selectedOption.value)
|
handleMentionSelect(selectedOption.type, selectedOption.value)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -236,7 +239,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||||||
cursorPosition,
|
cursorPosition,
|
||||||
setInputValue,
|
setInputValue,
|
||||||
justDeletedSpaceAfterMention,
|
justDeletedSpaceAfterMention,
|
||||||
searchPaths,
|
queryItems,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -411,7 +414,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||||||
selectedIndex={selectedMenuIndex}
|
selectedIndex={selectedMenuIndex}
|
||||||
setSelectedIndex={setSelectedMenuIndex}
|
setSelectedIndex={setSelectedMenuIndex}
|
||||||
selectedType={selectedType}
|
selectedType={selectedType}
|
||||||
searchPaths={searchPaths}
|
queryItems={queryItems}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import React, { useEffect, useRef, useState } from "react"
|
import React, { useEffect, useRef, useState } from "react"
|
||||||
import { getContextMenuOptions } from "../utils/mention-context"
|
import { getContextMenuOptions, ContextMenuOptionType, ContextMenuQueryItem } from "../utils/mention-context"
|
||||||
import { formatFilePathForTruncation } from "./CodeAccordian"
|
import { formatFilePathForTruncation } from "./CodeAccordian"
|
||||||
|
|
||||||
interface ContextMenuProps {
|
interface ContextMenuProps {
|
||||||
onSelect: (type: string, value: string) => void
|
onSelect: (type: ContextMenuOptionType, value?: string) => void
|
||||||
searchQuery: string
|
searchQuery: string
|
||||||
onMouseDown: () => void
|
onMouseDown: () => void
|
||||||
selectedIndex: number
|
selectedIndex: number
|
||||||
setSelectedIndex: (index: number) => void
|
setSelectedIndex: (index: number) => void
|
||||||
selectedType: string | null
|
selectedType: ContextMenuOptionType | null
|
||||||
searchPaths: { type: string; path: string }[]
|
queryItems: ContextMenuQueryItem[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const ContextMenu: React.FC<ContextMenuProps> = ({
|
const ContextMenu: React.FC<ContextMenuProps> = ({
|
||||||
@@ -19,16 +19,16 @@ const ContextMenu: React.FC<ContextMenuProps> = ({
|
|||||||
selectedIndex,
|
selectedIndex,
|
||||||
setSelectedIndex,
|
setSelectedIndex,
|
||||||
selectedType,
|
selectedType,
|
||||||
searchPaths,
|
queryItems,
|
||||||
}) => {
|
}) => {
|
||||||
const [filteredOptions, setFilteredOptions] = useState(
|
const [filteredOptions, setFilteredOptions] = useState<ContextMenuQueryItem[]>(
|
||||||
getContextMenuOptions(searchQuery, selectedType, searchPaths)
|
getContextMenuOptions(searchQuery, selectedType, queryItems)
|
||||||
)
|
)
|
||||||
const menuRef = useRef<HTMLDivElement>(null)
|
const menuRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setFilteredOptions(getContextMenuOptions(searchQuery, selectedType, searchPaths))
|
setFilteredOptions(getContextMenuOptions(searchQuery, selectedType, queryItems))
|
||||||
}, [searchQuery, selectedType, searchPaths])
|
}, [searchQuery, selectedType, queryItems])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (menuRef.current) {
|
if (menuRef.current) {
|
||||||
@@ -46,48 +46,57 @@ const ContextMenu: React.FC<ContextMenuProps> = ({
|
|||||||
}
|
}
|
||||||
}, [selectedIndex])
|
}, [selectedIndex])
|
||||||
|
|
||||||
const renderOptionContent = (option: { type: string; value: string }) => {
|
const renderOptionContent = (option: ContextMenuQueryItem) => {
|
||||||
switch (option.value) {
|
switch (option.type) {
|
||||||
case "file":
|
case ContextMenuOptionType.Problems:
|
||||||
case "folder":
|
return <span>Problems</span>
|
||||||
case "problems":
|
case ContextMenuOptionType.URL:
|
||||||
case "url":
|
return <span>Paste URL to scrape</span>
|
||||||
case "noResults":
|
case ContextMenuOptionType.NoResults:
|
||||||
return (
|
return <span>No results found</span>
|
||||||
<span
|
case ContextMenuOptionType.File:
|
||||||
style={{
|
case ContextMenuOptionType.Folder:
|
||||||
whiteSpace: "nowrap",
|
if (option.value) {
|
||||||
overflow: "hidden",
|
return (
|
||||||
textOverflow: "ellipsis",
|
<span
|
||||||
}}>
|
style={{
|
||||||
{option.value === "file"
|
whiteSpace: "nowrap",
|
||||||
? "Add File"
|
overflow: "hidden",
|
||||||
: option.value === "folder"
|
textOverflow: "ellipsis",
|
||||||
? "Add Folder"
|
direction: "rtl",
|
||||||
: option.value === "problems"
|
textAlign: "left",
|
||||||
? "Problems"
|
unicodeBidi: "plaintext",
|
||||||
: option.value === "url"
|
}}>
|
||||||
? "Paste URL to scrape"
|
{formatFilePathForTruncation(option.value || "") + "\u200E"}
|
||||||
: "No results found"}
|
</span>
|
||||||
</span>
|
)
|
||||||
)
|
} else {
|
||||||
default:
|
return <span>Add {option.type === ContextMenuOptionType.File ? "File" : "Folder"}</span>
|
||||||
return (
|
}
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
whiteSpace: "nowrap",
|
|
||||||
overflow: "hidden",
|
|
||||||
textOverflow: "ellipsis",
|
|
||||||
direction: "rtl",
|
|
||||||
textAlign: "left",
|
|
||||||
unicodeBidi: "plaintext",
|
|
||||||
}}>
|
|
||||||
{formatFilePathForTruncation(option.value) + "\u200E"}
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getIconForOption = (option: ContextMenuQueryItem): string => {
|
||||||
|
switch (option.type) {
|
||||||
|
case ContextMenuOptionType.File:
|
||||||
|
return "file"
|
||||||
|
case ContextMenuOptionType.Folder:
|
||||||
|
return "folder"
|
||||||
|
case ContextMenuOptionType.Problems:
|
||||||
|
return "warning"
|
||||||
|
case ContextMenuOptionType.URL:
|
||||||
|
return "link"
|
||||||
|
case ContextMenuOptionType.NoResults:
|
||||||
|
return "info"
|
||||||
|
default:
|
||||||
|
return "file"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isOptionSelectable = (option: ContextMenuQueryItem): boolean => {
|
||||||
|
return option.type !== ContextMenuOptionType.NoResults && option.type !== ContextMenuOptionType.URL
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -113,50 +122,47 @@ const ContextMenu: React.FC<ContextMenuProps> = ({
|
|||||||
}}>
|
}}>
|
||||||
{filteredOptions.map((option, index) => (
|
{filteredOptions.map((option, index) => (
|
||||||
<div
|
<div
|
||||||
key={option.value}
|
key={`${option.type}-${option.value || index}`}
|
||||||
onClick={() =>
|
onClick={() => isOptionSelectable(option) && onSelect(option.type, option.value)}
|
||||||
option.type !== "url" && option.type !== "noResults" && onSelect(option.type, option.value)
|
|
||||||
}
|
|
||||||
style={{
|
style={{
|
||||||
padding: "8px 12px",
|
padding: "8px 12px",
|
||||||
cursor: option.type !== "url" && option.type !== "noResults" ? "pointer" : "default",
|
cursor: isOptionSelectable(option) ? "pointer" : "default",
|
||||||
color: "var(--vscode-dropdown-foreground)",
|
color: "var(--vscode-dropdown-foreground)",
|
||||||
borderBottom: "1px solid var(--vscode-dropdown-border)",
|
borderBottom: "1px solid var(--vscode-dropdown-border)",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
index === selectedIndex && option.type !== "url" && option.type !== "noResults"
|
index === selectedIndex && isOptionSelectable(option)
|
||||||
? "var(--vscode-list-activeSelectionBackground)"
|
? "var(--vscode-list-activeSelectionBackground)"
|
||||||
: "",
|
: "",
|
||||||
}}
|
}}
|
||||||
onMouseEnter={() =>
|
onMouseEnter={() => isOptionSelectable(option) && setSelectedIndex(index)}>
|
||||||
option.type !== "url" && option.type !== "noResults" && setSelectedIndex(index)
|
|
||||||
}>
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
minWidth: 0, // Allows child to shrink below content size
|
minWidth: 0,
|
||||||
overflow: "hidden", // Ensures content doesn't overflow
|
overflow: "hidden",
|
||||||
}}>
|
}}>
|
||||||
<i
|
<i
|
||||||
className={`codicon codicon-${option.icon}`}
|
className={`codicon codicon-${getIconForOption(option)}`}
|
||||||
style={{ marginRight: "8px", flexShrink: 0, fontSize: "14px" }}
|
style={{ marginRight: "8px", flexShrink: 0, fontSize: "14px" }}
|
||||||
/>
|
/>
|
||||||
{renderOptionContent(option)}
|
{renderOptionContent(option)}
|
||||||
</div>
|
</div>
|
||||||
{(option.value === "file" || option.value === "folder") && (
|
{(option.type === ContextMenuOptionType.File || option.type === ContextMenuOptionType.Folder) &&
|
||||||
<i
|
!option.value && (
|
||||||
className="codicon codicon-chevron-right"
|
<i
|
||||||
style={{ fontSize: "14px", flexShrink: 0, marginLeft: 8 }}
|
className="codicon codicon-chevron-right"
|
||||||
/>
|
style={{ fontSize: "14px", flexShrink: 0, marginLeft: 8 }}
|
||||||
)}
|
/>
|
||||||
{(option.type === "problems" ||
|
)}
|
||||||
((option.type === "file" || option.type === "folder") &&
|
{(option.type === ContextMenuOptionType.Problems ||
|
||||||
option.value !== "file" &&
|
((option.type === ContextMenuOptionType.File ||
|
||||||
option.value !== "folder")) && (
|
option.type === ContextMenuOptionType.Folder) &&
|
||||||
|
option.value)) && (
|
||||||
<i
|
<i
|
||||||
className="codicon codicon-add"
|
className="codicon codicon-add"
|
||||||
style={{ fontSize: "14px", flexShrink: 0, marginLeft: 8 }}
|
style={{ fontSize: "14px", flexShrink: 0, marginLeft: 8 }}
|
||||||
|
|||||||
@@ -43,65 +43,61 @@ export function removeMention(text: string, position: number): { newText: string
|
|||||||
return { newText: text, newPosition: position }
|
return { newText: text, newPosition: position }
|
||||||
}
|
}
|
||||||
|
|
||||||
// export function queryPaths(
|
export enum ContextMenuOptionType {
|
||||||
// query: string,
|
File = "file",
|
||||||
// searchPaths: { type: string; path: string }[]
|
Folder = "folder",
|
||||||
// ): { type: string; path: string }[] {
|
Problems = "problems",
|
||||||
// const lowerQuery = query.toLowerCase()
|
URL = "url",
|
||||||
// return searchPaths.filter(
|
NoResults = "noResults",
|
||||||
// (item) => item.path.toLowerCase().includes(lowerQuery) || item.type.toLowerCase().includes(lowerQuery)
|
}
|
||||||
// )
|
|
||||||
// }
|
export interface ContextMenuQueryItem {
|
||||||
|
type: ContextMenuOptionType
|
||||||
|
value?: string
|
||||||
|
}
|
||||||
|
|
||||||
export function getContextMenuOptions(
|
export function getContextMenuOptions(
|
||||||
query: string,
|
query: string,
|
||||||
selectedType: string | null = null,
|
selectedType: ContextMenuOptionType | null = null,
|
||||||
searchPaths: { type: string; path: string }[]
|
queryItems: ContextMenuQueryItem[]
|
||||||
): { type: string; value: string; icon: string }[] {
|
): ContextMenuQueryItem[] {
|
||||||
if (query === "") {
|
if (query === "") {
|
||||||
if (selectedType === "file") {
|
if (selectedType === ContextMenuOptionType.File) {
|
||||||
const files = searchPaths
|
const files = queryItems
|
||||||
.filter((item) => item.type === "file")
|
.filter((item) => item.type === ContextMenuOptionType.File)
|
||||||
.map((item) => ({ type: "file", value: item.path, icon: "file" }))
|
.map((item) => ({ type: ContextMenuOptionType.File, value: item.value }))
|
||||||
return files.length > 0 ? files : [{ type: "noResults", value: "noResults", icon: "info" }]
|
return files.length > 0 ? files : [{ type: ContextMenuOptionType.NoResults }]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedType === "folder") {
|
if (selectedType === ContextMenuOptionType.Folder) {
|
||||||
const folders = searchPaths
|
const folders = queryItems
|
||||||
.filter((item) => item.type === "folder")
|
.filter((item) => item.type === ContextMenuOptionType.Folder)
|
||||||
.map((item) => ({ type: "folder", value: item.path, icon: "folder" }))
|
.map((item) => ({ type: ContextMenuOptionType.Folder, value: item.value }))
|
||||||
return folders.length > 0 ? folders : [{ type: "noResults", value: "noResults", icon: "info" }]
|
return folders.length > 0 ? folders : [{ type: ContextMenuOptionType.NoResults }]
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{ type: "url", value: "url", icon: "link" },
|
{ type: ContextMenuOptionType.URL },
|
||||||
{
|
{ type: ContextMenuOptionType.Problems },
|
||||||
type: "problems",
|
{ type: ContextMenuOptionType.Folder },
|
||||||
value: "problems",
|
{ type: ContextMenuOptionType.File },
|
||||||
icon: "warning",
|
|
||||||
},
|
|
||||||
{ type: "folder", value: "folder", icon: "folder" },
|
|
||||||
{ type: "file", value: "file", icon: "file" },
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const lowerQuery = query.toLowerCase()
|
const lowerQuery = query.toLowerCase()
|
||||||
|
|
||||||
if (query.startsWith("http")) {
|
if (query.startsWith("http")) {
|
||||||
// URLs
|
return [{ type: ContextMenuOptionType.URL, value: query }]
|
||||||
return [{ type: "url", value: query, icon: "link" }]
|
|
||||||
} else {
|
} else {
|
||||||
// Search for files and folders
|
const matchingItems = queryItems.filter((item) => item.value?.toLowerCase().includes(lowerQuery))
|
||||||
const matchingPaths = searchPaths.filter((item) => item.path.toLowerCase().includes(lowerQuery))
|
|
||||||
|
|
||||||
if (matchingPaths.length > 0) {
|
if (matchingItems.length > 0) {
|
||||||
return matchingPaths.map((item) => ({
|
return matchingItems.map((item) => ({
|
||||||
type: item.type,
|
type: item.type,
|
||||||
value: item.path,
|
value: item.value,
|
||||||
icon: item.type === "file" ? "file" : item.type === "problems" ? "warning" : "folder",
|
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
return [{ type: "noResults", value: "noResults", icon: "info" }]
|
return [{ type: ContextMenuOptionType.NoResults }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user