Add auto updater

This commit is contained in:
2026-03-10 23:38:57 +01:00
parent e8e5c24600
commit c3fbd7d4fe
20 changed files with 2272 additions and 14 deletions

View File

@@ -3,6 +3,7 @@ import { Command, Query } from './cqrs/types';
const LINUX_SCREEN_SHARE_MONITOR_AUDIO_CHUNK_CHANNEL = 'linux-screen-share-monitor-audio-chunk';
const LINUX_SCREEN_SHARE_MONITOR_AUDIO_ENDED_CHANNEL = 'linux-screen-share-monitor-audio-ended';
const AUTO_UPDATE_STATE_CHANGED_CHANNEL = 'auto-update-state-changed';
export interface LinuxScreenShareAudioRoutingInfo {
available: boolean;
@@ -40,6 +41,48 @@ export interface ClipboardFilePayload {
path?: string;
}
export type DesktopUpdateServerVersionStatus = 'unknown' | 'reported' | 'missing' | 'unavailable';
export interface DesktopUpdateServerContext {
manifestUrls: string[];
serverVersion: string | null;
serverVersionStatus: DesktopUpdateServerVersionStatus;
}
export interface DesktopUpdateState {
autoUpdateMode: 'auto' | 'off' | 'version';
availableVersions: string[];
configuredManifestUrls: string[];
currentVersion: string;
defaultManifestUrls: string[];
isSupported: boolean;
lastCheckedAt: number | null;
latestVersion: string | null;
manifestUrl: string | null;
manifestUrls: string[];
minimumServerVersion: string | null;
preferredVersion: string | null;
restartRequired: boolean;
serverBlocked: boolean;
serverBlockMessage: string | null;
serverVersion: string | null;
serverVersionStatus: DesktopUpdateServerVersionStatus;
status:
| 'idle'
| 'disabled'
| 'checking'
| 'downloading'
| 'up-to-date'
| 'restart-required'
| 'unsupported'
| 'no-manifest'
| 'target-unavailable'
| 'target-older-than-installed'
| 'error';
statusMessage: string | null;
targetVersion: string | null;
}
export interface ElectronAPI {
minimizeWindow: () => void;
maximizeWindow: () => void;
@@ -56,12 +99,29 @@ export interface ElectronAPI {
onLinuxScreenShareMonitorAudioEnded: (listener: (payload: LinuxScreenShareMonitorAudioEndedPayload) => void) => () => void;
getAppDataPath: () => Promise<string>;
getDesktopSettings: () => Promise<{
autoUpdateMode: 'auto' | 'off' | 'version';
hardwareAcceleration: boolean;
manifestUrls: string[];
preferredVersion: string | null;
runtimeHardwareAcceleration: boolean;
restartRequired: boolean;
}>;
setDesktopSettings: (patch: { hardwareAcceleration?: boolean }) => Promise<{
getAutoUpdateState: () => Promise<DesktopUpdateState>;
configureAutoUpdateContext: (context: Partial<DesktopUpdateServerContext>) => Promise<DesktopUpdateState>;
checkForAppUpdates: () => Promise<DesktopUpdateState>;
restartToApplyUpdate: () => Promise<boolean>;
onAutoUpdateStateChanged: (listener: (state: DesktopUpdateState) => void) => () => void;
setDesktopSettings: (patch: {
autoUpdateMode?: 'auto' | 'off' | 'version';
hardwareAcceleration?: boolean;
manifestUrls?: string[];
preferredVersion?: string | null;
vaapiVideoEncode?: boolean;
}) => Promise<{
autoUpdateMode: 'auto' | 'off' | 'version';
hardwareAcceleration: boolean;
manifestUrls: string[];
preferredVersion: string | null;
runtimeHardwareAcceleration: boolean;
restartRequired: boolean;
}>;
@@ -121,6 +181,21 @@ const electronAPI: ElectronAPI = {
},
getAppDataPath: () => ipcRenderer.invoke('get-app-data-path'),
getDesktopSettings: () => ipcRenderer.invoke('get-desktop-settings'),
getAutoUpdateState: () => ipcRenderer.invoke('get-auto-update-state'),
configureAutoUpdateContext: (context) => ipcRenderer.invoke('configure-auto-update-context', context),
checkForAppUpdates: () => ipcRenderer.invoke('check-for-app-updates'),
restartToApplyUpdate: () => ipcRenderer.invoke('restart-to-apply-update'),
onAutoUpdateStateChanged: (listener) => {
const wrappedListener = (_event: Electron.IpcRendererEvent, state: DesktopUpdateState) => {
listener(state);
};
ipcRenderer.on(AUTO_UPDATE_STATE_CHANGED_CHANNEL, wrappedListener);
return () => {
ipcRenderer.removeListener(AUTO_UPDATE_STATE_CHANGED_CHANNEL, wrappedListener);
};
},
setDesktopSettings: (patch) => ipcRenderer.invoke('set-desktop-settings', patch),
relaunchApp: () => ipcRenderer.invoke('relaunch-app'),
readClipboardFiles: () => ipcRenderer.invoke('read-clipboard-files'),