feat(screenshot): implement area screenshot functionality and integrate with shortcut management
This commit is contained in:
5
frontend/src-tauri/Cargo.lock
generated
5
frontend/src-tauri/Cargo.lock
generated
@ -1,12 +1,13 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "Haystack"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"chrono",
|
||||
"cocoa",
|
||||
"notify",
|
||||
"serde",
|
||||
@ -536,8 +537,10 @@ checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
|
@ -28,6 +28,7 @@ base64 = "0.21.7"
|
||||
tokio = { version = "1.36.0", features = ["full"] }
|
||||
tauri-plugin-store = "2.0.0-beta.12"
|
||||
tauri-plugin-http = "2.0.0-beta.12"
|
||||
chrono = "0.4"
|
||||
|
||||
[target."cfg(target_os = \"macos\")".dependencies]
|
||||
cocoa = "0.26"
|
||||
|
@ -1,7 +1,8 @@
|
||||
mod commands;
|
||||
mod shortcut;
|
||||
pub mod screenshot;
|
||||
pub mod shortcut;
|
||||
mod state;
|
||||
mod utils;
|
||||
pub mod utils;
|
||||
mod window;
|
||||
|
||||
use state::new_shared_watcher_state;
|
||||
|
53
frontend/src-tauri/src/screenshot.rs
Normal file
53
frontend/src-tauri/src/screenshot.rs
Normal file
@ -0,0 +1,53 @@
|
||||
use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
use tauri::{AppHandle, Runtime};
|
||||
|
||||
/// Takes a screenshot of a selected area and returns the image data as base64
|
||||
pub fn take_area_screenshot<R: Runtime>(app: &AppHandle<R>) -> Result<String, String> {
|
||||
// Create a temporary file path
|
||||
let temp_dir = std::env::temp_dir();
|
||||
let timestamp = chrono::Local::now().format("%Y%m%d_%H%M%S");
|
||||
let temp_file = temp_dir.join(format!("haystack_screenshot_{}.png", timestamp));
|
||||
|
||||
// Use screencapture command with -i flag for interactive selection
|
||||
let output = Command::new("screencapture")
|
||||
.arg("-i") // interactive selection
|
||||
.arg("-x") // don't play sound
|
||||
.arg("-o") // don't show cursor
|
||||
.arg("-r") // don't add shadow
|
||||
.arg(temp_file.to_str().unwrap())
|
||||
.output()
|
||||
.map_err(|e| format!("Failed to execute screencapture: {}", e))?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(format!(
|
||||
"screencapture failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
));
|
||||
}
|
||||
|
||||
// Read the captured image
|
||||
let contents =
|
||||
fs::read(&temp_file).map_err(|e| format!("Failed to read screenshot file: {}", e))?;
|
||||
|
||||
// Convert to base64
|
||||
let base64_string = BASE64.encode(&contents);
|
||||
|
||||
// Clean up the temporary file
|
||||
if let Err(e) = fs::remove_file(&temp_file) {
|
||||
println!("Warning: Failed to remove temporary screenshot file: {}", e);
|
||||
}
|
||||
|
||||
// Log the base64 string (truncated for readability)
|
||||
if base64_string.len() > 100 {
|
||||
println!(
|
||||
"Screenshot base64 (truncated): {}...",
|
||||
&base64_string[..100]
|
||||
);
|
||||
} else {
|
||||
println!("Screenshot base64: {}", base64_string);
|
||||
}
|
||||
|
||||
Ok(base64_string)
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
use crate::screenshot::take_area_screenshot;
|
||||
use tauri::App;
|
||||
use tauri::AppHandle;
|
||||
use tauri::Emitter;
|
||||
@ -200,6 +201,9 @@ fn register_shortcut_upon_start(
|
||||
// TODO: Implement screenshot functionality
|
||||
println!("Screenshot shortcut pressed");
|
||||
}
|
||||
if let Err(e) = take_area_screenshot(app) {
|
||||
println!("Failed to take screenshot: {}", e);
|
||||
}
|
||||
}
|
||||
})
|
||||
.build(),
|
||||
@ -268,11 +272,12 @@ pub fn change_screenshot_shortcut<R: Runtime>(
|
||||
|
||||
fn register_screenshot_shortcut<R: Runtime>(app: &AppHandle<R>, shortcut: Shortcut) {
|
||||
app.global_shortcut()
|
||||
.on_shortcut(shortcut, move |_app, scut, event| {
|
||||
.on_shortcut(shortcut, move |app, scut, event| {
|
||||
if scut == &shortcut {
|
||||
if let ShortcutState::Pressed = event.state() {
|
||||
// TODO: Implement screenshot functionality
|
||||
println!("Screenshot shortcut pressed");
|
||||
if let Err(e) = take_area_screenshot(app) {
|
||||
println!("Failed to take screenshot: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
Reference in New Issue
Block a user