From f57e1ccdad4927038f5324227b065bccc67a6cde Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Sat, 12 Apr 2025 11:18:44 -0500 Subject: [PATCH] Fix background updater --- frontend/src-tauri/Cargo.lock | 1 + frontend/src-tauri/Cargo.toml | 1 + frontend/src-tauri/src/lib.rs | 59 ++++++++++++++++++++++++++++++++--- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/frontend/src-tauri/Cargo.lock b/frontend/src-tauri/Cargo.lock index 0b3ae7d99..ad48cbd0a 100644 --- a/frontend/src-tauri/Cargo.lock +++ b/frontend/src-tauri/Cargo.lock @@ -2223,6 +2223,7 @@ name = "maple" version = "0.2.2" dependencies = [ "log", + "once_cell", "serde", "serde_json", "tauri", diff --git a/frontend/src-tauri/Cargo.toml b/frontend/src-tauri/Cargo.toml index 42efbe8cf..2c3ff6976 100644 --- a/frontend/src-tauri/Cargo.toml +++ b/frontend/src-tauri/Cargo.toml @@ -29,3 +29,4 @@ tauri-plugin = "2.1.1" tauri-plugin-deep-link = "2" tauri-plugin-opener = "2" tokio = { version = "1.0", features = ["time"] } +once_cell = "1.18.0" diff --git a/frontend/src-tauri/src/lib.rs b/frontend/src-tauri/src/lib.rs index 37b7b804e..bc43ab081 100644 --- a/frontend/src-tauri/src/lib.rs +++ b/frontend/src-tauri/src/lib.rs @@ -53,18 +53,18 @@ pub fn run() { // The update will be applied silently in the background // It will take effect the next time the application is started let _ = check_for_updates(app_handle.clone()).await; - + // Set up hourly update checks let hourly_app_handle = app_handle.clone(); tauri::async_runtime::spawn(async move { // Define one hour in seconds let one_hour = std::time::Duration::from_secs(3600); - + loop { // Wait one hour before checking again tokio::time::sleep(one_hour).await; log::info!("Performing scheduled hourly update check"); - + // Check for updates let _ = check_for_updates(hourly_app_handle.clone()).await; } @@ -195,6 +195,19 @@ pub fn run() { .expect("error while running tauri application"); } +// Create a global variable to track if an update is already prepared and notified +#[cfg(desktop)] +use once_cell::sync::Lazy; +#[cfg(desktop)] +use std::sync::atomic::{AtomicBool, Ordering}; +#[cfg(desktop)] +use std::sync::Mutex; + +#[cfg(desktop)] +static UPDATE_DOWNLOADED: AtomicBool = AtomicBool::new(false); +#[cfg(desktop)] +static CURRENT_VERSION: Lazy> = Lazy::new(|| Mutex::new(String::new())); + /// Check for updates silently in the background #[cfg(desktop)] async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<(), String> { @@ -214,6 +227,25 @@ async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<(), String> { // Check for updates match updater.check().await { Ok(Some(update)) => { + // Check if we've already downloaded this specific version + let current_downloaded_version = match CURRENT_VERSION.lock() { + Ok(guard) => guard.clone(), + Err(e) => { + log::error!("Failed to lock CURRENT_VERSION mutex: {}", e); + String::new() // Use empty string if lock fails + } + }; + + if UPDATE_DOWNLOADED.load(Ordering::SeqCst) + && current_downloaded_version == update.version + { + log::info!( + "Update to version {} already downloaded, skipping redundant download", + update.version + ); + return Ok(()); + } + log::info!("Update available, attempting to download and install"); // Download the update @@ -240,6 +272,25 @@ async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<(), String> { // Log that the update is ready log::info!("Update installed successfully. Will be applied on next application restart."); + // Mark this version as downloaded to prevent redundant downloads/notifications + { + match CURRENT_VERSION.lock() { + Ok(mut version) => *version = update.version.clone(), + Err(e) => log::error!("Failed to lock CURRENT_VERSION mutex when updating version: {}", e) + } + } + + // If we've already shown a notification, don't show another one + if UPDATE_DOWNLOADED.load(Ordering::SeqCst) { + log::info!( + "Update notification already shown, not showing another one" + ); + return Ok(()); + } + + // Mark as downloaded to prevent further update dialogs + UPDATE_DOWNLOADED.store(true, Ordering::SeqCst); + // Show a dialog prompting the user to restart let message = format!( "An update to version {} has been downloaded and is ready to install. \ @@ -255,7 +306,7 @@ async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<(), String> { // Show a friendly info dialog with Yes/No buttons dialog .message(message) - .title("Update Ready") + .title("Maple Update") .kind(MessageDialogKind::Info) // Use info icon for a friendlier look .buttons(MessageDialogButtons::OkCancelCustom( "Yes".to_string(),