parent
67746d59ee
commit
c71f9339de
|
@ -244,6 +244,36 @@ export default class WebpackModules {
|
|||
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.
|
||||
*/
|
||||
|
@ -276,4 +306,75 @@ export default class WebpackModules {
|
|||
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 SettingsTitle from "./settings/title";
|
||||
import Header from "./settings/sidebarheader";
|
||||
import {Filters} from "../modules/webpackmodules";
|
||||
|
||||
export default new class SettingsRenderer {
|
||||
|
||||
|
@ -60,8 +61,9 @@ export default new class SettingsRenderer {
|
|||
}, options));
|
||||
}
|
||||
|
||||
patchSections() {
|
||||
const UserSettings = WebpackModules.getByDisplayName("SettingsView");
|
||||
async patchSections() {
|
||||
const UserSettings = await WebpackModules.getLazy(Filters.byDisplayName("SettingsView"));
|
||||
|
||||
Patcher.after("SettingsManager", UserSettings.prototype, "getPredicateSections", (thisObject, args, returnValue) => {
|
||||
let location = returnValue.findIndex(s => s.section.toLowerCase() == "changelog") - 1;
|
||||
if (location < 0) return;
|
||||
|
@ -91,7 +93,7 @@ export default new class SettingsRenderer {
|
|||
}
|
||||
|
||||
forceUpdate() {
|
||||
const viewClass = WebpackModules.getByProps("standardSidebarView").standardSidebarView.split(" ")[0];
|
||||
const viewClass = WebpackModules.getByProps("standardSidebarView")?.standardSidebarView.split(" ")[0];
|
||||
const node = document.querySelector(`.${viewClass}`);
|
||||
if (!node) return;
|
||||
const stateNode = Utilities.findInReactTree(Utilities.getReactInstance(node), m => m && m.getPredicateSections, {walkable: ["return", "stateNode"]});
|
||||
|
|
Loading…
Reference in New Issue