mirror of
https://github.com/andrepimenta/claude-code-chat.git
synced 2025-12-13 13:49:47 +00:00
Allow copy paste images and screenshots
This commit is contained in:
@@ -234,6 +234,9 @@ class ClaudeChatProvider {
|
||||
case 'openFile':
|
||||
this._openFileInEditor(message.filePath);
|
||||
return;
|
||||
case 'createImageFile':
|
||||
this._createImageFile(message.imageData, message.imageType);
|
||||
return;
|
||||
}
|
||||
},
|
||||
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() {
|
||||
if (this._panel) {
|
||||
this._panel.dispose();
|
||||
|
||||
67
src/ui.ts
67
src/ui.ts
@@ -1299,6 +1299,44 @@ const html = `<!DOCTYPE html>
|
||||
try {
|
||||
// Try to get clipboard data from the event first
|
||||
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 = '';
|
||||
|
||||
if (clipboardData) {
|
||||
@@ -1771,6 +1809,35 @@ const html = `<!DOCTYPE html>
|
||||
}
|
||||
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':
|
||||
console.log('Tokens updated in real-time:', message.data);
|
||||
// Update token totals in real-time
|
||||
|
||||
Reference in New Issue
Block a user