diff --git a/.github/workflows/meta.yml b/.github/workflows/meta.yml index 5287c23..2ebc5a3 100644 --- a/.github/workflows/meta.yml +++ b/.github/workflows/meta.yml @@ -11,28 +11,28 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 # Install pnpm using packageManager key in package.json - - name: Use Node.js 18.18.2 - uses: actions/setup-node@v3 - with: - node-version: 18.18.2 + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 - - name: Install dependencies - run: pnpm i + - name: Install dependencies + run: pnpm i - - name: Update metainfo - run: pnpm updateMeta + - name: Update metainfo + run: pnpm updateMeta - - name: Commit and merge in changes - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git checkout -b ci/meta-update - git add meta/dev.vencord.Vesktop.metainfo.xml - git commit -m "Insert release changes for ${{ github.event.release.tag_name }}" - git push origin ci/meta-update - gh pr create -B main -H ci/meta-update -t "Metainfo for ${{ github.event.release.tag_name }}" -b "This PR updates the metainfo for release ${{ github.event.release.tag_name }}. @lewisakura @Vendicated" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + - name: Commit and merge in changes + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git checkout -b ci/meta-update + git add meta/dev.vencord.Vesktop.metainfo.xml + git commit -m "Insert release changes for ${{ github.event.release.tag_name }}" + git push origin ci/meta-update + gh pr create -B main -H ci/meta-update -t "Metainfo for ${{ github.event.release.tag_name }}" -b "This PR updates the metainfo for release ${{ github.event.release.tag_name }}. @lewisakura @Vendicated" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6968b73..9de1bc5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,13 +22,13 @@ jobs: platform: windows steps: - - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 # Install pnpm using packageManager key in package.json - - name: Use Node.js 18.18.2 - uses: actions/setup-node@v3 + - name: Use Node.js 20 + uses: actions/setup-node@v4 with: - node-version: 18.18.2 + node-version: 20 cache: "pnpm" - name: Install dependencies @@ -43,7 +43,7 @@ jobs: pnpm electron-builder --${{ matrix.platform }} --publish always env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - + - name: Run Electron Builder if: ${{ matrix.platform == 'mac' }} run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6d88280..daa62a5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,13 +11,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 # Install pnpm using packageManager key in package.json - - name: Use Node.js 18.18.2 - uses: actions/setup-node@v3 + - name: Use Node.js 20 + uses: actions/setup-node@v4 with: - node-version: 18.18.2 + node-version: 20 cache: "pnpm" - name: Install dependencies diff --git a/README.md b/README.md index 8ea22d2..af62292 100644 --- a/README.md +++ b/README.md @@ -21,15 +21,14 @@ Vesktop is a custom Discord desktop app If you don't know the difference, pick the Installer. -- [Installer](https://vencord.dev/download/vesktop/amd64/windows) -- [Portable](https://vencord.dev/download/vesktop/amd64/windows-portable) +- [Installer](https://vencord.dev/download/vesktop/universal/windows) +- Portable: + - [x64 / amd64](https://vencord.dev/download/vesktop/amd64/windows-portable) + - [arm64](https://vencord.dev/download/vesktop/arm64/windows-portable) ### Mac -If you don't know the difference, pick the Intel build. - -- [Intel build (amd64)](https://vencord.dev/download/vesktop/amd64/dmg) -- [Apple Silicon (arm64)](https://vencord.dev/download/vesktop/arm64/dmg) +[Vesktop.dmg](https://vencord.dev/download/vesktop/universal/dmg) ### Linux diff --git a/meta/dev.vencord.Vesktop.metainfo.xml b/meta/dev.vencord.Vesktop.metainfo.xml index 889b9fc..853d520 100644 --- a/meta/dev.vencord.Vesktop.metainfo.xml +++ b/meta/dev.vencord.Vesktop.metainfo.xml @@ -28,6 +28,34 @@ + + https://github.com/Vencord/Vesktop/releases/tag/v1.5.3 + +

Features

