Allow copy paste images and screenshots

This commit is contained in:
andrepimenta
2025-07-07 23:23:27 +01:00
parent bb20bb29c5
commit 0bdb0ce30a
2 changed files with 108 additions and 0 deletions

View File

@@ -234,6 +234,9 @@ class ClaudeChatProvider {
case 'openFile': case 'openFile':
this._openFileInEditor(message.filePath); this._openFileInEditor(message.filePath);
return; return;
case 'createImageFile':
this._createImageFile(message.imageData, message.imageType);
return;
} }
}, },
null, null,
@@ -1406,6 +1409,44 @@ class ClaudeChatProvider {
} }
} }
private async _createImageFile(imageData: string, imageType: string) {
try {
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
if (!workspaceFolder) {return;}
// Extract base64 data from data URL
const base64Data = imageData.split(',')[1];
const buffer = Buffer.from(base64Data, 'base64');
// Get file extension from image type
const extension = imageType.split('/')[1] || 'png';
// Create unique filename with timestamp
const timestamp = Date.now();
const imageFileName = `image_${timestamp}.${extension}`;
// Create images folder in workspace .vscode directory
const imagesDir = vscode.Uri.joinPath(workspaceFolder.uri, '.vscode', 'claude-code-chat-images');
await vscode.workspace.fs.createDirectory(imagesDir);
// Create the image file
const imagePath = vscode.Uri.joinPath(imagesDir, imageFileName);
await vscode.workspace.fs.writeFile(imagePath, buffer);
// Send the file path back to webview
this._panel?.webview.postMessage({
type: 'imagePath',
data: {
filePath: imagePath.fsPath
}
});
} catch (error) {
console.error('Error creating image file:', error);
vscode.window.showErrorMessage('Failed to create image file');
}
}
public dispose() { public dispose() {
if (this._panel) { if (this._panel) {
this._panel.dispose(); this._panel.dispose();

View File

@@ -1299,6 +1299,44 @@ const html = `<!DOCTYPE html>
try { try {
// Try to get clipboard data from the event first // Try to get clipboard data from the event first
const clipboardData = e.clipboardData; const clipboardData = e.clipboardData;
// Check for images first
if (clipboardData && clipboardData.items) {
let hasImage = false;
for (let i = 0; i < clipboardData.items.length; i++) {
const item = clipboardData.items[i];
if (item.type.startsWith('image/')) {
// Found an image, handle it
console.log('Image detected in clipboard:', item.type);
hasImage = true;
const blob = item.getAsFile();
if (blob) {
console.log('Converting image blob to base64...');
// Convert blob to base64
const reader = new FileReader();
reader.onload = function(event) {
const base64Data = event.target.result;
console.log('Sending image to extension for file creation');
// Send to extension to create file
vscode.postMessage({
type: 'createImageFile',
imageData: base64Data,
imageType: item.type
});
};
reader.readAsDataURL(blob);
}
break; // Process only the first image found
}
}
// If we found an image, don't process any text
if (hasImage) {
return;
}
}
// No image found, handle text
let text = ''; let text = '';
if (clipboardData) { if (clipboardData) {
@@ -1771,6 +1809,35 @@ const html = `<!DOCTYPE html>
} }
break; break;
case 'imagePath':
// Handle image file path response
if (message.data.filePath) {
// Get current cursor position and content
const cursorPosition = messageInput.selectionStart || messageInput.value.length;
const currentValue = messageInput.value || '';
// Insert the file path at the current cursor position
const textBefore = currentValue.substring(0, cursorPosition);
const textAfter = currentValue.substring(cursorPosition);
// Add a space before the path if there's text before and it doesn't end with whitespace
const separator = (textBefore && !textBefore.endsWith(' ') && !textBefore.endsWith('\\n')) ? ' ' : '';
messageInput.value = textBefore + separator + message.data.filePath + textAfter;
// Move cursor to end of inserted path
const newCursorPosition = cursorPosition + separator.length + message.data.filePath.length;
messageInput.setSelectionRange(newCursorPosition, newCursorPosition);
// Focus back on textarea and adjust height
messageInput.focus();
adjustTextareaHeight();
console.log('Inserted image path:', message.data.filePath);
console.log('Full textarea value:', messageInput.value);
}
break;
case 'updateTokens': case 'updateTokens':
console.log('Tokens updated in real-time:', message.data); console.log('Tokens updated in real-time:', message.data);
// Update token totals in real-time // Update token totals in real-time