diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index c4608d7..113fe8e 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -42,6 +42,7 @@ checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" name = "app" version = "0.1.0" dependencies = [ + "dirs", "home", "image", "serde", @@ -50,7 +51,7 @@ dependencies = [ "tauri-build", "tauri-utils", "webbrowser", - "wry", + "wry 0.24.1", ] [[package]] @@ -2535,6 +2536,63 @@ dependencies = [ "x11-dl", ] +[[package]] +name = "tao" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704522803dda895767f69198af8351b0a3f4fe2e293c3ca54cce0ecba05a97f2" +dependencies = [ + "bitflags", + "cairo-rs", + "cc", + "cocoa", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dispatch", + "gdk", + "gdk-pixbuf", + "gdk-sys", + "gdkx11-sys", + "gio", + "glib", + "glib-sys", + "gtk", + "image", + "instant", + "jni", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "once_cell", + "parking_lot", + "png", + "raw-window-handle", + "scopeguard", + "serde", + "tao-macros", + "unicode-segmentation", + "uuid 1.2.2", + "windows 0.39.0", + "windows-implement", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b6fcd8245d45a39ffc8715183d92ae242750eb57b285eb3bcd63dfd512afd09" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tar" version = "0.4.38" @@ -2683,7 +2741,7 @@ dependencies = [ "webkit2gtk", "webview2-com", "windows 0.39.0", - "wry", + "wry 0.23.4", ] [[package]] @@ -3438,7 +3496,45 @@ dependencies = [ "serde_json", "sha2", "soup2", - "tao", + "tao 0.15.8", + "thiserror", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows 0.39.0", + "windows-implement", +] + +[[package]] +name = "wry" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c846dc4dda988e959869dd0802cd27417c9696e584593e49178aeee28890d25" +dependencies = [ + "base64", + "block", + "cocoa", + "core-graphics", + "crossbeam-channel", + "dunce", + "gdk", + "gio", + "glib", + "gtk", + "html5ever", + "http", + "kuchiki", + "libc", + "log", + "objc", + "objc_id", + "once_cell", + "serde", + "serde_json", + "sha2", + "soup2", + "tao 0.16.0", "thiserror", "url", "webkit2gtk", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index fb38ca5..838725c 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -22,7 +22,8 @@ image = "0.24.5" home = "0.5" tauri-utils = "1.2.1" webbrowser = "0.8.2" -wry = "0.23.4" +wry = "0.24.1" +dirs = "4.0" [features] # by default Tauri runs in production mode diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 24034ef..76ee15c 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,6 +1,8 @@ // at the top of main.rs - that will prevent the console from showing #![windows_subsystem = "windows"] extern crate image; +use dirs::download_dir; +use std::path::PathBuf; use tauri_utils::config::{Config, WindowConfig}; use wry::{ application::{ @@ -12,9 +14,10 @@ use wry::{ webview::WebViewBuilder, }; -// enum UserEvent { -// NewWindow(String), -// } +enum UserEvent { + DownloadStarted(String, String), + DownloadComplete(Option, bool), +} #[cfg(target_os = "macos")] use wry::application::{ @@ -87,9 +90,8 @@ fn main() -> wry::Result<()> { .. } = get_windows_config().1.unwrap_or_default(); - // let event_loop: EventLoop = EventLoop::with_user_event(); - // let proxy = event_loop.create_proxy(); - let event_loop = EventLoop::new(); + let event_loop: EventLoop = EventLoop::with_user_event(); + let proxy = event_loop.create_proxy(); let common_window = WindowBuilder::new() .with_title("") .with_resizable(resizable) @@ -103,7 +105,7 @@ fn main() -> wry::Result<()> { #[cfg(target_os = "windows")] let window = { let mut icon_path = format!("png/{}_32.ico", package_name); - // 假如没有设置,就使用默认的即可 + // If there is no setting, use the default one. if !std::path::Path::new(&icon_path).exists() { icon_path = "png/icon_32.ico".to_string(); } @@ -128,6 +130,7 @@ fn main() -> wry::Result<()> { .build(&event_loop) .unwrap(); + // Handling events of JS -> Rust let handler = move |window: &Window, req: String| { if req == "drag_window" { let _ = window.drag_window(); @@ -140,7 +143,31 @@ fn main() -> wry::Result<()> { } }; - // 用于欺骗部分页面对于浏览器的强检测 + let download_started = { + let proxy = proxy.clone(); + move |uri: String, default_path: &mut PathBuf| { + let path = download_dir() + .unwrap() + .join(default_path.display().to_string()) + .as_path() + .to_path_buf(); + *default_path = path.clone(); + let submitted = proxy + .send_event(UserEvent::DownloadStarted( + uri.clone(), + path.display().to_string(), + )) + .is_ok(); + return submitted; + } + }; + + let download_completed = { + let proxy = proxy.clone(); + move |_uri, path, success| { + let _ = proxy.send_event(UserEvent::DownloadComplete(path, success)); + } + }; #[cfg(target_os = "macos")] let webview = { @@ -151,11 +178,9 @@ fn main() -> wry::Result<()> { .with_devtools(cfg!(feature = "devtools")) .with_initialization_script(include_str!("pake.js")) .with_ipc_handler(handler) - // .with_new_window_req_handler(move |uri: String| { - // let submitted = proxy.send_event(UserEvent::NewWindow(uri.clone())).is_ok(); - // submitted - // }) .with_back_forward_navigation_gestures(true) + .with_download_started_handler(download_started) + .with_download_completed_handler(download_completed) .build()? }; @@ -185,10 +210,8 @@ fn main() -> wry::Result<()> { .with_initialization_script(include_str!("pake.js")) .with_ipc_handler(handler) .with_web_context(&mut web_content) - // .with_new_window_req_handler(move |uri: String| { - // let submitted = proxy.send_event(UserEvent::NewWindow(uri.clone())).is_ok(); - // submitted - // }) + .with_download_started_handler(download_started) + .with_download_completed_handler(download_completed) .build()? }; #[cfg(feature = "devtools")] @@ -217,9 +240,18 @@ fn main() -> wry::Result<()> { println!("Clicked on {:?}", menu_id); println!("Clicked on {:?}", webview.window().is_visible()); } - // Event::UserEvent(UserEvent::NewWindow(uri)) => { - // webbrowser::open(&uri).expect("no browser"); - // } + Event::UserEvent(UserEvent::DownloadStarted(uri, temp_dir)) => { + println!("Download: {}", uri); + println!("Will write to: {:?}", temp_dir); + } + Event::UserEvent(UserEvent::DownloadComplete(_, success)) => { + println!("Succeeded: {}", success); + if success { + let _ = webview.evaluate_script("window.Toast('Save in downloads folder')"); + } else { + println!("No output path") + } + } _ => (), } }); diff --git a/src-tauri/src/pake.js b/src-tauri/src/pake.js index cad55dc..863be55 100644 --- a/src-tauri/src/pake.js +++ b/src-tauri/src/pake.js @@ -367,3 +367,19 @@ function zoomIn() { function zoomOut() { zoomCommon((htmlZoom) => `${Math.max(parseInt(htmlZoom) - 10, 30)}%`); } + + +function Toast(msg) { + const m = document.createElement('div'); + m.innerHTML = msg; + m.style.cssText = "max-width:60%;min-width: 180px;padding:0 8px;height: 36px;color: rgb(255, 255, 255);line-height: 36px;text-align: center;border-radius: 4px;position: fixed;bottom:16px;right: 16px;transform: translate(-50%, -50%);z-index: 999999;background: rgba(0, 0, 0,.9);font-size: 14px;"; + document.body.appendChild(m); + setTimeout(function() { + m.style.transition = 'transform ' + d + 's ease-in, opacity ' + d + 's ease-in'; + m.style.opacity = '0'; + setTimeout(function() { + document.body.removeChild(m) + }, 500); + }, 3000); +} +