XL v1.3.20
This commit is contained in:
parent
1f1f9318a8
commit
7b0faabf5d
|
@ -41,7 +41,7 @@ var XenoLib = (() => {
|
|||
twitter_username: ''
|
||||
}
|
||||
],
|
||||
version: '1.3.19',
|
||||
version: '1.3.20',
|
||||
description: 'Simple library to complement plugins with shared code without lowering performance.',
|
||||
github: 'https://github.com/1Lighty',
|
||||
github_raw: 'https://raw.githubusercontent.com/1Lighty/BetterDiscordPlugins/master/Plugins/1XenoLib.plugin.js'
|
||||
|
@ -50,7 +50,7 @@ var XenoLib = (() => {
|
|||
{
|
||||
title: 'Boring changes',
|
||||
type: 'fixed',
|
||||
items: ['Fix up startup warnings and errors.', 'Fixed notifications closing sometimes if you hover them near the end of the timeout.', 'Future proofing.']
|
||||
items: ['Fix up a couple of errors related to recent context menu changes.', 'Deprecated global context menu patching.']
|
||||
}
|
||||
],
|
||||
defaultConfig: [
|
||||
|
@ -95,7 +95,7 @@ var XenoLib = (() => {
|
|||
|
||||
/* Build */
|
||||
const buildPlugin = ([Plugin, Api]) => {
|
||||
const { ContextMenu, EmulatedTooltip, Toasts, Settings, Popouts, Modals, Utilities, WebpackModules, Filters, DiscordModules, ColorConverter, DOMTools, DiscordClasses, DiscordSelectors, ReactTools, ReactComponents, DiscordAPI, Logger, Patcher, PluginUpdater, PluginUtilities, DiscordClassModules, Structs } = Api;
|
||||
const { ContextMenu, EmulatedTooltip, Toasts, Settings, Popouts, Modals, Utilities, WebpackModules, Filters, DiscordModules, ColorConverter, DOMTools, DiscordClasses, DiscordSelectors, ReactTools, ReactComponents, DiscordAPI, Logger, PluginUpdater, PluginUtilities, DiscordClassModules, Structs } = Api;
|
||||
const { React, ModalStack, ContextMenuActions, ContextMenuItem, ContextMenuItemsGroup, ReactDOM, ChannelStore, GuildStore, UserStore, DiscordConstants, Dispatcher, GuildMemberStore, GuildActions, PrivateChannelActions, LayerManager, InviteActions, FlexChild, Titles, Changelog: ChangelogModal } = DiscordModules;
|
||||
|
||||
let CancelledAsync = false;
|
||||
|
@ -181,6 +181,25 @@ var XenoLib = (() => {
|
|||
XenoLib.getClass.__warns = {};
|
||||
XenoLib.getSingleClass.__warns = {};
|
||||
|
||||
XenoLib.createSmartPatcher = patcher => {
|
||||
const createPatcher = patcher => {
|
||||
return (moduleToPatch, functionName, callback, options = {}) => {
|
||||
const origDef = moduleToPatch[functionName];
|
||||
patcher(moduleToPatch, functionName, callback, options);
|
||||
if (origDef.isBDFDBpatched && moduleToPatch.BDFDBpatch && typeof moduleToPatch.BDFDBpatch[functionName].originalMethod === 'function') {
|
||||
patcher(moduleToPatch.BDFDBpatch[functionName], 'originalMethod', callback, options);
|
||||
}
|
||||
};
|
||||
};
|
||||
return Object.assign({}, patcher, {
|
||||
before: createPatcher(patcher.before),
|
||||
instead: createPatcher(patcher.instead),
|
||||
after: createPatcher(patcher.after)
|
||||
});
|
||||
};
|
||||
|
||||
const Patcher = XenoLib.createSmartPatcher(Api.Patcher);
|
||||
|
||||
const LibrarySettings = XenoLib.loadData(config.info.name, 'settings', DefaultLibrarySettings);
|
||||
|
||||
PluginUtilities.addStyle(
|
||||
|
@ -380,112 +399,40 @@ var XenoLib = (() => {
|
|||
}
|
||||
};
|
||||
|
||||
XenoLib.__contextPatches = [];
|
||||
try {
|
||||
if (global.XenoLib) if (global.XenoLib.__contextPatches && global.XenoLib.__contextPatches.length) XenoLib.__contextPatches.push(...global.XenoLib.__contextPatches);
|
||||
const ContextMenuClassname = XenoLib.getSingleClass('subMenuContext contextMenu'); /* I AM *SPEED* */
|
||||
const getContextMenuChild = val => {
|
||||
if (!val) return;
|
||||
const isValid = obj => obj.type === 'div' && obj.props && typeof obj.props.className === 'string' && obj.props.className.indexOf(ContextMenuClassname) !== -1 && Array.isArray(Utilities.getNestedProp(obj, 'props.children.props.children'));
|
||||
if (isValid(val)) return val.props.children;
|
||||
const children = Utilities.getNestedProp(val, 'props.children');
|
||||
if (!children) return;
|
||||
if (Array.isArray(children)) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const ret = getContextMenuChild(children[i]);
|
||||
if (ret) return ret.props.children;
|
||||
}
|
||||
} else if (isValid(children)) return children.props.children;
|
||||
};
|
||||
const handleContextMenu = (_this, ret, noRender) => {
|
||||
const menuGroups = getContextMenuChild(ret) || ret;
|
||||
if (!menuGroups) return /* Logger.warn('Failed to get context menu groups!', _this, ret) */;
|
||||
/* emulate a react class component */
|
||||
if (noRender) {
|
||||
let [value, set] = React.useState(false);
|
||||
let [state, setState] = React.useState({});
|
||||
_this.forceUpdate = () => set(!value);
|
||||
_this.state = state;
|
||||
_this.setState = setState;
|
||||
}
|
||||
if (!_this.state) _this.state = {};
|
||||
XenoLib.__contextPatches.forEach(e => {
|
||||
try {
|
||||
e(_this, menuGroups);
|
||||
} catch (e) {
|
||||
Logger.stacktrace('Error with patched context menu', e);
|
||||
}
|
||||
});
|
||||
};
|
||||
const getModule = regex => {
|
||||
try {
|
||||
const modules = WebpackModules.getAllModules();
|
||||
for (const index in modules) {
|
||||
if (!modules.hasOwnProperty(index)) continue;
|
||||
const module = modules[index];
|
||||
if (!module.exports || !module.exports.__esModule || !module.exports.default) continue;
|
||||
/* if BDFDB was inited before us, patch the already patched function */
|
||||
if (module.exports.default.toString().search(regex) !== -1 || (module.exports.default.isBDFDBpatched && module.exports.default.__originalMethod.toString().search(regex) !== -1)) return module;
|
||||
}
|
||||
} catch (e) {
|
||||
Logger.stacktrace(`Failed to getModule by regex ${regex}`, e);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
const renderContextMenus = ['NativeContextMenu', 'DeveloperContextMenu'];
|
||||
const hookContextMenus = [getModule(/case \w.ContextMenuTypes.CHANNEL_LIST_TEXT/), getModule(/case \w.ContextMenuTypes.GUILD_CHANNEL_LIST/), getModule(/case \w.ContextMenuTypes.USER_CHANNEL_MEMBERS/), getModule(/case \w\.ContextMenuTypes\.MESSAGE_MAIN/)];
|
||||
for (const type of renderContextMenus) {
|
||||
const module = WebpackModules.getByDisplayName(type);
|
||||
if (!module) {
|
||||
Logger.warn(`Failed to find ContextMenu type`, type);
|
||||
continue;
|
||||
}
|
||||
Patcher.after(module.prototype, 'render', (_this, _, ret) => handleContextMenu(_this, ret));
|
||||
}
|
||||
for (const menu of hookContextMenus) {
|
||||
if (!menu) continue;
|
||||
const origDef = menu.exports.default;
|
||||
Patcher.after(menu.exports, 'default', (_, [props], ret) => handleContextMenu({ props }, ret, true));
|
||||
if (origDef.isBDFDBpatched && menu.exports.BDFDBpatch && typeof menu.exports.BDFDBpatch.default.originalMethod === 'function') {
|
||||
Patcher.after(menu.exports.BDFDBpatch.default, 'originalMethod', (_, [props], ret) => handleContextMenu({ props }, ret, true));
|
||||
}
|
||||
}
|
||||
const GroupDMContextMenu = WebpackModules.getByDisplayName('FluxContainer(GroupDMContextMenu)');
|
||||
if (GroupDMContextMenu) {
|
||||
try {
|
||||
const type = new GroupDMContextMenu({}).render().type;
|
||||
Patcher.after(type.prototype, 'render', (_this, _, ret) => handleContextMenu(_this, ret));
|
||||
} catch (e) {
|
||||
Logger.stacktrace('Failed patching GroupDMContextMenu', e);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
Logger.stacktrace('Failed to patch context menus', e);
|
||||
}
|
||||
XenoLib.patchContext = callback => {
|
||||
XenoLib.__contextPatches.push(callback);
|
||||
};
|
||||
const deprecateFunction = (name, advice, ret = undefined) => () => (Logger.warn(`XenoLib.${name} is deprecated! ${advice}`), ret);
|
||||
|
||||
XenoLib.patchContext = deprecateFunction('patchContext', 'Do manual patching of context menus instead.');
|
||||
|
||||
const CTXMenu = WebpackModules.getByProps('default', 'MenuStyle');
|
||||
|
||||
class ContextMenuWrapper extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleOnClose = this.handleOnClose.bind(this);
|
||||
}
|
||||
handleOnClose() {
|
||||
ContextMenuActions.closeContextMenu();
|
||||
if (this.props.target instanceof HTMLElement) this.props.target.focus();
|
||||
}
|
||||
render() {
|
||||
return React.createElement('div', { className: DiscordClasses.ContextMenu.contextMenu }, this.props.menu);
|
||||
return React.createElement(CTXMenu.default, { onClose: this.handleOnClose, id: 'xenolib-context' }, this.props.menu);
|
||||
}
|
||||
}
|
||||
XenoLib.createSharedContext = (element, type, menuCreation) => {
|
||||
XenoLib.createSharedContext = (element, menuCreation) => {
|
||||
if (element.__XenoLib_ContextMenus) {
|
||||
element.__XenoLib_ContextMenus.push(menuCreation);
|
||||
} else {
|
||||
element.__XenoLib_ContextMenus = [menuCreation];
|
||||
const oOnContextMenu = element.props.onContextMenu;
|
||||
element.props.onContextMenu = e => (typeof oOnContextMenu === 'function' && oOnContextMenu(e), ContextMenuActions.openContextMenu(e, _ => React.createElement(ContextMenuWrapper, { menu: element.__XenoLib_ContextMenus.map(m => React.createElement(XenoLib.ReactComponents.ErrorBoundary, { label: 'shared context menu' }, m())), type })));
|
||||
element.props.onContextMenu = e => (typeof oOnContextMenu === 'function' && oOnContextMenu(e), ContextMenuActions.openContextMenu(e, _ => React.createElement(XenoLib.ReactComponents.ErrorBoundary, { label: 'CTX Menu' }, React.createElement(ContextMenuWrapper, { menu: element.__XenoLib_ContextMenus.map(m => m()), ..._ }))));
|
||||
}
|
||||
};
|
||||
|
||||
const ContextMenuSubMenuItem = WebpackModules.getByDisplayName('FluxContainer(SubMenuItem)');
|
||||
XenoLib.unpatchContext = callback => XenoLib.__contextPatches.splice(XenoLib.__contextPatches.indexOf(callback), 1);
|
||||
XenoLib.createContextMenuItem = (label, action, options = {}) => (!ContextMenuItem ? null : React.createElement(ContextMenuItem, { label, action: () => (!options.noClose && ContextMenuActions.closeContextMenu(), action()), ...options }));
|
||||
XenoLib.createContextMenuSubMenu = (label, items, options = {}) => (!ContextMenuSubMenuItem ? null : React.createElement(ContextMenuSubMenuItem, { label, render: items, ...options }));
|
||||
XenoLib.createContextMenuGroup = (children, options) => (!ContextMenuItemsGroup ? null : React.createElement(ContextMenuItemsGroup, { children, ...options }));
|
||||
const contextMenuItems = WebpackModules.find(m => m.MenuRadioItem && !m.default);
|
||||
XenoLib.unpatchContext = deprecateFunction('unpatchContext', 'Manual patching needs manual unpatching');
|
||||
XenoLib.createContextMenuItem = (label, action, id, options = {}) => (!contextMenuItems ? null : React.createElement(contextMenuItems.MenuItem, { label, id, action: () => (!options.noClose && ContextMenuActions.closeContextMenu(), action()), ...options }));
|
||||
XenoLib.createContextMenuSubMenu = (label, children, id, options = {}) => (!contextMenuItems ? null : React.createElement(contextMenuItems.MenuItem, { label, children, id, ...options }));
|
||||
XenoLib.createContextMenuGroup = (children, options) => (!contextMenuItems ? null : React.createElement(contextMenuItems.MenuGroup, { children, ...options }));
|
||||
|
||||
try {
|
||||
XenoLib.ReactComponents.ButtonOptions = WebpackModules.getByProps('ButtonLink');
|
||||
|
@ -542,7 +489,7 @@ var XenoLib = (() => {
|
|||
footerProps.children = [];
|
||||
if (websiteLink) footerProps.children.push(websiteLink);
|
||||
if (sourceLink) footerProps.children.push(websiteLink ? ' | ' : null, sourceLink);
|
||||
footerProps.children.push(websiteLink || sourceLink ? ' | ' : null, React.createElement('a', { className: 'bda-link', onClick: e => ContextMenuActions.openContextMenu(e, e => React.createElement('div', { className: DiscordClasses.ContextMenu.contextMenu }, XenoLib.createContextMenuGroup([XenoLib.createContextMenuItem('Paypal', () => window.open('https://paypal.me/lighty13')), XenoLib.createContextMenuItem('Ko-fi', () => window.open('https://ko-fi.com/lighty_')), XenoLib.createContextMenuItem('Patreon', () => window.open('https://www.patreon.com/lightyp'))]))) }, 'Donate'));
|
||||
footerProps.children.push(websiteLink || sourceLink ? ' | ' : null, React.createElement('a', { className: 'bda-link', onClick: e => ContextMenuActions.openContextMenu(e, e => React.createElement(XenoLib.ReactComponents.ErrorBoundary, { label: 'Donate button CTX menu' }, React.createElement(ContextMenuWrapper, { menu: XenoLib.createContextMenuGroup([XenoLib.createContextMenuItem('Paypal', () => window.open('https://paypal.me/lighty13'), 'paypal'), XenoLib.createContextMenuItem('Ko-fi', () => window.open('https://ko-fi.com/lighty_'), 'kofi'), XenoLib.createContextMenuItem('Patreon', () => window.open('https://www.patreon.com/lightyp'), 'patreon')]), ...e }))) }, 'Donate'));
|
||||
footerProps.children.push(' | ', supportServerLink || React.createElement('a', { className: 'bda-link', onClick: () => (LayerManager.popLayer(), InviteActions.acceptInviteAndTransitionToInviteChannel('NYvWdN5')) }, 'Support Server'));
|
||||
footerProps.children.push(' | ', React.createElement('a', { className: 'bda-link', onClick: () => (_this.props.addon.plugin.showChangelog ? _this.props.addon.plugin.showChangelog() : Modals.showChangelogModal(_this.props.addon.plugin.getName() + ' Changelog', _this.props.addon.plugin.getVersion(), _this.props.addon.plugin.getChanges())) }, 'Changelog'));
|
||||
footerProps = null;
|
||||
|
|
Loading…
Reference in New Issue