parent
67746d59ee
commit
c71f9339de
|
@ -244,6 +244,36 @@ export default class WebpackModules {
|
||||||
return this.getModule(Filters.byString(...strings), false);
|
return this.getModule(Filters.byString(...strings), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a module that lazily loaded.
|
||||||
|
* @param {(m) => boolean} filter A function to use to filter modules.
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
static getLazy(filter) {
|
||||||
|
const fromCache = this.getModule(filter);
|
||||||
|
if (fromCache) return Promise.resolve(fromCache);
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const cancel = () => {this.removeListener(listener)};
|
||||||
|
const listener = function (m) {
|
||||||
|
const directMatch = filter(m);
|
||||||
|
|
||||||
|
if (directMatch) {
|
||||||
|
cancel();
|
||||||
|
return resolve(directMatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultMatch = filter(m.default);
|
||||||
|
if (!defaultMatch) return;
|
||||||
|
|
||||||
|
cancel();
|
||||||
|
resolve(m.default);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addListener(listener);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Discord's __webpack_require__ function.
|
* Discord's __webpack_require__ function.
|
||||||
*/
|
*/
|
||||||
|
@ -276,4 +306,75 @@ export default class WebpackModules {
|
||||||
return this.require.c;
|
return this.require.c;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
// Webpack Chunk Observing
|
||||||
|
static get chunkName() {return "webpackChunkdiscord_app";}
|
||||||
|
|
||||||
|
static initialize() {
|
||||||
|
this.handlePush = this.handlePush.bind(this);
|
||||||
|
this.listeners = new Set();
|
||||||
|
|
||||||
|
this.__ORIGINAL_PUSH__ = window[this.chunkName].push;
|
||||||
|
Object.defineProperty(window[this.chunkName], "push", {
|
||||||
|
configurable: true,
|
||||||
|
get: () => this.handlePush,
|
||||||
|
set: (newPush) => {
|
||||||
|
this.__ORIGINAL_PUSH__ = newPush;
|
||||||
|
|
||||||
|
Object.defineProperty(window[this.chunkName], "push", {
|
||||||
|
value: this.handlePush,
|
||||||
|
configurable: true,
|
||||||
|
writable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a listener for when discord loaded a chunk. Useful for subscribing to lazy loaded modules.
|
||||||
|
* @param {Function} listener - Function to subscribe for chunks
|
||||||
|
* @returns {Function} A cancelling function
|
||||||
|
*/
|
||||||
|
static addListener(listener) {
|
||||||
|
this.listeners.add(listener);
|
||||||
|
return this.removeListener.bind(this, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a listener for when discord loaded a chunk.
|
||||||
|
* @param {Function} listener
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static removeListener(listener) {return this.listeners.delete(listener);}
|
||||||
|
|
||||||
|
static handlePush(chunk) {
|
||||||
|
const [, modules] = chunk;
|
||||||
|
|
||||||
|
for (const moduleId in modules) {
|
||||||
|
const originalModule = modules[moduleId];
|
||||||
|
|
||||||
|
modules[moduleId] = (module, exports, require) => {
|
||||||
|
try {
|
||||||
|
Reflect.apply(originalModule, null, [module, exports, require]);
|
||||||
|
|
||||||
|
const listeners = [...this.listeners];
|
||||||
|
for (let i = 0; i < listeners.length; i++) {
|
||||||
|
try {listeners[i](exports);}
|
||||||
|
catch (error) {
|
||||||
|
Logger.err("WebpackModules", "Could not fire callback listener:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.assign(modules[moduleId], originalModule, {
|
||||||
|
toString: () => originalModule.toString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Reflect.apply(this.__ORIGINAL_PUSH__, window[this.chunkName], [chunk]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WebpackModules.initialize();
|
|
@ -4,6 +4,7 @@ import AddonList from "./settings/addonlist";
|
||||||
import SettingsGroup from "./settings/group";
|
import SettingsGroup from "./settings/group";
|
||||||
import SettingsTitle from "./settings/title";
|
import SettingsTitle from "./settings/title";
|
||||||
import Header from "./settings/sidebarheader";
|
import Header from "./settings/sidebarheader";
|
||||||
|
import {Filters} from "../modules/webpackmodules";
|
||||||
|
|
||||||
export default new class SettingsRenderer {
|
export default new class SettingsRenderer {
|
||||||
|
|
||||||
|
@ -60,8 +61,9 @@ export default new class SettingsRenderer {
|
||||||
}, options));
|
}, options));
|
||||||
}
|
}
|
||||||
|
|
||||||
patchSections() {
|
async patchSections() {
|
||||||
const UserSettings = WebpackModules.getByDisplayName("SettingsView");
|
const UserSettings = await WebpackModules.getLazy(Filters.byDisplayName("SettingsView"));
|
||||||
|
|
||||||
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;
|
||||||
if (location < 0) return;
|
if (location < 0) return;
|
||||||
|
@ -91,7 +93,7 @@ export default new class SettingsRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
forceUpdate() {
|
forceUpdate() {
|
||||||
const viewClass = WebpackModules.getByProps("standardSidebarView").standardSidebarView.split(" ")[0];
|
const viewClass = WebpackModules.getByProps("standardSidebarView")?.standardSidebarView.split(" ")[0];
|
||||||
const node = document.querySelector(`.${viewClass}`);
|
const node = document.querySelector(`.${viewClass}`);
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
const stateNode = Utilities.findInReactTree(Utilities.getReactInstance(node), m => m && m.getPredicateSections, {walkable: ["return", "stateNode"]});
|
const stateNode = Utilities.findInReactTree(Utilities.getReactInstance(node), m => m && m.getPredicateSections, {walkable: ["return", "stateNode"]});
|
||||||
|
|
Loading…
Reference in New Issue