Partial fix for swc

This commit is contained in:
Zack Rauen 2022-09-26 23:33:51 -04:00
parent 8601193b51
commit 90b2870aa2
23 changed files with 254 additions and 118 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "betterdiscord", "name": "betterdiscord",
"version": "1.6.3", "version": "1.7.0",
"description": "Enhances Discord by adding functionality and themes.", "description": "Enhances Discord by adding functionality and themes.",
"main": "src/index.js", "main": "src/index.js",
"scripts": { "scripts": {

View File

@ -6,8 +6,8 @@ export {default as PublicServers} from "./general/publicservers";
export {default as VoiceDisconnect} from "./general/voicedisconnect"; export {default as VoiceDisconnect} from "./general/voicedisconnect";
export {default as MediaKeys} from "./general/mediakeys"; export {default as MediaKeys} from "./general/mediakeys";
export {default as EmoteModule} from "./emotes/emotes"; // export {default as EmoteModule} from "./emotes/emotes";
export {default as EmoteMenu} from "./emotes/emotemenu"; // export {default as EmoteMenu} from "./emotes/emotemenu";
// export {default as EmoteAutocaps} from "./emotes/emoteautocaps"; // export {default as EmoteAutocaps} from "./emotes/emoteautocaps";
export {default as DevToolsListener} from "./developer/devtools"; export {default as DevToolsListener} from "./developer/devtools";

View File

@ -3,7 +3,24 @@ import {DiscordModules, WebpackModules, Strings, DOM, React} from "modules";
import PublicServersMenu from "../../ui/publicservers/menu"; import PublicServersMenu from "../../ui/publicservers/menu";
import Globe from "../../ui/icons/globe"; import Globe from "../../ui/icons/globe";
const LayerStack = WebpackModules.getByProps("pushLayer"); const LayerManager = {
pushLayer(component) {
DiscordModules.Dispatcher.dispatch({
type: "LAYER_PUSH",
component
});
},
popLayer() {
DiscordModules.Dispatcher.dispatch({
type: "LAYER_POP"
});
},
popAllLayers() {
DiscordModules.Dispatcher.dispatch({
type: "LAYER_POP_ALL"
});
}
};
class ErrorBoundary extends React.Component { class ErrorBoundary extends React.Component {
constructor(props) { constructor(props) {
@ -27,30 +44,36 @@ export default new class PublicServers extends Builtin {
get id() {return "publicServers";} get id() {return "publicServers";}
enabled() { enabled() {
const PrivateChannelList = WebpackModules.getModule(m => m?.displayName === "ConnectedPrivateChannelsList", {defaultExport: false}); // let target = null;
const PrivateChannelListComponents = WebpackModules.getByProps("LinkButton"); // WebpackModules.getModule((_, m) => {
this.after(PrivateChannelList, "default", (_, __, returnValue) => { // if (m.exports?.toString().includes("privateChannelIds")) {
const destination = returnValue?.props?.children?.props?.children; // target = m.exports;
if (!destination || !Array.isArray(destination)) return; // }
if (destination.find(b => b?.props?.children?.props?.id === "public-server-button")) return; // });
// if (!target || !target.Z) return;
// const PrivateChannelListComponents = WebpackModules.getByProps("LinkButton");
// this.after(target, "Z", (_, __, returnValue) => {
// const destination = returnValue?.props?.children?.props?.children;
// if (!destination || !Array.isArray(destination)) return;
// if (destination.find(b => b?.props?.children?.props?.id === "public-server-button")) return;
destination.push( // destination.push(
React.createElement(ErrorBoundary, null, // React.createElement(ErrorBoundary, null,
React.createElement(PrivateChannelListComponents.LinkButton, // React.createElement(PrivateChannelListComponents.LinkButton,
{ // {
id: "public-server-button", // id: "public-server-button",
onClick: () => this.openPublicServers(), // onClick: () => this.openPublicServers(),
text: "Public Servers", // text: "Public Servers",
icon: () => React.createElement(Globe, {color: "currentColor"}) // icon: () => React.createElement(Globe, {color: "currentColor"})
} // }
) // )
) // )
); // );
}); // });
} }
disabled() { disabled() {
this.unpatchAll(); // this.unpatchAll();
// DOM.query("#bd-pub-li").remove(); // DOM.query("#bd-pub-li").remove();
} }
@ -67,7 +90,7 @@ export default new class PublicServers extends Builtin {
} }
openPublicServers() { openPublicServers() {
LayerStack.pushLayer(() => DiscordModules.React.createElement(PublicServersMenu, {close: LayerStack.popLayer})); LayerManager.pushLayer(() => DiscordModules.React.createElement(PublicServersMenu, {close: LayerManager.popLayer}));
} }
get button() { get button() {

View File

@ -1,20 +1,23 @@
// fixed, improved, added, progress // fixed, improved, added, progress
export default { export default {
description: "Discord is _still_ making a lot of internal changes!", description: "BetterDiscord is alive! At least... _sorta_.",
changes: [ changes: [
{ {
title: "Changes", title: "Known Issues",
type: "improved", type: "improved",
items: [ items: [
"Plugin startup errors should be more descriptive for developers.", "**Many many plugins are either completely broken or missing functionality.** Please refer to the respective developers for ETAs.",
"The Twitch Emote system is completely broken, and there is no ETA on being fixed.",
"The Public Servers module is also broken with no ETA for a fix.",
] ]
}, },
{ {
title: "Fixes", title: "Important News!",
type: "fixed", type: "fixed",
items: [ items: [
"Fixed an issue where custom css crashed Discord.", "Due to recent and upcoming changes, BetterDiscord is going to go through a rewrite.",
"Fixed an issue where `waitForModule` returned a boolean instead of a module.", "There is no ETA or timeline for this rewrite.",
"We will continue to try and __maintain__ this version of BetterDiscord without adding new features."
] ]
} }
] ]

View File

@ -4,7 +4,7 @@ export default [
id: "general", id: "general",
collapsible: true, collapsible: true,
settings: [ settings: [
{type: "switch", id: "emotes", value: true}, {type: "switch", id: "emotes", value: true, disabled: true},
{type: "switch", id: "publicServers", value: true}, {type: "switch", id: "publicServers", value: true},
{type: "switch", id: "voiceDisconnect", value: false}, {type: "switch", id: "voiceDisconnect", value: false},
{type: "switch", id: "showToasts", value: true}, {type: "switch", id: "showToasts", value: true},

View File

@ -8,8 +8,8 @@ import BDLogo from "../ui/icons/bdlogo";
import Logger from "common/logger"; import Logger from "common/logger";
const React = DiscordModules.React; const React = DiscordModules.React;
const Tooltip = WebpackModules.getByDisplayName("Tooltip"); const Tooltip = WebpackModules.getByPrototypes("renderTooltip");
const Anchor = WebpackModules.getByDisplayName("Anchor"); const Anchor = WebpackModules.getByProps("Link");
const Developers = [ const Developers = [
/* Zerebos#7790 */ /* Zerebos#7790 */
@ -21,7 +21,7 @@ const Developers = [
const DeveloperBadge = function DeveloperBadge({type, size = 16}) { const DeveloperBadge = function DeveloperBadge({type, size = 16}) {
return React.createElement(Tooltip, {color: "primary", position: "top", text: "BetterDiscord Developer"}, return React.createElement(Tooltip, {color: "primary", position: "top", text: "BetterDiscord Developer"},
props => React.createElement(Anchor, Object.assign({className: `bd-${type}-badge`, href: "https://github.com/BetterDiscord/BetterDiscord", title: "BetterDiscord", target: "_blank"}, props), props => React.createElement(Anchor.Link, Object.assign({className: `bd-${type}-badge`, href: "https://github.com/BetterDiscord/BetterDiscord", title: "BetterDiscord", target: "_blank"}, props),
React.createElement(BDLogo, {size, className: "bd-logo"}) React.createElement(BDLogo, {size, className: "bd-logo"})
) )
); );
@ -33,14 +33,14 @@ export default new class ComponentPatcher {
debug(...message) {return Logger.debug("ComponentPatcher", ...message);} debug(...message) {return Logger.debug("ComponentPatcher", ...message);}
initialize() { initialize() {
Utilities.suppressErrors(this.patchSocial.bind(this), "BD Social Patch")(); // Utilities.suppressErrors(this.patchSocial.bind(this), "BD Social Patch")();
Utilities.suppressErrors(this.patchMemberList.bind(this), "BD Member List Patch")(); // Utilities.suppressErrors(this.patchMemberList.bind(this), "BD Member List Patch")();
Utilities.suppressErrors(this.patchProfile.bind(this), "BD Profile Badges Patch")(); // Utilities.suppressErrors(this.patchProfile.bind(this), "BD Profile Badges Patch")();
} }
patchSocial() { patchSocial() {
if (this.socialPatch) return; if (this.socialPatch) return;
const TabBar = WebpackModules.getByDisplayName("TabBar"); const TabBar = WebpackModules.getByProps("Types", "Looks", "Header");
if (!TabBar) return; if (!TabBar) return;
this.socialPatch = Patcher.after("ComponentPatcher", TabBar.prototype, "render", (thisObject, args, returnValue) => { this.socialPatch = Patcher.after("ComponentPatcher", TabBar.prototype, "render", (thisObject, args, returnValue) => {
const children = returnValue.props.children; const children = returnValue.props.children;
@ -99,7 +99,7 @@ export default new class ComponentPatcher {
patchProfile() { patchProfile() {
if (this.profilePatch) return; if (this.profilePatch) return;
const UserProfileBadgeLists = WebpackModules.getModule(m => m?.default?.displayName === "UserProfileBadgeList", {first: false}); const UserProfileBadgeLists = WebpackModules.getModule(m => m?.toString()?.includes("PROFILE_USER_BADGES"), {first: false});
for (const UserProfileBadgeList of UserProfileBadgeLists) { for (const UserProfileBadgeList of UserProfileBadgeLists) {
this.profilePatch = Patcher.after("ComponentPatcher", UserProfileBadgeList, "default", (_, [{user}], res) => { this.profilePatch = Patcher.after("ComponentPatcher", UserProfileBadgeList, "default", (_, [{user}], res) => {
if (Developers.indexOf(user?.id) < 0) return; if (Developers.indexOf(user?.id) < 0) return;

View File

@ -3,6 +3,7 @@ import LocaleManager from "./localemanager";
import Logger from "common/logger"; import Logger from "common/logger";
import {Config, Changelog} from "data"; import {Config, Changelog} from "data";
import WebpackModules from "./webpackmodules";
import DOMManager from "./dommanager"; import DOMManager from "./dommanager";
import PluginManager from "./pluginmanager"; import PluginManager from "./pluginmanager";
import ThemeManager from "./thememanager"; import ThemeManager from "./thememanager";
@ -18,7 +19,6 @@ import IPC from "./ipc";
import LoadingIcon from "../loadingicon"; import LoadingIcon from "../loadingicon";
import Styles from "../styles/index.css"; import Styles from "../styles/index.css";
import Editor from "./editor"; import Editor from "./editor";
import {WebpackModules} from "modules";
export default new class Core { export default new class Core {
async startup() { async startup() {
@ -48,6 +48,7 @@ export default new class Core {
Logger.log("Startup", "Initializing Settings"); Logger.log("Startup", "Initializing Settings");
Settings.initialize(); Settings.initialize();
// SettingsRenderer.patchSections();
Logger.log("Startup", "Initializing DOMManager"); Logger.log("Startup", "Initializing DOMManager");
DOMManager.initialize(); DOMManager.initialize();
@ -68,6 +69,7 @@ export default new class Core {
for (const module in Builtins) { for (const module in Builtins) {
Builtins[module].initialize(); Builtins[module].initialize();
} }
this.polyfillWebpack(); this.polyfillWebpack();
Logger.log("Startup", "Loading Plugins"); Logger.log("Startup", "Loading Plugins");
// const pluginErrors = []; // const pluginErrors = [];
@ -86,9 +88,18 @@ export default new class Core {
const previousVersion = DataStore.getBDData("version"); const previousVersion = DataStore.getBDData("version");
if (Config.version > previousVersion) { if (Config.version > previousVersion) {
Modals.showChangelogModal(Changelog); // Modals.showChangelogModal(Changelog);
const md = [Changelog.description];
for (const type of Changelog.changes) {
md.push(`**${type.title}**`);
for (const entry of type.items) {
md.push(` - ${entry}`);
}
}
Modals.showConfirmationModal(`BetterDiscord v${Config.version}`, md, {cancelText: ""});
DataStore.setBDData("version", Config.version); DataStore.setBDData("version", Config.version);
} }
// SettingsRenderer.patchSections();
} }
polyfillWebpack() { polyfillWebpack() {

View File

@ -47,7 +47,7 @@ export default Utilities.memoizeObject({
get MentionStore() {return WebpackModules.getByProps("getMentions");}, get MentionStore() {return WebpackModules.getByProps("getMentions");},
/* User Stores and Utils */ /* User Stores and Utils */
get UserStore() {return WebpackModules.getByProps("getCurrentUser");}, get UserStore() {return WebpackModules.getByProps("getCurrentUser", "getUser");},
get UserStatusStore() {return WebpackModules.getByProps("getStatus", "getState");}, get UserStatusStore() {return WebpackModules.getByProps("getStatus", "getState");},
get UserTypingStore() {return WebpackModules.getByProps("isTyping");}, get UserTypingStore() {return WebpackModules.getByProps("isTyping");},
get UserActivityStore() {return WebpackModules.getByProps("getActivity");}, get UserActivityStore() {return WebpackModules.getByProps("getActivity");},
@ -133,14 +133,14 @@ export default Utilities.memoizeObject({
/* Electron & Other Internals with Utils*/ /* Electron & Other Internals with Utils*/
get ElectronModule() {return WebpackModules.getByProps("setBadge");}, get ElectronModule() {return WebpackModules.getByProps("setBadge");},
get Dispatcher() {return WebpackModules.getByProps("dispatch", "subscribe");}, get Dispatcher() {return WebpackModules.getByProps("dispatch", "subscribe", "register");},
get PathUtils() {return WebpackModules.getByProps("hasBasename");}, get PathUtils() {return WebpackModules.getByProps("hasBasename");},
get NotificationModule() {return WebpackModules.getByProps("showNotification");}, get NotificationModule() {return WebpackModules.getByProps("showNotification");},
get RouterModule() {return WebpackModules.getByProps("Router");}, get RouterModule() {return WebpackModules.getByProps("Router");},
get APIModule() {return WebpackModules.getByProps("getAPIBaseURL");}, get APIModule() {return WebpackModules.getByProps("getAPIBaseURL");},
get AnalyticEvents() {return WebpackModules.getByProps("AnalyticEventConfigs");}, get AnalyticEvents() {return WebpackModules.getByProps("AnalyticEventConfigs");},
get KeyGenerator() {return WebpackModules.getByRegex(/"binary"/);}, get KeyGenerator() {return WebpackModules.getByRegex(/"binary"/);},
get Buffers() {return WebpackModules.getByProps("Buffer", "kMaxLength");}, get Buffers() {return WebpackModules.getByProps("INSPECT_MAX_BYTES", "kMaxLength");},
get DeviceStore() {return WebpackModules.getByProps("getDevices");}, get DeviceStore() {return WebpackModules.getByProps("getDevices");},
get SoftwareInfo() {return WebpackModules.getByProps("os");}, get SoftwareInfo() {return WebpackModules.getByProps("os");},
get CurrentContext() {return WebpackModules.getByProps("setTagsContext");}, get CurrentContext() {return WebpackModules.getByProps("setTagsContext");},

View File

@ -16,10 +16,7 @@ export default new class LocaleManager {
initialize() { initialize() {
this.setLocale(this.discordLocale); this.setLocale(this.discordLocale);
Dispatcher.subscribe("USER_SETTINGS_UPDATE", ({settings}) => { Dispatcher.subscribe("USER_SETTINGS_UPDATE", (newLocale) => this.setLocale(newLocale));
const newLocale = settings.locale;
if (newLocale && newLocale != this.locale) this.setLocale(newLocale);
});
} }
setLocale(newLocale) { setLocale(newLocale) {

View File

@ -146,6 +146,7 @@ export default class WebpackModules {
return false; return false;
} }
}; };
const modules = this.getAllModules(); const modules = this.getAllModules();
const rm = []; const rm = [];
const indices = Object.keys(modules); const indices = Object.keys(modules);
@ -154,14 +155,42 @@ export default class WebpackModules {
if (!modules.hasOwnProperty(index)) continue; if (!modules.hasOwnProperty(index)) continue;
const module = modules[index]; const module = modules[index];
const {exports} = module; const {exports} = module;
if (exports === window) continue;
let foundModule = null; let foundModule = null;
if (!exports) continue; if (typeof(exports) === "object") {
if (exports.__esModule && exports.default && wrappedFilter(exports.default, module, index)) foundModule = defaultExport ? exports.default : exports; const wrappers = Object.getOwnPropertyDescriptors(exports);
if (wrappedFilter(exports, module, index)) foundModule = exports; const getters = Object.keys(wrappers).filter(k => wrappers[k].get);
if (!foundModule) continue; if (getters.length) {
if (first) return foundModule; for (const getter of getters) {
rm.push(foundModule); const wrappedExport = exports[getter];
if (!wrappedExport) continue;
if (wrappedExport.__esModule && wrappedExport.default && wrappedFilter(wrappedExport.default, module, index)) foundModule = defaultExport ? wrappedExport.default : wrappedExport;
if (wrappedFilter(wrappedExport, module, index)) foundModule = wrappedExport;
if (!foundModule) continue;
if (first) return foundModule;
rm.push(foundModule);
}
}
else {
if (!exports) continue;
if (exports.__esModule && exports.default && wrappedFilter(exports.default, module, index)) foundModule = defaultExport ? exports.default : exports;
if (wrappedFilter(exports, module, index)) foundModule = exports;
if (!foundModule) continue;
if (first) return foundModule;
rm.push(foundModule);
}
}
else {
if (!exports) continue;
if (exports.__esModule && exports.default && wrappedFilter(exports.default, module, index)) foundModule = defaultExport ? exports.default : exports;
if (wrappedFilter(exports, module, index)) foundModule = exports;
if (!foundModule) continue;
if (first) return foundModule;
rm.push(foundModule);
}
} }
return first || rm.length == 0 ? undefined : rm; return first || rm.length == 0 ? undefined : rm;
@ -205,11 +234,36 @@ export default class WebpackModules {
}; };
let foundModule = null; let foundModule = null;
if (exports.__esModule && exports.default && wrappedFilter(exports.default, module, index)) foundModule = defaultExport ? exports.default : exports; if (typeof(exports) === "object") {
if (wrappedFilter(exports, module, index)) foundModule = exports; const wrappers = Object.getOwnPropertyDescriptors(exports);
if (!foundModule) continue; const getters = Object.keys(wrappers).filter(k => wrappers[k].get);
if (first) returnedModules[q] = protect(foundModule); if (getters.length) {
else returnedModules[q].push(protect(foundModule)); for (const getter of getters) {
const wrappedExport = exports[getter];
if (!wrappedExport) continue;
if (wrappedExport.__esModule && wrappedExport.default && wrappedFilter(wrappedExport.default, module, index)) foundModule = defaultExport ? wrappedExport.default : wrappedExport;
if (wrappedFilter(wrappedExport, module, index)) foundModule = wrappedExport;
if (!foundModule) continue;
if (first) returnedModules[q] = foundModule;
else returnedModules[q].push(foundModule);
}
}
else {
if (!exports) continue;
if (exports.__esModule && exports.default && wrappedFilter(exports.default, module, index)) foundModule = defaultExport ? exports.default : exports;
if (wrappedFilter(exports, module, index)) foundModule = exports;
if (!foundModule) continue;
if (first) returnedModules[q] = foundModule;
else returnedModules[q].push(foundModule);
}
}
else {
if (exports.__esModule && exports.default && wrappedFilter(exports.default, module, index)) foundModule = defaultExport ? exports.default : exports;
if (wrappedFilter(exports, module, index)) foundModule = exports;
if (!foundModule) continue;
if (first) returnedModules[q] = foundModule;
else returnedModules[q].push(foundModule);
}
} }
} }
@ -327,12 +381,30 @@ export default class WebpackModules {
if (!exports) return; if (!exports) return;
let foundModule = null; let foundModule = null;
if (exports.__esModule && exports.default && wrappedFilter(exports.default)) foundModule = defaultExport ? exports.default : exports; if (typeof(exports) === "object") {
if (wrappedFilter(exports)) foundModule = exports; const wrappers = Object.getOwnPropertyDescriptors(exports);
if (!foundModule) return; const getters = Object.keys(wrappers).filter(k => wrappers[k].get);
if (getters.length) {
for (const getter of getters) {
const wrappedExport = exports[getter];
if (!wrappedExport) continue;
if (wrappedExport.__esModule && wrappedExport.default && wrappedFilter(wrappedExport.default)) foundModule = defaultExport ? wrappedExport.default : wrappedExport;
if (wrappedFilter(wrappedExport)) foundModule = wrappedExport;
}
}
else {
if (exports.__esModule && exports.default && wrappedFilter(exports.default)) foundModule = defaultExport ? exports.default : exports;
if (wrappedFilter(exports)) foundModule = exports;
}
}
else {
if (exports.__esModule && exports.default && wrappedFilter(exports.default)) foundModule = defaultExport ? exports.default : exports;
if (wrappedFilter(exports)) foundModule = exports;
}
if (!foundModule) return;
cancel(); cancel();
resolve(protect(foundModule)); resolve(foundModule);
}; };
this.addListener(listener); this.addListener(listener);

View File

@ -10,7 +10,7 @@ export default class Buffer {
static getBuffer() { static getBuffer() {
if (this.cached) return this.cached; if (this.cached) return this.cached;
this.cached = WebpackModules.getByProps("Buffer", "SlowBuffer"); this.cached = WebpackModules.getByProps("INSPECT_MAX_BYTES");
return this.cached; return this.cached;
} }

View File

@ -34,9 +34,10 @@ function validOptions(url, callback) {
function fixBuffer(options, callback) { function fixBuffer(options, callback) {
return (error, res, body) => { return (error, res, body) => {
if ("Content-Type" in Object(options.headers) && props.headers["Content-Type"] !== "text/plain") { if ("Content-Type" in Object(options.headers) && options.headers["Content-Type"] !== "text/plain") {
body = Buffer.from(body); body = Buffer.from(body);
} else { }
else {
body = Buffer.from(body).toString(); body = Buffer.from(body).toString();
} }

View File

@ -2,7 +2,7 @@ import {React, WebpackModules, DiscordModules, Settings} from "modules";
import Checkbox from "./checkbox"; import Checkbox from "./checkbox";
const Tooltip = WebpackModules.getByDisplayName("Tooltip"); const Tooltip = WebpackModules.getByPrototypes("renderTooltip");
const ThemeStore = DiscordModules.ThemeStore; const ThemeStore = DiscordModules.ThemeStore;
const languages = ["abap", "abc", "actionscript", "ada", "apache_conf", "asciidoc", "assembly_x86", "autohotkey", "batchfile", "bro", "c_cpp", "c9search", "cirru", "clojure", "cobol", "coffee", "coldfusion", "csharp", "csound_document", "csound_orchestra", "csound_score", "css", "curly", "d", "dart", "diff", "dockerfile", "dot", "drools", "dummy", "dummysyntax", "eiffel", "ejs", "elixir", "elm", "erlang", "forth", "fortran", "ftl", "gcode", "gherkin", "gitignore", "glsl", "gobstones", "golang", "graphqlschema", "groovy", "haml", "handlebars", "haskell", "haskell_cabal", "haxe", "hjson", "html", "html_elixir", "html_ruby", "ini", "io", "jack", "jade", "java", "javascript", "json", "jsoniq", "jsp", "jssm", "jsx", "julia", "kotlin", "latex", "less", "liquid", "lisp", "livescript", "logiql", "lsl", "lua", "luapage", "lucene", "makefile", "markdown", "mask", "matlab", "maze", "mel", "mushcode", "mysql", "nix", "nsis", "objectivec", "ocaml", "pascal", "perl", "pgsql", "php", "pig", "powershell", "praat", "prolog", "properties", "protobuf", "python", "r", "razor", "rdoc", "red", "rhtml", "rst", "ruby", "rust", "sass", "scad", "scala", "scheme", "scss", "sh", "sjs", "smarty", "snippets", "soy_template", "space", "sql", "sqlserver", "stylus", "svg", "swift", "tcl", "tex", "text", "textile", "toml", "tsx", "twig", "typescript", "vala", "vbscript", "velocity", "verilog", "vhdl", "wollok", "xml", "xquery", "yaml", "django"]; const languages = ["abap", "abc", "actionscript", "ada", "apache_conf", "asciidoc", "assembly_x86", "autohotkey", "batchfile", "bro", "c_cpp", "c9search", "cirru", "clojure", "cobol", "coffee", "coldfusion", "csharp", "csound_document", "csound_orchestra", "csound_score", "css", "curly", "d", "dart", "diff", "dockerfile", "dot", "drools", "dummy", "dummysyntax", "eiffel", "ejs", "elixir", "elm", "erlang", "forth", "fortran", "ftl", "gcode", "gherkin", "gitignore", "glsl", "gobstones", "golang", "graphqlschema", "groovy", "haml", "handlebars", "haskell", "haskell_cabal", "haxe", "hjson", "html", "html_elixir", "html_ruby", "ini", "io", "jack", "jade", "java", "javascript", "json", "jsoniq", "jsp", "jssm", "jsx", "julia", "kotlin", "latex", "less", "liquid", "lisp", "livescript", "logiql", "lsl", "lua", "luapage", "lucene", "makefile", "markdown", "mask", "matlab", "maze", "mel", "mushcode", "mysql", "nix", "nsis", "objectivec", "ocaml", "pascal", "perl", "pgsql", "php", "pig", "powershell", "praat", "prolog", "properties", "protobuf", "python", "r", "razor", "rdoc", "red", "rhtml", "rst", "ruby", "rust", "sass", "scad", "scala", "scheme", "scss", "sh", "sjs", "smarty", "snippets", "soy_template", "space", "sql", "sqlserver", "stylus", "svg", "swift", "tcl", "tex", "text", "textile", "toml", "tsx", "twig", "typescript", "vala", "vbscript", "velocity", "verilog", "vhdl", "wollok", "xml", "xquery", "yaml", "django"];

View File

@ -1,6 +1,6 @@
import {Settings, React, WebpackModules, Events, Strings} from "modules"; import {Settings, React, WebpackModules, Events, Strings} from "modules";
const TooltipWrapper = WebpackModules.getByDisplayName("Tooltip"); const TooltipWrapper = WebpackModules.getByPrototypes("renderTooltip");
export default class BDEmote extends React.Component { export default class BDEmote extends React.Component {
constructor(props) { constructor(props) {

View File

@ -2,9 +2,9 @@ import {React, WebpackModules} from "modules";
import EmoteModule from "../builtins/emotes/emotes"; import EmoteModule from "../builtins/emotes/emotes";
const ContextMenuActions = WebpackModules.getByProps("openContextMenu"); const ContextMenuActions = WebpackModules.getByProps("openContextMenu");
const {MenuItem, MenuGroup} = WebpackModules.find(m => m.MenuRadioItem && !m.default); const {MenuItem, MenuGroup} = WebpackModules.find(m => m.MenuRadioItem && !m.default) ?? {MenuItem: () => null, MenuGroup: () => null};
const ContextMenu = WebpackModules.getByProps("default", "MenuStyle").default; const ContextMenu = WebpackModules.getByProps("default", "MenuStyle")?.default;
const {ComponentDispatch} = WebpackModules.getByProps("ComponentDispatch"); const {ComponentDispatch} = WebpackModules.getByProps("ComponentDispatch") ?? {ComponentDispatch: () => null};
export default class EmoteIcon extends React.Component { export default class EmoteIcon extends React.Component {
render() { render() {

View File

@ -1,5 +1,5 @@
import {React, WebpackModules} from "modules"; import {React, WebpackModules} from "modules";
const {ScrollerAuto: Scroller} = WebpackModules.getByProps("ScrollerAuto"); const {ScrollerAuto: Scroller} = WebpackModules.getByProps("ScrollerAuto") ?? {ScrollerAuto: () => null};
export default class EmoteMenuCard extends React.Component { export default class EmoteMenuCard extends React.Component {
render() { render() {
return <div className={`bd-emote-menu`}> return <div className={`bd-emote-menu`}>

View File

@ -3,14 +3,14 @@ import FloatingWindowContainer from "./floating/container";
/* eslint-disable new-cap */ /* eslint-disable new-cap */
const LayerProviders = WebpackModules.getByProps("AppReferencePositionLayer"); const AppLayerProvider = WebpackModules.getByDisplayName("AppLayerProvider");
export default class FloatingWindows { export default class FloatingWindows {
static initialize() { static initialize() {
const containerRef = React.createRef(); const containerRef = React.createRef();
const container = <FloatingWindowContainer ref={containerRef} />; const container = <FloatingWindowContainer ref={containerRef} />;
const wrapped = LayerProviders const wrapped = AppLayerProvider
? React.createElement(LayerProviders.AppLayerProvider().props.layerContext.Provider, {value: [document.querySelector("#app-mount > .layerContainer-yqaFcK")]}, container) // eslint-disable-line new-cap ? React.createElement(AppLayerProvider().props.layerContext.Provider, {value: [document.querySelector("#app-mount > .layerContainer-2v_Sit")]}, container) // eslint-disable-line new-cap
: container; : container;
const div = DOM.createElement(`<div id="floating-windows-layer">`); const div = DOM.createElement(`<div id="floating-windows-layer">`);
DOMManager.bdBody.append(div); DOMManager.bdBody.append(div);

View File

@ -5,21 +5,27 @@ import FormattableString from "../structs/string";
import AddonErrorModal from "./addonerrormodal"; import AddonErrorModal from "./addonerrormodal";
import ErrorBoundary from "./errorboundary"; import ErrorBoundary from "./errorboundary";
export default class Modals { export default class Modals {
static get shouldShowAddonErrors() {return Settings.get("settings", "addons", "addonErrors");} static get shouldShowAddonErrors() {return Settings.get("settings", "addons", "addonErrors");}
static get ModalActions() {return WebpackModules.getByProps("openModal", "updateModal");} static get ModalActions() {
return {
openModal: WebpackModules.getModule(m => m?.toString().includes("onCloseCallback") && m?.toString().includes("Layer")),
closeModal: WebpackModules.getModule(m => m?.toString().includes("onCloseCallback()"))
};
}
static get ModalStack() {return WebpackModules.getByProps("push", "update", "pop", "popWithKey");} static get ModalStack() {return WebpackModules.getByProps("push", "update", "pop", "popWithKey");}
static get ModalComponents() {return WebpackModules.getByProps("ModalRoot");} static get ModalComponents() {return WebpackModules.getByProps("Header", "Footer");}
static get ModalRoot() {return WebpackModules.getModule(m => m?.toString().includes("ENTERING"));}
static get ModalClasses() {return WebpackModules.getByProps("modal", "content");} static get ModalClasses() {return WebpackModules.getByProps("modal", "content");}
static get AlertModal() {return WebpackModules.getByPrototypes("handleCancel", "handleSubmit", "handleMinorConfirm");}
static get FlexElements() {return WebpackModules.getByProps("Child", "Align");} static get FlexElements() {return WebpackModules.getByProps("Child", "Align");}
static get FormTitle() {return WebpackModules.findByDisplayName("FormTitle");} static get FormTitle() {return WebpackModules.getByProps("Tags", "Sizes");}
static get TextElement() {return WebpackModules.getByProps("Sizes", "Weights");} static get TextElement() {return WebpackModules.getModule(m => m?.Sizes?.SIZE_32 && m.Colors);}
static get ConfirmationModal() {return WebpackModules.findByDisplayName("ConfirmModal");} static get ConfirmationModal() {return WebpackModules.getModule(m => m?.toString()?.includes("confirmText"));}
static get Markdown() {return WebpackModules.find(m => m.displayName === "Markdown" && m.rules);} static get Markdown() {return WebpackModules.find(m => m?.prototype?.render && m.rules);}
static get Buttons() {return WebpackModules.getByProps("ButtonSizes");} static get Buttons() {return WebpackModules.getByProps("BorderColors");}
static default(title, content) { static default(title, content) {
const modal = DOM.createElement(`<div class="bd-modal-wrapper theme-dark"> const modal = DOM.createElement(`<div class="bd-modal-wrapper theme-dark">
@ -86,7 +92,7 @@ export default class Modals {
return ModalActions.openModal(props => { return ModalActions.openModal(props => {
return React.createElement(ConfirmationModal, Object.assign({ return React.createElement(ConfirmationModal, Object.assign({
header: title, header: title,
confirmButtonColor: danger ? this.Buttons.ButtonColors.RED : this.Buttons.ButtonColors.BRAND, confirmButtonColor: danger ? this.Buttons.Colors.RED : this.Buttons.Colors.BRAND,
confirmText: confirmText, confirmText: confirmText,
cancelText: cancelText, cancelText: cancelText,
onConfirm: onConfirm, onConfirm: onConfirm,
@ -104,7 +110,7 @@ export default class Modals {
} }
this.addonErrorsRef = React.createRef(); this.addonErrorsRef = React.createRef();
this.ModalActions.openModal(props => React.createElement(this.ModalComponents.ModalRoot, Object.assign(props, { this.ModalActions.openModal(props => React.createElement(this.ModalRoot, Object.assign(props, {
size: "medium", size: "medium",
className: "bd-error-modal", className: "bd-error-modal",
children: [ children: [
@ -114,9 +120,9 @@ export default class Modals {
themeErrors: Array.isArray(themeErrors) ? themeErrors : [], themeErrors: Array.isArray(themeErrors) ? themeErrors : [],
onClose: props.onClose onClose: props.onClose
}), }),
React.createElement(this.ModalComponents.ModalFooter, { React.createElement(this.ModalComponents.Footer, {
className: "bd-error-modal-footer", className: "bd-error-modal-footer",
}, React.createElement(this.Buttons.default, { }, React.createElement(this.Buttons, {
onClick: props.onClose, onClick: props.onClose,
className: "bd-button" className: "bd-button"
}, Strings.Modals.okay)) }, Strings.Modals.okay))
@ -221,17 +227,17 @@ export default class Modals {
const mc = this.ModalComponents; const mc = this.ModalComponents;
const modal = props => { const modal = props => {
return React.createElement(mc.ModalRoot, Object.assign({size: mc.ModalSize.MEDIUM, className: "bd-addon-modal"}, props), return React.createElement(ErrorBoundary, {}, React.createElement(this.ModalRoot, Object.assign({size: mc.Sizes.MEDIUM, className: "bd-addon-modal" + " " + mc.Sizes.MEDIUM}, props),
React.createElement(mc.ModalHeader, {separator: false, className: "bd-addon-modal-header"}, React.createElement(mc.Header, {separator: false, className: "bd-addon-modal-header"},
React.createElement(this.FormTitle, {tag: "h4"}, `${name} Settings`) React.createElement(this.FormTitle, {tag: "h4"}, `${name} Settings`)
), ),
React.createElement(mc.ModalContent, {className: "bd-addon-modal-settings"}, React.createElement(mc.Content, {className: "bd-addon-modal-settings"},
React.createElement(ErrorBoundary, {}, child) React.createElement(ErrorBoundary, {}, child)
), ),
React.createElement(mc.ModalFooter, {className: "bd-addon-modal-footer"}, React.createElement(mc.Footer, {className: "bd-addon-modal-footer"},
React.createElement(this.Buttons.default, {onClick: props.onClose, className: "bd-button"}, Strings.Modals.done) React.createElement(this.Buttons, {onClick: props.onClose, className: "bd-button"}, Strings.Modals.done)
) )
); ));
}; };
return this.ModalActions.openModal(props => { return this.ModalActions.openModal(props => {

View File

@ -1,4 +1,4 @@
import {React, WebpackModules, Strings} from "modules"; import {React, WebpackModules, Strings, DiscordModules} from "modules";
import Modals from "../modals"; import Modals from "../modals";
import SettingsTitle from "../settings/title"; import SettingsTitle from "../settings/title";
import ServerCard from "./card"; import ServerCard from "./card";
@ -8,9 +8,26 @@ import Search from "../settings/components/search";
import Previous from "../icons/previous"; import Previous from "../icons/previous";
import Next from "../icons/next"; import Next from "../icons/next";
const SettingsView = WebpackModules.getByDisplayName("SettingsView"); const SettingsView = WebpackModules.getByPrototypes("renderSidebar");
const GuildActions = WebpackModules.getByProps("transitionToGuildSync"); const GuildActions = WebpackModules.getByProps("transitionToGuildSync");
const LayerManager = WebpackModules.getByProps("popLayer"); const LayerManager = {
pushLayer(component) {
DiscordModules.Dispatcher.dispatch({
type: "LAYER_PUSH",
component
});
},
popLayer() {
DiscordModules.Dispatcher.dispatch({
type: "LAYER_POP"
});
},
popAllLayers() {
DiscordModules.Dispatcher.dispatch({
type: "LAYER_POP_ALL"
});
}
};
const EMPTY_RESULTS = { const EMPTY_RESULTS = {
servers: [], servers: [],

View File

@ -62,7 +62,7 @@ export default new class SettingsRenderer {
} }
async patchSections() { async patchSections() {
const UserSettings = await WebpackModules.getLazy(Filters.byDisplayName("SettingsView")); const UserSettings = await WebpackModules.getLazy(Filters.byPrototypeFields(["getPredicateSections"]));
Patcher.after("SettingsManager", UserSettings.prototype, "getPredicateSections", (thisObject, args, returnValue) => { Patcher.after("SettingsManager", UserSettings.prototype, "getPredicateSections", (thisObject, args, returnValue) => {
let location = returnValue.findIndex(s => s.section.toLowerCase() == "changelog") - 1; let location = returnValue.findIndex(s => s.section.toLowerCase() == "changelog") - 1;

View File

@ -1,7 +1,6 @@
import Logger from "common/logger"; import Logger from "common/logger";
import {React, Strings, WebpackModules, DiscordModules} from "modules"; import {React, Strings, WebpackModules, DiscordModules} from "modules";
import SimpleMarkdown from "../../structs/markdown"; import SimpleMarkdown from "../../structs/markdown";
import ReloadIcon from "../icons/reload";
import EditIcon from "../icons/edit"; import EditIcon from "../icons/edit";
import DeleteIcon from "../icons/delete"; import DeleteIcon from "../icons/delete";
import CogIcon from "../icons/cog"; import CogIcon from "../icons/cog";
@ -25,8 +24,25 @@ const LinkIcons = {
patreon: PatreonIcon patreon: PatreonIcon
}; };
const Tooltip = WebpackModules.getByDisplayName("Tooltip"); const Tooltip = WebpackModules.getByPrototypes("renderTooltip");
const LayerStack = WebpackModules.getByProps("popLayer"); const LayerManager = {
pushLayer(component) {
DiscordModules.Dispatcher.dispatch({
type: "LAYER_PUSH",
component
});
},
popLayer() {
DiscordModules.Dispatcher.dispatch({
type: "LAYER_POP"
});
},
popAllLayers() {
DiscordModules.Dispatcher.dispatch({
type: "LAYER_POP_ALL"
});
}
};
const UserStore = WebpackModules.getByProps("getCurrentUser"); const UserStore = WebpackModules.getByProps("getCurrentUser");
const ChannelStore = WebpackModules.getByProps("getDMFromUserId"); const ChannelStore = WebpackModules.getByProps("getDMFromUserId");
const PrivateChannelActions = WebpackModules.getByProps("openPrivateChannel"); const PrivateChannelActions = WebpackModules.getByProps("openPrivateChannel");
@ -41,7 +57,6 @@ export default class AddonCard extends React.Component {
this.panelRef = React.createRef(); this.panelRef = React.createRef();
this.onChange = this.onChange.bind(this); this.onChange = this.onChange.bind(this);
this.reload = this.reload.bind(this);
this.showSettings = this.showSettings.bind(this); this.showSettings = this.showSettings.bind(this);
this.messageAuthor = this.messageAuthor.bind(this); this.messageAuthor = this.messageAuthor.bind(this);
} }
@ -58,12 +73,6 @@ export default class AddonCard extends React.Component {
} }
} }
reload() {
if (!this.props.reload) return;
this.props.addon = this.props.reload(this.props.addon.id);
this.forceUpdate();
}
getString(value) {return typeof value == "string" ? value : value.toString();} getString(value) {return typeof value == "string" ? value : value.toString();}
onChange() { onChange() {
@ -74,7 +83,7 @@ export default class AddonCard extends React.Component {
messageAuthor() { messageAuthor() {
if (!this.props.addon.authorId) return; if (!this.props.addon.authorId) return;
if (LayerStack) LayerStack.popLayer(); if (LayerManager) LayerManager.popLayer();
if (!UserStore || !ChannelActions || !ChannelStore || !PrivateChannelActions) return; if (!UserStore || !ChannelActions || !ChannelStore || !PrivateChannelActions) return;
const selfId = UserStore.getCurrentUser().id; const selfId = UserStore.getCurrentUser().id;
if (selfId == this.props.addon.authorId) return; if (selfId == this.props.addon.authorId) return;
@ -114,7 +123,7 @@ export default class AddonCard extends React.Component {
let code = url; let code = url;
const tester = /\.gg\/(.*)$/; const tester = /\.gg\/(.*)$/;
if (tester.test(code)) code = code.match(tester)[1]; if (tester.test(code)) code = code.match(tester)[1];
DiscordModules.LayerStack.popLayer(); LayerManager.popLayer();
DiscordModules.InviteActions.acceptInviteAndTransitionToInviteChannel(code); DiscordModules.InviteActions.acceptInviteAndTransitionToInviteChannel(code);
}; };
} }
@ -124,7 +133,6 @@ export default class AddonCard extends React.Component {
get controls() { // {this.props.hasSettings && <button onClick={this.showSettings} className="bd-button bd-button-addon-settings" disabled={!this.props.enabled}>{Strings.Addons.addonSettings}</button>} get controls() { // {this.props.hasSettings && <button onClick={this.showSettings} className="bd-button bd-button-addon-settings" disabled={!this.props.enabled}>{Strings.Addons.addonSettings}</button>}
return <div className="bd-controls"> return <div className="bd-controls">
{this.props.hasSettings && this.makeControlButton(Strings.Addons.addonSettings, <CogIcon size={"20px"} />, this.showSettings, {disabled: !this.props.enabled})} {this.props.hasSettings && this.makeControlButton(Strings.Addons.addonSettings, <CogIcon size={"20px"} />, this.showSettings, {disabled: !this.props.enabled})}
{this.props.showReloadIcon && this.makeControlButton(Strings.Addons.reload, <ReloadIcon size={"20px"} />, this.reload)}
{this.props.editAddon && this.makeControlButton(Strings.Addons.editAddon, <EditIcon size={"20px"} />, this.props.editAddon)} {this.props.editAddon && this.makeControlButton(Strings.Addons.editAddon, <EditIcon size={"20px"} />, this.props.editAddon)}
{this.props.deleteAddon && this.makeControlButton(Strings.Addons.deleteAddon, <DeleteIcon size={"20px"} />, this.props.deleteAddon, {danger: true})} {this.props.deleteAddon && this.makeControlButton(Strings.Addons.deleteAddon, <DeleteIcon size={"20px"} />, this.props.deleteAddon, {danger: true})}
</div>; </div>;

View File

@ -1,9 +1,8 @@
import Logger from "common/logger"; import Logger from "common/logger";
import {React, Settings, Strings, Events, WebpackModules, DataStore} from "modules"; import {React, Strings, Events, WebpackModules, DataStore} from "modules";
import Modals from "../modals"; import Modals from "../modals";
import SettingsTitle from "./title"; import SettingsTitle from "./title";
import ReloadIcon from "../icons/reload";
import AddonCard from "./addoncard"; import AddonCard from "./addoncard";
import Dropdown from "./components/dropdown"; import Dropdown from "./components/dropdown";
import Search from "./components/search"; import Search from "./components/search";
@ -14,7 +13,7 @@ import GridIcon from "../icons/grid";
import NoResults from "../blankslates/noresults"; import NoResults from "../blankslates/noresults";
import EmptyImage from "../blankslates/emptyimage"; import EmptyImage from "../blankslates/emptyimage";
const Tooltip = WebpackModules.getByDisplayName("Tooltip"); const Tooltip = WebpackModules.getByPrototypes("renderTooltip");
export default class AddonList extends React.Component { export default class AddonList extends React.Component {
@ -125,7 +124,6 @@ export default class AddonList extends React.Component {
render() { render() {
const {title, folder, addonList, addonState, onChange, reload} = this.props; const {title, folder, addonList, addonState, onChange, reload} = this.props;
const showReloadIcon = !Settings.get("settings", "addons", "autoReload");
const button = folder ? {title: Strings.Addons.openFolder.format({type: title}), onClick: this.openFolder} : null; const button = folder ? {title: Strings.Addons.openFolder.format({type: title}), onClick: this.openFolder} : null;
let sortedAddons = addonList.sort((a, b) => { let sortedAddons = addonList.sort((a, b) => {
const sortByEnabled = this.state.sort === "isEnabled"; const sortByEnabled = this.state.sort === "isEnabled";
@ -152,7 +150,7 @@ export default class AddonList extends React.Component {
const renderedCards = sortedAddons.map(addon => { const renderedCards = sortedAddons.map(addon => {
const hasSettings = addon.instance && typeof(addon.instance.getSettingsPanel) === "function"; const hasSettings = addon.instance && typeof(addon.instance.getSettingsPanel) === "function";
const getSettings = hasSettings && addon.instance.getSettingsPanel.bind(addon.instance); const getSettings = hasSettings && addon.instance.getSettingsPanel.bind(addon.instance);
return <ErrorBoundary><AddonCard type={this.props.type} editAddon={this.editAddon.bind(this, addon.id)} deleteAddon={this.deleteAddon.bind(this, addon.id)} showReloadIcon={showReloadIcon} key={addon.id} enabled={addonState[addon.id]} addon={addon} onChange={onChange} reload={reload} hasSettings={hasSettings} getSettingsPanel={getSettings} /></ErrorBoundary>; return <ErrorBoundary><AddonCard type={this.props.type} editAddon={this.editAddon.bind(this, addon.id)} deleteAddon={this.deleteAddon.bind(this, addon.id)} key={addon.id} enabled={addonState[addon.id]} addon={addon} onChange={onChange} reload={reload} hasSettings={hasSettings} getSettingsPanel={getSettings} /></ErrorBoundary>;
}); });
const hasAddonsInstalled = this.props.addonList.length !== 0; const hasAddonsInstalled = this.props.addonList.length !== 0;
@ -160,7 +158,7 @@ export default class AddonList extends React.Component {
const hasResults = sortedAddons.length !== 0; const hasResults = sortedAddons.length !== 0;
return [ return [
<SettingsTitle key="title" text={title} button={button} otherChildren={showReloadIcon && <ReloadIcon className="bd-reload" onClick={this.reload.bind(this)} />} />, <SettingsTitle key="title" text={title} button={button} />,
<div className={"bd-controls bd-addon-controls"}> <div className={"bd-controls bd-addon-controls"}>
<Search onChange={this.search} placeholder={`${Strings.Addons.search.format({type: this.props.title})}...`} /> <Search onChange={this.search} placeholder={`${Strings.Addons.search.format({type: this.props.title})}...`} />
<div className="bd-controls-advanced"> <div className="bd-controls-advanced">

View File

@ -4,7 +4,7 @@ import HistoryIcon from "../icons/history";
import Modals from "../modals"; import Modals from "../modals";
const SidebarComponents = WebpackModules.getModule(m => m.Header && m.Separator && m.Item); const SidebarComponents = WebpackModules.getModule(m => m.Header && m.Separator && m.Item);
const Tooltip = WebpackModules.getByDisplayName("Tooltip"); const Tooltip = WebpackModules.getByPrototypes("renderTooltip");
export default class SettingsTitle extends React.Component { export default class SettingsTitle extends React.Component {
render() { render() {