Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17f1c4ff6f | ||
|
|
a7ded71404 | ||
|
|
31799ccfb0 |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "VencordDesktop",
|
"name": "VencordDesktop",
|
||||||
"version": "0.2.3",
|
"version": "0.2.4",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "",
|
"description": "",
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
|
|||||||
1
src/globals.d.ts
vendored
@@ -8,6 +8,7 @@ declare global {
|
|||||||
export var VencordDesktopNative: typeof import("preload/VencordDesktopNative").VencordDesktopNative;
|
export var VencordDesktopNative: typeof import("preload/VencordDesktopNative").VencordDesktopNative;
|
||||||
export var VencordDesktop: typeof import("renderer/index");
|
export var VencordDesktop: typeof import("renderer/index");
|
||||||
export var vcdLS: typeof localStorage;
|
export var vcdLS: typeof localStorage;
|
||||||
|
export var VCDP: any;
|
||||||
|
|
||||||
export var IS_DEV: boolean;
|
export var IS_DEV: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
import { app, BrowserWindow } from "electron";
|
import { app, BrowserWindow } from "electron";
|
||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { ICON_PATH, STATIC_DIR } from "shared/paths";
|
import { ICON_PATH, VIEW_DIR } from "shared/paths";
|
||||||
|
|
||||||
import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally";
|
import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally";
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ export function createAboutWindow() {
|
|||||||
|
|
||||||
makeLinksOpenExternally(about);
|
makeLinksOpenExternally(about);
|
||||||
|
|
||||||
const html = readFileSync(join(STATIC_DIR, "about.html"), "utf-8").replaceAll("%VERSION%", app.getVersion());
|
const html = readFileSync(join(VIEW_DIR, "about.html"), "utf-8").replaceAll("%VERSION%", app.getVersion());
|
||||||
|
|
||||||
about.loadURL("data:text/html;charset=utf-8," + html);
|
about.loadURL("data:text/html;charset=utf-8," + html);
|
||||||
|
|
||||||
|
|||||||
50
src/main/appBadge.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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, NativeImage, nativeImage } from "electron";
|
||||||
|
import { join } from "path";
|
||||||
|
import { BADGE_DIR } from "shared/paths";
|
||||||
|
|
||||||
|
const imgCache = new Map<number, NativeImage>();
|
||||||
|
function loadBadge(index: number) {
|
||||||
|
const cached = imgCache.get(index);
|
||||||
|
if (cached) return cached;
|
||||||
|
|
||||||
|
const img = nativeImage.createFromPath(join(BADGE_DIR, `${index}.ico`));
|
||||||
|
imgCache.set(index, img);
|
||||||
|
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastIndex: null | number = -1;
|
||||||
|
|
||||||
|
export function setBadgeCount(count: number) {
|
||||||
|
switch (process.platform) {
|
||||||
|
case "darwin":
|
||||||
|
case "linux":
|
||||||
|
if (count === -1) count = 0;
|
||||||
|
app.setBadgeCount(count);
|
||||||
|
break;
|
||||||
|
case "win32":
|
||||||
|
const [index, description] = getBadgeIndexAndDescription(count);
|
||||||
|
if (lastIndex === index) break;
|
||||||
|
|
||||||
|
lastIndex = index;
|
||||||
|
|
||||||
|
// circular import shenanigans
|
||||||
|
const { mainWin } = require("./mainWindow") as typeof import("./mainWindow");
|
||||||
|
mainWin.setOverlayIcon(index === null ? null : loadBadge(index), description);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBadgeIndexAndDescription(count: number): [number | null, string] {
|
||||||
|
if (count === -1) return [11, "Unread Messages"];
|
||||||
|
if (count === 0) return [null, "No Notifications"];
|
||||||
|
|
||||||
|
const index = Math.max(1, Math.min(count, 10));
|
||||||
|
return [index, `${index} Notification`];
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ import { BrowserWindow } from "electron/main";
|
|||||||
import { copyFileSync, mkdirSync, readdirSync } from "fs";
|
import { copyFileSync, mkdirSync, readdirSync } from "fs";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { SplashProps } from "shared/browserWinProperties";
|
import { SplashProps } from "shared/browserWinProperties";
|
||||||
import { STATIC_DIR } from "shared/paths";
|
import { VIEW_DIR } from "shared/paths";
|
||||||
|
|
||||||
import { autoStart } from "./autoStart";
|
import { autoStart } from "./autoStart";
|
||||||
import { DATA_DIR } from "./constants";
|
import { DATA_DIR } from "./constants";
|
||||||
@@ -33,7 +33,7 @@ export function createFirstLaunchTour() {
|
|||||||
width: 550
|
width: 550
|
||||||
});
|
});
|
||||||
|
|
||||||
win.loadFile(join(STATIC_DIR, "first-launch.html"));
|
win.loadFile(join(VIEW_DIR, "first-launch.html"));
|
||||||
win.webContents.addListener("console-message", (_e, _l, msg) => {
|
win.webContents.addListener("console-message", (_e, _l, msg) => {
|
||||||
if (msg === "cancel") return app.exit();
|
if (msg === "cancel") return app.exit();
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { join } from "path";
|
|||||||
import { debounce } from "shared/utils/debounce";
|
import { debounce } from "shared/utils/debounce";
|
||||||
|
|
||||||
import { IpcEvents } from "../shared/IpcEvents";
|
import { IpcEvents } from "../shared/IpcEvents";
|
||||||
|
import { setBadgeCount } from "./appBadge";
|
||||||
import { autoStart } from "./autoStart";
|
import { autoStart } from "./autoStart";
|
||||||
import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE } from "./constants";
|
import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE } from "./constants";
|
||||||
import { mainWin } from "./mainWindow";
|
import { mainWin } from "./mainWindow";
|
||||||
@@ -75,6 +76,14 @@ ipcMain.handle(IpcEvents.SPELLCHECK_SET_LANGUAGES, (_, languages: string[]) => {
|
|||||||
if (applicable.length) ses.setSpellCheckerLanguages(applicable);
|
if (applicable.length) ses.setSpellCheckerLanguages(applicable);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle(IpcEvents.SPELLCHECK_REPLACE_MISSPELLING, (e, word: string) => {
|
||||||
|
e.sender.replaceMisspelling(word);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle(IpcEvents.SPELLCHECK_ADD_TO_DICTIONARY, (e, word: string) => {
|
||||||
|
e.sender.session.addWordToSpellCheckerDictionary(word);
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
|
ipcMain.handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
|
||||||
const res = await dialog.showOpenDialog(mainWin!, {
|
const res = await dialog.showOpenDialog(mainWin!, {
|
||||||
properties: ["openDirectory"]
|
properties: ["openDirectory"]
|
||||||
@@ -89,6 +98,8 @@ ipcMain.handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
|
|||||||
return dir;
|
return dir;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle(IpcEvents.SET_BADGE_COUNT, (_, count: number) => setBadgeCount(count));
|
||||||
|
|
||||||
function readCss() {
|
function readCss() {
|
||||||
return readFile(VENCORD_QUICKCSS_FILE, "utf-8").catch(() => "");
|
return readFile(VENCORD_QUICKCSS_FILE, "utf-8").catch(() => "");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
import { app, BrowserWindow, BrowserWindowConstructorOptions, Menu, Tray } from "electron";
|
import { app, BrowserWindow, BrowserWindowConstructorOptions, Menu, Tray } from "electron";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
|
import { IpcEvents } from "shared/IpcEvents";
|
||||||
import { once } from "shared/utils/once";
|
import { once } from "shared/utils/once";
|
||||||
|
|
||||||
import { ICON_PATH } from "../shared/paths";
|
import { ICON_PATH } from "../shared/paths";
|
||||||
@@ -216,6 +217,12 @@ function initSettingsListeners(win: BrowserWindow) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initSpellCheck(win: BrowserWindow) {
|
||||||
|
win.webContents.on("context-menu", (_, data) => {
|
||||||
|
win.webContents.send(IpcEvents.SPELLCHECK_RESULT, data.misspelledWord, data.dictionarySuggestions);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function createMainWindow() {
|
function createMainWindow() {
|
||||||
const win = (mainWin = new BrowserWindow({
|
const win = (mainWin = new BrowserWindow({
|
||||||
show: false,
|
show: false,
|
||||||
@@ -225,7 +232,8 @@ function createMainWindow() {
|
|||||||
sandbox: false,
|
sandbox: false,
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
devTools: true,
|
devTools: true,
|
||||||
preload: join(__dirname, "preload.js")
|
preload: join(__dirname, "preload.js"),
|
||||||
|
spellcheck: true
|
||||||
},
|
},
|
||||||
icon: ICON_PATH,
|
icon: ICON_PATH,
|
||||||
frame: VencordSettings.store.frameless !== true,
|
frame: VencordSettings.store.frameless !== true,
|
||||||
@@ -255,6 +263,7 @@ function createMainWindow() {
|
|||||||
initMenuBar(win);
|
initMenuBar(win);
|
||||||
makeLinksOpenExternally(win);
|
makeLinksOpenExternally(win);
|
||||||
initSettingsListeners(win);
|
initSettingsListeners(win);
|
||||||
|
initSpellCheck(win);
|
||||||
|
|
||||||
win.webContents.setUserAgent(
|
win.webContents.setUserAgent(
|
||||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
|
||||||
|
|||||||
@@ -7,12 +7,12 @@
|
|||||||
import { BrowserWindow } from "electron";
|
import { BrowserWindow } from "electron";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { SplashProps } from "shared/browserWinProperties";
|
import { SplashProps } from "shared/browserWinProperties";
|
||||||
import { STATIC_DIR } from "shared/paths";
|
import { VIEW_DIR } from "shared/paths";
|
||||||
|
|
||||||
export function createSplashWindow() {
|
export function createSplashWindow() {
|
||||||
const splash = new BrowserWindow(SplashProps);
|
const splash = new BrowserWindow(SplashProps);
|
||||||
|
|
||||||
splash.loadFile(join(STATIC_DIR, "splash.html"));
|
splash.loadFile(join(VIEW_DIR, "splash.html"));
|
||||||
|
|
||||||
return splash;
|
return splash;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,26 @@
|
|||||||
* Copyright (c) 2023 Vendicated and Vencord contributors
|
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { ipcRenderer } from "electron";
|
||||||
import type { Settings } from "shared/settings";
|
import type { Settings } from "shared/settings";
|
||||||
import type { LiteralUnion } from "type-fest";
|
import type { LiteralUnion } from "type-fest";
|
||||||
|
|
||||||
import { IpcEvents } from "../shared/IpcEvents";
|
import { IpcEvents } from "../shared/IpcEvents";
|
||||||
import { invoke, sendSync } from "./typedIpcs";
|
import { invoke, sendSync } from "./typedIpcs";
|
||||||
|
|
||||||
|
type SpellCheckerResultCallback = (word: string, suggestions: string[]) => void;
|
||||||
|
|
||||||
|
const spellCheckCallbacks = new Set<SpellCheckerResultCallback>();
|
||||||
|
|
||||||
|
ipcRenderer.on(IpcEvents.SPELLCHECK_RESULT, (_, w: string, s: string[]) => {
|
||||||
|
spellCheckCallbacks.forEach(cb => cb(w, s));
|
||||||
|
});
|
||||||
|
|
||||||
export const VencordDesktopNative = {
|
export const VencordDesktopNative = {
|
||||||
app: {
|
app: {
|
||||||
relaunch: () => invoke<void>(IpcEvents.RELAUNCH),
|
relaunch: () => invoke<void>(IpcEvents.RELAUNCH),
|
||||||
getVersion: () => sendSync<void>(IpcEvents.GET_VERSION)
|
getVersion: () => sendSync<void>(IpcEvents.GET_VERSION),
|
||||||
|
setBadgeCount: (count: number) => invoke<void>(IpcEvents.SET_BADGE_COUNT, count)
|
||||||
},
|
},
|
||||||
autostart: {
|
autostart: {
|
||||||
isEnabled: () => sendSync<boolean>(IpcEvents.AUTOSTART_ENABLED),
|
isEnabled: () => sendSync<boolean>(IpcEvents.AUTOSTART_ENABLED),
|
||||||
@@ -29,8 +39,15 @@ export const VencordDesktopNative = {
|
|||||||
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)
|
setLanguages: (languages: readonly string[]) => invoke<void>(IpcEvents.SPELLCHECK_SET_LANGUAGES, languages),
|
||||||
// todo: perhaps add ways to learn words
|
onSpellcheckResult(cb: SpellCheckerResultCallback) {
|
||||||
|
spellCheckCallbacks.add(cb);
|
||||||
|
},
|
||||||
|
offSpellcheckResult(cb: SpellCheckerResultCallback) {
|
||||||
|
spellCheckCallbacks.delete(cb);
|
||||||
|
},
|
||||||
|
replaceMisspelling: (word: string) => invoke<void>(IpcEvents.SPELLCHECK_REPLACE_MISSPELLING, word),
|
||||||
|
addToDictionary: (word: string) => invoke<void>(IpcEvents.SPELLCHECK_ADD_TO_DICTIONARY, word)
|
||||||
},
|
},
|
||||||
win: {
|
win: {
|
||||||
focus: () => invoke<void>(IpcEvents.FOCUS)
|
focus: () => invoke<void>(IpcEvents.FOCUS)
|
||||||
|
|||||||
43
src/renderer/appBadge.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* 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 { filters, waitFor } from "@vencord/types/webpack";
|
||||||
|
import { RelationshipStore } from "@vencord/types/webpack/common";
|
||||||
|
|
||||||
|
import { Settings } from "./settings";
|
||||||
|
|
||||||
|
let GuildReadStateStore: any;
|
||||||
|
let NotificationSettingsStore: any;
|
||||||
|
|
||||||
|
export function setBadge() {
|
||||||
|
if (Settings.store.appBadge === false) return;
|
||||||
|
|
||||||
|
const mentionCount = GuildReadStateStore.getTotalMentionCount();
|
||||||
|
const pendingRequests = RelationshipStore.getPendingCount();
|
||||||
|
const hasUnread = GuildReadStateStore.hasAnyUnread();
|
||||||
|
const disableUnreadBadge = NotificationSettingsStore.getDisableUnreadBadge();
|
||||||
|
|
||||||
|
let totalCount = mentionCount + pendingRequests;
|
||||||
|
if (!totalCount && hasUnread && !disableUnreadBadge) totalCount = -1;
|
||||||
|
|
||||||
|
VencordDesktopNative.app.setBadgeCount(totalCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
let toFind = 3;
|
||||||
|
|
||||||
|
function waitForAndSubscribeToStore(name: string, cb?: (m: any) => void) {
|
||||||
|
waitFor(filters.byStoreName(name), store => {
|
||||||
|
cb?.(store);
|
||||||
|
store.addChangeListener(setBadge);
|
||||||
|
|
||||||
|
toFind--;
|
||||||
|
if (toFind === 0) setBadge();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForAndSubscribeToStore("GuildReadStateStore", store => (GuildReadStateStore = store));
|
||||||
|
waitForAndSubscribeToStore("NotificationSettingsStore", store => (NotificationSettingsStore = store));
|
||||||
|
waitForAndSubscribeToStore("RelationshipStore");
|
||||||
@@ -8,6 +8,7 @@ import "./settings.css";
|
|||||||
|
|
||||||
import { Margins } from "@vencord/types/utils";
|
import { Margins } from "@vencord/types/utils";
|
||||||
import { Button, Forms, Select, Switch, Text, useState } from "@vencord/types/webpack/common";
|
import { Button, Forms, Select, Switch, Text, useState } from "@vencord/types/webpack/common";
|
||||||
|
import { setBadge } from "renderer/appBadge";
|
||||||
import { useSettings } from "renderer/settings";
|
import { useSettings } from "renderer/settings";
|
||||||
|
|
||||||
export default function SettingsUi() {
|
export default function SettingsUi() {
|
||||||
@@ -72,6 +73,18 @@ export default function SettingsUi() {
|
|||||||
Start With System
|
Start With System
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
value={Settings.appBadge ?? true}
|
||||||
|
onChange={v => {
|
||||||
|
Settings.appBadge = v;
|
||||||
|
if (v) setBadge();
|
||||||
|
else VencordDesktopNative.app.setBadgeCount(0);
|
||||||
|
}}
|
||||||
|
note="Show mention badge on the app icon"
|
||||||
|
>
|
||||||
|
Notification Badge
|
||||||
|
</Switch>
|
||||||
|
|
||||||
{switches.map(([key, text, note, def, predicate]) => (
|
{switches.map(([key, text, note, def, predicate]) => (
|
||||||
<Switch
|
<Switch
|
||||||
value={(Settings[key as any] ?? def ?? false) && predicate?.() !== false}
|
value={(Settings[key as any] ?? def ?? false) && predicate?.() !== false}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import "./fixes";
|
import "./fixes";
|
||||||
|
import "./appBadge";
|
||||||
|
import "./patches";
|
||||||
|
|
||||||
console.log("read if cute :3");
|
console.log("read if cute :3");
|
||||||
|
|
||||||
|
|||||||
8
src/renderer/patches/index.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO: Possibly auto generate glob if we have more patches in the future
|
||||||
|
import "./spellCheck";
|
||||||
30
src/renderer/patches/shared.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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 { Patch } from "@vencord/types/utils/types";
|
||||||
|
|
||||||
|
window.VCDP = {};
|
||||||
|
|
||||||
|
interface PatchData {
|
||||||
|
patches: Omit<Patch, "plugin">[];
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addPatch<P extends PatchData>(p: P) {
|
||||||
|
const { patches, ...globals } = p;
|
||||||
|
|
||||||
|
for (const patch of patches as Patch[]) {
|
||||||
|
if (!Array.isArray(patch.replacement)) patch.replacement = [patch.replacement];
|
||||||
|
for (const r of patch.replacement) {
|
||||||
|
if (typeof r.replace === "string") r.replace = r.replace.replaceAll("$self", "VCDP");
|
||||||
|
}
|
||||||
|
|
||||||
|
patch.plugin = "VencordDesktop";
|
||||||
|
Vencord.Plugins.patches.push(patch as Patch);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(VCDP, globals);
|
||||||
|
}
|
||||||
60
src/renderer/patches/spellCheck.tsx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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 { addContextMenuPatch } from "@vencord/types/api/ContextMenu";
|
||||||
|
import { Menu } from "@vencord/types/webpack/common";
|
||||||
|
|
||||||
|
import { addPatch } from "./shared";
|
||||||
|
|
||||||
|
let word: string;
|
||||||
|
let corrections: string[];
|
||||||
|
|
||||||
|
// Make spellcheck suggestions work
|
||||||
|
addPatch({
|
||||||
|
patches: [
|
||||||
|
{
|
||||||
|
find: ".enableSpellCheck)",
|
||||||
|
replacement: {
|
||||||
|
// if (isDesktop) { DiscordNative.onSpellcheck(openMenu(props)) } else { e.preventDefault(); openMenu(props) }
|
||||||
|
match: /else\{.{1,3}\.preventDefault\(\);(.{1,3}\(.{1,3}\))\}/,
|
||||||
|
// ... else { $self.onSlateContext(() => openMenu(props)) }
|
||||||
|
replace: "else {$self.onSlateContext(() => $1)}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
onSlateContext(openMenu: () => void) {
|
||||||
|
const cb = (w: string, c: string[]) => {
|
||||||
|
VencordDesktopNative.spellcheck.offSpellcheckResult(cb);
|
||||||
|
word = w;
|
||||||
|
corrections = c;
|
||||||
|
openMenu();
|
||||||
|
};
|
||||||
|
VencordDesktopNative.spellcheck.onSpellcheckResult(cb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuPatch("textarea-context", children => () => {
|
||||||
|
if (!word || !corrections?.length) return;
|
||||||
|
|
||||||
|
children.push(
|
||||||
|
<Menu.MenuGroup>
|
||||||
|
{corrections.map(c => (
|
||||||
|
<Menu.MenuItem
|
||||||
|
id={"vcd-spellcheck-suggestion-" + c}
|
||||||
|
label={c}
|
||||||
|
action={() => VencordDesktopNative.spellcheck.replaceMisspelling(c)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
<Menu.MenuSeparator />
|
||||||
|
<Menu.MenuItem
|
||||||
|
id="vcd-spellcheck-learn"
|
||||||
|
label={`Add ${word} to dictionary`}
|
||||||
|
action={() => VencordDesktopNative.spellcheck.addToDictionary(word)}
|
||||||
|
/>
|
||||||
|
</Menu.MenuGroup>
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -27,6 +27,11 @@ export const enum IpcEvents {
|
|||||||
UPDATE_IGNORE = "VCD_UPDATE_IGNORE",
|
UPDATE_IGNORE = "VCD_UPDATE_IGNORE",
|
||||||
|
|
||||||
SPELLCHECK_SET_LANGUAGES = "VCD_SPELLCHECK_SET_LANGUAGES",
|
SPELLCHECK_SET_LANGUAGES = "VCD_SPELLCHECK_SET_LANGUAGES",
|
||||||
|
SPELLCHECK_RESULT = "VCD_SPELLCHECK_RESULT",
|
||||||
|
SPELLCHECK_REPLACE_MISSPELLING = "VCD_SPELLCHECK_REPLACE_MISSPELLING",
|
||||||
|
SPELLCHECK_ADD_TO_DICTIONARY = "VCD_SPELLCHECK_ADD_TO_DICTIONARY",
|
||||||
|
|
||||||
|
SET_BADGE_COUNT = "VCD_SET_BADGE_COUNT",
|
||||||
|
|
||||||
CAPTURER_GET_LARGE_THUMBNAIL = "VCD_CAPTURER_GET_LARGE_THUMBNAIL",
|
CAPTURER_GET_LARGE_THUMBNAIL = "VCD_CAPTURER_GET_LARGE_THUMBNAIL",
|
||||||
|
|
||||||
|
|||||||
@@ -7,4 +7,6 @@
|
|||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
|
|
||||||
export const STATIC_DIR = /* @__PURE__ */ join(__dirname, "..", "..", "static");
|
export const STATIC_DIR = /* @__PURE__ */ join(__dirname, "..", "..", "static");
|
||||||
|
export const VIEW_DIR = /* @__PURE__ */ join(STATIC_DIR, "views");
|
||||||
|
export const BADGE_DIR = /* @__PURE__ */ join(STATIC_DIR, "badges");
|
||||||
export const ICON_PATH = /* @__PURE__ */ join(STATIC_DIR, "icon.png");
|
export const ICON_PATH = /* @__PURE__ */ join(STATIC_DIR, "icon.png");
|
||||||
|
|||||||
1
src/shared/settings.d.ts
vendored
@@ -19,6 +19,7 @@ export interface Settings {
|
|||||||
skippedUpdate?: string;
|
skippedUpdate?: string;
|
||||||
staticTitle?: boolean;
|
staticTitle?: boolean;
|
||||||
arRPC?: boolean;
|
arRPC?: boolean;
|
||||||
|
appBadge?: boolean;
|
||||||
|
|
||||||
firstLaunch?: boolean;
|
firstLaunch?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { githubGet, ReleaseData } from "main/utils/vencordLoader";
|
|||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { SplashProps } from "shared/browserWinProperties";
|
import { SplashProps } from "shared/browserWinProperties";
|
||||||
import { IpcEvents } from "shared/IpcEvents";
|
import { IpcEvents } from "shared/IpcEvents";
|
||||||
import { STATIC_DIR } from "shared/paths";
|
import { VIEW_DIR } from "shared/paths";
|
||||||
|
|
||||||
export interface UpdateData {
|
export interface UpdateData {
|
||||||
currentVersion: string;
|
currentVersion: string;
|
||||||
@@ -101,5 +101,5 @@ function openNewUpdateWindow() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
win.loadFile(join(STATIC_DIR, "updater.html"));
|
win.loadFile(join(VIEW_DIR, "updater.html"));
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
static/badges/1.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/badges/10.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/badges/11.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/badges/2.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/badges/3.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/badges/4.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/badges/5.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/badges/6.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/badges/7.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/badges/8.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/badges/9.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |