mirror of
https://github.com/Vencord/Vesktop.git
synced 2025-02-24 14:15:09 +00:00
Merge branch 'Vencord:main' into main
This commit is contained in:
commit
a946c5d2af
15 changed files with 3328 additions and 2723 deletions
1
.npmrc
1
.npmrc
|
@ -1 +1,2 @@
|
||||||
node-linker=hoisted
|
node-linker=hoisted
|
||||||
|
package-manager-strict=false
|
33
package.json
33
package.json
|
@ -27,15 +27,15 @@
|
||||||
"arrpc": "github:OpenAsar/arrpc#6960a8fd4d65d566da93dbdb8a7ca474aa0a3c9c"
|
"arrpc": "github:OpenAsar/arrpc#6960a8fd4d65d566da93dbdb8a7ca474aa0a3c9c"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@vencord/venmic": "^3.4.2"
|
"@vencord/venmic": "^3.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
|
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
|
||||||
"@types/node": "^20.11.26",
|
"@types/node": "^20.11.26",
|
||||||
"@types/react": "^18.2.65",
|
"@types/react": "^18.2.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||||
"@typescript-eslint/parser": "^7.2.0",
|
"@typescript-eslint/parser": "^7.2.0",
|
||||||
"@vencord/types": "^0.1.2",
|
"@vencord/types": "^1.8.4",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"electron": "^29.1.1",
|
"electron": "^29.1.1",
|
||||||
"electron-builder": "^24.13.3",
|
"electron-builder": "^24.13.3",
|
||||||
|
@ -136,20 +136,21 @@
|
||||||
"icon": "build/icon.icns",
|
"icon": "build/icon.icns",
|
||||||
"iconSize": 105,
|
"iconSize": 105,
|
||||||
"window": {
|
"window": {
|
||||||
"width": 512,
|
"width": 512,
|
||||||
"height": 340
|
"height": 340
|
||||||
},
|
},
|
||||||
|
"contents": [
|
||||||
"contents": [{
|
{
|
||||||
"x": 140,
|
"x": 140,
|
||||||
"y": 160
|
"y": 160
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"x": 372,
|
"x": 372,
|
||||||
"y": 160,
|
"y": 160,
|
||||||
"type": "link",
|
"type": "link",
|
||||||
"path": "/Applications"
|
"path": "/Applications"
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"nsis": {
|
"nsis": {
|
||||||
"include": "build/installer.nsh",
|
"include": "build/installer.nsh",
|
||||||
|
|
5871
pnpm-lock.yaml
generated
5871
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -5,11 +5,22 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { app } from "electron";
|
import { app } from "electron";
|
||||||
import { existsSync, readdirSync, renameSync, rmdirSync } from "fs";
|
import { existsSync, mkdirSync, readdirSync, renameSync, rmdirSync } from "fs";
|
||||||
import { join } from "path";
|
import { dirname, join } from "path";
|
||||||
|
|
||||||
|
const vesktopDir = dirname(process.execPath);
|
||||||
|
|
||||||
|
export const PORTABLE =
|
||||||
|
process.platform === "win32" &&
|
||||||
|
!process.execPath.toLowerCase().endsWith("electron.exe") &&
|
||||||
|
!existsSync(join(vesktopDir, "Uninstall Vesktop.exe"));
|
||||||
|
|
||||||
const LEGACY_DATA_DIR = join(app.getPath("appData"), "VencordDesktop", "VencordDesktop");
|
const LEGACY_DATA_DIR = join(app.getPath("appData"), "VencordDesktop", "VencordDesktop");
|
||||||
export const DATA_DIR = process.env.VENCORD_USER_DATA_DIR || join(app.getPath("userData"));
|
export const DATA_DIR =
|
||||||
|
process.env.VENCORD_USER_DATA_DIR || (PORTABLE ? join(vesktopDir, "Data") : join(app.getPath("userData")));
|
||||||
|
|
||||||
|
mkdirSync(DATA_DIR, { recursive: true });
|
||||||
|
|
||||||
// TODO: remove eventually
|
// TODO: remove eventually
|
||||||
if (existsSync(LEGACY_DATA_DIR)) {
|
if (existsSync(LEGACY_DATA_DIR)) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -40,18 +40,23 @@ function init() {
|
||||||
app.commandLine.appendSwitch("disable-smooth-scrolling");
|
app.commandLine.appendSwitch("disable-smooth-scrolling");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// disable renderer backgrounding to prevent the app from unloading when in the background
|
||||||
|
// https://github.com/electron/electron/issues/2822
|
||||||
|
// https://github.com/GoogleChrome/chrome-launcher/blob/5a27dd574d47a75fec0fb50f7b774ebf8a9791ba/docs/chrome-flags-for-tools.md#task-throttling
|
||||||
|
app.commandLine.appendSwitch("disable-renderer-backgrounding");
|
||||||
|
app.commandLine.appendSwitch("disable-background-timer-throttling");
|
||||||
|
app.commandLine.appendSwitch("disable-backgrounding-occluded-windows");
|
||||||
|
if (process.platform === "win32") {
|
||||||
|
disabledFeatures.push("CalculateNativeWinOcclusion");
|
||||||
|
}
|
||||||
|
|
||||||
// work around chrome 66 disabling autoplay by default
|
// work around chrome 66 disabling autoplay by default
|
||||||
app.commandLine.appendSwitch("autoplay-policy", "no-user-gesture-required");
|
app.commandLine.appendSwitch("autoplay-policy", "no-user-gesture-required");
|
||||||
// WinRetrieveSuggestionsOnlyOnDemand: Work around electron 13 bug w/ async spellchecking on Windows.
|
// WinRetrieveSuggestionsOnlyOnDemand: Work around electron 13 bug w/ async spellchecking on Windows.
|
||||||
// HardwareMediaKeyHandling,MediaSessionService: Prevent Discord from registering as a media service.
|
// HardwareMediaKeyHandling,MediaSessionService: Prevent Discord from registering as a media service.
|
||||||
//
|
//
|
||||||
// WidgetLayering (Vencord Added): Fix DevTools context menus https://github.com/electron/electron/issues/38790
|
// WidgetLayering (Vencord Added): Fix DevTools context menus https://github.com/electron/electron/issues/38790
|
||||||
disabledFeatures.push(
|
disabledFeatures.push("WinRetrieveSuggestionsOnlyOnDemand", "HardwareMediaKeyHandling", "MediaSessionService");
|
||||||
"WinRetrieveSuggestionsOnlyOnDemand",
|
|
||||||
"HardwareMediaKeyHandling",
|
|
||||||
"MediaSessionService",
|
|
||||||
"WidgetLayering"
|
|
||||||
);
|
|
||||||
|
|
||||||
app.commandLine.appendSwitch("enable-features", [...new Set(enabledFeatures)].filter(Boolean).join(","));
|
app.commandLine.appendSwitch("enable-features", [...new Set(enabledFeatures)].filter(Boolean).join(","));
|
||||||
app.commandLine.appendSwitch("disable-features", [...new Set(disabledFeatures)].filter(Boolean).join(","));
|
app.commandLine.appendSwitch("disable-features", [...new Set(disabledFeatures)].filter(Boolean).join(","));
|
||||||
|
|
|
@ -103,12 +103,8 @@ handle(IpcEvents.MAXIMIZE, e => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
handle(IpcEvents.SPELLCHECK_SET_LANGUAGES, (_, languages: string[]) => {
|
handleSync(IpcEvents.SPELLCHECK_GET_AVAILABLE_LANGUAGES, e => {
|
||||||
const ses = session.defaultSession;
|
e.returnValue = session.defaultSession.availableSpellCheckerLanguages;
|
||||||
|
|
||||||
const available = ses.availableSpellCheckerLanguages;
|
|
||||||
const applicable = languages.filter(l => available.includes(l)).slice(0, 3);
|
|
||||||
if (applicable.length) ses.setSpellCheckerLanguages(applicable);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
handle(IpcEvents.SPELLCHECK_REPLACE_MISSPELLING, (e, word: string) => {
|
handle(IpcEvents.SPELLCHECK_REPLACE_MISSPELLING, (e, word: string) => {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
nativeImage,
|
nativeImage,
|
||||||
nativeTheme,
|
nativeTheme,
|
||||||
screen,
|
screen,
|
||||||
|
session,
|
||||||
Tray
|
Tray
|
||||||
} from "electron";
|
} from "electron";
|
||||||
import { rm } from "fs/promises";
|
import { rm } from "fs/promises";
|
||||||
|
@ -373,12 +374,27 @@ function initSettingsListeners(win: BrowserWindow) {
|
||||||
addSettingsListener("enableMenu", enabled => {
|
addSettingsListener("enableMenu", enabled => {
|
||||||
win.setAutoHideMenuBar(enabled ?? false);
|
win.setAutoHideMenuBar(enabled ?? false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addSettingsListener("spellCheckLanguages", languages => initSpellCheckLanguages(win, languages));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function initSpellCheckLanguages(win: BrowserWindow, languages?: string[]) {
|
||||||
|
languages ??= await win.webContents.executeJavaScript("[...new Set(navigator.languages)]").catch(() => []);
|
||||||
|
if (!languages) return;
|
||||||
|
|
||||||
|
const ses = session.defaultSession;
|
||||||
|
|
||||||
|
const available = ses.availableSpellCheckerLanguages;
|
||||||
|
const applicable = languages.filter(l => available.includes(l)).slice(0, 5);
|
||||||
|
if (applicable.length) ses.setSpellCheckerLanguages(applicable);
|
||||||
}
|
}
|
||||||
|
|
||||||
function initSpellCheck(win: BrowserWindow) {
|
function initSpellCheck(win: BrowserWindow) {
|
||||||
win.webContents.on("context-menu", (_, data) => {
|
win.webContents.on("context-menu", (_, data) => {
|
||||||
win.webContents.send(IpcEvents.SPELLCHECK_RESULT, data.misspelledWord, data.dictionarySuggestions);
|
win.webContents.send(IpcEvents.SPELLCHECK_RESULT, data.misspelledWord, data.dictionarySuggestions);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
initSpellCheckLanguages(win, Settings.store.spellCheckLanguages);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createMainWindow() {
|
function createMainWindow() {
|
||||||
|
@ -400,7 +416,9 @@ function createMainWindow() {
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
devTools: true,
|
devTools: true,
|
||||||
preload: join(__dirname, "preload.js"),
|
preload: join(__dirname, "preload.js"),
|
||||||
spellcheck: true
|
spellcheck: true,
|
||||||
|
// disable renderer backgrounding to prevent the app from unloading when in the background
|
||||||
|
backgroundThrottling: false
|
||||||
},
|
},
|
||||||
icon: ICON_PATH,
|
icon: ICON_PATH,
|
||||||
frame: !noFrame,
|
frame: !noFrame,
|
||||||
|
|
|
@ -35,11 +35,6 @@ function loadSettings<T extends object = any>(file: string, name: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Settings = loadSettings<TSettings>(SETTINGS_FILE, "Vesktop settings");
|
export const Settings = loadSettings<TSettings>(SETTINGS_FILE, "Vesktop settings");
|
||||||
if (Object.hasOwn(Settings.plain, "discordWindowsTitleBar")) {
|
|
||||||
Settings.plain.customTitleBar = Settings.plain.discordWindowsTitleBar;
|
|
||||||
delete Settings.plain.discordWindowsTitleBar;
|
|
||||||
Settings.markAsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const VencordSettings = loadSettings<any>(VENCORD_SETTINGS_FILE, "Vencord settings");
|
export const VencordSettings = loadSettings<any>(VENCORD_SETTINGS_FILE, "Vencord settings");
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ export const VesktopNative = {
|
||||||
set: (settings: Settings, path?: string) => invoke<void>(IpcEvents.SET_SETTINGS, settings, path)
|
set: (settings: Settings, path?: string) => invoke<void>(IpcEvents.SET_SETTINGS, settings, path)
|
||||||
},
|
},
|
||||||
spellcheck: {
|
spellcheck: {
|
||||||
setLanguages: (languages: readonly string[]) => invoke<void>(IpcEvents.SPELLCHECK_SET_LANGUAGES, languages),
|
getAvailableLanguages: () => sendSync<string[]>(IpcEvents.SPELLCHECK_GET_AVAILABLE_LANGUAGES),
|
||||||
onSpellcheckResult(cb: SpellCheckerResultCallback) {
|
onSpellcheckResult(cb: SpellCheckerResultCallback) {
|
||||||
spellCheckCallbacks.add(cb);
|
spellCheckCallbacks.add(cb);
|
||||||
},
|
},
|
||||||
|
|
|
@ -40,5 +40,3 @@ if (IS_DEV) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
VesktopNative.spellcheck.setLanguages(window.navigator.languages);
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import "./themedSplash";
|
||||||
console.log("read if cute :3");
|
console.log("read if cute :3");
|
||||||
|
|
||||||
export * as Components from "./components";
|
export * as Components from "./components";
|
||||||
import { findByPropsLazy } from "@vencord/types/webpack";
|
import { findByPropsLazy, onceReady } from "@vencord/types/webpack";
|
||||||
import { FluxDispatcher } from "@vencord/types/webpack/common";
|
import { FluxDispatcher } from "@vencord/types/webpack/common";
|
||||||
|
|
||||||
import SettingsUi from "./components/settings/Settings";
|
import SettingsUi from "./components/settings/Settings";
|
||||||
|
@ -52,8 +52,10 @@ const arRPC = Vencord.Plugins.plugins["WebRichPresence (arRPC)"] as any as {
|
||||||
handleEvent(e: MessageEvent): void;
|
handleEvent(e: MessageEvent): void;
|
||||||
};
|
};
|
||||||
|
|
||||||
VesktopNative.arrpc.onActivity(data => {
|
VesktopNative.arrpc.onActivity(async data => {
|
||||||
if (!Settings.store.arRPC) return;
|
if (!Settings.store.arRPC) return;
|
||||||
|
|
||||||
|
await onceReady;
|
||||||
|
|
||||||
arRPC.handleEvent(new MessageEvent("message", { data }));
|
arRPC.handleEvent(new MessageEvent("message", { data }));
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
|
|
||||||
import { addContextMenuPatch } from "@vencord/types/api/ContextMenu";
|
import { addContextMenuPatch } from "@vencord/types/api/ContextMenu";
|
||||||
import { findStoreLazy } from "@vencord/types/webpack";
|
import { findStoreLazy } from "@vencord/types/webpack";
|
||||||
import { FluxDispatcher, Menu, useStateFromStores } from "@vencord/types/webpack/common";
|
import { FluxDispatcher, Menu, useMemo, useStateFromStores } from "@vencord/types/webpack/common";
|
||||||
|
import { useSettings } from "renderer/settings";
|
||||||
|
|
||||||
import { addPatch } from "./shared";
|
import { addPatch } from "./shared";
|
||||||
|
|
||||||
|
@ -50,7 +51,16 @@ addContextMenuPatch("textarea-context", children => {
|
||||||
const spellCheckEnabled = useStateFromStores([SpellCheckStore], () => SpellCheckStore.isEnabled());
|
const spellCheckEnabled = useStateFromStores([SpellCheckStore], () => SpellCheckStore.isEnabled());
|
||||||
const hasCorrections = Boolean(word && corrections?.length);
|
const hasCorrections = Boolean(word && corrections?.length);
|
||||||
|
|
||||||
children.push(
|
const availableLanguages = useMemo(VesktopNative.spellcheck.getAvailableLanguages, []);
|
||||||
|
|
||||||
|
const settings = useSettings();
|
||||||
|
const spellCheckLanguages = (settings.spellCheckLanguages ??= [...new Set(navigator.languages)]);
|
||||||
|
|
||||||
|
const pasteSectionIndex = children.findIndex(c => c?.props?.children?.some(c => c?.props?.id === "paste"));
|
||||||
|
|
||||||
|
children.splice(
|
||||||
|
pasteSectionIndex === -1 ? children.length : pasteSectionIndex,
|
||||||
|
0,
|
||||||
<Menu.MenuGroup>
|
<Menu.MenuGroup>
|
||||||
{hasCorrections && (
|
{hasCorrections && (
|
||||||
<>
|
<>
|
||||||
|
@ -69,14 +79,39 @@ addContextMenuPatch("textarea-context", children => {
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<Menu.MenuCheckboxItem
|
|
||||||
id="vcd-spellcheck-enabled"
|
<Menu.MenuItem id="vcd-spellcheck-settings" label="Spellcheck Settings">
|
||||||
label="Enable Spellcheck"
|
<Menu.MenuCheckboxItem
|
||||||
checked={spellCheckEnabled}
|
id="vcd-spellcheck-enabled"
|
||||||
action={() => {
|
label="Enable Spellcheck"
|
||||||
FluxDispatcher.dispatch({ type: "SPELLCHECK_TOGGLE" });
|
checked={spellCheckEnabled}
|
||||||
}}
|
action={() => {
|
||||||
/>
|
FluxDispatcher.dispatch({ type: "SPELLCHECK_TOGGLE" });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Menu.MenuItem id="vcd-spellcheck-languages" label="Languages" disabled={!spellCheckEnabled}>
|
||||||
|
{availableLanguages.map(lang => {
|
||||||
|
const isEnabled = spellCheckLanguages.includes(lang);
|
||||||
|
return (
|
||||||
|
<Menu.MenuCheckboxItem
|
||||||
|
id={"vcd-spellcheck-lang-" + lang}
|
||||||
|
label={lang}
|
||||||
|
checked={isEnabled}
|
||||||
|
disabled={!isEnabled && spellCheckLanguages.length >= 5}
|
||||||
|
action={() => {
|
||||||
|
const newSpellCheckLanguages = spellCheckLanguages.filter(l => l !== lang);
|
||||||
|
if (newSpellCheckLanguages.length === spellCheckLanguages.length) {
|
||||||
|
newSpellCheckLanguages.push(lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.spellCheckLanguages = newSpellCheckLanguages;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Menu.MenuItem>
|
||||||
|
</Menu.MenuItem>
|
||||||
</Menu.MenuGroup>
|
</Menu.MenuGroup>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,7 +32,7 @@ export const enum IpcEvents {
|
||||||
UPDATER_DOWNLOAD = "VCD_UPDATER_DOWNLOAD",
|
UPDATER_DOWNLOAD = "VCD_UPDATER_DOWNLOAD",
|
||||||
UPDATE_IGNORE = "VCD_UPDATE_IGNORE",
|
UPDATE_IGNORE = "VCD_UPDATE_IGNORE",
|
||||||
|
|
||||||
SPELLCHECK_SET_LANGUAGES = "VCD_SPELLCHECK_SET_LANGUAGES",
|
SPELLCHECK_GET_AVAILABLE_LANGUAGES = "VCD_SPELLCHECK_GET_AVAILABLE_LANGUAGES",
|
||||||
SPELLCHECK_RESULT = "VCD_SPELLCHECK_RESULT",
|
SPELLCHECK_RESULT = "VCD_SPELLCHECK_RESULT",
|
||||||
SPELLCHECK_REPLACE_MISSPELLING = "VCD_SPELLCHECK_REPLACE_MISSPELLING",
|
SPELLCHECK_REPLACE_MISSPELLING = "VCD_SPELLCHECK_REPLACE_MISSPELLING",
|
||||||
SPELLCHECK_ADD_TO_DICTIONARY = "VCD_SPELLCHECK_ADD_TO_DICTIONARY",
|
SPELLCHECK_ADD_TO_DICTIONARY = "VCD_SPELLCHECK_ADD_TO_DICTIONARY",
|
||||||
|
|
4
src/shared/settings.d.ts
vendored
4
src/shared/settings.d.ts
vendored
|
@ -21,8 +21,6 @@ export interface Settings {
|
||||||
appBadge?: boolean;
|
appBadge?: boolean;
|
||||||
disableMinSize?: boolean;
|
disableMinSize?: boolean;
|
||||||
clickTrayToShowHide?: boolean;
|
clickTrayToShowHide?: boolean;
|
||||||
/** @deprecated use customTitleBar */
|
|
||||||
discordWindowsTitleBar?: boolean;
|
|
||||||
customTitleBar?: boolean;
|
customTitleBar?: boolean;
|
||||||
trayIconPath?: string;
|
trayIconPath?: string;
|
||||||
|
|
||||||
|
@ -31,6 +29,8 @@ export interface Settings {
|
||||||
splashTheming?: boolean;
|
splashTheming?: boolean;
|
||||||
splashColor?: string;
|
splashColor?: string;
|
||||||
splashBackground?: string;
|
splashBackground?: string;
|
||||||
|
|
||||||
|
spellCheckLanguages?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { app, BrowserWindow, shell } from "electron";
|
import { app, BrowserWindow, shell } from "electron";
|
||||||
|
import { PORTABLE } from "main/constants";
|
||||||
import { Settings, State } from "main/settings";
|
import { Settings, State } from "main/settings";
|
||||||
import { handle } from "main/utils/ipcWrappers";
|
import { handle } from "main/utils/ipcWrappers";
|
||||||
import { makeLinksOpenExternally } from "main/utils/makeLinksOpenExternally";
|
import { makeLinksOpenExternally } from "main/utils/makeLinksOpenExternally";
|
||||||
|
@ -23,17 +24,12 @@ let updateData: UpdateData;
|
||||||
|
|
||||||
handle(IpcEvents.UPDATER_GET_DATA, () => updateData);
|
handle(IpcEvents.UPDATER_GET_DATA, () => updateData);
|
||||||
handle(IpcEvents.UPDATER_DOWNLOAD, () => {
|
handle(IpcEvents.UPDATER_DOWNLOAD, () => {
|
||||||
const portable = !!process.env.PORTABLE_EXECUTABLE_FILE;
|
|
||||||
|
|
||||||
const { assets } = updateData.release;
|
const { assets } = updateData.release;
|
||||||
const url = (() => {
|
const url = (() => {
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case "win32":
|
case "win32":
|
||||||
return assets.find(a => {
|
return assets.find(a => {
|
||||||
if (!a.name.endsWith(".exe")) return false;
|
return a.name.endsWith(PORTABLE ? "win.zip" : ".exe");
|
||||||
|
|
||||||
const isSetup = a.name.includes("Setup");
|
|
||||||
return portable ? !isSetup : isSetup;
|
|
||||||
})!.browser_download_url;
|
})!.browser_download_url;
|
||||||
case "darwin":
|
case "darwin":
|
||||||
return assets.find(a =>
|
return assets.find(a =>
|
||||||
|
|
Loading…
Add table
Reference in a new issue