+
    +
  • added arm64 Windows support
  • +
  • windows & macOS builds are now universal
  • +
  • added option to configure spellcheck languages
  • +
  • will auto-update from now on
  • +
  • updated electron to 31 & Chromium to 126
  • +
  • macOS: Added customized dmg background by @khcrysalis
  • +
  • Windows Portable: store settings in portable folder by @MrGarlic1
  • +
  • linux audioshare: added granular selection, more options, better ui by @Curve
  • +
  • changed default screen-sharing quality to 720p 30 FPS by @Tiagoquix
  • +
+

Fixes

+
    +
  • macOS: Added workaround for making things in draggable area clickable by @HAHALOSAH
  • +
  • fixed Screenshare UI for non-linux systems by @PolisanTheEasyNick
  • +
  • fixed opening on screen that was disconnected by @MrGarlic1
  • +
  • mac: hide native window controls with custom titlebar enabled by @MrGarlic1
  • +
  • fixed some broken patches by @D3SOX
  • +
  • fixed framerate in constraints by @kittykel
  • +
  • fixed some first launch switches not applying
  • +
  • fixed potential sandbox escape via custom vencord location
  • +
+
+
https://github.com/Vencord/Vesktop/releases/tag/v1.5.2 @@ -182,7 +210,7 @@ https://github.com/Vencord/Vesktop InstantMessaging - AudioVideo + Network pointing diff --git a/package.json b/package.json index 91554bc..3e4f73e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vesktop", - "version": "1.5.2", + "version": "1.5.3", "private": true, "description": "", "keywords": [], @@ -24,7 +24,8 @@ "updateMeta": "tsx scripts/utils/updateMeta.mts" }, "dependencies": { - "arrpc": "github:OpenAsar/arrpc#c62ec6a04c8d870530aa6944257fe745f6c59a24" + "arrpc": "github:OpenAsar/arrpc#c62ec6a04c8d870530aa6944257fe745f6c59a24", + "electron-updater": "^6.2.1" }, "optionalDependencies": { "@vencord/venmic": "^6.1.0" @@ -37,7 +38,7 @@ "@typescript-eslint/parser": "^7.2.0", "@vencord/types": "^1.8.4", "dotenv": "^16.4.5", - "electron": "^31.0.1", + "electron": "^31.1.0", "electron-builder": "^24.13.3", "esbuild": "^0.20.1", "eslint": "^8.57.0", @@ -65,6 +66,7 @@ "productName": "Vesktop", "files": [ "!*", + "!node_modules", "dist/js", "static", "package.json", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9cbb7be..ea1758f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,6 +16,9 @@ importers: arrpc: specifier: github:OpenAsar/arrpc#c62ec6a04c8d870530aa6944257fe745f6c59a24 version: https://codeload.github.com/OpenAsar/arrpc/tar.gz/c62ec6a04c8d870530aa6944257fe745f6c59a24(patch_hash=biyukfa6dww2wxujy4eyvkhrti) + electron-updater: + specifier: ^6.2.1 + version: 6.2.1 optionalDependencies: '@vencord/venmic': specifier: ^6.1.0 @@ -43,8 +46,8 @@ importers: specifier: ^16.4.5 version: 16.4.5 electron: - specifier: ^31.0.1 - version: 31.0.1 + specifier: ^31.1.0 + version: 31.1.0 electron-builder: specifier: ^24.13.3 version: 24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) @@ -429,6 +432,7 @@ packages: '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} @@ -436,6 +440,7 @@ packages: '@humanwhocodes/object-schema@2.0.2': resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + deprecated: Use @eslint/object-schema instead '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} @@ -1085,8 +1090,11 @@ packages: electron-publish@24.13.1: resolution: {integrity: sha512-2ZgdEqJ8e9D17Hwp5LEq5mLQPjqU3lv/IALvgp+4W8VeNhryfGhYEQC/PgDPMrnWUp+l60Ou5SJLsu+k4mhQ8A==} - electron@31.0.1: - resolution: {integrity: sha512-2eBcp4iqLkTsml6mMq+iqrS5u3kJ/2mpOLP7Mj7lo0uNK3OyfNqRS9z1ArsHjBF2/HV250Te/O9nKrwQRTX/+g==} + electron-updater@6.2.1: + resolution: {integrity: sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==} + + electron@31.1.0: + resolution: {integrity: sha512-TBOwqLxSxnx6+pH6GMri7R3JPH2AkuGJHfWZS0p1HsmN+Qr1T9b0IRJnnehSd/3NZAmAre4ft9Ljec7zjyKFJA==} engines: {node: '>= 12.20.55'} hasBin: true @@ -1796,9 +1804,15 @@ packages: lodash.difference@4.5.0: resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + lodash.flatten@4.4.0: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} @@ -2379,6 +2393,9 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + tiny-typed-emitter@2.1.0: + resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==} + tmp-promise@3.0.3: resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} @@ -3659,7 +3676,20 @@ snapshots: transitivePeerDependencies: - supports-color - electron@31.0.1: + electron-updater@6.2.1: + dependencies: + builder-util-runtime: 9.2.4 + fs-extra: 10.1.0 + js-yaml: 4.1.0 + lazy-val: 1.0.5 + lodash.escaperegexp: 4.1.2 + lodash.isequal: 4.5.0 + semver: 7.6.0 + tiny-typed-emitter: 2.1.0 + transitivePeerDependencies: + - supports-color + + electron@31.1.0: dependencies: '@electron/get': 2.0.3 '@types/node': 20.11.26 @@ -4520,8 +4550,12 @@ snapshots: lodash.difference@4.5.0: {} + lodash.escaperegexp@4.1.2: {} + lodash.flatten@4.4.0: {} + lodash.isequal@4.5.0: {} + lodash.isplainobject@4.0.6: {} lodash.merge@4.6.2: {} @@ -5133,6 +5167,8 @@ snapshots: text-table@0.2.0: {} + tiny-typed-emitter@2.1.0: {} + tmp-promise@3.0.3: dependencies: tmp: 0.2.3 diff --git a/scripts/build/build.mts b/scripts/build/build.mts index 27f45cc..243381b 100644 --- a/scripts/build/build.mts +++ b/scripts/build/build.mts @@ -63,12 +63,6 @@ await Promise.all([ outfile: "dist/js/preload.js", footer: { js: "//# sourceURL=VCDPreload" } }), - createContext({ - ...NodeCommonOpts, - entryPoints: ["src/updater/preload.ts"], - outfile: "dist/js/updaterPreload.js", - footer: { js: "//# sourceURL=VCDUpdaterPreload" } - }), createContext({ ...CommonOpts, globalName: "Vesktop", diff --git a/src/main/constants.ts b/src/main/constants.ts index 1bce303..40d91a5 100644 --- a/src/main/constants.ts +++ b/src/main/constants.ts @@ -37,7 +37,8 @@ if (existsSync(LEGACY_DATA_DIR)) { console.error("Migration failed", e); } } -app.setPath("sessionData", join(DATA_DIR, "sessionData")); +const SESSION_DATA_DIR = join(DATA_DIR, "sessionData"); +app.setPath("sessionData", SESSION_DATA_DIR); export const VENCORD_SETTINGS_DIR = join(DATA_DIR, "settings"); export const VENCORD_QUICKCSS_FILE = join(VENCORD_SETTINGS_DIR, "quickCss.css"); @@ -47,7 +48,8 @@ export const VENCORD_THEMES_DIR = join(DATA_DIR, "themes"); // needs to be inline require because of circular dependency // as otherwise "DATA_DIR" (which is used by ./settings) will be uninitialised export const VENCORD_FILES_DIR = - (require("./settings") as typeof import("./settings")).Settings.store.vencordDir || join(DATA_DIR, "vencordDist"); + (require("./settings") as typeof import("./settings")).State.store.vencordDir || + join(SESSION_DATA_DIR, "vencordFiles"); export const USER_AGENT = `Vesktop/${app.getVersion()} (https://github.com/Vencord/Vesktop)`; @@ -60,10 +62,10 @@ export const DEFAULT_HEIGHT = 720; export const DISCORD_HOSTNAMES = ["discord.com", "canary.discord.com", "ptb.discord.com"]; const BrowserUserAgents = { - darwin: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", - linux: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", + darwin: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36", + linux: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36", windows: - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" }; export const BrowserUserAgent = BrowserUserAgents[process.platform] || BrowserUserAgents.windows; diff --git a/src/main/firstLaunch.ts b/src/main/firstLaunch.ts index d1bbceb..dee4882 100644 --- a/src/main/firstLaunch.ts +++ b/src/main/firstLaunch.ts @@ -18,11 +18,11 @@ import { Settings, State } from "./settings"; import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally"; interface Data { - minimizeToTray: boolean; discordBranch: "stable" | "canary" | "ptb"; - autoStart: boolean; - importSettings: boolean; - richPresence: boolean; + minimizeToTray?: "on"; + autoStart?: "on"; + importSettings?: "on"; + richPresence?: "on"; } export function createFirstLaunchTour() { @@ -44,10 +44,11 @@ export function createFirstLaunchTour() { if (!msg.startsWith("form:")) return; const data = JSON.parse(msg.slice(5)) as Data; + console.log(data); State.store.firstLaunch = false; - Settings.store.minimizeToTray = data.minimizeToTray; Settings.store.discordBranch = data.discordBranch; - Settings.store.arRPC = data.richPresence; + Settings.store.minimizeToTray = !!data.minimizeToTray; + Settings.store.arRPC = !!data.richPresence; if (data.autoStart) autoStart.enable(); diff --git a/src/main/index.ts b/src/main/index.ts index d5bb626..175eff5 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -7,7 +7,7 @@ import "./ipc"; import { app, BrowserWindow, nativeTheme } from "electron"; -import { checkUpdates } from "updater/main"; +import { autoUpdater } from "electron-updater"; import { DATA_DIR } from "./constants"; import { createFirstLaunchTour } from "./firstLaunch"; @@ -19,6 +19,8 @@ import { isDeckGameMode } from "./utils/steamOS"; if (IS_DEV) { require("source-map-support").install(); +} else { + autoUpdater.checkForUpdatesAndNotify(); } // Make the Vencord files use our DATA_DIR @@ -84,7 +86,6 @@ function init() { }); app.whenReady().then(async () => { - checkUpdates(); if (process.platform === "win32") app.setAppUserModelId("dev.vencord.vesktop"); registerScreenShareHandler(); diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 237efe0..6e04085 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -19,7 +19,7 @@ import { setBadgeCount } from "./appBadge"; import { autoStart } from "./autoStart"; import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants"; import { mainWin } from "./mainWindow"; -import { Settings } from "./settings"; +import { Settings, State } from "./settings"; import { handle, handleSync } from "./utils/ipcWrappers"; import { PopoutWindows } from "./utils/popout"; import { isDeckGameMode, showGamePage } from "./utils/steamOS"; @@ -105,7 +105,14 @@ handle(IpcEvents.SPELLCHECK_ADD_TO_DICTIONARY, (e, word: string) => { e.sender.session.addWordToSpellCheckerDictionary(word); }); -handle(IpcEvents.SELECT_VENCORD_DIR, async () => { +handleSync(IpcEvents.GET_VENCORD_DIR, e => (e.returnValue = State.store.vencordDir)); + +handle(IpcEvents.SELECT_VENCORD_DIR, async (_e, value?: null) => { + if (value === null) { + delete State.store.vencordDir; + return "ok"; + } + const res = await dialog.showOpenDialog(mainWin!, { properties: ["openDirectory"] }); @@ -114,7 +121,9 @@ handle(IpcEvents.SELECT_VENCORD_DIR, async () => { const dir = res.filePaths[0]; if (!isValidVencordInstall(dir)) return "invalid"; - return dir; + State.store.vencordDir = dir; + + return "ok"; }); handle(IpcEvents.SET_BADGE_COUNT, (_, count: number) => setBadgeCount(count)); diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 5bbbb61..d860b37 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -91,7 +91,7 @@ function initTray(win: BrowserWindow) { click: createAboutWindow }, { - label: "Update Vencord", + label: "Repair Vencord", async click() { await downloadVencordFiles(); app.relaunch(); @@ -108,14 +108,14 @@ function initTray(win: BrowserWindow) { type: "separator" }, { - label: "Relaunch", + label: "Restart", click() { app.relaunch(); app.quit(); } }, { - label: "Quit Vesktop", + label: "Quit", click() { isQuitting = true; app.quit(); diff --git a/src/main/settings.ts b/src/main/settings.ts index f2c1b80..b2aeea9 100644 --- a/src/main/settings.ts +++ b/src/main/settings.ts @@ -41,14 +41,7 @@ export const VencordSettings = loadSettings(VENCORD_SETTINGS_FILE, "Vencord if (Object.hasOwn(Settings.plain, "firstLaunch") && !existsSync(STATE_FILE)) { console.warn("legacy state in settings.json detected. migrating to state.json"); const state = {} as TState; - for (const prop of [ - "firstLaunch", - "maximized", - "minimized", - "skippedUpdate", - "steamOSLayoutVersion", - "windowBounds" - ] as const) { + for (const prop of ["firstLaunch", "maximized", "minimized", "steamOSLayoutVersion", "windowBounds"] as const) { state[prop] = Settings.plain[prop]; delete Settings.plain[prop]; } diff --git a/src/main/utils/vencordLoader.ts b/src/main/utils/vencordLoader.ts index 1bac37a..c0bac6a 100644 --- a/src/main/utils/vencordLoader.ts +++ b/src/main/utils/vencordLoader.ts @@ -4,7 +4,8 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ -import { existsSync, mkdirSync } from "fs"; +import { mkdirSync } from "fs"; +import { access, constants as FsConstants } from "fs/promises"; import { join } from "path"; import { USER_AGENT, VENCORD_FILES_DIR } from "../constants"; @@ -56,12 +57,18 @@ export async function downloadVencordFiles() { ); } -export function isValidVencordInstall(dir: string) { - return FILES_TO_DOWNLOAD.every(f => existsSync(join(dir, f))); +const existsAsync = (path: string) => + access(path, FsConstants.F_OK) + .then(() => true) + .catch(() => false); + +export async function isValidVencordInstall(dir: string) { + return Promise.all(FILES_TO_DOWNLOAD.map(f => existsAsync(join(dir, f)))).then(arr => !arr.includes(false)); } export async function ensureVencordFiles() { - if (isValidVencordInstall(VENCORD_FILES_DIR)) return; + if (await isValidVencordInstall(VENCORD_FILES_DIR)) return; + mkdirSync(VENCORD_FILES_DIR, { recursive: true }); await downloadVencordFiles(); diff --git a/src/preload/VesktopNative.ts b/src/preload/VesktopNative.ts index 6bc9f9d..5f93cfe 100644 --- a/src/preload/VesktopNative.ts +++ b/src/preload/VesktopNative.ts @@ -7,7 +7,6 @@ import { Node } from "@vencord/venmic"; import { ipcRenderer } from "electron"; import type { Settings } from "shared/settings"; -import type { LiteralUnion } from "type-fest"; import { IpcEvents } from "../shared/IpcEvents"; import { invoke, sendSync } from "./typedIpc"; @@ -34,7 +33,8 @@ export const VesktopNative = { }, fileManager: { showItemInFolder: (path: string) => invoke(IpcEvents.SHOW_ITEM_IN_FOLDER, path), - selectVencordDir: () => invoke>(IpcEvents.SELECT_VENCORD_DIR) + getVencordDir: () => sendSync(IpcEvents.GET_VENCORD_DIR), + selectVencordDir: (value?: null) => invoke<"cancelled" | "invalid" | "ok">(IpcEvents.SELECT_VENCORD_DIR, value) }, settings: { get: () => sendSync(IpcEvents.GET_SETTINGS), diff --git a/src/renderer/components/ScreenSharePicker.tsx b/src/renderer/components/ScreenSharePicker.tsx index e0cff77..c7403b9 100644 --- a/src/renderer/components/ScreenSharePicker.tsx +++ b/src/renderer/components/ScreenSharePicker.tsx @@ -721,7 +721,7 @@ function ModalComponent({ const constraints = { ...track.getConstraints(), - frameRate, + frameRate: { min: frameRate, ideal: frameRate }, width: { min: 640, ideal: width, max: width }, height: { min: 480, ideal: height, max: height }, advanced: [{ width: width, height: height }], diff --git a/src/renderer/components/settings/Settings.tsx b/src/renderer/components/settings/Settings.tsx index d6de13c..d56f0ea 100644 --- a/src/renderer/components/settings/Settings.tsx +++ b/src/renderer/components/settings/Settings.tsx @@ -102,15 +102,7 @@ const SettingsOptions: Record> defaultValue: false } ], - "Notifications & Updates": [ - NotificationBadgeToggle, - { - key: "checkUpdates", - title: "Check for updates", - description: "Automatically check for Vesktop updates", - defaultValue: true - } - ], + Notifications: [NotificationBadgeToggle], Miscelleanous: [ { key: "arRPC", diff --git a/src/renderer/components/settings/VencordLocationPicker.tsx b/src/renderer/components/settings/VencordLocationPicker.tsx index 3759ae2..9af4711 100644 --- a/src/renderer/components/settings/VencordLocationPicker.tsx +++ b/src/renderer/components/settings/VencordLocationPicker.tsx @@ -4,24 +4,28 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ +import { useForceUpdater } from "@vencord/types/utils"; import { Button, Forms, Toasts } from "@vencord/types/webpack/common"; import { SettingsComponent } from "./Settings"; export const VencordLocationPicker: SettingsComponent = ({ settings }) => { + const forceUpdate = useForceUpdater(); + const vencordDir = VesktopNative.fileManager.getVencordDir(); + return ( <> Vencord files are loaded from{" "} - {settings.vencordDir ? ( + {vencordDir ? ( { e.preventDefault(); - VesktopNative.fileManager.showItemInFolder(settings.vencordDir!); + VesktopNative.fileManager.showItemInFolder(vencordDir!); }} > - {settings.vencordDir} + {vencordDir} ) : ( "the default location" @@ -34,7 +38,14 @@ export const VencordLocationPicker: SettingsComponent = ({ settings }) => { const choice = await VesktopNative.fileManager.selectVencordDir(); switch (choice) { case "cancelled": - return; + break; + case "ok": + Toasts.show({ + message: "Vencord install changed. Fully restart Vesktop to apply.", + id: Toasts.genId(), + type: Toasts.Type.SUCCESS + }); + break; case "invalid": Toasts.show({ message: @@ -42,9 +53,9 @@ export const VencordLocationPicker: SettingsComponent = ({ settings }) => { id: Toasts.genId(), type: Toasts.Type.FAILURE }); - return; + break; } - settings.vencordDir = choice; + forceUpdate(); }} > Change @@ -52,7 +63,10 @@ export const VencordLocationPicker: SettingsComponent = ({ settings }) => { diff --git a/src/renderer/fixes.css b/src/renderer/fixes.css index aeec1bf..20e80aa 100644 --- a/src/renderer/fixes.css +++ b/src/renderer/fixes.css @@ -8,4 +8,9 @@ * { scrollbar-width: unset !important; scrollbar-color: unset !important; -} \ No newline at end of file +} + +/* Workaround for making things in the draggable area clickable again on macOS */ +.platform-osx [class*=topic_], .platform-osx [class*=notice_] button { + -webkit-app-region: no-drag; +} diff --git a/src/renderer/index.ts b/src/renderer/index.ts index 278b195..01c80ce 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -13,7 +13,7 @@ console.log("read if cute :3"); export * as Components from "./components"; import { findByPropsLazy, onceReady } from "@vencord/types/webpack"; -import { FluxDispatcher } from "@vencord/types/webpack/common"; +import { Alerts, FluxDispatcher } from "@vencord/types/webpack/common"; import SettingsUi from "./components/settings/Settings"; import { Settings } from "./settings"; @@ -61,3 +61,19 @@ VesktopNative.arrpc.onActivity(async data => { arRPC.handleEvent(new MessageEvent("message", { data })); }); + +// TODO: remove soon +const vencordDir = "vencordDir" as keyof typeof Settings.store; +if (Settings.store[vencordDir]) { + onceReady.then(() => + setTimeout( + () => + Alerts.show({ + title: "Custom Vencord Location", + body: "Due to security hardening changes in Vesktop, your custom Vencord location had to be reset. Please configure it again in the settings.", + onConfirm: () => delete Settings.store[vencordDir] + }), + 5000 + ) + ); +} diff --git a/src/renderer/patches/screenShareFixes.ts b/src/renderer/patches/screenShareFixes.ts index 66e4b14..00487d3 100644 --- a/src/renderer/patches/screenShareFixes.ts +++ b/src/renderer/patches/screenShareFixes.ts @@ -36,7 +36,7 @@ if (isLinux) { const constraints = { ...track.getConstraints(), - frameRate, + frameRate: { min: frameRate, ideal: frameRate }, width: { min: 640, ideal: width, max: width }, height: { min: 480, ideal: height, max: height }, advanced: [{ width: width, height: height }], diff --git a/src/shared/IpcEvents.ts b/src/shared/IpcEvents.ts index 987e5c9..62ea94c 100644 --- a/src/shared/IpcEvents.ts +++ b/src/shared/IpcEvents.ts @@ -23,6 +23,7 @@ export const enum IpcEvents { GET_SETTINGS = "VCD_GET_SETTINGS", SET_SETTINGS = "VCD_SET_SETTINGS", + GET_VENCORD_DIR = "VCD_GET_VENCORD_DIR", SELECT_VENCORD_DIR = "VCD_SELECT_VENCORD_DIR", UPDATER_GET_DATA = "VCD_UPDATER_GET_DATA", diff --git a/src/shared/settings.d.ts b/src/shared/settings.d.ts index 3eb96a0..9597f85 100644 --- a/src/shared/settings.d.ts +++ b/src/shared/settings.d.ts @@ -8,7 +8,6 @@ import type { Rectangle } from "electron"; export interface Settings { discordBranch?: "stable" | "canary" | "ptb"; - vencordDir?: string; transparencyOption?: "none" | "mica" | "tabbed" | "acrylic"; tray?: boolean; minimizeToTray?: boolean; @@ -23,8 +22,6 @@ export interface Settings { clickTrayToShowHide?: boolean; customTitleBar?: boolean; - checkUpdates?: boolean; - splashTheming?: boolean; splashColor?: string; splashBackground?: string; @@ -50,8 +47,9 @@ export interface State { windowBounds?: Rectangle; displayid: int; - skippedUpdate?: string; firstLaunch?: boolean; steamOSLayoutVersion?: number; + + vencordDir?: string; } diff --git a/src/shared/utils/SettingsStore.ts b/src/shared/utils/SettingsStore.ts index 22dd145..6aa7771 100644 --- a/src/shared/utils/SettingsStore.ts +++ b/src/shared/utils/SettingsStore.ts @@ -59,6 +59,19 @@ export class SettingsStore { self.pathListeners.get(setPath)?.forEach(cb => cb(value)); return true; + }, + deleteProperty(target, key: string) { + if (!(key in target)) return true; + + const res = Reflect.deleteProperty(target, key); + if (!res) return false; + + const setPath = `${path}${path && "."}${key}`; + + self.globalListeners.forEach(cb => cb(root, setPath)); + self.pathListeners.get(setPath)?.forEach(cb => cb(undefined)); + + return res; } }); } diff --git a/src/updater/main.ts b/src/updater/main.ts deleted file mode 100644 index 4c19ffd..0000000 --- a/src/updater/main.ts +++ /dev/null @@ -1,115 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-3.0 - * Vesktop, a desktop app aiming to give you a snappier Discord Experience - * Copyright (c) 2023 Vendicated and Vencord contributors - */ - -import { app, BrowserWindow, shell } from "electron"; -import { PORTABLE } from "main/constants"; -import { Settings, State } from "main/settings"; -import { handle } from "main/utils/ipcWrappers"; -import { makeLinksOpenExternally } from "main/utils/makeLinksOpenExternally"; -import { githubGet, ReleaseData } from "main/utils/vencordLoader"; -import { join } from "path"; -import { IpcEvents } from "shared/IpcEvents"; -import { ICON_PATH, VIEW_DIR } from "shared/paths"; - -export interface UpdateData { - currentVersion: string; - latestVersion: string; - release: ReleaseData; -} - -let updateData: UpdateData; - -handle(IpcEvents.UPDATER_GET_DATA, () => updateData); -handle(IpcEvents.UPDATER_DOWNLOAD, () => { - const { assets } = updateData.release; - const url = (() => { - switch (process.platform) { - case "win32": - return assets.find(a => { - return a.name.endsWith(PORTABLE ? "win.zip" : ".exe"); - })!.browser_download_url; - case "darwin": - return assets.find(a => - process.arch === "arm64" - ? a.name.endsWith("-arm64-mac.zip") - : a.name.endsWith("-mac.zip") && !a.name.includes("arm64") - )!.browser_download_url; - case "linux": - return updateData.release.html_url; - default: - throw new Error(`Unsupported platform: ${process.platform}`); - } - })(); - - shell.openExternal(url); -}); - -handle(IpcEvents.UPDATE_IGNORE, () => { - State.store.skippedUpdate = updateData.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 (Settings.store.checkUpdates === false) return; - - try { - const raw = await githubGet("/repos/Vencord/Vesktop/releases/latest"); - const data: ReleaseData = await raw.json(); - - const oldVersion = app.getVersion(); - const newVersion = data.tag_name.replace(/^v/, ""); - updateData = { - currentVersion: oldVersion, - latestVersion: newVersion, - release: data - }; - - if (State.store.skippedUpdate !== newVersion && isOutdated(oldVersion, newVersion)) { - openNewUpdateWindow(); - } - } catch (e) { - console.error("AppUpdater: Failed to check for updates\n", e); - } -} - -function openNewUpdateWindow() { - const win = new BrowserWindow({ - width: 500, - autoHideMenuBar: true, - alwaysOnTop: true, - webPreferences: { - preload: join(__dirname, "updaterPreload.js"), - nodeIntegration: false, - contextIsolation: true, - sandbox: true - }, - icon: ICON_PATH - }); - - makeLinksOpenExternally(win); - - win.loadFile(join(VIEW_DIR, "updater.html")); -} diff --git a/src/updater/preload.ts b/src/updater/preload.ts deleted file mode 100644 index 80e4dee..0000000 --- a/src/updater/preload.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-3.0 - * Vesktop, a desktop app aiming to give you a snappier Discord Experience - * Copyright (c) 2023 Vendicated and Vencord contributors - */ - -import { contextBridge } from "electron"; -import { invoke } from "preload/typedIpc"; -import { IpcEvents } from "shared/IpcEvents"; - -import type { UpdateData } from "./main"; - -contextBridge.exposeInMainWorld("Updater", { - getData: () => invoke(IpcEvents.UPDATER_GET_DATA), - download: () => { - invoke(IpcEvents.UPDATER_DOWNLOAD); - invoke(IpcEvents.CLOSE); - }, - ignore: () => invoke(IpcEvents.UPDATE_IGNORE), - close: () => invoke(IpcEvents.CLOSE) -});