From a41a86165f6924c96beb21c85cc908ba483b20a7 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Wed, 28 Aug 2024 08:57:40 +0200 Subject: [PATCH] Migrated the update check function from Tauri JS to the runtime API --- .../Layout/MainLayout.razor.cs | 4 +- app/MindWork AI Studio/Tools/Rust.cs | 18 ++++- .../Tools/Services/UpdateService.cs | 9 +-- runtime/src/main.rs | 79 +++++++++---------- 4 files changed, 57 insertions(+), 53 deletions(-) diff --git a/app/MindWork AI Studio/Layout/MainLayout.razor.cs b/app/MindWork AI Studio/Layout/MainLayout.razor.cs index 11fa7248..5e5df417 100644 --- a/app/MindWork AI Studio/Layout/MainLayout.razor.cs +++ b/app/MindWork AI Studio/Layout/MainLayout.razor.cs @@ -85,8 +85,8 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, IDis this.MessageBus.RegisterComponent(this); this.MessageBus.ApplyFilters(this, [], [ Event.UPDATE_AVAILABLE, Event.USER_SEARCH_FOR_UPDATE, Event.CONFIGURATION_CHANGED ]); - // Set the js runtime for the update service: - UpdateService.SetBlazorDependencies(this.JsRuntime, this.Snackbar); + // Set the snackbar for the update service: + UpdateService.SetBlazorDependencies(this.Snackbar); TemporaryChatService.Initialize(); // Should the navigation bar be open by default? diff --git a/app/MindWork AI Studio/Tools/Rust.cs b/app/MindWork AI Studio/Tools/Rust.cs index d78f8a0f..2eb5ad60 100644 --- a/app/MindWork AI Studio/Tools/Rust.cs +++ b/app/MindWork AI Studio/Tools/Rust.cs @@ -118,10 +118,22 @@ public sealed class Rust(string apiPort) : IDisposable } } - public async Task CheckForUpdate(IJSRuntime jsRuntime) + public async Task CheckForUpdate() { - var cts = new CancellationTokenSource(TimeSpan.FromSeconds(16)); - return await jsRuntime.InvokeAsync("window.__TAURI__.invoke", cts.Token, "check_for_update"); + try + { + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(16)); + return await this.http.GetFromJsonAsync("/updates/check", cts.Token); + } + catch (Exception e) + { + this.logger!.LogError(e, "Failed to check for an update."); + return new UpdateResponse + { + Error = true, + UpdateIsAvailable = false, + }; + } } public async Task InstallUpdate(IJSRuntime jsRuntime) diff --git a/app/MindWork AI Studio/Tools/Services/UpdateService.cs b/app/MindWork AI Studio/Tools/Services/UpdateService.cs index c8cfef68..df163849 100644 --- a/app/MindWork AI Studio/Tools/Services/UpdateService.cs +++ b/app/MindWork AI Studio/Tools/Services/UpdateService.cs @@ -7,10 +7,6 @@ namespace AIStudio.Tools.Services; public sealed class UpdateService : BackgroundService, IMessageBusReceiver { - // We cannot inject IJSRuntime into our service. This is because - // the service is not a Blazor component. We need to pass the IJSRuntime from - // the MainLayout component to the service. - private static IJSRuntime? JS_RUNTIME; private static bool IS_INITIALIZED; private static ISnackbar? SNACKBAR; @@ -96,7 +92,7 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver if(!IS_INITIALIZED) return; - var response = await this.rust.CheckForUpdate(JS_RUNTIME!); + var response = await this.rust.CheckForUpdate(); if (response.UpdateIsAvailable) { await this.messageBus.SendMessage(null, Event.UPDATE_AVAILABLE, response); @@ -115,10 +111,9 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver } } - public static void SetBlazorDependencies(IJSRuntime jsRuntime, ISnackbar snackbar) + public static void SetBlazorDependencies(ISnackbar snackbar) { SNACKBAR = snackbar; - JS_RUNTIME = jsRuntime; IS_INITIALIZED = true; } } \ No newline at end of file diff --git a/runtime/src/main.rs b/runtime/src/main.rs index aa14fc60..06c55fc0 100644 --- a/runtime/src/main.rs +++ b/runtime/src/main.rs @@ -194,7 +194,7 @@ async fn main() { // tauri::async_runtime::spawn(async move { _ = rocket::custom(figment) - .mount("/", routes![dotnet_port, dotnet_ready, set_clipboard]) + .mount("/", routes![dotnet_port, dotnet_ready, set_clipboard, check_for_update]) .ignite().await.unwrap() .launch().await.unwrap(); }); @@ -312,8 +312,7 @@ async fn main() { }) .plugin(tauri_plugin_window_state::Builder::default().build()) .invoke_handler(tauri::generate_handler![ - store_secret, get_secret, delete_secret, - check_for_update, install_update + store_secret, get_secret, delete_secret, install_update ]) .build(tauri::generate_context!()) .expect("Error while running Tauri application"); @@ -673,51 +672,49 @@ fn stop_servers() { } } -#[tauri::command] -async fn check_for_update() -> CheckUpdateResponse { +#[get("/updates/check")] +async fn check_for_update() -> Json { let app_handle = MAIN_WINDOW.lock().unwrap().as_ref().unwrap().app_handle(); - tauri::async_runtime::spawn(async move { - let response = app_handle.updater().check().await; - match response { - Ok(update_response) => match update_response.is_update_available() { - true => { - *CHECK_UPDATE_RESPONSE.lock().unwrap() = Some(update_response.clone()); - let new_version = update_response.latest_version(); - info!(Source = "Updater"; "An update to version '{new_version}' is available."); - let changelog = update_response.body(); - CheckUpdateResponse { - update_is_available: true, - error: false, - new_version: new_version.to_string(), - changelog: match changelog { - Some(c) => c.to_string(), - None => String::from(""), - }, - } - }, - - false => { - info!(Source = "Updater"; "No updates are available."); - CheckUpdateResponse { - update_is_available: false, - error: false, - new_version: String::from(""), - changelog: String::from(""), - } - }, + let response = app_handle.updater().check().await; + match response { + Ok(update_response) => match update_response.is_update_available() { + true => { + *CHECK_UPDATE_RESPONSE.lock().unwrap() = Some(update_response.clone()); + let new_version = update_response.latest_version(); + info!(Source = "Updater"; "An update to version '{new_version}' is available."); + let changelog = update_response.body(); + Json(CheckUpdateResponse { + update_is_available: true, + error: false, + new_version: new_version.to_string(), + changelog: match changelog { + Some(c) => c.to_string(), + None => String::from(""), + }, + }) }, - Err(e) => { - warn!(Source = "Updater"; "Failed to check for updates: {e}."); - CheckUpdateResponse { + false => { + info!(Source = "Updater"; "No updates are available."); + Json(CheckUpdateResponse { update_is_available: false, - error: true, + error: false, new_version: String::from(""), changelog: String::from(""), - } + }) }, - } - }).await.unwrap() + }, + + Err(e) => { + warn!(Source = "Updater"; "Failed to check for updates: {e}."); + Json(CheckUpdateResponse { + update_is_available: false, + error: true, + new_version: String::from(""), + changelog: String::from(""), + }) + }, + } } #[derive(Serialize)]