Просмотр исходного кода

desktop: move updater logic to js

Brendan Allan 2 месяцев назад
Родитель
Сommit
78547f3c59

+ 3 - 0
bun.lock

@@ -354,6 +354,7 @@
         "@tauri-apps/api": "^2",
         "@tauri-apps/plugin-dialog": "~2",
         "@tauri-apps/plugin-opener": "^2",
+        "@tauri-apps/plugin-process": "~2",
         "@tauri-apps/plugin-shell": "~2",
         "@tauri-apps/plugin-updater": "~2",
         "solid-js": "catalog:",
@@ -1655,6 +1656,8 @@
 
     "@tauri-apps/plugin-opener": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-ei/yRRoCklWHImwpCcDK3VhNXx+QXM9793aQ64YxpqVF0BDuuIlXhZgiAkc15wnPVav+IbkYhmDJIv5R326Mew=="],
 
+    "@tauri-apps/plugin-process": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA=="],
+
     "@tauri-apps/plugin-shell": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-Xod+pRcFxmOWFWEnqH5yZcA7qwAMuaaDkMR1Sply+F8VfBj++CGnj2xf5UoialmjZ2Cvd8qrvSCbU+7GgNVsKQ=="],
 
     "@tauri-apps/plugin-updater": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-j++sgY8XpeDvzImTrzWA08OqqGqgkNyxczLD7FjNJJx/uXxMZFz5nDcfkyoI/rCjYuj2101Tci/r/HFmOmoxCg=="],

+ 1 - 0
packages/tauri/package.json

@@ -15,6 +15,7 @@
     "@tauri-apps/api": "^2",
     "@tauri-apps/plugin-dialog": "~2",
     "@tauri-apps/plugin-opener": "^2",
+    "@tauri-apps/plugin-process": "~2",
     "@tauri-apps/plugin-shell": "~2",
     "@tauri-apps/plugin-updater": "~2",
     "solid-js": "catalog:"

+ 11 - 0
packages/tauri/src-tauri/Cargo.lock

@@ -2511,6 +2511,7 @@ dependencies = [
  "tauri-build",
  "tauri-plugin-dialog",
  "tauri-plugin-opener",
+ "tauri-plugin-process",
  "tauri-plugin-shell",
  "tauri-plugin-updater",
  "tokio",
@@ -4143,6 +4144,16 @@ dependencies = [
  "zbus",
 ]
 
+[[package]]
+name = "tauri-plugin-process"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d55511a7bf6cd70c8767b02c97bf8134fa434daf3926cfc1be0a0f94132d165a"
+dependencies = [
+ "tauri",
+ "tauri-plugin",
+]
+
 [[package]]
 name = "tauri-plugin-shell"
 version = "2.3.3"

+ 1 - 0
packages/tauri/src-tauri/Cargo.toml

@@ -28,3 +28,4 @@ serde = { version = "1", features = ["derive"] }
 serde_json = "1"
 tokio = "1.48.0"
 listeners = "0.3"
+tauri-plugin-process = "2"

+ 2 - 1
packages/tauri/src-tauri/capabilities/default.json

@@ -9,6 +9,7 @@
     "core:window:allow-start-dragging",
     "shell:default",
     "updater:default",
-    "dialog:default"
+    "dialog:default",
+    "process:default"
   ]
 }

+ 21 - 73
packages/tauri/src-tauri/src/lib.rs

@@ -8,7 +8,6 @@ use tauri::{AppHandle, Manager, RunEvent, WebviewUrl, WebviewWindow};
 use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogResult};
 use tauri_plugin_shell::process::{CommandChild, CommandEvent};
 use tauri_plugin_shell::ShellExt;
-use tauri_plugin_updater::UpdaterExt;
 use tokio::net::TcpSocket;
 
 #[derive(Clone)]
