File drag and drop

This commit is contained in:
Matt Rubens 2025-02-25 02:40:37 -05:00
parent 82b282ba01
commit 77a6e2be6d
5 changed files with 27 additions and 6 deletions

View file

@ -2386,6 +2386,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
const allowedCommands = vscode.workspace.getConfiguration("roo-cline").get<string[]>("allowedCommands") || []
const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) || ""
return {
version: this.context.extension?.packageJSON?.version ?? "",
apiConfiguration,
@ -2432,6 +2434,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
experiments: experiments ?? experimentDefault,
mcpServers: this.mcpHub?.getAllServers() ?? [],
maxOpenTabsContext: maxOpenTabsContext ?? 20,
cwd: cwd,
}
}

View file

@ -129,6 +129,7 @@ export interface ExtensionState {
customModes: ModeConfig[]
toolRequirements?: Record<string, boolean> // Map of tool names to their requirements (e.g. {"apply_diff": true} if diffEnabled)
maxOpenTabsContext: number // Maximum number of VSCode open tabs to include in context (0-500)
cwd?: string // Current working directory
}
export interface ClineMessage {

View file

@ -50,7 +50,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
},
ref,
) => {
const { filePaths, openedTabs, currentApiConfigName, listApiConfigMeta, customModes } = useExtensionState()
const { filePaths, openedTabs, currentApiConfigName, listApiConfigMeta, customModes, cwd } = useExtensionState()
const [gitCommits, setGitCommits] = useState<any[]>([])
const [showDropdown, setShowDropdown] = useState(false)
@ -589,18 +589,35 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
const files = Array.from(e.dataTransfer.files)
const text = e.dataTransfer.getData("text")
if (text) {
const newValue = inputValue.slice(0, cursorPosition) + text + inputValue.slice(cursorPosition)
let mentionText = text
const normalizedText = text.replace(/\\/g, "/")
const normalizedCwd = cwd ? cwd.replace(/\\/g, "/") : ""
// Always use case-insensitive comparison for path matching
if (normalizedCwd) {
const lowerText = normalizedText.toLowerCase()
const lowerCwd = normalizedCwd.toLowerCase()
if (lowerText.startsWith(lowerCwd)) {
mentionText = "@" + normalizedText.substring(normalizedCwd.length)
}
}
const newValue =
inputValue.slice(0, cursorPosition) + mentionText + " " + inputValue.slice(cursorPosition)
setInputValue(newValue)
const newCursorPosition = cursorPosition + text.length
const newCursorPosition = cursorPosition + mentionText.length + 1
setCursorPosition(newCursorPosition)
setIntendedCursorPosition(newCursorPosition)
return
}
const acceptedTypes = ["png", "jpeg", "webp"]
const imageFiles = files.filter((file) => {
const [type, subtype] = file.type.split("/")
return type === "image" && acceptedTypes.includes(subtype)
})
if (!shouldDisableImages && imageFiles.length > 0) {
const imagePromises = imageFiles.map((file) => {
return new Promise<string | null>((resolve) => {

View file

@ -880,9 +880,8 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
const placeholderText = useMemo(() => {
const baseText = task ? "Type a message..." : "Type your task here..."
const contextText = "(@ to add context, / to switch modes"
const imageText = shouldDisableImages ? "" : ", hold shift to drag in images"
const helpText = imageText ? `\n${contextText}${imageText})` : `\n${contextText})`
return baseText + helpText
const imageText = shouldDisableImages ? "hold shift to drag in files" : ", hold shift to drag in files/images"
return baseText + `\n${contextText}${imageText})`
}, [task, shouldDisableImages])
const itemContent = useCallback(

View file

@ -118,6 +118,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
autoApprovalEnabled: false,
customModes: [],
maxOpenTabsContext: 20,
cwd: "",
})
const [didHydrateState, setDidHydrateState] = useState(false)