diff --git a/src-tauri/src/auto_updater.rs b/src-tauri/src/auto_updater.rs index e577e9e..8a594d3 100644 --- a/src-tauri/src/auto_updater.rs +++ b/src-tauri/src/auto_updater.rs @@ -428,7 +428,7 @@ impl AutoUpdater { .join("auto_update_state.json") } - fn load_auto_update_state( + pub fn load_auto_update_state( &self, ) -> Result> { let state_file = self.get_auto_update_state_file(); @@ -442,7 +442,7 @@ impl AutoUpdater { Ok(state) } - fn save_auto_update_state( + pub fn save_auto_update_state( &self, state: &AutoUpdateState, ) -> Result<(), Box> { diff --git a/src-tauri/src/settings_manager.rs b/src-tauri/src/settings_manager.rs index a234325..3fca7c2 100644 --- a/src-tauri/src/settings_manager.rs +++ b/src-tauri/src/settings_manager.rs @@ -204,14 +204,40 @@ pub async fn clear_all_version_cache_and_refetch( .clear_all_cache() .map_err(|e| format!("Failed to clear version cache: {e}"))?; + // Disable all browsers during the update process + let auto_updater = crate::auto_updater::AutoUpdater::instance(); + let supported_browsers = + crate::browser_version_service::BrowserVersionService::instance().get_supported_browsers(); + + // Load current state and disable all browsers + let mut state = auto_updater + .load_auto_update_state() + .map_err(|e| format!("Failed to load auto update state: {e}"))?; + for browser in &supported_browsers { + state.disabled_browsers.insert(browser.clone()); + } + auto_updater + .save_auto_update_state(&state) + .map_err(|e| format!("Failed to save auto update state: {e}"))?; + let updater = version_updater::get_version_updater(); let updater_guard = updater.lock().await; - updater_guard + let result = updater_guard .trigger_manual_update(&app_handle) .await - .map_err(|e| format!("Failed to trigger version update: {e}"))?; + .map_err(|e| format!("Failed to trigger version update: {e}")); + // Re-enable all browsers after the update completes (regardless of success/failure) + let mut final_state = auto_updater.load_auto_update_state().unwrap_or_default(); + for browser in &supported_browsers { + final_state.disabled_browsers.remove(browser); + } + if let Err(e) = auto_updater.save_auto_update_state(&final_state) { + eprintln!("Warning: Failed to re-enable browsers after cache clear: {e}"); + } + + result?; Ok(()) } diff --git a/src/components/settings-dialog.tsx b/src/components/settings-dialog.tsx index 6f67a5f..0b25e46 100644 --- a/src/components/settings-dialog.tsx +++ b/src/components/settings-dialog.tsx @@ -1,6 +1,7 @@ "use client"; import { invoke } from "@tauri-apps/api/core"; +import { listen } from "@tauri-apps/api/event"; import { useTheme } from "next-themes"; import { useCallback, useEffect, useState } from "react"; import { BsCamera, BsMic } from "react-icons/bs"; @@ -25,7 +26,13 @@ import { } from "@/components/ui/select"; import type { PermissionType } from "@/hooks/use-permissions"; import { usePermissions } from "@/hooks/use-permissions"; -import { showErrorToast, showSuccessToast } from "@/lib/toast-utils"; +import { getBrowserDisplayName } from "@/lib/browser-utils"; +import { + dismissToast, + showErrorToast, + showSuccessToast, + showUnifiedVersionUpdateToast, +} from "@/lib/toast-utils"; interface AppSettings { set_as_default_browser: boolean; @@ -38,6 +45,15 @@ interface PermissionInfo { description: string; } +interface VersionUpdateProgress { + current_browser: string; + total_browsers: number; + completed_browsers: number; + new_versions_found: number; + browser_new_versions: number; + status: string; // "updating", "completed", "error" +} + interface SettingsDialogProps { isOpen: boolean; onClose: () => void; @@ -180,11 +196,7 @@ export function SettingsDialog({ isOpen, onClose }: SettingsDialogProps) { setIsClearingCache(true); try { await invoke("clear_all_version_cache_and_refetch"); - showSuccessToast("Cache cleared successfully", { - description: - "All browser version cache has been cleared and browsers are being refreshed.", - duration: 4000, - }); + // Don't show immediate success toast - let the version update progress events handle it } catch (error) { console.error("Failed to clear cache:", error); showErrorToast("Failed to clear cache", { @@ -253,9 +265,83 @@ export function SettingsDialog({ isOpen, onClose }: SettingsDialogProps) { checkDefaultBrowserStatus().catch(console.error); }, 500); // Check every 500ms - // Cleanup interval on component unmount or dialog close + // Listen for version update progress events + let unlistenFn: (() => void) | null = null; + const setupVersionUpdateListener = async () => { + try { + unlistenFn = await listen( + "version-update-progress", + (event) => { + const progress = event.payload; + + if (progress.status === "updating") { + // Show unified progress toast + const currentBrowserName = progress.current_browser + ? getBrowserDisplayName(progress.current_browser) + : undefined; + + showUnifiedVersionUpdateToast( + "Checking for browser updates...", + { + description: currentBrowserName + ? `Fetching ${currentBrowserName} release information...` + : "Initializing version check...", + progress: { + current: progress.completed_browsers, + total: progress.total_browsers, + found: progress.new_versions_found, + current_browser: currentBrowserName, + }, + }, + ); + } else if (progress.status === "completed") { + dismissToast("unified-version-update"); + + if (progress.new_versions_found > 0) { + showSuccessToast("Browser versions updated successfully", { + duration: 5000, + description: + "Auto-downloads will start shortly for available updates.", + }); + } else { + showSuccessToast("No new browser versions found", { + duration: 3000, + description: "All browser versions are up to date", + }); + } + } else if (progress.status === "error") { + dismissToast("unified-version-update"); + + showErrorToast("Failed to update browser versions", { + duration: 6000, + description: "Check your internet connection and try again", + }); + } + }, + ); + } catch (error) { + console.error( + "Failed to setup version update progress listener:", + error, + ); + } + }; + + setupVersionUpdateListener(); + + // Cleanup interval and listener on component unmount or dialog close return () => { clearInterval(intervalId); + if (unlistenFn) { + try { + unlistenFn(); + } catch (error) { + console.error( + "Failed to cleanup version update progress listener:", + error, + ); + } + } }; } }, [isOpen, loadPermissions, checkDefaultBrowserStatus, loadSettings]);