Add a few small features
- Fixes colored text - Fixes detach window not showing saved css (closes #635) - Adds option to prevent Discord from hijacking the media keys (closes #410) - Adds command line flag to launch a vanilla version of Discord `--vanilla` (closes #337) - Adds option for app-wide ctrl+shift+c shortcut for inspect element (closes #349) - Adds emote blocklist to BdApi via `BdApi.Emotes.blocklist` (closes #408)
This commit is contained in:
parent
59d9ec3dea
commit
a223806060
|
@ -8,4 +8,5 @@ export const RUN_SCRIPT = "bd-run-script";
|
|||
export const NAVIGATE = "bd-did-navigate-in-page";
|
||||
export const OPEN_DEVTOOLS = "bd-open-devtools";
|
||||
export const CLOSE_DEVTOOLS = "bd-close-devtools";
|
||||
export const OPEN_WINDOW = "bd-open-window";
|
||||
export const OPEN_WINDOW = "bd-open-window";
|
||||
export const INSPECT_ELEMENT = "bd-inspect-element";
|
|
@ -1,34 +1,35 @@
|
|||
const path = require("path");
|
||||
const electron = require("electron");
|
||||
const Module = require("module");
|
||||
import path from "path";
|
||||
import {app} from "electron";
|
||||
import Module from "module";
|
||||
|
||||
import ipc from "./modules/ipc";
|
||||
import BrowserWindow from "./modules/browserwindow";
|
||||
import CSP from "./modules/csp";
|
||||
|
||||
|
||||
process.env.NODE_OPTIONS = "--no-force-async-hooks-checks";
|
||||
electron.app.commandLine.appendSwitch("no-force-async-hooks-checks");
|
||||
process.electronBinding("command_line").appendSwitch("no-force-async-hooks-checks");
|
||||
if (!process.argv.includes("--vanilla")) {
|
||||
process.env.NODE_OPTIONS = "--no-force-async-hooks-checks";
|
||||
app.commandLine.appendSwitch("no-force-async-hooks-checks");
|
||||
process.electronBinding("command_line").appendSwitch("no-force-async-hooks-checks");
|
||||
|
||||
|
||||
// Patch and replace the built-in BrowserWindow
|
||||
BrowserWindow.patchBrowserWindow();
|
||||
// Patch and replace the built-in BrowserWindow
|
||||
BrowserWindow.patchBrowserWindow();
|
||||
|
||||
// Register all IPC events
|
||||
ipc.registerEvents();
|
||||
// Register all IPC events
|
||||
ipc.registerEvents();
|
||||
|
||||
|
||||
// Remove CSP immediately on linux since they install to discord_desktop_core still
|
||||
if (process.platform == "win32" || process.platform == "darwin") electron.app.once("ready", CSP.remove);
|
||||
else CSP.remove();
|
||||
// Remove CSP immediately on linux since they install to discord_desktop_core still
|
||||
if (process.platform == "win32" || process.platform == "darwin") app.once("ready", CSP.remove);
|
||||
else CSP.remove();
|
||||
}
|
||||
|
||||
// Use Discord's info to run the app
|
||||
if (process.platform == "win32" || process.platform == "darwin") {
|
||||
const basePath = path.join(electron.app.getAppPath(), "..", "app.asar");
|
||||
const basePath = path.join(app.getAppPath(), "..", "app.asar");
|
||||
const pkg = __non_webpack_require__(path.join(basePath, "package.json"));
|
||||
electron.app.setAppPath(basePath);
|
||||
electron.app.name = pkg.name;
|
||||
app.setAppPath(basePath);
|
||||
app.name = pkg.name;
|
||||
Module._load(path.join(basePath, pkg.main), null, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const electron = require("electron");
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import electron from "electron";
|
||||
|
||||
import ReactDevTools from "./reactdevtools";
|
||||
import * as IPCEvents from "common/constants/ipcevents";
|
||||
|
@ -21,8 +21,12 @@ electron.app.once("ready", async () => {
|
|||
await ReactDevTools.install();
|
||||
});
|
||||
|
||||
let hasCrashed = false;
|
||||
|
||||
if (BetterDiscord.getSetting("general", "mediaKeys")) {
|
||||
electron.app.commandLine.appendSwitch("disable-features", "HardwareMediaKeyHandling,MediaSessionService");
|
||||
}
|
||||
|
||||
let hasCrashed = false;
|
||||
export default class BetterDiscord {
|
||||
static getWindowPrefs() {
|
||||
if (!fs.existsSync(buildInfoFile)) return {};
|
||||
|
@ -37,7 +41,7 @@ export default class BetterDiscord {
|
|||
|
||||
try {
|
||||
const buildInfo = __non_webpack_require__(buildInfoFile);
|
||||
const settingsFile = path.resolve(dataPath, "data", buildInfo.releaseChannel, "settings.json");
|
||||
const settingsFile = path.resolve(dataPath, "data", buildInfo.releaseChannel, "settings.json");
|
||||
this._settings = __non_webpack_require__(settingsFile) ?? {};
|
||||
return this._settings[category]?.[key];
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const electron = require("electron");
|
||||
const path = require("path");
|
||||
import electron from "electron";
|
||||
import path from "path";
|
||||
|
||||
import BetterDiscord from "./betterdiscord";
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const electron = require("electron");
|
||||
import electron from "electron";
|
||||
|
||||
export default class {
|
||||
static remove() {
|
||||
|
|
|
@ -8,20 +8,20 @@ const getPath = (event, pathReq) => {
|
|||
case "appPath":
|
||||
returnPath = app.getAppPath();
|
||||
break;
|
||||
case "appData":
|
||||
case "userData":
|
||||
case "home":
|
||||
case "cache":
|
||||
case "temp":
|
||||
case "exe":
|
||||
case "module":
|
||||
case "desktop":
|
||||
case "documents":
|
||||
case "downloads":
|
||||
case "music":
|
||||
case "pictures":
|
||||
case "videos":
|
||||
case "recent":
|
||||
case "appData":
|
||||
case "userData":
|
||||
case "home":
|
||||
case "cache":
|
||||
case "temp":
|
||||
case "exe":
|
||||
case "module":
|
||||
case "desktop":
|
||||
case "documents":
|
||||
case "downloads":
|
||||
case "music":
|
||||
case "pictures":
|
||||
case "videos":
|
||||
case "recent":
|
||||
case "logs":
|
||||
returnPath = app.getPath(pathReq);
|
||||
break;
|
||||
|
@ -62,12 +62,21 @@ const createBrowserWindow = async (event, url, {windowOptions, closeOnUrl} = {})
|
|||
});
|
||||
};
|
||||
|
||||
const inspectElement = async event => {
|
||||
if (!event.sender.isDevToolsOpened()) {
|
||||
event.sender.openDevTools();
|
||||
while (!event.sender.isDevToolsOpened()) await new Promise(r => setTimeout(r, 100));
|
||||
}
|
||||
event.sender.devToolsWebContents.executeJavaScript("DevToolsAPI.enterInspectElementMode();");
|
||||
};
|
||||
|
||||
export default class IPCMain {
|
||||
static registerEvents() {
|
||||
ipc.on(IPCEvents.GET_PATH, getPath);
|
||||
ipc.on(IPCEvents.RELAUNCH, relaunch);
|
||||
ipc.on(IPCEvents.OPEN_DEVTOOLS, openDevTools);
|
||||
ipc.on(IPCEvents.CLOSE_DEVTOOLS, closeDevTools);
|
||||
ipc.on(IPCEvents.INSPECT_ELEMENT, inspectElement);
|
||||
ipc.handle(IPCEvents.RUN_SCRIPT, runScript);
|
||||
ipc.handle(IPCEvents.OPEN_WINDOW, createBrowserWindow);
|
||||
}
|
||||
|
|
|
@ -6174,9 +6174,9 @@
|
|||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.4.tgz",
|
||||
"integrity": "sha512-deLOfD+RvFgrpAmSZgfGdWYE+OKyHcVHaRQ7NphG/63scpRvTHHeQMAxGGvaLVGJ+HYVcCXlzcTK0ZehFf+eHQ==",
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
|
||||
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
|
@ -8812,8 +8812,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"readdirp": {
|
||||
"version": "3.4.0",
|
||||
|
|
|
@ -18,24 +18,10 @@ export default new class ColoredText extends Builtin {
|
|||
}
|
||||
|
||||
injectColoredText() {
|
||||
const MessageContent = WebpackModules.getModule(m => m.default && m.default.displayName && m.default.displayName == "Message");
|
||||
this.before(MessageContent, "default", (thisObject, [props]) => {
|
||||
if (!props || !props.childrenMessageContent) return;
|
||||
const messageContent = props.childrenMessageContent;
|
||||
if (!messageContent.type || !messageContent.type.type || messageContent.type.type.displayName != "MessageContent") return;
|
||||
|
||||
const originalType = messageContent.type.type;
|
||||
if (originalType.__originalMethod) return; // Don't patch again
|
||||
const self = this;
|
||||
messageContent.type.type = function (childProps) {
|
||||
const returnValue = originalType(childProps);
|
||||
const roleColor = self.getRoleColor(childProps.message.channel_id, childProps.message.author.id) || "";
|
||||
returnValue.props.style = {color: roleColor};
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
messageContent.type.type.__originalMethod = originalType;
|
||||
Object.assign(messageContent.type.type, originalType);
|
||||
const MessageContent = WebpackModules.getModule(m => m.type && m.type.displayName === "MessageContent");
|
||||
this.after(MessageContent, "type", (thisObject, [props], returnValue) => {
|
||||
const roleColor = this.getRoleColor(props.message.channel_id, props.message.author.id) || "";
|
||||
returnValue.props.style = {color: roleColor};
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ export {default as WindowPrefs} from "./windowprefs";
|
|||
export {default as ClassNormalizer} from "./general/classnormalizer";
|
||||
export {default as PublicServers} from "./general/publicservers";
|
||||
export {default as VoiceDisconnect} from "./general/voicedisconnect";
|
||||
export {default as MediaKeys} from "./general/mediakeys";
|
||||
|
||||
export {default as TwentyFourHour} from "./appearance/24hour";
|
||||
export {default as ColoredText} from "./appearance/coloredtext";
|
||||
|
@ -18,4 +19,5 @@ export {default as EmoteMenu} from "./emotes/emotemenu";
|
|||
// export {default as EmoteAutocaps} from "./emotes/emoteautocaps";
|
||||
|
||||
export {default as Debugger} from "./developer/debugger";
|
||||
export {default as ReactDevTools} from "./developer/reactdevtools";
|
||||
export {default as ReactDevTools} from "./developer/reactdevtools";
|
||||
export {default as InspectElement} from "./developer/inspectelement";
|
|
@ -71,7 +71,7 @@ export default new class CustomCSS extends Builtin {
|
|||
onClick: (thisObject) => {
|
||||
if (this.isDetached) return;
|
||||
if (this.nativeOpen) return this.openNative();
|
||||
else if (this.startDetached) return this.openDetached();
|
||||
else if (this.startDetached) return this.openDetached(this.savedCss);
|
||||
const settingsView = Utilities.findInRenderTree(thisObject._reactInternalFiber, m => m && m.onSetSection, {walkable: ["child", "memoizedProps", "props", "children"]});
|
||||
if (settingsView && settingsView.onSetSection) settingsView.onSetSection(this.id);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import Builtin from "../../structs/builtin";
|
||||
import IPC from "../../modules/ipc";
|
||||
|
||||
export default new class InspectElement extends Builtin {
|
||||
get name() {return "InspectElementHotkey";}
|
||||
get category() {return "developer";}
|
||||
get id() {return "inspectElement";}
|
||||
|
||||
enabled() {
|
||||
document.addEventListener("keydown", this.inspectElement);
|
||||
}
|
||||
|
||||
disabled() {
|
||||
document.removeEventListener("keydown", this.inspectElement);
|
||||
}
|
||||
|
||||
inspectElement(e) {
|
||||
if (e.ctrlKey && e.shiftKey && e.which === 67) { // Ctrl + Shift + C
|
||||
IPC.inspectElement();
|
||||
}
|
||||
}
|
||||
};
|
|
@ -37,7 +37,7 @@ export default new class EmoteModule extends Builtin {
|
|||
|
||||
get(id) {return super.get("emotes", "general", id);}
|
||||
|
||||
get MessageComponent() {return WebpackModules.find(m => m.default && m.default.displayName && m.default.displayName == "Message");}
|
||||
get MessageComponent() {return WebpackModules.find(m => m.default && m.default.toString().search("childrenRepliedMessage") > -1);}
|
||||
|
||||
get Emotes() {return Emotes;}
|
||||
get TwitchGlobal() {return Emotes.TwitchGlobal;}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import Builtin from "../../structs/builtin";
|
||||
import Modals from "../../ui/modals";
|
||||
import {Strings, IPC} from "modules";
|
||||
|
||||
export default new class MediaKeys extends Builtin {
|
||||
get name() {return "DisableMediaKeys";}
|
||||
get category() {return "general";}
|
||||
get id() {return "mediaKeys";}
|
||||
|
||||
enabled() {
|
||||
this.showModal();
|
||||
}
|
||||
|
||||
disabled() {
|
||||
this.showModal();
|
||||
}
|
||||
|
||||
showModal() {
|
||||
if (!this.initialized) return;
|
||||
Modals.showConfirmationModal(Strings.Modals.additionalInfo, Strings.Modals.restartPrompt, {
|
||||
confirmText: Strings.Modals.restartNow,
|
||||
cancelText: Strings.Modals.restartLater,
|
||||
danger: true,
|
||||
onConfirm: () => IPC.relaunch()
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
import Builtin from "../structs/builtin";
|
||||
import Modals from "../ui/modals";
|
||||
import {DataStore, Strings, IPC} from "modules";
|
||||
import {Strings, IPC} from "modules";
|
||||
|
||||
export default new class WindowPrefs extends Builtin {
|
||||
get name() {return "WindowPrefs";}
|
||||
|
|
|
@ -8,7 +8,8 @@ export default [
|
|||
{type: "switch", id: "publicServers", value: true},
|
||||
{type: "switch", id: "voiceDisconnect", value: false},
|
||||
{type: "switch", id: "classNormalizer", value: false},
|
||||
{type: "switch", id: "showToasts", value: true}
|
||||
{type: "switch", id: "showToasts", value: true},
|
||||
{type: "switch", id: "mediaKeys", value: false}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -52,7 +53,8 @@ export default [
|
|||
shown: false,
|
||||
settings: [
|
||||
{type: "switch", id: "debuggerHotkey", value: false},
|
||||
{type: "switch", id: "reactDevTools", value: false}
|
||||
{type: "switch", id: "reactDevTools", value: false},
|
||||
{type: "switch", id: "inspectElement", value: false}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -109,6 +109,10 @@ export default {
|
|||
reactDevTools: {
|
||||
name: "React Developer Tools",
|
||||
note: "Injects your local installation of React Developer Tools into Discord"
|
||||
},
|
||||
inspectElement: {
|
||||
name: "Inspect Element Hotkey",
|
||||
note: "Enables the inspect element hotkey (ctrl + shift + c) that is common in most browsers"
|
||||
}
|
||||
},
|
||||
window: {
|
||||
|
@ -150,6 +154,10 @@ export default {
|
|||
animateOnHover: {
|
||||
name: "Animate On Hover",
|
||||
note: "Only animate the emote modifiers on hover"
|
||||
},
|
||||
mediaKeys: {
|
||||
name: "Disable Media Keys",
|
||||
note: "Prevents Discord from hijacking your media keys after playing a video."
|
||||
}
|
||||
},
|
||||
categories: {
|
||||
|
@ -269,7 +277,7 @@ export default {
|
|||
},
|
||||
ReactDevTools: {
|
||||
notFound: "Extension Not Found",
|
||||
notFoundDetails: "Unable to find the React Developer Tools extension on your PC. Please install the extension on your local Chrome installation."
|
||||
notFoundDetails: "Unable to find the React Developer Tools extension on your PC. Please install the extension on your local Chrome installation."
|
||||
},
|
||||
Sorting: {
|
||||
sortBy: "Sort By",
|
||||
|
|
|
@ -31,4 +31,8 @@ export default new class IPCRenderer {
|
|||
openWindow(url, options) {
|
||||
return ipc.invoke(IPCEvents.OPEN_WINDOW, url, options);
|
||||
}
|
||||
|
||||
inspectElement() {
|
||||
ipc.send(IPCEvents.INSPECT_ELEMENT);
|
||||
}
|
||||
};
|
|
@ -21,6 +21,7 @@ const BdApi = {
|
|||
get emotes() {
|
||||
return new Proxy(Emotes.Emotes, {
|
||||
get(category) {
|
||||
if (category === "blocklist") return Emotes.blocklist;
|
||||
const group = Emotes.Emotes[category];
|
||||
if (!group) return undefined;
|
||||
return new Proxy(group, {
|
||||
|
|
Loading…
Reference in New Issue