diff --git a/package-lock.json b/package-lock.json index 545c3c1..ece4dc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,9 +17,12 @@ "@tanstack/react-query-devtools": "5.24.1", "@tanstack/react-virtual": "3.2.0", "@tauri-apps/api": "2.9.1", + "@tauri-apps/plugin-dialog": "2.6.0", "@tauri-apps/plugin-fs": "2.4.5", "@tauri-apps/plugin-notification": "2.3.3", "@tauri-apps/plugin-opener": "2", + "@tauri-apps/plugin-process": "2.3.1", + "@tauri-apps/plugin-updater": "2.10.0", "@vanilla-extract/css": "1.9.3", "@vanilla-extract/recipes": "0.3.0", "@vanilla-extract/vite-plugin": "3.7.1", @@ -4537,6 +4540,15 @@ "url": "https://opencollective.com/tauri" } }, + "node_modules/@tauri-apps/plugin-dialog": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.6.0.tgz", + "integrity": "sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, "node_modules/@tauri-apps/plugin-fs": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.4.5.tgz", @@ -4564,6 +4576,34 @@ "@tauri-apps/api": "^2.8.0" } }, + "node_modules/@tauri-apps/plugin-process": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-process/-/plugin-process-2.3.1.tgz", + "integrity": "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-updater": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-updater/-/plugin-updater-2.10.0.tgz", + "integrity": "sha512-ljN8jPlnT0aSn8ecYhuBib84alxfMx6Hc8vJSKMJyzGbTPFZAC44T2I1QNFZssgWKrAlofvJqCC6Rr472JWfkQ==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.10.1" + } + }, + "node_modules/@tauri-apps/plugin-updater/node_modules/@tauri-apps/api": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.10.1.tgz", + "integrity": "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", diff --git a/package.json b/package.json index 3cd852e..9af3353 100644 --- a/package.json +++ b/package.json @@ -28,9 +28,12 @@ "@tanstack/react-query-devtools": "5.24.1", "@tanstack/react-virtual": "3.2.0", "@tauri-apps/api": "2.9.1", + "@tauri-apps/plugin-dialog": "2.6.0", "@tauri-apps/plugin-fs": "2.4.5", "@tauri-apps/plugin-notification": "2.3.3", "@tauri-apps/plugin-opener": "2", + "@tauri-apps/plugin-process": "2.3.1", + "@tauri-apps/plugin-updater": "2.10.0", "@vanilla-extract/css": "1.9.3", "@vanilla-extract/recipes": "0.3.0", "@vanilla-extract/vite-plugin": "3.7.1", diff --git a/src/index.tsx b/src/index.tsx index e2035ef..566081c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -13,6 +13,9 @@ import './index.css'; import { trimTrailingSlash } from './app/utils/common'; import App from './app/pages/App'; import { applySafeAreaInsets } from './app/utils/tauri'; +import { check } from '@tauri-apps/plugin-updater'; +import { ask } from '@tauri-apps/plugin-dialog'; +import { relaunch } from '@tauri-apps/plugin-process'; // import i18n (needs to be bundled ;)) import './app/i18n'; @@ -42,6 +45,28 @@ if ('serviceWorker' in navigator) { }); } +/** + * Check for app updates using Tauri updater + * Prompts user if update is available and handles download/install + */ +async function checkForUpdates() { + try { + const update = await check(); + if (update) { + const shouldUpdate = await ask( + `A new version (${update.version}) is available. Would you like to update now?`, + { title: 'Update Available', kind: 'info' } + ); + if (shouldUpdate) { + await update.downloadAndInstall(); + await relaunch(); + } + } + } catch (error) { + console.error('Failed to check for updates:', error); + } +} + const mountApp = () => { const rootContainer = document.getElementById('root'); @@ -55,3 +80,8 @@ const mountApp = () => { }; mountApp(); + +// Check for updates after app loads (with delay to not block startup) +setTimeout(() => { + checkForUpdates(); +}, 3000);