Implement autoupdater functionality and enhance icon management

- Added a new UpdateNotification component to inform users about available updates and facilitate installation.
- Integrated useAutoUpdater hook for managing update checks and installations.
- Updated package.json with new build and generate scripts for release preparation and key generation.
- Enhanced tauri configuration to support autoupdater with signing keys and endpoints.
- Created scripts for preparing signed releases and updating icons, ensuring a streamlined workflow for asset management.
- Added detailed documentation for autoupdater setup and icon update workflow.
This commit is contained in:
Jamie Pine
2026-01-25 15:38:31 -08:00
parent 0e38d47855
commit 7d1ee4c1b9
65 changed files with 1624 additions and 55 deletions
+104
View File
@@ -0,0 +1,104 @@
import { useEffect, useState } from 'react';
import { check, type Update } from '@tauri-apps/plugin-updater';
import { relaunch } from '@tauri-apps/plugin-process';
export interface UpdateStatus {
checking: boolean;
available: boolean;
version?: string;
downloading: boolean;
installing: boolean;
error?: string;
}
export function useAutoUpdater(checkOnMount = false) {
const [status, setStatus] = useState<UpdateStatus>({
checking: false,
available: false,
downloading: false,
installing: false,
});
const [update, setUpdate] = useState<Update | null>(null);
const checkForUpdates = async () => {
try {
setStatus((prev) => ({ ...prev, checking: true, error: undefined }));
const foundUpdate = await check();
if (foundUpdate?.available) {
setUpdate(foundUpdate);
setStatus({
checking: false,
available: true,
version: foundUpdate.version,
downloading: false,
installing: false,
});
} else {
setStatus({
checking: false,
available: false,
downloading: false,
installing: false,
});
}
} catch (error) {
setStatus({
checking: false,
available: false,
downloading: false,
installing: false,
error: error instanceof Error ? error.message : 'Failed to check for updates',
});
}
};
const downloadAndInstall = async () => {
if (!update) return;
try {
setStatus((prev) => ({ ...prev, downloading: true, error: undefined }));
await update.downloadAndInstall((event) => {
switch (event.event) {
case 'Started':
setStatus((prev) => ({ ...prev, downloading: true }));
break;
case 'Progress':
console.log(`Downloaded ${event.data.chunkLength} bytes`);
break;
case 'Finished':
setStatus((prev) => ({
...prev,
downloading: false,
installing: true,
}));
break;
}
});
await relaunch();
} catch (error) {
setStatus((prev) => ({
...prev,
downloading: false,
installing: false,
error: error instanceof Error ? error.message : 'Failed to install update',
}));
}
};
useEffect(() => {
if (checkOnMount) {
checkForUpdates();
}
}, [checkOnMount]);
return {
status,
checkForUpdates,
downloadAndInstall,
};
}