Initial Updater work

This commit is contained in:
Vendicated 2023-04-10 04:11:21 +02:00
parent d1acb0490b
commit fb24f40412
No known key found for this signature in database
GPG key ID: A1DC0CFB5615D905
8 changed files with 123 additions and 13 deletions

View file

@ -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";
const isDev = process.argv.includes("--dev");
@ -36,6 +42,11 @@ await Promise.all([
entryPoints: ["src/preload/index.ts"],
outfile: "dist/js/preload.js"
}),
createContext({
...NodeCommonOpts,
entryPoints: ["src/updater/preload.ts"],
outfile: "dist/js/updaterPreload.js"
}),
createContext({
...CommonOpts,
globalName: "VencordDesktop",
@ -55,8 +66,10 @@ const watch = process.argv.includes("--watch");
if (watch) {
await Promise.all(contexts.map(ctx => ctx.watch()));
} else {
await Promise.all(contexts.map(async ctx => {
await ctx.rebuild();
await ctx.dispose();
}));
await Promise.all(
contexts.map(async ctx => {
await ctx.rebuild();
await ctx.dispose();
})
);
}

View file

@ -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 { join } from "path";
const EXT = process.platform === "win32" ? ".cmd" : "";
const OPTS: SpawnOptions = {
stdio: "inherit",
stdio: "inherit"
};
function spawn(bin: string, args: string[]) {

View file

@ -8,6 +8,7 @@ import "./ipc";
import { app, BrowserWindow } from "electron";
import { join } from "path";
import { checkUpdates } from "updater/main";
import { ICON_PATH } from "../shared/paths";
import { once } from "../shared/utils/once";
@ -40,6 +41,8 @@ if (!app.requestSingleInstanceLock()) {
});
app.whenReady().then(async () => {
checkUpdates();
if (process.platform === "win32") app.setAppUserModelId("dev.vencord.desktop");
else if (process.platform === "darwin") app.dock.setIcon(ICON_PATH);

View file

@ -10,10 +10,20 @@ import { join } from "path";
import { USER_AGENT, VENCORD_FILES_DIR } from "../constants";
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"];
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) {
return simpleGet(API_BASE + endpoint, {
headers: {
@ -24,13 +34,9 @@ export async function githubGet(endpoint: string) {
}
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 = data.assets as Array<{
name: string;
browser_download_url: string;
}>;
const { assets } = JSON.parse(release.toString("utf-8")) as ReleaseData;
await Promise.all(
assets

View file

@ -19,5 +19,7 @@ export const enum IpcEvents {
GET_SETTINGS = "VCD_GET_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
View 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
View 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
View file

@ -0,0 +1,7 @@
<div>hi</div>
<p></p>
<script type="module">
const version = await Updater.getLatestVersion();
document.querySelector("p").textContent = version;
</script>