diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 1280d2e..e32b684 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -1,8 +1,8 @@ use chrono::DateTime; -use tauri::{utils::config::WindowConfig, Manager}; +use tauri::{ipc::Channel, utils::config::WindowConfig, Manager}; use crate::{ - entities::{AppState, EveryLoginData}, + entities::{AppState, DownloadEvent, EveryLoginData}, requests::*, setting::Setting, }; @@ -435,11 +435,7 @@ pub fn set_background_blur( app_state: tauri::State<'_, AppState>, blur: u32, ) -> Result<(), String> { - app_state - .setting - .write() - .unwrap() - .set_background_blur(blur); + app_state.setting.write().unwrap().set_background_blur(blur); app_state .setting .read() @@ -450,12 +446,25 @@ pub fn set_background_blur( } #[tauri::command(async)] -pub async fn manually_check_update(app: tauri::AppHandle) -> Result<(), String> { - #[cfg(not(any(target_os = "android", target_os = "linux")))] - crate::update(app, true) - .await - .map_err(|err| err.to_string())?; +pub async fn manually_check_update( + app: tauri::AppHandle, + manually: bool, + on_event: Channel, +) -> Result<(), String> { + static mut AUTO_CHECK: bool = true; // 只能自动检查更新一次 + #[cfg(not(any(target_os = "android", target_os = "linux")))] + if unsafe { AUTO_CHECK } || manually { + // 如果第一次自动或者手动更新 + update(app, manually, on_event) + .await + .map_err(|err| err.to_string())?; + } + if !manually { + unsafe { + AUTO_CHECK = false; + } + } if cfg!(target_os = "android") || cfg!(target_os = "linux") { Err("安卓/Linux 不支持更新,请到 GitHub 查看是否有更新。".into()) } else { @@ -518,3 +527,79 @@ pub async fn return_os_type() -> i32 { res } + +#[cfg(not(any(target_os = "android", target_os = "linux")))] +async fn update( + app: tauri::AppHandle, + manually: bool, + on_event: Channel, +) -> Result<(), String> { + use tauri_plugin_dialog::DialogExt; + #[cfg(not(any(target_os = "android", target_os = "linux")))] + use tauri_plugin_updater::UpdaterExt; + + if let Some(update) = app + .updater() + .map_err(|e| e.to_string())? + .check() + .await + .map_err(|e| e.to_string())? + { + // 对话框 + let answer = app + .dialog() + .message(format!( + "有新版本!{}->{}\n是否更新?", + update.current_version, update.version + )) + .title("貌似有版本更新?") + .buttons(tauri_plugin_dialog::MessageDialogButtons::OkCancel) + .blocking_show(); + + if answer { + on_event + .send(DownloadEvent::Started { new_version: true }) + .unwrap(); + + let mut downloaded = 0; + update + .download_and_install( + |chunk_length, content_length| { + downloaded += chunk_length; + // println!("downloaded {downloaded} from {content_length:?}"); + on_event + .send(DownloadEvent::Progress { + downloaded, + content_length: content_length.unwrap_or_default(), + }) + .unwrap(); + }, + || { + // println!("download finished"); + on_event + .send(DownloadEvent::Finished { finished: true }) + .unwrap(); + }, + ) + .await + .map_err(|e| e.to_string())?; + app.dialog() + .message("下载完成,点击重启") + .kind(tauri_plugin_dialog::MessageDialogKind::Info) + .title("这是个提示框") + .buttons(tauri_plugin_dialog::MessageDialogButtons::Ok) + .blocking_show(); + // println!("update installed"); + app.restart(); + } + } else if manually { + app.dialog() + .message("没有更新😭") + .kind(tauri_plugin_dialog::MessageDialogKind::Info) + .title("这是个提示框") + .buttons(tauri_plugin_dialog::MessageDialogButtons::Ok) + .blocking_show(); + } + + Ok(()) +} diff --git a/src-tauri/src/entities.rs b/src-tauri/src/entities.rs index 9acb5e5..09af042 100644 --- a/src-tauri/src/entities.rs +++ b/src-tauri/src/entities.rs @@ -92,4 +92,18 @@ pub struct AmmeterData { pub message: String, #[serde(rename = "statusCode")] pub status_code: String, -} \ No newline at end of file +} + +#[derive(Clone, Serialize)] +#[serde(rename_all = "camelCase", tag = "event", content = "data")] +pub enum DownloadEvent { + #[serde(rename_all = "camelCase")] + Started { new_version: bool }, + #[serde(rename_all = "camelCase")] + Progress { + downloaded: usize, + content_length: u64, + }, + #[serde(rename_all = "camelCase")] + Finished { finished: bool }, +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 5c885b0..e0e8610 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -10,9 +10,7 @@ use crate::commands::*; use crate::entities::AppState; use crate::setting::Setting; use tauri::Manager; -use tauri_plugin_dialog::DialogExt; -#[cfg(not(any(target_os = "android", target_os = "linux")))] -use tauri_plugin_updater::UpdaterExt; + #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { @@ -60,10 +58,6 @@ pub fn run() { #[cfg(not(any(target_os = "android", target_os = "linux")))] { background_init(app)?; - let handle = app.handle().clone(); - tauri::async_runtime::spawn(async move { - let _ = update(handle, false).await; - }); } Ok(()) }) @@ -94,51 +88,3 @@ fn background_init(app: &mut tauri::App) -> Result<(), Box anyhow::Result<()> { - if let Some(update) = app.updater()?.check().await? { - // 对话框 - let answer = app - .dialog() - .message(format!( - "有新版本!{}->{}\n是否更新?", - update.current_version, update.version - )) - .title("貌似有版本更新?") - .buttons(tauri_plugin_dialog::MessageDialogButtons::OkCancel) - .blocking_show(); - - if answer { - let mut downloaded = 0; - update - .download_and_install( - |chunk_length, content_length| { - downloaded += chunk_length; - println!("downloaded {downloaded} from {content_length:?}"); - }, - || { - println!("download finished"); - }, - ) - .await?; - app.dialog() - .message("下载完成,点击重启") - .kind(tauri_plugin_dialog::MessageDialogKind::Info) - .title("这是个提示框") - .buttons(tauri_plugin_dialog::MessageDialogButtons::Ok) - .blocking_show(); - println!("update installed"); - app.restart(); - } - } else if manually { - app.dialog() - .message("没有更新😭") - .kind(tauri_plugin_dialog::MessageDialogKind::Info) - .title("这是个提示框") - .buttons(tauri_plugin_dialog::MessageDialogButtons::Ok) - .blocking_show(); - } - - Ok(()) -} diff --git a/src/App.vue b/src/App.vue index 83e5147..b093973 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,6 +2,7 @@ import { ref, computed, Ref, DefineComponent, onMounted } from "vue"; import { darkTheme } from "naive-ui"; import { invoke, convertFileSrc } from "@tauri-apps/api/core"; +import { check_update, is_download, download_percent } from "./update"; // routers import Login from "./pages/Login.vue"; @@ -14,6 +15,7 @@ import UnbindMacs from "./pages/UnbindMacs.vue"; import SpeedTest from "./pages/SpeedTest.vue"; import MonthlyUserLog from "./pages/MonthlyUserLog.vue"; import OtherTools from "./pages/OtherTools.vue"; + type RouteComponent = DefineComponent<{}, {}, any>; interface Routes { @@ -109,6 +111,13 @@ const apply_background = async () => { } } }; + +// download + +onMounted(() => { + check_update(false); +}); + - + diff --git a/src/pages/Login.vue b/src/pages/Login.vue index 1680ec9..fefeba2 100644 --- a/src/pages/Login.vue +++ b/src/pages/Login.vue @@ -5,6 +5,7 @@ import { useMessage, useLoadingBar } from "naive-ui"; import { ColorPaletteOutline } from "@vicons/ionicons5"; import { open } from "@tauri-apps/plugin-shell"; import { dataDir } from "@tauri-apps/api/path"; +import { check_update } from "../update"; const loadingBar = useLoadingBar(); const pop_message = useMessage(); @@ -120,7 +121,7 @@ const railStyle = ({ }; const manually_check_update = async () => { - await invoke("manually_check_update").catch((err) => pop_message.error(err)); + await check_update(true); }; const submit_login_ustb_wifi = async () => { @@ -153,9 +154,9 @@ const set_background_blur = async () => { }; const open_config = async () => { - let path = await dataDir() + "/ustb-wifi-tools" ; - console.log(path); - + // explorer 还是强的,能识别斜杠 + let path = (await dataDir()) + "/ustb-wifi-tools"; + // console.log(path); await open(path); }; diff --git a/src/update.ts b/src/update.ts new file mode 100644 index 0000000..fd0607b --- /dev/null +++ b/src/update.ts @@ -0,0 +1,45 @@ +import { Channel, invoke } from "@tauri-apps/api/core"; +import { ref } from "vue"; + +export const is_download = ref(false); +export const download_percent = ref(0); + +type DownloadEvent = + | { + event: "started"; + data: { + newVersion: boolean; + }; + } + | { + event: "progress"; + data: { + downloaded: number; + contentLength: number; + }; + } + | { + event: "finished"; + data: { + finished: boolean; + }; + }; + +const onEvent = new Channel(); +onEvent.onmessage = (message) => { + if (message.event === "started") { + is_download.value = message.data.newVersion; // 这没有意义 + } else if (message.event === "progress") { + download_percent.value = + parseFloat( + (message.data.downloaded / message.data.contentLength).toFixed(2) + ) * 100; + } +}; + +export const check_update = async (manually: boolean) => { + await invoke("manually_check_update", { + manually, + onEvent, + }).catch((err) => console.log(err)); +}; \ No newline at end of file