feat(updater): wire tauri-plugin-updater with GitHub releases endpoint + update toast

This commit is contained in:
2026-04-18 09:41:42 +01:00
parent ddcf93649c
commit 8b5d92f466
6 changed files with 63 additions and 0 deletions

View File

@@ -27,6 +27,7 @@ tauri = { version = "2", features = ["tray-icon"] }
tauri-plugin-opener = "2"
tauri-plugin-dialog = "2"
tauri-plugin-global-shortcut = "2"
tauri-plugin-updater = "2"
# Serialisation
serde = { version = "1", features = ["derive"] }

View File

@@ -7,4 +7,5 @@ pub mod live;
pub mod models;
pub mod transcription;
pub mod transcripts;
pub mod update;
pub mod windows;

View File

@@ -0,0 +1,38 @@
use tauri::AppHandle;
use tauri_plugin_updater::UpdaterExt;
/// Check for an available update. Returns Some(version_string) if one is
/// available, None if already up to date, and Err if the check fails.
#[tauri::command]
pub async fn check_for_update(app: AppHandle) -> Result<Option<String>, String> {
let update = app
.updater()
.map_err(|e| format!("Updater not available: {e}"))?
.check()
.await
.map_err(|e| format!("Update check failed: {e}"))?;
match update {
Some(u) => Ok(Some(u.version.to_string())),
None => Ok(None),
}
}
/// Download and stage the update. The app will install it on next launch.
#[tauri::command]
pub async fn install_update(app: AppHandle) -> Result<(), String> {
let update = app
.updater()
.map_err(|e| format!("Updater not available: {e}"))?
.check()
.await
.map_err(|e| format!("Update check failed: {e}"))?
.ok_or_else(|| "No update available".to_string())?;
update
.download_and_install(|_, _| {}, || {})
.await
.map_err(|e| format!("Install failed: {e}"))?;
Ok(())
}

View File

@@ -123,6 +123,7 @@ pub fn run() {
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
.plugin(tauri_plugin_updater::Builder::new().build())
.setup(|app| {
// Initialise database (blocking in setup — runs once at startup)
let db_path = database_path();
@@ -285,6 +286,9 @@ pub fn run() {
commands::hotkey::start_evdev_hotkey,
commands::hotkey::update_evdev_hotkey,
commands::hotkey::stop_evdev_hotkey,
// Updater
commands::update::check_for_update,
commands::update::install_update,
])
.run(tauri::generate_context!())
.expect("error while running Kon");

View File

@@ -26,6 +26,15 @@
"csp": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' asset: https://asset.localhost; connect-src ipc: http://ipc.localhost asset: https://asset.localhost http://localhost:* ws://localhost:*; media-src 'self' asset: https://asset.localhost"
}
},
"plugins": {
"updater": {
"endpoints": [
"https://github.com/jakejars/kon/releases/latest/download/latest.json"
],
"dialog": false,
"pubkey": ""
}
},
"bundle": {
"active": true,
"targets": "all",

View File

@@ -10,6 +10,7 @@
import { loadOsInfo } from "$lib/utils/osInfo.js";
import { page, settings, saveSettings } from "$lib/stores/page.svelte.js";
import { getPreferences, updatePreferences } from "$lib/stores/preferences.svelte.js";
import { toasts } from "$lib/stores/toasts.svelte.js";
import { page as sveltePage } from "$app/stores";
@@ -230,6 +231,15 @@
} catch {
// If commands fail, skip first-run check
}
// Background update check — non-blocking, silent on failure
invoke("check_for_update")
.then((version) => {
if (version) {
toasts.info(`Kon ${version} is available. Restart to install.`);
}
})
.catch(() => { /* update check failure must not affect the app */ });
});
onDestroy(() => {