From 91fac5f2e47dd0a9bbd37c07f1c134c2a0161620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9B=AE=E6=A3=83?= Date: Sat, 3 Feb 2024 17:31:19 +0800 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20rs=20=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/Cargo.lock | 34 ++++++ src-tauri/Cargo.toml | 2 +- src-tauri/src/client.rs | 192 ------------------------------- src-tauri/src/client/menu.rs | 212 +++++++++++++++++++++++++++++++++++ src-tauri/src/client/mod.rs | 42 +++++++ src-tauri/src/commands.rs | 88 +++++++++++++++ src-tauri/src/main.rs | 154 ++++++------------------- src-tauri/src/plugins.rs | 25 +++++ src-tauri/tauri.conf.json | 4 + src/utils/TGClient.ts | 11 +- 10 files changed, 442 insertions(+), 322 deletions(-) delete mode 100644 src-tauri/src/client.rs create mode 100644 src-tauri/src/client/menu.rs create mode 100644 src-tauri/src/client/mod.rs create mode 100644 src-tauri/src/commands.rs create mode 100644 src-tauri/src/plugins.rs diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index f2912b1c..da7d5033 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2373,6 +2373,16 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "open" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2078c0039e6a54a0c42c28faa984e115fb4c2d5bf2208f77d1961002df8576f8" +dependencies = [ + "pathdiff", + "windows-sys 0.42.0", +] + [[package]] name = "openssl" version = "0.10.63" @@ -2494,6 +2504,12 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -3992,10 +4008,12 @@ dependencies = [ "ignore", "objc", "once_cell", + "open", "os_info", "percent-encoding", "rand 0.8.5", "raw-window-handle", + "regex", "reqwest", "rfd", "semver", @@ -4053,6 +4071,7 @@ dependencies = [ "png", "proc-macro2", "quote", + "regex", "semver", "serde", "serde_json", @@ -4994,6 +5013,21 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278" +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-sys" version = "0.45.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index e9efa753..633350e1 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -17,7 +17,7 @@ chrono = "0.4.31" log = "^0.4" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tauri = { version = "1.4", features = [ "window-set-always-on-top", "window-set-fullscreen", "dialog-message", "process-exit", "fs-read-dir", "window-hide", "os-all", "clipboard-all", "dialog-open", "dialog-save", "fs-create-dir", "fs-remove-dir", "fs-write-file", "fs-remove-file", "fs-read-file", "path-all", "fs-exists", "window-close", "window-set-title", "window-unminimize", "window-show", "window-set-focus", "http-request"] } +tauri = { version = "1.4", features = [ "shell-open", "window-set-always-on-top", "window-set-fullscreen", "dialog-message", "process-exit", "fs-read-dir", "window-hide", "os-all", "clipboard-all", "dialog-open", "dialog-save", "fs-create-dir", "fs-remove-dir", "fs-write-file", "fs-remove-file", "fs-read-file", "path-all", "fs-exists", "window-close", "window-set-title", "window-unminimize", "window-show", "window-set-focus", "http-request"] } tauri-utils = "1.5.0" url = "2.4.1" walkdir = "2" diff --git a/src-tauri/src/client.rs b/src-tauri/src/client.rs deleted file mode 100644 index 082bc687..00000000 --- a/src-tauri/src/client.rs +++ /dev/null @@ -1,192 +0,0 @@ -//! @file src/client.rs -//! @desc 客户端模块,负责操作米游社客户端 -//! @since Beta v0.4.3 - -use tauri::{ - AppHandle, CustomMenuItem, LogicalSize, Manager, Menu, Size, Submenu, WindowBuilder, WindowUrl, -}; -use url::Url; - -// 创建子菜单-工具 -fn create_utils_menu() -> Menu { - let retry_bridge = CustomMenuItem::new("retry".to_string(), "重试桥接"); - let mock_touch = CustomMenuItem::new("mock_touch".to_string(), "模拟触摸"); - let remove_overlay = CustomMenuItem::new("remove_overlay".to_string(), "移除遮罩"); - // 旋转窗口/切换横屏或者竖屏 - let rotate_window = CustomMenuItem::new("rotate_window".to_string(), "旋转窗口"); - return Menu::new() - .add_item(retry_bridge) - .add_item(mock_touch) - .add_item(remove_overlay) - .add_item(rotate_window); -} - -// 创建米游社客户端菜单 -fn create_mhy_menu(func: String) -> Menu { - let top = CustomMenuItem::new("top".to_string(), "置顶"); - let cancel_top = CustomMenuItem::new("cancel_top".to_string(), "取消置顶"); - let sign_in = CustomMenuItem::new("sign_in".to_string(), "用户登录"); - let open_post = CustomMenuItem::new("open_post".to_string(), "打开帖子"); - let utils_menu = Submenu::new("工具".to_string(), create_utils_menu()); - // 如果是登录 - if func == "config_sign_in" { - return Menu::new().add_item(sign_in); - } - return Menu::new() - .add_item(top) - .add_item(cancel_top) - .add_item(open_post) - .add_submenu(utils_menu); -} - -// 获取米游社客户端入口地址 -fn get_mhy_client_url(func: String) -> WindowUrl { - let mut url_res: Url = "https://bbs.mihoyo.com/ys/".parse().unwrap(); - if func == "sign_in" { - url_res = "https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?act_id=e202009291139501" - .parse() - .unwrap(); - } else if func == "game_record" { - url_res = - "https://webstatic.mihoyo.com/app/community-game-records/index.html?bbs_presentation_style=fullscreen".parse().unwrap(); - } else if func == "birthday" { - url_res = "https://webstatic.mihoyo.com/ys/event/e20220303-birthday/index.html?activity_id=20220301153521" - .parse() - .unwrap(); - } - return WindowUrl::External(url_res); -} - -// 操作米游社客户端 -#[tauri::command] -pub async fn create_mhy_client(handle: AppHandle, func: String, url: String) { - let mut mhy_window_config = handle.config().tauri.windows.get(1).unwrap().clone(); - // 如果没有传入 url 参数,则使用默认的米游社客户端入口地址 - if url != "" { - mhy_window_config.url = WindowUrl::External(url.parse().unwrap()); - } else { - mhy_window_config.url = get_mhy_client_url(func.clone()); - } - if func == "birthday" - || func == "web_act" - || url.starts_with("https://webstatic.mihoyo.com/ys/event/e20220303-birthday/index.html") - { - mhy_window_config.width = 1280.0; - mhy_window_config.height = 720.0; - } - let has_mhy_client = handle.get_window("mhy_client").is_some(); - if has_mhy_client { - dbg!("mhy_client exists"); - return; - } - WindowBuilder::from_config(&handle, mhy_window_config) - .menu(create_mhy_menu(func)) - .build() - .expect("failed to create mhy_client") - .on_menu_event(move |event| match event.menu_item_id() { - "top" => { - let window = handle.get_window("mhy_client").unwrap(); - window.set_always_on_top(true).unwrap(); - } - "cancel_top" => { - let window = handle.get_window("mhy_client").unwrap(); - window.set_always_on_top(false).unwrap(); - } - "open_post" => { - let window = handle.get_window("mhy_client").unwrap(); - let execute_js = r#"javascript:(async function(){ - let url = new URL(window.location.href); - const whiteList = [ - "bbs.mihoyo.com", - "www.miyoushe.com", - "m.miyoushe.com", - ]; - if(!whiteList.includes(url.hostname)){ - alert(`当前页面不是米游社帖子页面\n${window.location.href}`); - return; - } - if(!url.pathname.includes("/article/") && !url.hash.includes("/article/")){ - alert(`当前页面不是米游社帖子页面\n${window.location.href}`); - return; - } - let postId; - if(url.pathname.includes("/article/")){ - postId = url.pathname.split("/").pop(); - }else{ - postId = url.hash.split("/").pop(); - } - if(typeof postId !== "string"){ - alert("帖子 ID 无效"); - return; - } - const arg = { - method: 'teyvat_open', - payload: postId, - } - await window.__TAURI__.event.emit('post_mhy_client',JSON.stringify(arg)); - })()"#; - window.eval(&execute_js).ok().unwrap(); - } - "retry" => { - let window = handle.get_window("mhy_client").unwrap(); - let execute_js = r#"javascript:(async function(){ - const arg = { - method: 'teyvat_retry', - } - await window.__TAURI__.event.emit('post_mhy_client',JSON.stringify(arg)); - })()"#; - window.eval(&execute_js).ok().unwrap(); - } - "mock_touch" => { - let window = handle.get_window("mhy_client").unwrap(); - let execute_js = r#"javascript:(async function(){ - const arg = { - method: 'teyvat_touch', - } - await window.__TAURI__.event.emit('post_mhy_client',JSON.stringify(arg)); - })()"#; - window.eval(&execute_js).ok().unwrap(); - } - "remove_overlay" => { - let window = handle.get_window("mhy_client").unwrap(); - let execute_js = r#"javascript:(async function(){ - const arg = { - method: 'teyvat_remove', - } - await window.__TAURI__.event.emit('post_mhy_client',JSON.stringify(arg)); - })()"#; - window.eval(&execute_js).ok().unwrap(); - } - "rotate_window" => { - let window = handle.get_window("mhy_client").unwrap(); - // 获取窗口宽高比 - let cur_size = window.inner_size().ok().unwrap(); - if cur_size.width > cur_size.height { - window.set_size(Size::Logical(LogicalSize { width: 400.0, height: 800.0 })).unwrap(); - } else { - window.set_size(Size::Logical(LogicalSize { width: 1280.0, height: 720.0 })).unwrap(); - } - window.center().unwrap(); - window.set_focus().unwrap(); - } - "sign_in" => { - let window = handle.get_window("mhy_client").unwrap(); - let execute_js = r#"javascript:(async function(){ - // 首先检测是不是 user.mihoyo.com - const url = new URL(window.location.href); - if(url.hostname !== "user.mihoyo.com"){ - alert("当前页面不是米游社登录页面"); - return; - } - const ck = document.cookie; - const arg = { - method: 'teyvat_sign_in', - payload: ck, - } - await window.__TAURI__.event.emit('post_mhy_client',JSON.stringify(arg)); - })()"#; - window.eval(&execute_js).ok().unwrap(); - } - _ => {} - }); -} diff --git a/src-tauri/src/client/menu.rs b/src-tauri/src/client/menu.rs new file mode 100644 index 00000000..745a5af9 --- /dev/null +++ b/src-tauri/src/client/menu.rs @@ -0,0 +1,212 @@ +//! @file src/client/menu.rs +//! @desc 客户端菜单模块,负责操作米游社客户端菜单 +//! @since Beta v0.4.3 + +use tauri::{AppHandle, CustomMenuItem, LogicalSize, Manager, Menu, Size, Submenu, WindowUrl}; +use url::Url; + +pub fn get_mhy_client_url(func: String) -> WindowUrl { + let mut url_res: Url = "https://bbs.mihoyo.com/ys/".parse().unwrap(); + if func == "sign_in" { + url_res = "https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?act_id=e202009291139501" + .parse() + .unwrap(); + } else if func == "game_record" { + url_res = + "https://webstatic.mihoyo.com/app/community-game-records/index.html?bbs_presentation_style=fullscreen".parse().unwrap(); + } else if func == "birthday" { + url_res = "https://webstatic.mihoyo.com/ys/event/e20220303-birthday/index.html?activity_id=20220301153521" + .parse() + .unwrap(); + } + return WindowUrl::External(url_res); +} + +// 创建子菜单-工具 +fn create_utils_menu() -> Menu { + let retry_bridge = CustomMenuItem::new("retry".to_string(), "重试桥接"); + let mock_touch = CustomMenuItem::new("mock_touch".to_string(), "模拟触摸"); + let remove_overlay = CustomMenuItem::new("remove_overlay".to_string(), "移除遮罩"); + // 旋转窗口/切换横屏或者竖屏 + let rotate_window = CustomMenuItem::new("rotate_window".to_string(), "旋转窗口"); + return Menu::new() + .add_item(retry_bridge) + .add_item(mock_touch) + .add_item(remove_overlay) + .add_item(rotate_window); +} + +// 创建米游社客户端菜单 +pub fn create_mhy_menu(func: String) -> Menu { + let top = CustomMenuItem::new("top".to_string(), "置顶"); + let cancel_top = CustomMenuItem::new("cancel_top".to_string(), "取消置顶"); + let sign_in = CustomMenuItem::new("sign_in".to_string(), "用户登录"); + let open_post = CustomMenuItem::new("open_post".to_string(), "打开帖子"); + let utils_menu = Submenu::new("工具".to_string(), create_utils_menu()); + // 如果是登录 + if func == "config_sign_in" { + return Menu::new().add_item(sign_in); + } + return Menu::new() + .add_item(top) + .add_item(cancel_top) + .add_item(open_post) + .add_submenu(utils_menu); +} + +// 菜单栏事件处理 +pub fn handle_menu_event(app_handle: AppHandle, event: tauri::MenuEvent) { + match event.menu_item_id() { + "top" => handle_menu_top(app_handle), + "cancel_top" => handle_menu_cancel_top(app_handle), + "sign_in" => handle_menu_sign_in(app_handle), + "open_post" => handle_menu_open_post(app_handle), + "retry" => handle_menu_retry(app_handle), + "mock_touch" => handle_menu_mock_touch(app_handle), + "remove_overlay" => handle_menu_remove_overlay(app_handle), + "rotate_window" => handle_menu_rotate_window(app_handle), + _ => {} + } +} + +// 处理置顶菜单 +fn handle_menu_top(app_handle: AppHandle) { + let window = app_handle.get_window("mhy_client"); + if window.is_some() { + window.unwrap().set_always_on_top(true).unwrap(); + } +} + +// 处理取消置顶菜单 +fn handle_menu_cancel_top(app_handle: AppHandle) { + let window = app_handle.get_window("mhy_client"); + if window.is_some() { + window.unwrap().set_always_on_top(false).unwrap(); + } +} + +// 处理用户登录菜单 +fn handle_menu_sign_in(app_handle: AppHandle) { + let window = app_handle.get_window("mhy_client"); + let execute_js = r#" + javascript:(async function(){ + // 首先检测是不是 user.mihoyo.com + const url = new URL(window.location.href); + if(url.hostname !== "user.mihoyo.com"){ + alert("当前页面不是米游社登录页面"); + return; + } + const ck = document.cookie; + const arg = { + method: 'teyvat_sign_in', + payload: ck, + } + await window.__TAURI__.event.emit('post_mhy_client',JSON.stringify(arg)); + })()"#; + if window.is_some() { + window.unwrap().eval(&execute_js).ok().unwrap(); + } +} + +// 处理打开帖子菜单 +fn handle_menu_open_post(app_handle: AppHandle) { + let window = app_handle.get_window("mhy_client"); + let execute_js = r#" + javascript:(async function(){ + let url = new URL(window.location.href); + const whiteList = [ + "bbs.mihoyo.com", + "www.miyoushe.com", + "m.miyoushe.com", + ]; + if(!whiteList.includes(url.hostname)){ + alert(`当前页面不是米游社帖子页面\n${window.location.href}`); + return; + } + if(!url.pathname.includes("/article/") && !url.hash.includes("/article/")){ + alert(`当前页面不是米游社帖子页面\n${window.location.href}`); + return; + } + let postId; + if(url.pathname.includes("/article/")){ + postId = url.pathname.split("/").pop(); + }else{ + postId = url.hash.split("/").pop(); + } + if(typeof postId !== "string"){ + alert("帖子 ID 无效"); + return; + } + const arg = { + method: 'teyvat_open', + payload: postId, + } + await window.__TAURI__.event.emit('post_mhy_client',JSON.stringify(arg)); + })()"#; + if window.is_some() { + window.unwrap().eval(&execute_js).ok().unwrap(); + } +} + +// 处理重试桥接菜单 +fn handle_menu_retry(app_handle: AppHandle) { + let window = app_handle.get_window("mhy_client"); + let execute_js = r#" + javascript:(async function(){ + const arg = { + method: 'teyvat_retry', + } + await window.__TAURI__.event.emit('post_mhy_client',JSON.stringify(arg)); + })()"#; + if window.is_some() { + window.unwrap().eval(&execute_js).ok().unwrap(); + } +} + +// 处理模拟触摸菜单 +fn handle_menu_mock_touch(app_handle: AppHandle) { + let window = app_handle.get_window("mhy_client"); + let execute_js = r#" + javascript:(async function(){ + const arg = { + method: 'teyvat_touch', + } + await window.__TAURI__.event.emit('post_mhy_client',JSON.stringify(arg)); + })()"#; + if window.is_some() { + window.unwrap().eval(&execute_js).ok().unwrap(); + } +} + +// 处理移除遮罩菜单 +fn handle_menu_remove_overlay(app_handle: AppHandle) { + let window = app_handle.get_window("mhy_client"); + let execute_js = r#" + javascript:(async function(){ + const arg = { + method: 'teyvat_remove', + } + await window.__TAURI__.event.emit('post_mhy_client',JSON.stringify(arg)); + })()"#; + if window.is_some() { + window.unwrap().eval(&execute_js).ok().unwrap(); + } +} + +// 处理旋转窗口菜单 +fn handle_menu_rotate_window(app_handle: AppHandle) { + let window_get = app_handle.get_window("mhy_client"); + if window_get == None { + return; + } + let window = window_get.unwrap(); + // 获取窗口宽高比 + let cur_size = window.inner_size().ok().unwrap(); + if cur_size.width > cur_size.height { + window.set_size(Size::Logical(LogicalSize { width: 400.0, height: 800.0 })).unwrap(); + } else { + window.set_size(Size::Logical(LogicalSize { width: 1280.0, height: 720.0 })).unwrap(); + } + window.center().unwrap(); + window.set_focus().unwrap(); +} diff --git a/src-tauri/src/client/mod.rs b/src-tauri/src/client/mod.rs new file mode 100644 index 00000000..128a4e34 --- /dev/null +++ b/src-tauri/src/client/mod.rs @@ -0,0 +1,42 @@ +//! @file src/client/mod.rs +//! @desc 客户端模块,负责操作米游社客户端 +//! @since Beta v0.4.3 + +mod menu; +use tauri::async_runtime::block_on; +use tauri::{AppHandle, Manager, WindowBuilder, WindowEvent, WindowUrl}; + +#[tauri::command] +pub async fn create_mhy_client(handle: AppHandle, func: String, url: String) { + let mut mhy_window_config = handle.config().tauri.windows.get(1).unwrap().clone(); + mhy_window_config.visible = true; + if url != "" { + mhy_window_config.url = WindowUrl::External(url.parse().unwrap()); + } else { + mhy_window_config.url = menu::get_mhy_client_url(func.clone()); + } + if func == "birthday" + || func == "web_act" + || url.starts_with("https://webstatic.mihoyo.com/ys/event/e20220303-birthday/index.html") + { + mhy_window_config.width = 1280.0; + mhy_window_config.height = 720.0; + } + let window_get = handle.get_window("mhy_client"); + if window_get.is_some() { + let mhy_client = window_get.unwrap(); + mhy_client.on_window_event(move |e| { + if let WindowEvent::Destroyed = e { + let future = create_mhy_client(handle.clone(), func.clone(), url.clone()); + block_on(future); + } + }); + mhy_client.close().unwrap(); + return; + } + WindowBuilder::from_config(&handle, mhy_window_config) + .menu(menu::create_mhy_menu(func)) + .build() + .expect("failed to create mhy_client") + .on_menu_event(move |event| menu::handle_menu_event(handle.clone(), event)); +} diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs new file mode 100644 index 00000000..ad9db7d3 --- /dev/null +++ b/src-tauri/src/commands.rs @@ -0,0 +1,88 @@ +//! @file src/commands.rs +//! @desc 命令模块,负责处理命令 +//! @since Beta v0.4.3 + +use tauri::{Manager, WindowBuilder}; +use tauri_utils::config::WindowConfig; + +// 放一个常数,用来判断应用是否初始化 +static mut APP_INITIALIZED: bool = false; +static mut DEEP_LINK_REGISTERED: bool = false; + +// 初始化应用 +#[tauri::command] +pub async fn init_app(app_handle: tauri::AppHandle) { + unsafe { + if APP_INITIALIZED == true && DEEP_LINK_REGISTERED == true { + return; + } + } + dbg!("init_app"); + let _mhy = app_handle.get_window("mhy_client"); + if _mhy.is_some() { + std::thread::sleep(std::time::Duration::from_millis(1000)); + _mhy.unwrap().close().unwrap(); + } + app_handle.emit_all("initApp", ()).unwrap(); + unsafe { + APP_INITIALIZED = true; + } +} + +// 注册deep link +#[tauri::command] +pub async fn register_deep_link(app_handle: tauri::AppHandle) { + unsafe { + if DEEP_LINK_REGISTERED == true { + return; + } + } + dbg!("register_deep_link"); + tauri_plugin_deep_link::register("teyvatguide", move |request| { + dbg!(&request); + app_handle.emit_all("active_deep_link", request).unwrap(); + }) + .unwrap(); + unsafe { + DEEP_LINK_REGISTERED = true; + } +} + +// 创建窗口 +#[tauri::command] +pub async fn create_window(app_handle: tauri::AppHandle, label: String, mut option: WindowConfig) { + let window_old = app_handle.get_window(&label); + option.label = label.clone(); + if window_old.is_some() { + dbg!("window exists"); + window_old.unwrap().close().unwrap(); + return; + } + let window_new = + Some(WindowBuilder::from_config(&app_handle, option).build().expect("failed to create window")); + window_new.unwrap(); +} + +// 执行 js +#[tauri::command] +pub async fn execute_js(app_handle: tauri::AppHandle, label: String, js: String) { + let window = app_handle.get_window(&label); + if window.is_some() { + window.unwrap().eval(&js).ok().unwrap(); + } +} + +// 获取目录大小 +#[tauri::command] +pub async fn get_dir_size(path: String) -> u64 { + let walk_dir = walkdir::WalkDir::new(path); + let mut size = 0; + for entry in walk_dir { + let entry = entry.unwrap(); + let file_type = entry.file_type(); + if file_type.is_file() { + size += entry.metadata().unwrap().len(); + } + } + size +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index dace8d5d..3e5a65be 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,142 +1,58 @@ //! @file src/main.rs //! @desc 主模块,用于启动应用 -//! @since Beta v0.4.2 +//! @since Beta v0.4.3 // Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] -use log::LevelFilter; -use tauri::{Manager, WindowBuilder}; -use tauri_plugin_log::{LogTarget, TimezoneStrategy}; -use tauri_utils::config::WindowConfig; +use tauri::Manager; mod client; +mod commands; +mod plugins; mod utils; -// 放一个常数,用来判断应用是否初始化 -static mut APP_INITIALIZED: bool = false; -static mut DEEP_LINK_REGISTERED: bool = false; - -#[tauri::command] -async fn init_app(app_handle: tauri::AppHandle) { - unsafe { - if APP_INITIALIZED == true && DEEP_LINK_REGISTERED == true { - return; +// 窗口事件处理 +fn window_event_handler(event: tauri::GlobalWindowEvent) -> () { + match event.event() { + tauri::WindowEvent::CloseRequested { api, .. } => { + api.prevent_close(); + let window = event.window().clone(); + if window.label() == "TeyvatGuide" { + // 子窗口 label 的数组 + const SUB_WINDOW_LABELS: [&str; 3] = ["Sub_window", "Dev_JSON", "mhy_client"]; + for label in SUB_WINDOW_LABELS.iter() { + let sub = window.get_window(label); + if sub.is_some() { + sub.unwrap().close().unwrap(); + } + } + } + window.close().unwrap(); } + _ => {} } - dbg!("init_app"); - let _mhy = app_handle.get_window("mhy_client"); - if _mhy.is_some() { - std::thread::sleep(std::time::Duration::from_millis(1000)); - _mhy.unwrap().close().unwrap(); - } - app_handle.emit_all("initApp", ()).unwrap(); - unsafe { - APP_INITIALIZED = true; - } -} - -#[tauri::command] -async fn register_deep_link(app_handle: tauri::AppHandle) { - unsafe { - if DEEP_LINK_REGISTERED == true { - return; - } - } - dbg!("register_deep_link"); - tauri_plugin_deep_link::register("teyvatguide", move |request| { - dbg!(&request); - app_handle.emit_all("active_deep_link", request).unwrap(); - }) - .unwrap(); - unsafe { - DEEP_LINK_REGISTERED = true; - } -} - -// 执行 js -#[tauri::command] -async fn execute_js(app_handle: tauri::AppHandle, label: String, js: String) { - let window = app_handle.get_window(&label); - if window.is_none() { - return; - } - window.unwrap().eval(&js).ok().unwrap(); -} - -// 创建窗口 -#[tauri::command] -async fn create_window(app_handle: tauri::AppHandle, label: String, mut option: WindowConfig) { - let window_old = app_handle.get_window(&label); - option.label = label.clone(); - if window_old.is_some() { - dbg!("window exists"); - window_old.unwrap().close().unwrap(); - return; - } - let window_new = - Some(WindowBuilder::from_config(&app_handle, option).build().expect("failed to create window")); - window_new.unwrap(); -} - -// 读取目录大小 -#[tauri::command] -async fn get_dir_size(path: String) -> u64 { - let walk_dir = walkdir::WalkDir::new(path); - let mut size = 0; - for entry in walk_dir { - let entry = entry.unwrap(); - let file_type = entry.file_type(); - if file_type.is_file() { - size += entry.metadata().unwrap().len(); - } - } - size } fn main() { tauri_plugin_deep_link::prepare("teyvatguide"); tauri::Builder::default() - .on_window_event(|event| { - match event.event() { - tauri::WindowEvent::CloseRequested { api, .. } => { - api.prevent_close(); - let window = event.window().clone(); - if window.label() == "TeyvatGuide" { - // 子窗口 label 的数组 - const SUB_WINDOW_LABELS: [&str; 3] = ["Sub_window", "Dev_JSON", "mhy_client"]; - for label in SUB_WINDOW_LABELS.iter() { - let sub = window.get_window(label); - if sub.is_some() { - sub.unwrap().close().unwrap(); - } - } - } - window.close().unwrap(); - } - _ => {} - } - }) - .plugin(tauri_plugin_sql::Builder::default().build()) - .plugin( - tauri_plugin_log::Builder::default() - .targets([LogTarget::LogDir, LogTarget::Stdout]) - .timezone_strategy(TimezoneStrategy::UseLocal) - .level(LevelFilter::Info) - .log_name(utils::get_current_date()) - .build(), - ) + .on_window_event(|event| window_event_handler(event)) + .plugin(plugins::build_sql_plugin()) + .plugin(plugins::build_log_plugin()) .invoke_handler(tauri::generate_handler![ - register_deep_link, - init_app, - execute_js, - create_window, - get_dir_size, + commands::init_app, + commands::register_deep_link, + commands::create_window, + commands::execute_js, + commands::get_dir_size, client::create_mhy_client, ]) .setup(|_app| { - let _window = _app.get_window("TeyvatGuide").unwrap(); - #[cfg(debug_assertions)] // only include this code on debug builds - _window.open_devtools(); // open the devtools on startup + #[cfg(debug_assertions)] + let _window = _app.get_window("TeyvatGuide"); + if _window.is_some() { + _window.unwrap().open_devtools(); + } Ok(()) }) .run(tauri::generate_context!()) diff --git a/src-tauri/src/plugins.rs b/src-tauri/src/plugins.rs new file mode 100644 index 00000000..dcddcf7c --- /dev/null +++ b/src-tauri/src/plugins.rs @@ -0,0 +1,25 @@ +//! @file src/plugins.rs +//! @desc 插件模块,用于注册插件 +//! @since Beta v0.4.3 + +use super::utils; +use log::LevelFilter; +use tauri::plugin::TauriPlugin; +use tauri::Runtime; +use tauri_plugin_log::{LogTarget, TimezoneStrategy}; +use tauri_plugin_sql::PluginConfig; + +// sqlite 插件 +pub fn build_sql_plugin() -> TauriPlugin> { + tauri_plugin_sql::Builder::default().build() +} + +// 日志插件 +pub fn build_log_plugin() -> TauriPlugin { + tauri_plugin_log::Builder::default() + .targets([LogTarget::LogDir, LogTarget::Stdout]) + .timezone_strategy(TimezoneStrategy::UseLocal) + .level(LevelFilter::Info) + .log_name(utils::get_current_date()) + .build() +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index c279fb0f..d26c38e5 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -58,6 +58,10 @@ "process": { "all": false, "exit": true + }, + "shell": { + "all": false, + "open": true } }, "bundle": { diff --git a/src/utils/TGClient.ts b/src/utils/TGClient.ts index 113aa79a..0d4d4ce6 100644 --- a/src/utils/TGClient.ts +++ b/src/utils/TGClient.ts @@ -450,22 +450,13 @@ class TGClient { /** * @func open - * @since Beta v0.3.7 + * @since Beta v0.4.3 * @desc 打开米游社客户端 * @param {string} func - 方法名 * @param {string} url - url * @returns {void} - 无返回值 */ async open(func: string, url?: string): Promise { - if (this.window !== null) { - try { - await this.window.close(); - } catch (e) { - console.error(e); - await invoke("create_mhy_client", { func: "default", url: "" }); - await this.open(func, url); - } - } if (url === undefined) url = this.getUrl(func); this.route = [url]; await TGLogger.Info(`[TGClient][open][${func}] ${url}`);