refactor: Store pasted images in memory as base64 data URLs
- Remove save_clipboard_image and cleanup_temp_images backend commands - Update FloatingPromptInput to store pasted images as data URLs in the prompt - Update ImagePreview component to handle both file paths and data URLs - Update extractImagePaths to properly handle quoted data URLs - Update handleRemoveImage to handle data URL removal This eliminates file system operations for pasted images and stores them directly in the prompt as base64 data URLs (e.g., @"data:image/png;base64,..."). Images are now fully self-contained within the session without creating temp files.
This commit is contained in:
@@ -922,104 +922,7 @@ pub async fn load_session_history(
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
/// Saves a clipboard image to a temporary location for a session
|
||||
///
|
||||
/// This command handles pasted images by saving them to a temp directory
|
||||
/// within the project structure, making them accessible for Claude.
|
||||
#[tauri::command]
|
||||
pub async fn save_clipboard_image(
|
||||
project_path: String,
|
||||
session_id: String,
|
||||
image_data: String, // Base64 encoded image data
|
||||
mime_type: String,
|
||||
) -> Result<String, String> {
|
||||
log::info!(
|
||||
"Saving clipboard image for session: {} in project: {}",
|
||||
session_id,
|
||||
project_path
|
||||
);
|
||||
|
||||
// Parse the base64 data (remove data URL prefix if present)
|
||||
let base64_data = if image_data.starts_with("data:") {
|
||||
image_data
|
||||
.split(',')
|
||||
.nth(1)
|
||||
.ok_or("Invalid data URL format")?
|
||||
} else {
|
||||
&image_data
|
||||
};
|
||||
|
||||
// Decode base64 to bytes
|
||||
use base64::Engine;
|
||||
let image_bytes = base64::engine::general_purpose::STANDARD
|
||||
.decode(base64_data)
|
||||
.map_err(|e| format!("Failed to decode base64 image: {}", e))?;
|
||||
|
||||
// Determine file extension from MIME type
|
||||
let extension = match mime_type.as_str() {
|
||||
"image/png" => "png",
|
||||
"image/jpeg" | "image/jpg" => "jpg",
|
||||
"image/gif" => "gif",
|
||||
"image/webp" => "webp",
|
||||
"image/svg+xml" => "svg",
|
||||
_ => "png", // Default to PNG
|
||||
};
|
||||
|
||||
// Create temp directory for the project if it doesn't exist
|
||||
let project_path_buf = PathBuf::from(&project_path);
|
||||
let temp_dir = project_path_buf.join(".claude_temp").join(&session_id);
|
||||
fs::create_dir_all(&temp_dir)
|
||||
.map_err(|e| format!("Failed to create temp directory: {}", e))?;
|
||||
|
||||
// Generate unique filename with timestamp
|
||||
let timestamp = SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_millis();
|
||||
let filename = format!("pasted_image_{}.{}", timestamp, extension);
|
||||
let file_path = temp_dir.join(&filename);
|
||||
|
||||
// Write image to file
|
||||
fs::write(&file_path, image_bytes)
|
||||
.map_err(|e| format!("Failed to write image file: {}", e))?;
|
||||
|
||||
// Return the absolute path
|
||||
let absolute_path = file_path
|
||||
.canonicalize()
|
||||
.map_err(|e| format!("Failed to get absolute path: {}", e))?
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
|
||||
log::info!("Saved clipboard image to: {}", absolute_path);
|
||||
Ok(absolute_path)
|
||||
}
|
||||
|
||||
/// Cleans up temporary images for a session
|
||||
///
|
||||
/// This command removes the temporary directory created for pasted images
|
||||
/// when a session ends to avoid accumulating temporary files.
|
||||
#[tauri::command]
|
||||
pub async fn cleanup_temp_images(
|
||||
project_path: String,
|
||||
session_id: String,
|
||||
) -> Result<(), String> {
|
||||
log::info!(
|
||||
"Cleaning up temp images for session: {} in project: {}",
|
||||
session_id,
|
||||
project_path
|
||||
);
|
||||
|
||||
let project_path_buf = PathBuf::from(&project_path);
|
||||
let temp_dir = project_path_buf.join(".claude_temp").join(&session_id);
|
||||
|
||||
if temp_dir.exists() {
|
||||
fs::remove_dir_all(&temp_dir)
|
||||
.map_err(|e| format!("Failed to remove temp directory: {}", e))?;
|
||||
log::info!("Cleaned up temp directory: {}", temp_dir.display());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Execute a new interactive Claude Code session with streaming output
|
||||
#[tauri::command]
|
||||
|
Reference in New Issue
Block a user