@@ -102,14 +101,11 @@ pub fn run() {
     let mut builder = tauri::Builder::default()
         .plugin(tauri_plugin_dialog::init())
         .plugin(tauri_plugin_shell::init())
+        .plugin(tauri_plugin_process::init())
         .plugin(tauri_plugin_opener::init())
         .setup(move |app| {
             let app = app.handle().clone();
 
-            if updater_enabled {
-                tauri::async_runtime::spawn(run_updater(app.clone()));
-            }
-
             tauri::async_runtime::spawn(async move {
                 let port = get_sidecar_port();
                 let socket_connected = is_server_running(port).await;
@@ -141,7 +137,7 @@ pub fn run() {
 
                     let timestamp = Instant::now();
                     loop {
-                        if timestamp.elapsed() > Duration::from_secs(3) {
+                        if timestamp.elapsed() > Duration::from_secs(7) {
                             todo!("Handle server spawn timeout");
                         }
 
@@ -167,7 +163,13 @@ pub fn run() {
                         .title("OpenCode")
                         .inner_size(800.0, 600.0)
                         .decorations(true)
-                        .zoom_hotkeys_enabled(true);
+                        .zoom_hotkeys_enabled(true)
+                        .initialization_script(format!(
+                            r#"
+                          window.__OPENCODE__ ??= {{}};
+                          window.__OPENCODE__.updaterEnabled = {updater_enabled}
+                        "#
+                        ));
 
                 #[cfg(target_os = "macos")]
                 {
@@ -193,78 +195,24 @@ pub fn run() {
             if let RunEvent::Exit = event {
                 println!("Received Exit");
 
-                let _ = app
-                    .state::<ServerState>()
+                let Some(server_state) = app.try_state::<ServerState>() else {
+                    println!("Server not running");
+                    return;
+                };
+
+                let Some(server_state) = server_state
                     .0
                     .lock()
                     .expect("Failed to acquire mutex lock")
                     .take()
-                    .expect("State not found")
-                    .kill();
+                else {
+                    println!("Server state missing");
+                    return;
+                };
+
+                let _ = server_state.kill();
 
                 println!("Killed server");
             }
         });
 }
-
-async fn run_updater(app: AppHandle) {
-    let update = match app
-        .updater_builder()
-        .version_comparator(|v, r| {
-            dbg!(&v, &r);
-            r.version > v
-        })
-        .build()
-        .unwrap()
-        .check()
-        .await
-    {
-        Ok(u) => u,
-        Err(e) => {
-            dbg!(e);
-            app.dialog()
-                .message("Failed to check for updates")
-                .show(|_| {});
-            return;
-        }
-    };
-
-    dbg!(update.is_some());
-
-    let Some(update) = update else {
-        return;
-    };
-
-    let Ok(update_bytes) = update.download(|_, _| {}, || {}).await else {
-        return;
-    };
-
-    let should_update = app
-        .dialog()
-        .message(format!(
-            "Version {} of OpenCode is available, would you like to install it?",
-            &update.version
-        ))
-        .buttons(MessageDialogButtons::YesNo)
-        .blocking_show();
-
-    if !should_update {
-        return;
-    }
-
-    if update.install(update_bytes).is_err() {
-        app.dialog()
-            .message("Failed to install update")
-            .blocking_show();
-    }
-
-    let should_restart = app
-        .dialog()
-        .message("Update installed successfully, would you like to restart OpenCode?")
-        .buttons(MessageDialogButtons::YesNo)
-        .blocking_show();
-
-    if should_restart {
-        app.restart();
-    }
-}

+ 9 - 3
packages/tauri/src/index.tsx

@@ -1,6 +1,8 @@
 // @refresh reload
 import { render } from "solid-js/web"
 import { DesktopInterface, PlatformProvider, Platform } from "@opencode-ai/desktop"
+import { runUpdater } from "./updater";
+import { onMount } from "solid-js";
 
 const root = document.getElementById("root")
 if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
@@ -12,10 +14,14 @@ if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
 const platform: Platform = {}
 
 render(
-  () => (
-    <PlatformProvider value={platform}>
+  () => {
+    onMount(() => {
+      if(window.__OPENCODE__.updaterEnabled) runUpdater();
+    });
+
+    return <PlatformProvider value={platform}>
       <DesktopInterface />
     </PlatformProvider>
-  ),
+  },
   root!,
 )

+ 37 - 0
packages/tauri/src/updater.ts

@@ -0,0 +1,37 @@
+import { check, DownloadEvent } from '@tauri-apps/plugin-updater';
+import { relaunch } from '@tauri-apps/plugin-process';
+import { ask, message } from '@tauri-apps/plugin-dialog';
+
+export async function runUpdater(onDownloadEvent?:(progress: DownloadEvent) => void) {
+  let update;
+  try {
+    update = await check();
+  } catch {
+    await message("Failed to check for updates")
+    return false
+  }
+
+  if (!update) return;
+  if (update.version <= update.currentVersion) return;
+
+  try {
+    await update.download(onDownloadEvent);
+  } catch {
+    return false
+  }
+
+  const shouldUpdate = await ask(`Version ${update.version} of OpenCode is available, would you like to install it?`)
+  if (!shouldUpdate) return;
+
+  try {
+    await update.install();
+  } catch {
+    await message("Failed to install update")
+    return false
+  }
+
+  const shouldRestart = await ask("Update installed successfully, would you like to restart OpenCode?");
+  if(shouldRestart) await relaunch()
+
+  return true;
+}