diff --git a/package.json b/package.json index 81ee4b9..5bbec49 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "arrpc": "github:OpenAsar/arrpc#6960a8fd4d65d566da93dbdb8a7ca474aa0a3c9c" }, "optionalDependencies": { - "@vencord/venmic": "^3.4.2" + "@vencord/venmic": "^3.5.0" }, "devDependencies": { "@fal-works/esbuild-plugin-global-externals": "^2.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f7e1bd4..6221301 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,8 +13,8 @@ importers: version: https://codeload.github.com/OpenAsar/arrpc/tar.gz/6960a8fd4d65d566da93dbdb8a7ca474aa0a3c9c optionalDependencies: '@vencord/venmic': - specifier: ^3.4.2 - version: 3.4.2 + specifier: ^3.5.0 + version: 3.5.0 devDependencies: '@fal-works/esbuild-plugin-global-externals': specifier: ^2.1.2 @@ -603,8 +603,8 @@ packages: '@vencord/types@1.8.4': resolution: {integrity: sha512-ogLqIOHVO+5zxKUVxAfGIAUZoEfIomrlg6f0cZ/2yd5vBAn1fA9Gi/NASoKfHZuJt8ZcYw329bgn0ah/VufqMg==} - '@vencord/venmic@3.4.2': - resolution: {integrity: sha512-nwGjarof1wVvecGksGONfb+PduhY4gSuHTm39LktiQayHS69+yv4lepq4k1lxZzjOgFTy5VXfmJqxt+BpqoUUQ==} + '@vencord/venmic@3.5.0': + resolution: {integrity: sha512-kPvrPcIeMkuqQriuiQAJ9rEBeqGR2nmFBuUtbZRGyiNRF9RDAfWSJYqhHVm6F7wbcqrSZio6FazZuBo0LvjJRw==} engines: {node: '>=14.15'} os: [linux] @@ -678,6 +678,7 @@ packages: are-we-there-yet@3.0.1: resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1400,6 +1401,7 @@ packages: gauge@4.0.4: resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} @@ -1937,6 +1939,7 @@ packages: npmlog@6.0.2: resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. object-copy@0.1.0: resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} @@ -3028,7 +3031,7 @@ snapshots: standalone-electron-types: 1.0.0 type-fest: 3.13.1 - '@vencord/venmic@3.4.2': + '@vencord/venmic@3.5.0': dependencies: cmake-js: 7.3.0 node-addon-api: 8.0.0 diff --git a/src/main/ipc.ts b/src/main/ipc.ts index cd562e8..3a1a187 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -103,12 +103,8 @@ handle(IpcEvents.MAXIMIZE, e => { } }); -handle(IpcEvents.SPELLCHECK_SET_LANGUAGES, (_, languages: string[]) => { - const ses = session.defaultSession; - - const available = ses.availableSpellCheckerLanguages; - const applicable = languages.filter(l => available.includes(l)).slice(0, 3); - if (applicable.length) ses.setSpellCheckerLanguages(applicable); +handleSync(IpcEvents.SPELLCHECK_GET_AVAILABLE_LANGUAGES, e => { + e.returnValue = session.defaultSession.availableSpellCheckerLanguages; }); handle(IpcEvents.SPELLCHECK_REPLACE_MISSPELLING, (e, word: string) => { diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 92e2238..721114d 100755 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -14,6 +14,7 @@ import { nativeImage, nativeTheme, screen, + session, Tray } from "electron"; import { readFile, rm } from "fs/promises"; @@ -361,12 +362,27 @@ function initSettingsListeners(win: BrowserWindow) { addSettingsListener("enableMenu", enabled => { 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) { win.webContents.on("context-menu", (_, data) => { win.webContents.send(IpcEvents.SPELLCHECK_RESULT, data.misspelledWord, data.dictionarySuggestions); }); + + initSpellCheckLanguages(win, Settings.store.spellCheckLanguages); } function createMainWindow() { diff --git a/src/main/settings.ts b/src/main/settings.ts index 03c705e..f2c1b80 100644 --- a/src/main/settings.ts +++ b/src/main/settings.ts @@ -35,11 +35,6 @@ function loadSettings(file: string, name: string) { } export const Settings = loadSettings(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(VENCORD_SETTINGS_FILE, "Vencord settings"); diff --git a/src/preload/VesktopNative.ts b/src/preload/VesktopNative.ts index 731d602..88edbfc 100644 --- a/src/preload/VesktopNative.ts +++ b/src/preload/VesktopNative.ts @@ -43,7 +43,7 @@ export const VesktopNative = { set: (settings: Settings, path?: string) => invoke(IpcEvents.SET_SETTINGS, settings, path) }, spellcheck: { - setLanguages: (languages: readonly string[]) => invoke(IpcEvents.SPELLCHECK_SET_LANGUAGES, languages), + getAvailableLanguages: () => sendSync(IpcEvents.SPELLCHECK_GET_AVAILABLE_LANGUAGES), onSpellcheckResult(cb: SpellCheckerResultCallback) { spellCheckCallbacks.add(cb); }, diff --git a/src/preload/index.ts b/src/preload/index.ts index 2cc0d11..75bf9cd 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -40,5 +40,3 @@ if (IS_DEV) { }); } // #endregion - -VesktopNative.spellcheck.setLanguages(window.navigator.languages); diff --git a/src/renderer/index.ts b/src/renderer/index.ts index 1ccc2e4..99dca25 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -12,7 +12,7 @@ import "./themedSplash"; console.log("read if cute :3"); 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 SettingsUi from "./components/settings/Settings"; @@ -52,8 +52,10 @@ const arRPC = Vencord.Plugins.plugins["WebRichPresence (arRPC)"] as any as { handleEvent(e: MessageEvent): void; }; -VesktopNative.arrpc.onActivity(data => { +VesktopNative.arrpc.onActivity(async data => { if (!Settings.store.arRPC) return; + await onceReady; + arRPC.handleEvent(new MessageEvent("message", { data })); }); diff --git a/src/renderer/patches/spellCheck.tsx b/src/renderer/patches/spellCheck.tsx index 9f0dbbd..040d41b 100644 --- a/src/renderer/patches/spellCheck.tsx +++ b/src/renderer/patches/spellCheck.tsx @@ -6,7 +6,8 @@ import { addContextMenuPatch } from "@vencord/types/api/ContextMenu"; 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"; @@ -50,7 +51,16 @@ addContextMenuPatch("textarea-context", children => { const spellCheckEnabled = useStateFromStores([SpellCheckStore], () => SpellCheckStore.isEnabled()); 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, {hasCorrections && ( <> @@ -69,14 +79,39 @@ addContextMenuPatch("textarea-context", children => { /> )} - { - FluxDispatcher.dispatch({ type: "SPELLCHECK_TOGGLE" }); - }} - /> + + + { + FluxDispatcher.dispatch({ type: "SPELLCHECK_TOGGLE" }); + }} + /> + + + {availableLanguages.map(lang => { + const isEnabled = spellCheckLanguages.includes(lang); + return ( + = 5} + action={() => { + const newSpellCheckLanguages = spellCheckLanguages.filter(l => l !== lang); + if (newSpellCheckLanguages.length === spellCheckLanguages.length) { + newSpellCheckLanguages.push(lang); + } + + settings.spellCheckLanguages = newSpellCheckLanguages; + }} + /> + ); + })} + + ); }); diff --git a/src/shared/IpcEvents.ts b/src/shared/IpcEvents.ts index 002e0c6..b7813fd 100644 --- a/src/shared/IpcEvents.ts +++ b/src/shared/IpcEvents.ts @@ -29,7 +29,7 @@ export const enum IpcEvents { UPDATER_DOWNLOAD = "VCD_UPDATER_DOWNLOAD", 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_REPLACE_MISSPELLING = "VCD_SPELLCHECK_REPLACE_MISSPELLING", SPELLCHECK_ADD_TO_DICTIONARY = "VCD_SPELLCHECK_ADD_TO_DICTIONARY", diff --git a/src/shared/settings.d.ts b/src/shared/settings.d.ts index 430a2aa..6c746ba 100644 --- a/src/shared/settings.d.ts +++ b/src/shared/settings.d.ts @@ -22,8 +22,6 @@ export interface Settings { appBadge?: boolean; disableMinSize?: boolean; clickTrayToShowHide?: boolean; - /** @deprecated use customTitleBar */ - discordWindowsTitleBar?: boolean; customTitleBar?: boolean; checkUpdates?: boolean; @@ -31,6 +29,8 @@ export interface Settings { splashTheming?: boolean; splashColor?: string; splashBackground?: string; + + spellCheckLanguages?: string[]; } export interface State {