Initial Updater work
This commit is contained in:
parent
d1acb0490b
commit
fb24f40412
8 changed files with 123 additions and 13 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0
|
||||||
|
* Vencord Desktop, a desktop app aiming to give you a snappier Discord Experience
|
||||||
|
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||||
|
*/
|
||||||
|
|
||||||
import { BuildContext, BuildOptions, context } from "esbuild";
|
import { BuildContext, BuildOptions, context } from "esbuild";
|
||||||
|
|
||||||
const isDev = process.argv.includes("--dev");
|
const isDev = process.argv.includes("--dev");
|
||||||
|
@ -36,6 +42,11 @@ await Promise.all([
|
||||||
entryPoints: ["src/preload/index.ts"],
|
entryPoints: ["src/preload/index.ts"],
|
||||||
outfile: "dist/js/preload.js"
|
outfile: "dist/js/preload.js"
|
||||||
}),
|
}),
|
||||||
|
createContext({
|
||||||
|
...NodeCommonOpts,
|
||||||
|
entryPoints: ["src/updater/preload.ts"],
|
||||||
|
outfile: "dist/js/updaterPreload.js"
|
||||||
|
}),
|
||||||
createContext({
|
createContext({
|
||||||
...CommonOpts,
|
...CommonOpts,
|
||||||
globalName: "VencordDesktop",
|
globalName: "VencordDesktop",
|
||||||
|
@ -55,8 +66,10 @@ const watch = process.argv.includes("--watch");
|
||||||
if (watch) {
|
if (watch) {
|
||||||
await Promise.all(contexts.map(ctx => ctx.watch()));
|
await Promise.all(contexts.map(ctx => ctx.watch()));
|
||||||
} else {
|
} else {
|
||||||
await Promise.all(contexts.map(async ctx => {
|
await Promise.all(
|
||||||
|
contexts.map(async ctx => {
|
||||||
await ctx.rebuild();
|
await ctx.rebuild();
|
||||||
await ctx.dispose();
|
await ctx.dispose();
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0
|
||||||
|
* Vencord Desktop, a desktop app aiming to give you a snappier Discord Experience
|
||||||
|
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||||
|
*/
|
||||||
|
|
||||||
import { spawn as cpSpawn, SpawnOptions } from "child_process";
|
import { spawn as cpSpawn, SpawnOptions } from "child_process";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
|
|
||||||
const EXT = process.platform === "win32" ? ".cmd" : "";
|
const EXT = process.platform === "win32" ? ".cmd" : "";
|
||||||
|
|
||||||
const OPTS: SpawnOptions = {
|
const OPTS: SpawnOptions = {
|
||||||
stdio: "inherit",
|
stdio: "inherit"
|
||||||
};
|
};
|
||||||
|
|
||||||
function spawn(bin: string, args: string[]) {
|
function spawn(bin: string, args: string[]) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import "./ipc";
|
||||||
|
|
||||||
import { app, BrowserWindow } from "electron";
|
import { app, BrowserWindow } from "electron";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
|
import { checkUpdates } from "updater/main";
|
||||||
|
|
||||||
import { ICON_PATH } from "../shared/paths";
|
import { ICON_PATH } from "../shared/paths";
|
||||||
import { once } from "../shared/utils/once";
|
import { once } from "../shared/utils/once";
|
||||||
|
@ -40,6 +41,8 @@ if (!app.requestSingleInstanceLock()) {
|
||||||
});
|
});
|
||||||
|
|
||||||
app.whenReady().then(async () => {
|
app.whenReady().then(async () => {
|
||||||
|
checkUpdates();
|
||||||
|
|
||||||
if (process.platform === "win32") app.setAppUserModelId("dev.vencord.desktop");
|
if (process.platform === "win32") app.setAppUserModelId("dev.vencord.desktop");
|
||||||
else if (process.platform === "darwin") app.dock.setIcon(ICON_PATH);
|
else if (process.platform === "darwin") app.dock.setIcon(ICON_PATH);
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,20 @@ import { join } from "path";
|
||||||
import { USER_AGENT, VENCORD_FILES_DIR } from "../constants";
|
import { USER_AGENT, VENCORD_FILES_DIR } from "../constants";
|
||||||
import { downloadFile, simpleGet } from "./http";
|
import { downloadFile, simpleGet } from "./http";
|
||||||
|
|
||||||
const API_BASE = "https://api.github.com/repos/Vendicated/Vencord";
|
const API_BASE = "https://api.github.com";
|
||||||
|
|
||||||
const FILES_TO_DOWNLOAD = ["vencordDesktopMain.js", "preload.js", "vencordDesktopRenderer.js", "renderer.css"];
|
const FILES_TO_DOWNLOAD = ["vencordDesktopMain.js", "preload.js", "vencordDesktopRenderer.js", "renderer.css"];
|
||||||
|
|
||||||
|
export interface ReleaseData {
|
||||||
|
name: string;
|
||||||
|
tag_name: string;
|
||||||
|
html_url: string;
|
||||||
|
assets: Array<{
|
||||||
|
name: string;
|
||||||
|
browser_download_url: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
export async function githubGet(endpoint: string) {
|
export async function githubGet(endpoint: string) {
|
||||||
return simpleGet(API_BASE + endpoint, {
|
return simpleGet(API_BASE + endpoint, {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -24,13 +34,9 @@ export async function githubGet(endpoint: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function downloadVencordFiles() {
|
export async function downloadVencordFiles() {
|
||||||
const release = await githubGet("/releases/latest");
|
const release = await githubGet("/repos/Vendicated/Vencord/releases/latest");
|
||||||
|
|
||||||
const data = JSON.parse(release.toString("utf-8"));
|
const { assets } = JSON.parse(release.toString("utf-8")) as ReleaseData;
|
||||||
const assets = data.assets as Array<{
|
|
||||||
name: string;
|
|
||||||
browser_download_url: string;
|
|
||||||
}>;
|
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
assets
|
assets
|
||||||
|
|
|
@ -19,5 +19,7 @@ export const enum IpcEvents {
|
||||||
GET_SETTINGS = "VCD_GET_SETTINGS",
|
GET_SETTINGS = "VCD_GET_SETTINGS",
|
||||||
SET_SETTINGS = "VCD_SET_SETTINGS",
|
SET_SETTINGS = "VCD_SET_SETTINGS",
|
||||||
|
|
||||||
SELECT_VENCORD_DIR = "VCD_SELECT_VENCORD_DIR"
|
SELECT_VENCORD_DIR = "VCD_SELECT_VENCORD_DIR",
|
||||||
|
|
||||||
|
UPDATER_GET_LATEST_VERSION = "VCD_UPDATER_GET_LATEST_VERSION"
|
||||||
}
|
}
|
||||||
|
|
61
src/updater/main.ts
Normal file
61
src/updater/main.ts
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0
|
||||||
|
* Vencord Desktop, a desktop app aiming to give you a snappier Discord Experience
|
||||||
|
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { app, BrowserWindow, ipcMain } from "electron";
|
||||||
|
import { githubGet, ReleaseData } from "main/utils/vencordLoader";
|
||||||
|
import { join } from "path";
|
||||||
|
import { IpcEvents } from "shared/IpcEvents";
|
||||||
|
import { STATIC_DIR } from "shared/paths";
|
||||||
|
|
||||||
|
let latestVersion: string;
|
||||||
|
|
||||||
|
ipcMain.handle(IpcEvents.UPDATER_GET_LATEST_VERSION, () => latestVersion);
|
||||||
|
|
||||||
|
function isOutdated(oldVersion: string, newVersion: string) {
|
||||||
|
const oldParts = oldVersion.split(".");
|
||||||
|
const newParts = newVersion.split(".");
|
||||||
|
|
||||||
|
if (oldParts.length !== newParts.length)
|
||||||
|
throw new Error(`Incompatible version strings (old: ${oldVersion}, new: ${newVersion})`);
|
||||||
|
|
||||||
|
for (let i = 0; i < oldParts.length; i++) {
|
||||||
|
const oldPart = Number(oldParts[i]);
|
||||||
|
const newPart = Number(newParts[i]);
|
||||||
|
|
||||||
|
if (isNaN(oldPart) || isNaN(newPart))
|
||||||
|
throw new Error(`Invalid version string (old: ${oldVersion}, new: ${newVersion})`);
|
||||||
|
|
||||||
|
if (oldPart < newPart) return true;
|
||||||
|
if (oldPart > newPart) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function checkUpdates() {
|
||||||
|
if (IS_DEV) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const raw = await githubGet("/repos/Vencord/Desktop/releases/latest");
|
||||||
|
const { tag_name } = JSON.parse(raw.toString("utf-8")) as ReleaseData;
|
||||||
|
|
||||||
|
const oldVersion = app.getVersion();
|
||||||
|
const newVersion = (latestVersion = tag_name.replace(/^v/, ""));
|
||||||
|
if (isOutdated(oldVersion, newVersion)) openNewUpdateWindow();
|
||||||
|
} catch (e) {
|
||||||
|
console.error("AppUpdater: Failed to check for updates\n", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openNewUpdateWindow() {
|
||||||
|
const win = new BrowserWindow({
|
||||||
|
webPreferences: {
|
||||||
|
preload: join(__dirname, "updaterPreload.js")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
win.loadFile(join(STATIC_DIR, "updater.html"));
|
||||||
|
}
|
12
src/updater/preload.ts
Normal file
12
src/updater/preload.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0
|
||||||
|
* Vencord Desktop, a desktop app aiming to give you a snappier Discord Experience
|
||||||
|
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { contextBridge, ipcRenderer } from "electron";
|
||||||
|
import { IpcEvents } from "shared/IpcEvents";
|
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld("Updater", {
|
||||||
|
getLatestVersion: () => ipcRenderer.invoke(IpcEvents.UPDATER_GET_LATEST_VERSION)
|
||||||
|
});
|
7
static/updater.html
Normal file
7
static/updater.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<div>hi</div>
|
||||||
|
<p></p>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
const version = await Updater.getLatestVersion();
|
||||||
|
document.querySelector("p").textContent = version;
|
||||||
|
</script>
|
Reference in a new issue