diff --git a/interface.d.ts b/interface.d.ts index 265b6bf2f..56535d972 100644 --- a/interface.d.ts +++ b/interface.d.ts @@ -63,6 +63,9 @@ export interface IElectronAPI { kittycad: (access: string, args: any) => any listMachines: () => Promise getMachineApiIp: () => Promise + onUpdateDownloadStart: ( + callback: (value: { version: string }) => void + ) => Electron.IpcRenderer onUpdateDownloaded: ( callback: (value: string) => void ) => Electron.IpcRenderer diff --git a/src/index.tsx b/src/index.tsx index 6e9b4f4a7..c19e8e23a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -8,6 +8,7 @@ import ModalContainer from 'react-modal-promise' import { isDesktop } from 'lib/isDesktop' import { AppStreamProvider } from 'AppState' import { ToastUpdate } from 'components/ToastUpdate' +import { AUTO_UPDATER_TOAST_ID } from 'lib/constants' // uncomment for xstate inspector // import { DEV } from 'env' @@ -53,7 +54,15 @@ root.render( // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals() -isDesktop() && +if (isDesktop()) { + // List for update download progress to begin + // to show a loading toast. + // TODO: Make use of the progress value in future. Currently this fires only once. + window.electron.onUpdateDownloadProgress(({ version }) => { + const message = `Downloading update (${version})...` + console.log(message) + toast.loading(message, { id: AUTO_UPDATER_TOAST_ID }) + }) window.electron.onUpdateDownloaded((version: string) => { const message = `A new update (${version}) was downloaded and will be available next time you open the app.` console.log(message) @@ -64,6 +73,7 @@ isDesktop() && window.electron.appRestart() }, }), - { duration: 30000 } + { duration: 30000, id: AUTO_UPDATER_TOAST_ID } ) }) +} diff --git a/src/lib/constants.ts b/src/lib/constants.ts index e29c815f4..540c79734 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -102,3 +102,6 @@ export const KCL_SAMPLES_MANIFEST_URLS = { 'https://raw.githubusercontent.com/KittyCAD/kcl-samples/main/manifst.json', localFallback: '/kcl-samples-manifest-fallback.json', } as const + +/** Toast id for the app auto-updater toast */ +export const AUTO_UPDATER_TOAST_ID = 'auto-updater-toast' diff --git a/src/main.ts b/src/main.ts index c561910b0..e1be4b3f5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -263,6 +263,19 @@ app.on('ready', () => { autoUpdater.on('update-available', (info) => { console.log('update-available', info) + autoUpdater.prependOnceListener('download-progress', (progress) => { + // For now, we'll send the version to the loading toast start. + console.log('update-download-start', { + version: info.version, + }) + mainWindow?.webContents.send('update-download-start', progress) + }) + + autoUpdater.on('download-progress', (progress) => { + // TODO: in a future PR (https://github.com/KittyCAD/modeling-app/issues/3994) + // send this data to mainWindow to show a progress bar for the download. + console.log('download-progress', progress) + }) }) autoUpdater.on('update-downloaded', (info) => { diff --git a/src/preload.ts b/src/preload.ts index 2d5e3eec4..c87da4243 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -15,6 +15,10 @@ const startDeviceFlow = (host: string): Promise => ipcRenderer.invoke('startDeviceFlow', host) const loginWithDeviceFlow = (): Promise => ipcRenderer.invoke('loginWithDeviceFlow') +const onUpdateDownloadStart = ( + callback: (value: { version: string; }) => void +) => + ipcRenderer.on('update-download-start', (_event, value) => callback(value)) const onUpdateDownloaded = (callback: (value: string) => void) => ipcRenderer.on('update-downloaded', (_event, value) => callback(value)) const appRestart = () => ipcRenderer.invoke('app.restart') @@ -126,6 +130,7 @@ contextBridge.exposeInMainWorld('electron', { kittycad, listMachines, getMachineApiIp, + onUpdateDownloadStart, onUpdateDownloaded, appRestart, })