slight refactor, get rid of most circulars

This commit is contained in:
Zack Rauen 2019-06-23 00:11:50 -04:00
parent 6bb5808063
commit 1f4535427f
20 changed files with 253 additions and 450 deletions

File diff suppressed because one or more lines are too long

47
package-lock.json generated
View File

@ -1778,6 +1778,12 @@
"safe-buffer": "^5.0.1"
}
},
"circular-dependency-plugin": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.0.2.tgz",
"integrity": "sha512-oC7/DVAyfcY3UWKm0sN/oVoDedQDQiw/vIiAnuTWTpE5s0zWf7l3WY417Xw/Fbi/QbAjctAkxgMiS9P0s3zkmA==",
"dev": true
},
"class-utils": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
@ -2811,8 +2817,7 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"aproba": {
"version": "1.2.0",
@ -2833,14 +2838,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -2855,20 +2858,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"core-util-is": {
"version": "1.0.2",
@ -2985,8 +2985,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"ini": {
"version": "1.3.5",
@ -2998,7 +2997,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -3013,7 +3011,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -3021,14 +3018,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -3047,7 +3042,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -3128,8 +3122,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"object-assign": {
"version": "4.1.1",
@ -3141,7 +3134,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -3227,8 +3219,7 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"safer-buffer": {
"version": "2.1.2",
@ -3264,7 +3255,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -3284,7 +3274,6 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -3328,14 +3317,12 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"dev": true,
"optional": true
"dev": true
}
}
},

View File

@ -28,6 +28,7 @@
"@babel/preset-react": "^7.0.0",
"@babel/register": "^7.0.0",
"babel-loader": "^8.0.6",
"circular-dependency-plugin": "^5.0.2",
"gulp": "^4.0.0",
"gulp-csso": "^3.0.1",
"gulp-rename": "^1.4.0",

View File

@ -3,7 +3,7 @@ import Builtin from "../structs/builtin";
import {Config, EmoteInfo, EmoteConfig} from "data";
import {Utilities, WebpackModules, DataStore, DiscordModules, Events, Settings} from "modules";
import BDEmote from "../ui/emote";
import {Toasts} from "ui";
import Toasts from "../ui/toasts";
const Emotes = {
TwitchGlobal: {},

View File

@ -1,6 +1,6 @@
import Builtin from "../structs/builtin";
import {BDV2, DiscordModules, WebpackModules} from "modules";
import {PublicServersMenu} from "ui";
import {DiscordModules, WebpackModules} from "modules";
import PublicServersMenu from "../ui/publicservers/menu";
const LayerStack = WebpackModules.getByProps("pushLayer");
@ -10,7 +10,7 @@ export default new class PublicServers extends Builtin {
get id() {return "publicServers";}
enabled() {
const wrapper = BDV2.guildClasses.wrapper.split(" ")[0];
const wrapper = DiscordModules.GuildClasses.wrapper.split(" ")[0];
const guilds = $(`.${wrapper} .scroller-2FKFPG >:first-child`);
guilds.after(this.button);
}
@ -25,10 +25,10 @@ export default new class PublicServers extends Builtin {
get button() {
const btn = $("<div/>", {
"class": BDV2.guildClasses.listItem,
"class": DiscordModules.GuildClasses.listItem,
"id": "bd-pub-li"
}).append($("<div/>", {
"class": "wrapper-25eVIn " + BDV2.guildClasses.circleButtonMask,
"class": "wrapper-25eVIn " + DiscordModules.GuildClasses.circleButtonMask,
"text": "public",
"id": "bd-pub-button",
"click": () => { this.openPublicServers(); }

View File

@ -1,67 +1,49 @@
import WebpackModules from "./webpackmodules";
import BdApi from "./pluginapi";
import DiscordModules from "./discordmodules";
import Utilities from "./utilities";
import Patcher from "./patcher";
import BDLogo from "../ui/icons/bdlogo";
export default new class V2 {
constructor() {
this.editorDetached = false;
}
initialize() {
BdApi.suppressErrors(this.patchSocial.bind(this), "BD Social Patch")();
BdApi.suppressErrors(this.patchGuildPills.bind(this), "BD Guild Pills Patch")();
BdApi.suppressErrors(this.patchGuildListItems.bind(this), "BD Guild List Items Patch")();
BdApi.suppressErrors(this.patchGuildSeparator.bind(this), "BD Guild Separator Patch")();
Utilities.suppressErrors(this.patchSocial.bind(this), "BD Social Patch")();
Utilities.suppressErrors(this.patchGuildPills.bind(this), "BD Guild Pills Patch")();
Utilities.suppressErrors(this.patchGuildListItems.bind(this), "BD Guild List Items Patch")();
Utilities.suppressErrors(this.patchGuildSeparator.bind(this), "BD Guild Separator Patch")();
}
get messageClasses() {return WebpackModules.getByProps("message", "containerCozy");}
get guildClasses() {
const guildsWrapper = WebpackModules.getByProps("wrapper", "unreadMentionsBar");
const guilds = WebpackModules.getByProps("guildsError", "selected");
const pill = WebpackModules.getByProps("blobContainer");
return Object.assign({}, guildsWrapper, guilds, pill);
}
get MessageContentComponent() {return WebpackModules.getModule(m => m.defaultProps && m.defaultProps.hasOwnProperty("disableButtons"));}
get TimeFormatter() {return WebpackModules.getByProps("dateFormat");}
get TooltipWrapper() {return WebpackModules.getByDisplayName("TooltipDeprecated");}
get NativeModule() {return WebpackModules.getByProps("setBadge");}
get Tooltips() {return WebpackModules.getModule(m => m.hide && m.show && !m.search && !m.submit && !m.search && !m.activateRagingDemon && !m.dismiss);}
get KeyGenerator() {return WebpackModules.getModule(m => m.toString && /"binary"/.test(m.toString()));}
patchSocial() {
if (this.socialPatch) return;
const TabBar = BdApi.findModule(m => m.displayName == "TabBar");
const Anchor = BdApi.findModule(m => m.displayName == "Anchor");
const TabBar = WebpackModules.getByDisplayName("TabBar");
const Anchor = WebpackModules.getByDisplayName("Anchor");
if (!TabBar || !Anchor) return;
this.socialPatch = BdApi.monkeyPatch(TabBar.prototype, "render", {after: (data) => {
const children = data.returnValue.props.children;
this.socialPatch = Patcher.after("ThemeHelper", TabBar.prototype, "render", (_, __, returnValue) => {
const children = returnValue.props.children;
if (!children || !children.length) return;
if (children[children.length - 2].type.displayName !== "Separator") return;
if (!children[children.length - 1].type.toString().includes("socialLinks")) return;
const original = children[children.length - 1].type;
const newOne = function() {
const returnVal = original(...arguments);
returnVal.props.children.push(BdApi.React.createElement(Anchor, {className: "bd-social-link", href: "https://github.com/rauenzi/BetterDiscordApp", rel: "author", title: "BandagedBD", target: "_blank"},
BdApi.React.createElement(BDLogo, {size: "16px", className: "bd-social-logo"})
returnVal.props.children.push(DiscordModules.React.createElement(Anchor, {className: "bd-social-link", href: "https://github.com/rauenzi/BetterDiscordApp", rel: "author", title: "BandagedBD", target: "_blank"},
DiscordModules.React.createElement(BDLogo, {size: "16px", className: "bd-social-logo"})
));
return returnVal;
};
children[children.length - 1].type = newOne;
}});
});
}
patchGuildListItems() {
if (this.guildListItemsPatch) return;
const listItemClass = this.guildClasses.listItem.split(" ")[0];
const blobClass = this.guildClasses.blobContainer.split(" ")[0];
const reactInstance = BdApi.getInternalInstance(document.querySelector(`.${listItemClass} .${blobClass}`).parentElement);
const listItemClass = DiscordModules.GuildClasses.listItem.split(" ")[0];
const blobClass = DiscordModules.GuildClasses.blobContainer.split(" ")[0];
const reactInstance = Utilities.getReactInstance(document.querySelector(`.${listItemClass} .${blobClass}`).parentElement);
const GuildComponent = reactInstance.return.type;
if (!GuildComponent) return;
this.guildListItemsPatch = BdApi.monkeyPatch(GuildComponent.prototype, "render", {after: (data) => {
const returnValue = data.returnValue;
const guildData = data.thisObject.props;
this.guildListItemsPatch = Patcher.after("ThemeHelper", GuildComponent.prototype, "render", (thisObject, _, returnValue) => {
const guildData = thisObject.props;
returnValue.props.className += " bd-guild";
if (guildData.unread) returnValue.props.className += " bd-unread";
if (guildData.selected) returnValue.props.className += " bd-selected";
@ -70,35 +52,37 @@ export default new class V2 {
if (guildData.badge) returnValue.props.className += " bd-badge";
if (guildData.animatable) returnValue.props.className += " bd-animatable";
return returnValue;
}});
});
}
patchGuildPills() {
if (this.guildPillPatch) return;
const guildPill = BdApi.findModule(m => m.default && m.default.toString && m.default.toString().includes("translate3d"));
const guildPill = WebpackModules.getModule(m => m.default && !m.default.displayName && m.default.toString && m.default.toString().includes("translate3d"));
if (!guildPill) return;
this.guildPillPatch = BdApi.monkeyPatch(guildPill, "default", {after: (data) => {
const props = data.methodArguments[0];
if (props.unread) data.returnValue.props.className += " bd-unread";
if (props.selected) data.returnValue.props.className += " bd-selected";
if (props.hovered) data.returnValue.props.className += " bd-hovered";
return data.returnValue;
}});
this.guildPillPatch = Patcher.after("ThemeHelper", guildPill, "default", (_, args, returnValue) => {
const props = args[0];
if (props.unread) returnValue.props.className += " bd-unread";
if (props.selected) returnValue.props.className += " bd-selected";
if (props.hovered) returnValue.props.className += " bd-hovered";
return returnValue;
});
}
patchGuildSeparator() {
if (this.guildSeparatorPatch) return;
const Guilds = BdApi.findModuleByDisplayName("Guilds");
const guildComponents = BdApi.findModuleByProps("renderListItem");
const Guilds = WebpackModules.getByDisplayName("Guilds");
const guildComponents = WebpackModules.getByProps("renderListItem");
if (!guildComponents || !Guilds) return;
const GuildSeparator = function() {
const returnValue = guildComponents.Separator(...arguments);
returnValue.props.className += " bd-guild-separator";
return returnValue;
};
this.guildSeparatorPatch = BdApi.monkeyPatch(Guilds.prototype, "render", {after: (data) => {
data.returnValue.props.children[1].props.children[3].type = GuildSeparator;
}});
this.guildSeparatorPatch = Patcher.after("ThemeHelper", Guilds.prototype, "render", (_, __, returnValue) => {
const Separator = Utilities.findInReactTree(returnValue, m => m.type && !m.type.displayName && typeof(m.type) == "function" && Utilities.isEmpty(m.props));
if (!Separator) return;
Separator.type = GuildSeparator;
});
}
};

View File

@ -5,7 +5,7 @@ import Events from "./emitter";
import DataStore from "./datastore";
import ContentError from "../structs/contenterror";
import MetaError from "../structs/metaerror";
import {Toasts} from "ui";
import Toasts from "../ui/toasts";
const path = require("path");
const fs = require("fs");

View File

@ -8,8 +8,12 @@ import PluginManager from "./pluginmanager";
import ThemeManager from "./thememanager";
import Settings from "./settingsmanager";
import * as Builtins from "builtins";
import {Modals} from "ui";
import Modals from "../ui/modals";
import ReactComponents from "./reactcomponents";
import DataStore from "./datastore";
import DiscordModules from "./discordmodules";
const GuildClasses = DiscordModules.GuildClasses;
function Core() {
}
@ -23,31 +27,23 @@ Core.prototype.init = async function() {
Modals.alert("Not Supported", "BetterDiscord v" + Config.version + " (your version)" + " is not supported by the latest js (" + Config.bbdVersion + ").<br><br> Please download the latest version from <a href='https://github.com/rauenzi/BetterDiscordApp/releases/latest' target='_blank'>GitHub</a>");
return;
}
// const latestLocalVersion = Config.updater ? Config.updater.LatestVersion : Config.latestVersion;
// if (latestLocalVersion > Config.version) {
// Modals.alert("Update Available", `
// An update for BandagedBD is available (${latestLocalVersion})! Please Reinstall!<br /><br />
// <a href='https://github.com/rauenzi/BetterDiscordApp/releases/latest' target='_blank'>Download Installer</a>
// `);
// }
DataStore.initialize();
ReactComponents.initialize();
const latestLocalVersion = Config.updater ? Config.updater.LatestVersion : Config.latestVersion;
if (latestLocalVersion > Config.version) {
Modals.alert("Update Available", `
An update for BandagedBD is available (${latestLocalVersion})! Please Reinstall!<br /><br />
<a href='https://github.com/rauenzi/BetterDiscordApp/releases/latest' target='_blank'>Download Installer</a>
`);
}
Logger.log("Startup", "Initializing Settings");
Settings.initialize();
Logger.log("Startup", "Initializing EmoteModule");
// window.emotePromise = EmoteModule.init().then(() => {
// EmoteModule.initialized = true;
// Logger.log("Startup", "Initializing QuickEmoteMenu");
// Events.dispatch("emotes-loaded");
// // QuickEmoteMenu.init();
// });
// this.injectExternals();
DOMManager.initialize();
await this.checkForGuilds();
await this.waitForGuilds();
BDV2.initialize();
Logger.log("Startup", "Updating Settings");
for (const module in Builtins) Builtins[module].initialize();
Logger.log("Startup", "Loading Plugins");
@ -61,21 +57,19 @@ Core.prototype.init = async function() {
Logger.log("Startup", "Removing Loading Icon");
document.getElementsByClassName("bd-loaderv2")[0].remove();
Logger.log("Startup", "Initializing Main Observer");
this.initObserver();
// Show loading errors
Logger.log("Startup", "Collecting Startup Errors");
Modals.showContentErrors({plugins: pluginErrors, themes: themeErrors});
};
Core.prototype.checkForGuilds = function() {
Core.prototype.waitForGuilds = function() {
return new Promise(resolve => {
const checkForGuilds = function() {
if (document.readyState != "complete") setTimeout(checkForGuilds, 100);
const wrapper = BDV2.guildClasses.wrapper.split(" ")[0];
const guild = BDV2.guildClasses.listItem.split(" ")[0];
const blob = BDV2.guildClasses.blobContainer.split(" ")[0];
const wrapper = GuildClasses.wrapper.split(" ")[0];
const guild = GuildClasses.listItem.split(" ")[0];
const blob = GuildClasses.blobContainer.split(" ")[0];
if (document.querySelectorAll(`.${wrapper} .${guild} .${blob}`).length > 0) return resolve(Config.deferLoaded = true);
setTimeout(checkForGuilds, 100);
};
@ -84,34 +78,4 @@ Core.prototype.checkForGuilds = function() {
});
};
Core.prototype.initObserver = function () {
const mainObserver = new MutationObserver((mutations) => {
for (let i = 0, mlen = mutations.length; i < mlen; i++) {
const mutation = mutations[i];
// if there was nothing added, skip
if (!mutation.addedNodes.length || !(mutation.addedNodes[0] instanceof Element)) continue;
const node = mutation.addedNodes[0];
if (node.classList.contains("layer-3QrUeG")) {
if (node.getElementsByClassName("guild-settings-base-section").length) node.setAttribute("layer-id", "server-settings");
// if (node.getElementsByClassName("socialLinks-3jqNFy").length) {
// node.setAttribute("layer-id", "user-settings");
// node.setAttribute("id", "user-settings");
// if (!document.getElementById("bd-settings-sidebar")) Settings.renderSidebar();
// }
}
}
});
mainObserver.observe(document, {
childList: true,
subtree: true
});
};
export default new Core();

View File

@ -142,5 +142,13 @@ export default Utilities.memoizeObject({
get Buffers() {return WebpackModules.getByProps("Buffer", "kMaxLength");},
get DeviceStore() {return WebpackModules.getByProps("getDevices");},
get SoftwareInfo() {return WebpackModules.getByProps("os");},
get CurrentContext() {return WebpackModules.getByProps("setTagsContext");}
get CurrentContext() {return WebpackModules.getByProps("setTagsContext");},
/* Commonly Used Classes */
get GuildClasses() {
const guildsWrapper = WebpackModules.getByProps("wrapper", "unreadMentionsBar");
const guilds = WebpackModules.getByProps("guildsError", "selected");
const pill = WebpackModules.getByProps("blobContainer");
return Object.assign({}, guildsWrapper, guilds, pill);
}
});

View File

@ -1,29 +1,15 @@
import Utilities from "./utilities";
import WebpackModules from "./webpackmodules";
export {default as WebpackModules} from "./webpackmodules";
import DiscordModules from "./discordmodules";
import BDV2 from "./bdv2";
import BdApi from "./pluginapi";
import Core from "./core";
import ContentManager from "./contentmanager";
import DataStore from "./datastore";
// import DevMode from "./devmode";
import Events from "./emitter";
// import EmoteModule from "./emotes";
import PluginManager from "./pluginmanager";
// import PublicServers from "./publicservers";
import ThemeManager from "./thememanager";
import Settings from "./settingsmanager";
import DOMManager from "./dommanager";
import Logger from "./logger";
import Patcher from "./patcher";
export const React = DiscordModules.React;
export const ReactDOM = DiscordModules.ReactDOM;
export {DiscordModules};
export {BDV2, BdApi, Core, ContentManager, DataStore, Logger,
Events, PluginManager, DOMManager, ThemeManager, Patcher,
Utilities, WebpackModules, DiscordModules, Settings};
export {default as Utilities} from "./utilities";
export {default as DataStore} from "./datastore";
export {default as Events} from "./emitter";
export {default as Settings} from "./settingsmanager";
export {default as DOMManager} from "./dommanager";
export {default as Logger} from "./logger";
export {default as Patcher} from "./patcher";
export {default as ReactComponents} from "./reactcomponents";

View File

@ -3,7 +3,8 @@ import WebpackModules from "./webpackmodules";
import DiscordModules from "./discordmodules";
import DataStore from "./datastore";
import DOMManager from "./dommanager";
import {Toasts, Modals} from "ui";
import Toasts from "../ui/toasts";
import Modals from "../ui/modals";
const BdApi = {
get React() { return DiscordModules.React; },

View File

@ -2,10 +2,12 @@ import {Config} from "data";
import Logger from "./logger";
import ContentManager from "./contentmanager";
import Utilities from "./utilities";
import {Toasts, Modals} from "ui";
import ContentError from "../structs/contenterror";
import Settings from "./settingsmanager";
import {SettingsPanel as SettingsRenderer} from "ui";
import Toasts from "../ui/toasts";
import Modals from "../ui/modals";
import SettingsRenderer from "../ui/settings";
const path = require("path");
const electronRemote = require("electron").remote;

View File

@ -2,13 +2,13 @@ import {SettingsConfig} from "data";
import Logger from "./logger";
import DataStore from "./datastore";
import Events from "./emitter";
import WebpackModules from "./webpackmodules";
// import WebpackModules from "./webpackmodules";
import DiscordModules from "./discordmodules";
import Patcher from "./patcher";
import ReactComponents from "./reactcomponents";
// import Patcher from "./patcher";
// import ReactComponents from "./reactcomponents";
import {SettingsPanel as SettingsRenderer} from "ui";
import Utilities from "./utilities";
// import SettingsRenderer from "../ui/settings/settings";
// import Utilities from "./utilities";
export default new class SettingsManager {
@ -20,9 +20,8 @@ export default new class SettingsManager {
}
initialize() {
DataStore.initialize();
this.loadSettings();
this.patchSections();
// this.patchSections();
}
registerCollection(id, name, settings, button = null) {
@ -43,6 +42,7 @@ export default new class SettingsManager {
this.collections.splice(location, 1);
}
// TODO: Move this to SettingsRenderer and also add a registerContentPanel
registerPanel(id, name, options) {
if (this.panels.find(p => p.id == id)) return Logger.error("Settings", "Already have a panel with id " + id);
const {element, onClick, order = 1} = options;
@ -103,45 +103,6 @@ export default new class SettingsManager {
}
}
async patchSections() {
Patcher.after("SettingsManager", WebpackModules.getByDisplayName("FluxContainer(GuildSettings)").prototype, "render", (thisObject) => {
thisObject._reactInternalFiber.return.return.return.return.return.return.memoizedProps.id = "guild-settings";
});
const UserSettings = await ReactComponents.get("UserSettings", m => m.prototype && m.prototype.generateSections);
Patcher.after("SettingsManager", UserSettings.prototype, "render", (thisObject) => {
thisObject._reactInternalFiber.return.return.return.return.return.return.return.memoizedProps.id = "user-settings";
});
Patcher.after("SettingsManager", UserSettings.prototype, "generateSections", (thisObject, args, returnValue) => {
let location = returnValue.findIndex(s => s.section.toLowerCase() == "linux") + 1;
const insert = (section) => {
returnValue.splice(location, 0, section);
location++;
};
insert({section: "DIVIDER"});
insert({section: "HEADER", label: "BandagedBD"});
for (const collection of this.collections) {
if (collection.disabled) continue;
insert({
section: collection.name,
label: collection.name,
element: () => SettingsRenderer.buildSettingsPanel(collection.name, collection.settings, this.state[collection.id], this.onSettingChange.bind(this, collection.id), collection.button ? collection.button : null)
});
}
for (const panel of this.panels.sort((a,b) => a.order > b.order)) {
if (panel.clickListener) panel.onClick = (event) => panel.clickListener(thisObject, event, returnValue);
insert(panel);
}
insert({section: "CUSTOM", element: () => SettingsRenderer.attribution});
});
this.forceUpdate();
}
forceUpdate() {
const viewClass = WebpackModules.getByProps("standardSidebarView").standardSidebarView.split(" ")[0];
const node = document.querySelector(`.${viewClass}`);
Utilities.getReactInstance(node).return.return.return.return.return.return.stateNode.forceUpdate();
}
saveSettings() {
DataStore.setData("settings", this.state);
}

View File

@ -1,9 +1,11 @@
import {Config} from "data";
import ContentManager from "./contentmanager";
import {Modals} from "ui";
import Settings from "./settingsmanager";
import DOMManager from "./dommanager";
import {SettingsPanel as SettingsRenderer} from "ui";
import Toasts from "../ui/toasts";
import Modals from "../ui/modals";
import SettingsRenderer from "../ui/settings";
const path = require("path");
@ -55,11 +57,13 @@ export default new class ThemeManager extends ContentManager {
const content = typeof(idOrContent) == "string" ? this.contentList.find(p => p.id == idOrContent) : idOrContent;
if (!content) return;
DOMManager.injectTheme(content.id, content.css);
Toasts.show(`${content.name} v${content.version} has been applied.`);
}
removeTheme(idOrContent) {
const content = typeof(idOrContent) == "string" ? this.contentList.find(p => p.id == idOrContent) : idOrContent;
if (!content) return;
DOMManager.removeTheme(content.id);
Toasts.show(`${content.name} v${content.version} has been removed.`);
}
};

View File

@ -4,146 +4,7 @@
* @version 0.0.2
*/
import DiscordModules from "./discordmodules";
// const DiscordModules = Utilities.memoizeObject({
// get React() {return WebpackModules.getByProps("createElement", "cloneElement");},
// get ReactDOM() {return WebpackModules.getByProps("render", "findDOMNode");},
// get Flux() {return WebpackModules.getByProps("connectStores");},
// get Events() {return WebpackModules.getByPrototypes("setMaxListeners", "emit");},
// /* Guild Info, Stores, and Utilities */
// get GuildStore() {return WebpackModules.getByProps("getGuild");},
// get SortedGuildStore() {return WebpackModules.getByProps("getSortedGuilds");},
// get SelectedGuildStore() {return WebpackModules.getByProps("getLastSelectedGuildId");},
// get GuildSync() {return WebpackModules.getByProps("getSyncedGuilds");},
// get GuildInfo() {return WebpackModules.getByProps("getAcronym");},
// get GuildChannelsStore() {return WebpackModules.getByProps("getChannels", "getDefaultChannel");},
// get GuildMemberStore() {return WebpackModules.getByProps("getMember");},
// get MemberCountStore() {return WebpackModules.getByProps("getMemberCounts");},
// get GuildEmojiStore() {return WebpackModules.getByProps("getEmojis");},
// get GuildActions() {return WebpackModules.getByProps("markGuildAsRead");},
// get GuildPermissions() {return WebpackModules.getByProps("getGuildPermissions");},
// /* Channel Store & Actions */
// get ChannelStore() {return WebpackModules.getByProps("getChannels", "getDMFromUserId");},
// get SelectedChannelStore() {return WebpackModules.getByProps("getLastSelectedChannelId");},
// get ChannelActions() {return WebpackModules.getByProps("selectChannel");},
// get PrivateChannelActions() {return WebpackModules.getByProps("openPrivateChannel");},
// get ChannelSelector() {return WebpackModules.getByProps("selectGuild", "selectChannel");},
// /* Current User Info, State and Settings */
// get UserInfoStore() {return WebpackModules.getByProps("getToken");},
// get UserSettingsStore() {return WebpackModules.getByProps("guildPositions");},
// get AccountManager() {return WebpackModules.getByProps("register", "login");},
// get UserSettingsUpdater() {return WebpackModules.getByProps("updateRemoteSettings");},
// get OnlineWatcher() {return WebpackModules.getByProps("isOnline");},
// get CurrentUserIdle() {return WebpackModules.getByProps("getIdleTime");},
// get RelationshipStore() {return WebpackModules.getByProps("isBlocked", "getFriendIDs");},
// get RelationshipManager() {return WebpackModules.getByProps("addRelationship");},
// get MentionStore() {return WebpackModules.getByProps("getMentions");},
// /* User Stores and Utils */
// get UserStore() {return WebpackModules.getByProps("getCurrentUser");},
// get UserStatusStore() {return WebpackModules.getByProps("getStatus", "getState");},
// get UserTypingStore() {return WebpackModules.getByProps("isTyping");},
// get UserActivityStore() {return WebpackModules.getByProps("getActivity");},
// get UserNameResolver() {return WebpackModules.getByProps("getName");},
// get UserNoteStore() {return WebpackModules.getByProps("getNote");},
// get UserNoteActions() {return WebpackModules.getByProps("updateNote");},
// /* Emoji Store and Utils */
// get EmojiInfo() {return WebpackModules.getByProps("isEmojiDisabled");},
// get EmojiUtils() {return WebpackModules.getByProps("getGuildEmoji");},
// get EmojiStore() {return WebpackModules.getByProps("getByCategory", "EMOJI_NAME_RE");},
// /* Invite Store and Utils */
// get InviteStore() {return WebpackModules.getByProps("getInvites");},
// get InviteResolver() {return WebpackModules.getByProps("findInvite");},
// get InviteActions() {return WebpackModules.getByProps("acceptInvite");},
// /* Discord Objects & Utils */
// get DiscordConstants() {return WebpackModules.getByProps("Permissions", "ActivityTypes", "StatusTypes");},
// get DiscordPermissions() {return WebpackModules.getByProps("Permissions", "ActivityTypes", "StatusTypes").Permissions;},
// get PermissionUtils() {return WebpackModules.getByProps("getHighestRole");},
// get ColorConverter() {return WebpackModules.getByProps("hex2int");},
// get ColorShader() {return WebpackModules.getByProps("darken");},
// get TinyColor() {return WebpackModules.getByPrototypes("toRgb");},
// get ClassResolver() {return WebpackModules.getByProps("getClass");},
// get ButtonData() {return WebpackModules.getByProps("ButtonSizes");},
// get IconNames() {return WebpackModules.getByProps("IconNames");},
// get NavigationUtils() {return WebpackModules.getByProps("transitionTo", "replaceWith", "getHistory");},
// /* Discord Messages */
// get MessageStore() {return WebpackModules.getByProps("getMessages");},
// get MessageActions() {return WebpackModules.getByProps("jumpToMessage", "_sendMessage");},
// get MessageQueue() {return WebpackModules.getByProps("enqueue");},
// get MessageParser() {return WebpackModules.getByProps("createMessage", "parse", "unparse");},
// /* Text Processing */
// get hljs() {return WebpackModules.getByProps("highlight", "highlightBlock");},
// get SimpleMarkdown() {return WebpackModules.getByProps("parseBlock", "parseInline", "defaultOutput");},
// /* Experiments */
// get ExperimentStore() {return WebpackModules.getByProps("getExperimentOverrides");},
// get ExperimentsManager() {return WebpackModules.getByProps("isDeveloper");},
// get CurrentExperiment() {return WebpackModules.getByProps("getExperimentId");},
// /* Images, Avatars and Utils */
// get ImageResolver() {return WebpackModules.getByProps("getUserAvatarURL", "getGuildIconURL");},
// get ImageUtils() {return WebpackModules.getByProps("getSizedImageSrc");},
// get AvatarDefaults() {return WebpackModules.getByProps("getUserAvatarURL", "DEFAULT_AVATARS");},
// /* Window, DOM, HTML */
// get WindowInfo() {return WebpackModules.getByProps("isFocused", "windowSize");},
// get TagInfo() {return WebpackModules.getByProps("VALID_TAG_NAMES");},
// get DOMInfo() {return WebpackModules.getByProps("canUseDOM");},
// /* Locale/Location and Time */
// get LocaleManager() {return WebpackModules.getByProps("setLocale");},
// get Moment() {return WebpackModules.getByProps("parseZone");},
// get LocationManager() {return WebpackModules.getByProps("createLocation");},
// get Timestamps() {return WebpackModules.getByProps("fromTimestamp");},
// get TimeFormatter() {return WebpackModules.getByProps("dateFormat");},
// /* Strings and Utils */
// get Strings() {return WebpackModules.getByProps("Messages").Messages;},
// get StringFormats() {return WebpackModules.getByProps("a", "z");},
// get StringUtils() {return WebpackModules.getByProps("toASCII");},
// /* URLs and Utils */
// get URLParser() {return WebpackModules.getByProps("Url", "parse");},
// get ExtraURLs() {return WebpackModules.getByProps("getArticleURL");},
// /* Drag & Drop */
// get DNDActions() {return WebpackModules.getByProps("beginDrag");},
// get DNDSources() {return WebpackModules.getByProps("addTarget");},
// get DNDObjects() {return WebpackModules.getByProps("DragSource");},
// /* Media Stuff (Audio/Video) */
// get MediaDeviceInfo() {return WebpackModules.getByProps("Codecs", "SUPPORTED_BROWSERS");},
// get MediaInfo() {return WebpackModules.getByProps("getOutputVolume");},
// get MediaEngineInfo() {return WebpackModules.getByProps("MediaEngineFeatures");},
// get VoiceInfo() {return WebpackModules.getByProps("EchoCancellation");},
// get VideoStream() {return WebpackModules.getByProps("getVideoStream");},
// get SoundModule() {return WebpackModules.getByProps("playSound");},
// /* Electron & Other Internals with Utils*/
// get ElectronModule() {return WebpackModules.getByProps("setBadge");},
// get Dispatcher() {return WebpackModules.getByProps("dirtyDispatch");},
// get PathUtils() {return WebpackModules.getByProps("hasBasename");},
// get NotificationModule() {return WebpackModules.getByProps("showNotification");},
// get RouterModule() {return WebpackModules.getByProps("Router");},
// get APIModule() {return WebpackModules.getByProps("getAPIBaseURL");},
// get AnalyticEvents() {return WebpackModules.getByProps("AnalyticEventConfigs");},
// get KeyGenerator() {return WebpackModules.getByRegex(/"binary"/);},
// get Buffers() {return WebpackModules.getByProps("Buffer", "kMaxLength");},
// get DeviceStore() {return WebpackModules.getByProps("getDevices");},
// get SoftwareInfo() {return WebpackModules.getByProps("os");},
// get CurrentContext() {return WebpackModules.getByProps("setTagsContext");}
// });
// export {DiscordModules};
// import DiscordModules from "./discordmodules";
/**
* Checks if a given module matches a set of parameters.
@ -282,12 +143,12 @@ export default class WebpackModules {
* @param {Function} fallback A function to use to filter modules if not finding a known module
* @return {Any}
*/
static getModuleByName(name, fallback) {
if (DiscordModules.hasOwnProperty(name)) return DiscordModules[name];
if (!fallback) return undefined;
const module = this.getModule(fallback, true);
return module ? DiscordModules[name] = module : undefined;
}
// static getModuleByName(name, fallback) {
// if (DiscordModules.hasOwnProperty(name)) return DiscordModules[name];
// if (!fallback) return undefined;
// const module = this.getModule(fallback, true);
// return module ? DiscordModules[name] = module : undefined;
// }
/**
* Finds a module by its display name.

View File

@ -1,6 +1,8 @@
import {BDV2, Settings, React} from "modules";
import {Settings, React, WebpackModules} from "modules";
import EmoteMenu from "../builtins/emotemenu";
const TooltipWrapper = WebpackModules.getByDisplayName("TooltipDeprecated");
export default class BDEmote extends React.Component {
constructor(props) {
super(props);
@ -43,7 +45,7 @@ export default class BDEmote extends React.Component {
}
render() {
return React.createElement(BDV2.TooltipWrapper, {
return React.createElement(TooltipWrapper, {
color: "black",
position: "top",
text: this.label,

80
src/ui/settings.js Normal file
View File

@ -0,0 +1,80 @@
import {Config} from "data";
import {React, WebpackModules, Patcher, ReactComponents, Utilities, Settings} from "modules";
import ContentList from "./settings/contentlist";
import SettingsGroup from "./settings/group";
import SettingsTitle from "./settings/title";
export default new class SettingsRenderer {
constructor() {
this.patchSections();
}
buildSettingsPanel(title, config, state, onChange, button = null) {
config.forEach(section => {
section.settings.forEach(item => item.value = state[section.id][item.id]);
});
return this.getSettingsPanel(title, config, onChange, button);
}
getSettingsPanel(title, groups, onChange, button = null) {
return [React.createElement(SettingsTitle, {text: title, button: button}), groups.map(section => {
return React.createElement(SettingsGroup, Object.assign({}, section, {onChange}));
})];
}
getContentPanel(title, contentList, contentState, options = {}) {
return React.createElement(ContentList, Object.assign({}, {
title: title,
contentList: contentList,
contentState: contentState
}, options));
}
get attribution() {
return React.createElement("div", {className: "bd-version", style: {fontSize: "12px", fontWeight: "600", color: "#72767d", padding: "2px 10px"}},
`BBD v${Config.bbdVersion} by `,
React.createElement("a", {href: "https://github.com/rauenzi/", target: "_blank"}, "Zerebos")
);
}
async patchSections() {
Patcher.after("SettingsManager", WebpackModules.getByDisplayName("FluxContainer(GuildSettings)").prototype, "render", (thisObject) => {
thisObject._reactInternalFiber.return.return.return.return.return.return.memoizedProps.id = "guild-settings";
});
const UserSettings = await ReactComponents.get("UserSettings", m => m.prototype && m.prototype.generateSections);
Patcher.after("SettingsManager", UserSettings.prototype, "render", (thisObject) => {
thisObject._reactInternalFiber.return.return.return.return.return.return.return.memoizedProps.id = "user-settings";
});
Patcher.after("SettingsManager", UserSettings.prototype, "generateSections", (thisObject, args, returnValue) => {
let location = returnValue.findIndex(s => s.section.toLowerCase() == "linux") + 1;
const insert = (section) => {
returnValue.splice(location, 0, section);
location++;
};
insert({section: "DIVIDER"});
insert({section: "HEADER", label: "BandagedBD"});
for (const collection of Settings.collections) {
if (collection.disabled) continue;
insert({
section: collection.name,
label: collection.name,
element: () => this.buildSettingsPanel(collection.name, collection.settings, Settings.state[collection.id], Settings.onSettingChange.bind(Settings, collection.id), collection.button ? collection.button : null)
});
}
for (const panel of Settings.panels.sort((a,b) => a.order > b.order)) {
if (panel.clickListener) panel.onClick = (event) => panel.clickListener(thisObject, event, returnValue);
insert(panel);
}
insert({section: "CUSTOM", element: () => this.attribution});
});
this.forceUpdate();
}
forceUpdate() {
const viewClass = WebpackModules.getByProps("standardSidebarView").standardSidebarView.split(" ")[0];
const node = document.querySelector(`.${viewClass}`);
Utilities.getReactInstance(node).return.return.return.return.return.return.stateNode.forceUpdate();
}
};

View File

@ -1,37 +0,0 @@
import {Config} from "data";
import {React} from "modules";
import ContentList from "./contentlist";
import SettingsGroup from "../settings/group";
import SettingsTitle from "./title";
export default class V2_SettingsPanel {
static buildSettingsPanel(title, config, state, onChange, button = null) {
config.forEach(section => {
section.settings.forEach(item => item.value = state[section.id][item.id]);
});
return this.getSettingsPanel(title, config, onChange, button);
}
static getSettingsPanel(title, groups, onChange, button = null) {
return [React.createElement(SettingsTitle, {text: title, button: button}), groups.map(section => {
return React.createElement(SettingsGroup, Object.assign({}, section, {onChange}));
})];
}
static getContentPanel(title, contentList, contentState, options = {}) {
return React.createElement(ContentList, Object.assign({}, {
title: title,
contentList: contentList,
contentState: contentState
}, options));
}
static get attribution() {
return React.createElement("div", {className: "bd-version", style: {fontSize: "12px", fontWeight: "600", color: "#72767d", padding: "2px 10px"}},
`BBD v${Config.bbdVersion} by `,
React.createElement("a", {href: "https://github.com/rauenzi/", target: "_blank"}, "Zerebos")
);
}
}

View File

@ -1,4 +1,4 @@
export {default as SettingsPanel} from "./settings/settings";
export {default as PublicServersMenu} from "./publicservers/menu";
export {default as Toasts} from "./toasts";
export {default as Modals} from "./modals";
// export {default as SettingsPanel} from "./settings/settings";
// export {default as PublicServersMenu} from "./publicservers/menu";
// export {default as Toasts} from "./toasts";
// export {default as Modals} from "./modals";

View File

@ -1,4 +1,5 @@
const path = require("path");
const CircularDependencyPlugin = require("circular-dependency-plugin");
module.exports = {
mode: "development",
@ -24,8 +25,7 @@ module.exports = {
modules: [
path.resolve("src", "builtins"),
path.resolve("src", "data"),
path.resolve("src", "modules"),
path.resolve("src", "ui")
path.resolve("src", "modules")
]
},
module: {
@ -44,5 +44,16 @@ module.exports = {
}
}
]
}
},
plugins: [
new CircularDependencyPlugin({
// exclude detection of files based on a RegExp
exclude: /a\.js|node_modules/,
// add errors to webpack instead of warnings
// failOnError: true,
// set the current working directory for displaying module paths
cwd: process.cwd(),
})
]
};