From 80f2c72847d6aee760c170609948f75161d634e1 Mon Sep 17 00:00:00 2001 From: CJ Pais Date: Fri, 27 Jun 2025 12:27:01 -0700 Subject: [PATCH] fix update? --- bun.lockb | Bin 67231 -> 67231 bytes package.json | 2 +- src-tauri/Cargo.lock | 11 +++ src-tauri/Cargo.toml | 1 + src-tauri/capabilities/default.json | 2 + src-tauri/src/lib.rs | 1 + src/components/footer/Footer.tsx | 141 +++++++++++++++++++--------- 7 files changed, 115 insertions(+), 43 deletions(-) diff --git a/bun.lockb b/bun.lockb index 9efbf5563f3017e821a09073c25eae05a4bd0e85..ecaab7a13cd58e3d15cd6a279d01469a218a6e7f 100755 GIT binary patch delta 21 bcmbQ=%QC;0Wy70wY;{HqK(P7Ky0zf|U-1aI delta 21 dcmbQ=%QC;0Wy70wY;i_<#(D;uKdoCE4gh2+30D9B diff --git a/package.json b/package.json index a404183..668f99e 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "@tauri-apps/plugin-global-shortcut": "~2", "@tauri-apps/plugin-opener": "^2", "@tauri-apps/plugin-os": "~2", - "@tauri-apps/plugin-process": "^2.3.0", + "@tauri-apps/plugin-process": "~2", "@tauri-apps/plugin-store": "~2", "@tauri-apps/plugin-stronghold": "~2", "@tauri-apps/plugin-updater": "~2", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 9982965..ee966a2 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2006,6 +2006,7 @@ dependencies = [ "tauri-plugin-macos-permissions", "tauri-plugin-opener", "tauri-plugin-os", + "tauri-plugin-process", "tauri-plugin-single-instance", "tauri-plugin-store", "tauri-plugin-updater", @@ -5101,6 +5102,16 @@ dependencies = [ "thiserror 2.0.11", ] +[[package]] +name = "tauri-plugin-process" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7461c622a5ea00eb9cd9f7a08dbd3bf79484499fd5c21aa2964677f64ca651ab" +dependencies = [ + "tauri", + "tauri-plugin", +] + [[package]] name = "tauri-plugin-single-instance" version = "2.2.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index e1d9de2..640521c 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -41,6 +41,7 @@ vad-rs = "0.1.5" tauri-plugin-store = "2" tauri-plugin-os = "2" enigo = "0.5.0" +tauri-plugin-process = "2" [target.'cfg(target_os = "macos")'.dependencies] whisper-rs = { version = "0.13.2", features = ["metal"] } diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 5b8acce..91054d8 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -7,6 +7,8 @@ "core:default", "opener:default", "store:default", + "updater:default", + "process:default", "global-shortcut:allow-is-registered", "global-shortcut:allow-register", "global-shortcut:allow-unregister", diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 18aac40..d6a3da3 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -35,6 +35,7 @@ pub fn run() { env_logger::init(); tauri::Builder::default() + .plugin(tauri_plugin_process::init()) .plugin(tauri_plugin_updater::Builder::new().build()) .plugin(tauri_plugin_os::init()) .plugin(tauri_plugin_clipboard_manager::init()) diff --git a/src/components/footer/Footer.tsx b/src/components/footer/Footer.tsx index dbc9576..06a8d10 100644 --- a/src/components/footer/Footer.tsx +++ b/src/components/footer/Footer.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useRef } from "react"; import { check } from "@tauri-apps/plugin-updater"; import { relaunch } from "@tauri-apps/plugin-process"; import { getVersion } from "@tauri-apps/api/app"; @@ -7,40 +7,43 @@ import { listen } from "@tauri-apps/api/event"; const Footer: React.FC = () => { const [isChecking, setIsChecking] = useState(false); const [updateAvailable, setUpdateAvailable] = useState(false); - const [isUpdating, setIsUpdating] = useState(false); + const [isInstalling, setIsInstalling] = useState(false); + const [downloadProgress, setDownloadProgress] = useState(0); const [version, setVersion] = useState(""); const [showUpToDate, setShowUpToDate] = useState(false); - const [isManualCheck, setIsManualCheck] = useState(false); + + const upToDateTimeoutRef = useRef(); + const isManualCheckRef = useRef(false); + const downloadedBytesRef = useRef(0); + const contentLengthRef = useRef(0); useEffect(() => { - // Get version from Tauri app info const fetchVersion = async () => { try { const appVersion = await getVersion(); setVersion(appVersion); } catch (error) { console.error("Failed to get app version:", error); - setVersion("0.1.3"); // fallback version + setVersion("0.1.2"); } }; fetchVersion(); - - // Automatically check for updates on launch checkForUpdates(); - // Listen for menu-triggered update checks const unlisten = listen("check-for-updates", () => { - checkForUpdates(); + handleManualUpdateCheck(); }); return () => { + if (upToDateTimeoutRef.current) { + clearTimeout(upToDateTimeoutRef.current); + } unlisten.then((fn) => fn()); }; }, []); const checkForUpdates = async () => { - // Don't check again if already checking if (isChecking) return; try { @@ -50,50 +53,100 @@ const Footer: React.FC = () => { if (update) { setUpdateAvailable(true); setShowUpToDate(false); - console.log("Update available:", update.version); } else { - console.log("No updates available"); - // Reset update available state in case it was previously true setUpdateAvailable(false); - // Show "up to date" message only for manual checks - if (isManualCheck) { + if (isManualCheckRef.current) { setShowUpToDate(true); - // Hide the message after 3 seconds - setTimeout(() => setShowUpToDate(false), 3000); + if (upToDateTimeoutRef.current) { + clearTimeout(upToDateTimeoutRef.current); + } + upToDateTimeoutRef.current = setTimeout(() => { + setShowUpToDate(false); + }, 3000); } } } catch (error) { console.error("Failed to check for updates:", error); } finally { setIsChecking(false); - setIsManualCheck(false); + isManualCheckRef.current = false; } }; const handleManualUpdateCheck = () => { - setIsManualCheck(true); + isManualCheckRef.current = true; checkForUpdates(); }; const installUpdate = async () => { try { - setIsUpdating(true); + setIsInstalling(true); + setDownloadProgress(0); + downloadedBytesRef.current = 0; + contentLengthRef.current = 0; const update = await check(); - if (update) { - console.log("Installing update..."); - await update.downloadAndInstall(); - - // Restart the app to apply the update - await relaunch(); + if (!update) { + console.log("No update available during install attempt"); + return; } + + await update.downloadAndInstall((event) => { + switch (event.event) { + case "Started": + downloadedBytesRef.current = 0; + contentLengthRef.current = event.data.contentLength ?? 0; + break; + case "Progress": + downloadedBytesRef.current += event.data.chunkLength; + const progress = + contentLengthRef.current > 0 + ? Math.round( + (downloadedBytesRef.current / contentLengthRef.current) * + 100, + ) + : 0; + setDownloadProgress(Math.min(progress, 100)); + break; + } + }); + await relaunch(); } catch (error) { console.error("Failed to install update:", error); - setIsUpdating(false); + } finally { + setIsInstalling(false); + setDownloadProgress(0); + downloadedBytesRef.current = 0; + contentLengthRef.current = 0; } }; + const getStatusText = () => { + if (isInstalling) { + return downloadProgress > 0 && downloadProgress < 100 + ? `Downloading... ${downloadProgress.toString().padStart(3)}%` + : downloadProgress === 100 + ? "Installing..." + : "Preparing..."; + } + if (isChecking) return "Checking..."; + if (showUpToDate) return "Up to date"; + if (updateAvailable) return "Update available"; + return "Check for updates"; + }; + + const getStatusAction = () => { + if (updateAvailable && !isInstalling) return installUpdate; + if (!isChecking && !isInstalling && !updateAvailable) + return handleManualUpdateCheck; + return undefined; + }; + + const isDisabled = isChecking || isInstalling; + const isClickable = + !isDisabled && (updateAvailable || (!isChecking && !showUpToDate)); + return (
@@ -101,25 +154,29 @@ const Footer: React.FC = () => { v{version}
-
- {updateAvailable ? ( +
+ {isClickable ? ( - ) : showUpToDate ? ( - Up to date ) : ( - + {getStatusText()} + )} + + {isInstalling && downloadProgress > 0 && downloadProgress < 100 && ( + )}