diff --git a/client/src/components/WelcomeLogo.tsx b/client/src/components/WelcomeLogo.tsx
index 3a52d534..c8fbae34 100644
--- a/client/src/components/WelcomeLogo.tsx
+++ b/client/src/components/WelcomeLogo.tsx
@@ -19,7 +19,15 @@ function useConnectionAddress() {
export const WelcomeLogo = ({className}: {className?: string}) => {
const connectionAddress = useConnectionAddress();
const clientData = useClientData();
-
+ const [updateText, setUpdateText] = useState("");
+ useEffect(() => {
+ window.thorium?.registerUpdateHandler(message => {
+ setUpdateText(message);
+ });
+ return () => {
+ window.thorium?.registerUpdateHandler(() => {});
+ };
+ }, []);
return (
@@ -32,9 +40,16 @@ export const WelcomeLogo = ({className}: {className?: string}) => {
Thorium Nova
-
- Version {packageJson.version}
-
+ {updateText ? (
+ updateText
+ ) : (
+
+ Version {packageJson.version}
+
+ )}
diff --git a/client/src/main.tsx b/client/src/main.tsx
index c389094e..595223aa 100644
--- a/client/src/main.tsx
+++ b/client/src/main.tsx
@@ -13,6 +13,7 @@ declare global {
thorium: {
getAddress: () => Promise
;
getHostSecret: () => Promise;
+ registerUpdateHandler: (handler: (update: string) => void) => void;
};
}
}
diff --git a/desktop/main/electron.ts b/desktop/main/electron.ts
index e1646f54..02e1d5da 100644
--- a/desktop/main/electron.ts
+++ b/desktop/main/electron.ts
@@ -8,6 +8,9 @@ import {
stopThoriumServer,
} from "./helpers/startThoriumServer";
import {ipcHandlers} from "./helpers/ipcHandlers";
+import {autoUpdater} from "electron-updater";
+import {initWin} from "./helpers/autoUpdate";
+
let win: BrowserWindow | null = null;
app.enableSandbox();
@@ -66,7 +69,7 @@ async function createWindow() {
},
show: false,
});
-
+ initWin(win);
win.webContents.setWindowOpenHandler(({url}) => {
shell.openExternal(url);
return {action: "deny"};
@@ -90,6 +93,7 @@ async function createWindow() {
}
app.whenReady().then(() => {
+ autoUpdater.checkForUpdatesAndNotify();
createWindow();
});
diff --git a/desktop/main/helpers/autoUpdate.ts b/desktop/main/helpers/autoUpdate.ts
new file mode 100644
index 00000000..a609f338
--- /dev/null
+++ b/desktop/main/helpers/autoUpdate.ts
@@ -0,0 +1,37 @@
+import {autoUpdater} from "electron-updater";
+import {BrowserWindow} from "electron";
+
+let win: BrowserWindow | null = null;
+export function initWin(newWin: BrowserWindow) {
+ win = newWin;
+}
+function sendStatusToWindow(text: string) {
+ win?.webContents.send("update-message", text);
+}
+autoUpdater.on("checking-for-update", () => {
+ sendStatusToWindow("Checking for update...");
+});
+autoUpdater.on("update-available", info => {
+ sendStatusToWindow("Update available.");
+});
+autoUpdater.on("update-not-available", info => {
+ sendStatusToWindow("");
+});
+autoUpdater.on("error", err => {
+ sendStatusToWindow("Error in auto-updater. " + err);
+});
+autoUpdater.on("download-progress", progressObj => {
+ let log_message = "Download speed: " + progressObj.bytesPerSecond;
+ log_message = log_message + " - Downloaded " + progressObj.percent + "%";
+ log_message =
+ log_message +
+ " (" +
+ progressObj.transferred +
+ "/" +
+ progressObj.total +
+ ")";
+ sendStatusToWindow(log_message);
+});
+autoUpdater.on("update-downloaded", info => {
+ sendStatusToWindow("Update downloaded - restart to apply");
+});
diff --git a/desktop/main/preload.ts b/desktop/main/preload.ts
index 29f58c99..86d896a2 100644
--- a/desktop/main/preload.ts
+++ b/desktop/main/preload.ts
@@ -1,5 +1,10 @@
import {ipcRenderer} from "electron";
+let updateHandler = (message: string) => {};
+ipcRenderer.on("update-message", (event, message) => {
+ updateHandler(message);
+});
+
const thorium = {
getAddress: function () {
return ipcRenderer.invoke("get-address");
@@ -7,6 +12,9 @@ const thorium = {
getHostSecret: function () {
return ipcRenderer.invoke("get-secret");
},
+ registerUpdateHandler: function (handler: typeof updateHandler) {
+ updateHandler = handler;
+ },
};
window.thorium = thorium;
diff --git a/desktop/package.json b/desktop/package.json
index 53ca3658..2297404f 100644
--- a/desktop/package.json
+++ b/desktop/package.json
@@ -4,7 +4,7 @@
"description": "",
"scripts": {
"dev": "",
- "start": "concurrently \"electron-esbuild dev\" \"copy-dir-cli resources ../dist/resources\"",
+ "start": "concurrently \"electron-esbuild dev\" \"npx copy-dir-cli resources ../dist/resources\"",
"build": "electron-esbuild build",
"typecheck": "tsc --noEmit"
},
@@ -19,6 +19,7 @@
"bonjour": "^3.5.0",
"electron-better-ipc": "^2.0.1",
"electron-store": "^8.0.1",
+ "electron-updater": "^5.0.1",
"electron-util": "^0.17.2"
}
}
diff --git a/package-lock.json b/package-lock.json
index 88d0b740..68ad4f7d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -495,6 +495,7 @@
"bonjour": "^3.5.0",
"electron-better-ipc": "^2.0.1",
"electron-store": "^8.0.1",
+ "electron-updater": "^5.0.1",
"electron-util": "^0.17.2"
},
"devDependencies": {
@@ -5161,6 +5162,11 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/semver": {
+ "version": "7.3.9",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz",
+ "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ=="
+ },
"node_modules/@types/stack-utils": {
"version": "2.0.1",
"dev": true,
@@ -6015,7 +6021,6 @@
},
"node_modules/argparse": {
"version": "2.0.1",
- "dev": true,
"license": "Python-2.0"
},
"node_modules/argv-formatter": {
@@ -9222,6 +9227,79 @@
"version": "1.4.18",
"license": "ISC"
},
+ "node_modules/electron-updater": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-5.0.1.tgz",
+ "integrity": "sha512-dNnXPCqYmergXy3jgg4UICuD50Orug9GQe/5xfHy+BE2Fy0icB0QE+y6iQWdCDf7yeONxwMBf4HgIkGG5pIaVg==",
+ "dependencies": {
+ "@types/semver": "^7.3.6",
+ "builder-util-runtime": "9.0.0",
+ "fs-extra": "^10.0.0",
+ "js-yaml": "^4.1.0",
+ "lazy-val": "^1.0.5",
+ "lodash.escaperegexp": "^4.1.2",
+ "lodash.isequal": "^4.5.0",
+ "semver": "^7.3.5"
+ }
+ },
+ "node_modules/electron-updater/node_modules/builder-util-runtime": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.0.0.tgz",
+ "integrity": "sha512-SkpEtSmTkREDHRJnxKEv43aAYp8sYWY8fxYBhGLBLOBIRXeaIp6Kv3lBgSD7uR8jQtC7CA659sqJrpSV6zNvSA==",
+ "dependencies": {
+ "debug": "^4.3.2",
+ "sax": "^1.2.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/electron-updater/node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/electron-updater/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/electron-updater/node_modules/semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/electron-updater/node_modules/universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
"node_modules/electron-util": {
"version": "0.17.2",
"license": "MIT",
@@ -11770,7 +11848,6 @@
},
"node_modules/graceful-fs": {
"version": "4.2.8",
- "devOptional": true,
"license": "ISC"
},
"node_modules/graceful-readlink": {
@@ -15176,7 +15253,6 @@
},
"node_modules/js-yaml": {
"version": "4.1.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
@@ -15562,7 +15638,6 @@
},
"node_modules/lazy-val": {
"version": "1.0.5",
- "dev": true,
"license": "MIT"
},
"node_modules/less": {
@@ -15811,7 +15886,6 @@
},
"node_modules/lodash.escaperegexp": {
"version": "4.1.2",
- "dev": true,
"license": "MIT"
},
"node_modules/lodash.forown": {
@@ -15829,6 +15903,11 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+ },
"node_modules/lodash.ismatch": {
"version": "4.4.0",
"dev": true,
@@ -24126,7 +24205,6 @@
},
"node_modules/sax": {
"version": "1.2.4",
- "devOptional": true,
"license": "ISC"
},
"node_modules/saxes": {
@@ -30354,6 +30432,11 @@
"version": "0.16.2",
"dev": true
},
+ "@types/semver": {
+ "version": "7.3.9",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz",
+ "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ=="
+ },
"@types/stack-utils": {
"version": "2.0.1",
"dev": true
@@ -30877,8 +30960,7 @@
"version": "5.0.1"
},
"argparse": {
- "version": "2.0.1",
- "dev": true
+ "version": "2.0.1"
},
"argv-formatter": {
"version": "1.0.0",
@@ -31780,7 +31862,7 @@
"@dnd-kit/sortable": "^6.0.0",
"@floating-ui/react-dom": "^0.6.0",
"@geckos.io/snapshot-interpolation": "^1.1.0",
- "@headlessui/react": "1.5.0",
+ "@headlessui/react": "^1.5.0",
"@mdx-js/mdx": "^2.0.0-next.9",
"@mdx-js/react": "^1.6.22",
"@msgpack/msgpack": "^2.7.1",
@@ -32808,6 +32890,7 @@
"electron-better-ipc": "^2.0.1",
"electron-esbuild": "^3.0.0",
"electron-store": "^8.0.1",
+ "electron-updater": "^5.0.1",
"electron-util": "^0.17.2"
},
"dependencies": {
@@ -33405,6 +33488,64 @@
"electron-to-chromium": {
"version": "1.4.18"
},
+ "electron-updater": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-5.0.1.tgz",
+ "integrity": "sha512-dNnXPCqYmergXy3jgg4UICuD50Orug9GQe/5xfHy+BE2Fy0icB0QE+y6iQWdCDf7yeONxwMBf4HgIkGG5pIaVg==",
+ "requires": {
+ "@types/semver": "^7.3.6",
+ "builder-util-runtime": "9.0.0",
+ "fs-extra": "^10.0.0",
+ "js-yaml": "^4.1.0",
+ "lazy-val": "^1.0.5",
+ "lodash.escaperegexp": "^4.1.2",
+ "lodash.isequal": "^4.5.0",
+ "semver": "^7.3.5"
+ },
+ "dependencies": {
+ "builder-util-runtime": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.0.0.tgz",
+ "integrity": "sha512-SkpEtSmTkREDHRJnxKEv43aAYp8sYWY8fxYBhGLBLOBIRXeaIp6Kv3lBgSD7uR8jQtC7CA659sqJrpSV6zNvSA==",
+ "requires": {
+ "debug": "^4.3.2",
+ "sax": "^1.2.4"
+ }
+ },
+ "fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^2.0.0"
+ }
+ },
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
+ }
+ }
+ },
"electron-util": {
"version": "0.17.2",
"requires": {
@@ -35060,8 +35201,7 @@
}
},
"graceful-fs": {
- "version": "4.2.8",
- "devOptional": true
+ "version": "4.2.8"
},
"graceful-readlink": {
"version": "1.0.1",
@@ -37304,7 +37444,6 @@
},
"js-yaml": {
"version": "4.1.0",
- "dev": true,
"requires": {
"argparse": "^2.0.1"
}
@@ -37579,8 +37718,7 @@
}
},
"lazy-val": {
- "version": "1.0.5",
- "dev": true
+ "version": "1.0.5"
},
"less": {
"version": "4.1.2",
@@ -37746,8 +37884,7 @@
"dev": true
},
"lodash.escaperegexp": {
- "version": "4.1.2",
- "dev": true
+ "version": "4.1.2"
},
"lodash.forown": {
"version": "4.4.0",
@@ -37761,6 +37898,11 @@
"version": "4.6.0",
"dev": true
},
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+ },
"lodash.ismatch": {
"version": "4.4.0",
"dev": true
@@ -43142,8 +43284,7 @@
}
},
"sax": {
- "version": "1.2.4",
- "devOptional": true
+ "version": "1.2.4"
},
"saxes": {
"version": "5.0.1",