diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index be1fba0..ce4353d 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -22,7 +22,7 @@ tauri-plugin-updater = "2.3.0" tauri-plugin-dialog = "2.2.0" tauri-plugin-fs = "2.2.0" tauri-plugin-clipboard = "2.1.11" -tauri-plugin-prevent-default = "1.0.0" +tauri-plugin-prevent-default = "1.0.1" tauri-plugin-global-shortcut = "2.2.0" sqlx = { version = "0.8.2", features = ["runtime-tokio-native-tls", "sqlite", "chrono"] } serde = { version = "1.0.216", features = ["derive"] } @@ -43,6 +43,8 @@ chrono = { version = "0.4.39", features = ["serde"] } uuid = "1.11.0" active-win-pos-rs = "0.8.3" include_dir = "0.7.4" +hyperpolyglot = { git = "https://github.com/0pandadev/hyperpolyglot" } +applications = { git = "https://github.com/HuakunShen/applications-rs", branch = "dev" } [features] custom-protocol = ["tauri/custom-protocol"] diff --git a/src-tauri/src/api/clipboard.rs b/src-tauri/src/api/clipboard.rs index 28debc3..927b70e 100644 --- a/src-tauri/src/api/clipboard.rs +++ b/src-tauri/src/api/clipboard.rs @@ -1,20 +1,21 @@ +use base64::{engine::general_purpose::STANDARD, Engine}; +use hyperpolyglot; use lazy_static::lazy_static; use rdev::{simulate, EventType, Key}; +use regex::Regex; use sqlx::SqlitePool; -use uuid::Uuid; use std::fs; use std::sync::atomic::{AtomicBool, Ordering}; use std::{thread, time::Duration}; use tauri::{AppHandle, Emitter, Listener, Manager, Runtime}; use tauri_plugin_clipboard::Clipboard; use tokio::runtime::Runtime as TokioRuntime; -use regex::Regex; use url::Url; -use base64::{Engine, engine::general_purpose::STANDARD}; +use uuid::Uuid; +use crate::db; use crate::utils::commands::get_app_info; use crate::utils::favicon::fetch_favicon_as_base64; -use crate::db; use crate::utils::types::{ContentType, HistoryItem}; lazy_static! { @@ -111,43 +112,64 @@ pub fn setup(app: &AppHandle) { .unwrap_or_else(|e| e); let _ = db::history::add_history_item( pool, - HistoryItem::new(app_name, ContentType::Image, file_path, None, app_icon), + HistoryItem::new(app_name, ContentType::Image, file_path, None, app_icon, None), ).await; } } else if available_types.files { println!("Handling files change"); if let Ok(files) = clipboard.read_files() { - let files_str = files.join(", "); - let _ = db::history::add_history_item( - pool, - HistoryItem::new(app_name, ContentType::File, files_str, None, app_icon), - ).await; + for file in files { + let _ = db::history::add_history_item( + pool.clone(), + HistoryItem::new( + app_name.clone(), + ContentType::File, + file, + None, + app_icon.clone(), + None + ), + ).await; + } } } else if available_types.text { println!("Handling text change"); if let Ok(text) = clipboard.read_text() { let url_regex = Regex::new(r"^https?://(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&//=]*)$").unwrap(); - + if url_regex.is_match(&text) { if let Ok(url) = Url::parse(&text) { let favicon = match fetch_favicon_as_base64(url).await { Ok(Some(f)) => Some(f), _ => None, }; - + let _ = db::history::add_history_item( pool, - HistoryItem::new(app_name, ContentType::Link, text, favicon, app_icon) + HistoryItem::new(app_name, ContentType::Link, text, favicon, app_icon, None) ).await; } } else { if text.is_empty() { return; } - let _ = db::history::add_history_item( - pool, - HistoryItem::new(app_name, ContentType::Text, text, None, app_icon) - ).await; + + if let Some(detection) = hyperpolyglot::detect_from_text(&text) { + let language = match detection { + hyperpolyglot::Detection::Heuristics(lang) => lang.to_string(), + _ => detection.language().to_string(), + }; + + let _ = db::history::add_history_item( + pool, + HistoryItem::new(app_name, ContentType::Code, text, None, app_icon, Some(language)) + ).await; + } else { + let _ = db::history::add_history_item( + pool, + HistoryItem::new(app_name, ContentType::Text, text, None, app_icon, None) + ).await; + } } } } else { @@ -183,16 +205,19 @@ pub fn start_monitor(app_handle: AppHandle) -> Result<(), String> { Ok(()) } -async fn save_image_to_file(app_handle: &AppHandle, base64_data: &str) -> Result> { +async fn save_image_to_file( + app_handle: &AppHandle, + base64_data: &str, +) -> Result> { let app_data_dir = app_handle.path().app_data_dir().unwrap(); let images_dir = app_data_dir.join("images"); fs::create_dir_all(&images_dir)?; - + let file_name = format!("{}.png", Uuid::new_v4()); let file_path = images_dir.join(&file_name); - + let bytes = STANDARD.decode(base64_data)?; fs::write(&file_path, bytes)?; - + Ok(file_path.to_string_lossy().into_owned()) -} \ No newline at end of file +}