From 1b9173922c933571f14f8a214333f7f758918e91 Mon Sep 17 00:00:00 2001
From: Robert Delaney <71196819+doggybootsy@users.noreply.github.com>
Date: Thu, 4 Aug 2022 17:42:29 -0700
Subject: [PATCH 1/2] Fix for the discord recent updates and some minor changes
Changes `dirtyDispatch` -> `dispatch`
Removes usage of `ActionTypes` (Unless its vz's constant)
Changes how the settings menu patch works
- Opens it then instantly closes it
Instead of waiting for the 'window.webpackChunkdiscord_app' object, it just creates it
---
renderer/src/api/I18n.js | 2 +-
renderer/src/api/settings/store/Actions.js | 8 +-
.../attributes/modules/components/Anchor.js | 4 +-
.../attributes/modules/members/Member.js | 29 ++--
.../attributes/modules/misc/Settings.js | 4 +-
renderer/src/builtins/settings/index.js | 147 +++++++-----------
renderer/src/index.js | 4 +-
renderer/src/modules/components/Anchor.jsx | 4 +-
renderer/src/modules/components/index.js | 6 +-
renderer/src/modules/discord/constants.js | 2 +-
.../discord/modal/userProfile/action/open.js | 4 +-
renderer/src/modules/webpack/index.js | 17 +-
12 files changed, 99 insertions(+), 132 deletions(-)
diff --git a/renderer/src/api/I18n.js b/renderer/src/api/I18n.js
index 11b0d7dd..3f9319da 100644
--- a/renderer/src/api/I18n.js
+++ b/renderer/src/api/I18n.js
@@ -52,7 +52,7 @@ export default class I18n extends API {
async start () {
locale = getModule('locale', 'theme')?.locale;
- FluxDispatcher.subscribe($discord.constants.ActionTypes.I18N_LOAD_SUCCESS, this._handleLocaleChange);
+ FluxDispatcher.subscribe('I18N_LOAD_SUCCESS', this._handleLocaleChange);
this.injectAllStrings(__coreMessages);
}
diff --git a/renderer/src/api/settings/store/Actions.js b/renderer/src/api/settings/store/Actions.js
index c6a3df46..86a112ac 100644
--- a/renderer/src/api/settings/store/Actions.js
+++ b/renderer/src/api/settings/store/Actions.js
@@ -3,7 +3,7 @@ import { ActionTypes } from '@vizality/constants';
export default {
toggleSetting (category, setting, defaultValue) {
- FluxDispatcher.dirtyDispatch({
+ FluxDispatcher.dispatch({
type: ActionTypes.VIZALITY_TOGGLE_SETTING,
category,
setting,
@@ -12,7 +12,7 @@ export default {
},
updateSettings (category, settings) {
- FluxDispatcher.dirtyDispatch({
+ FluxDispatcher.dispatch({
type: ActionTypes.VIZALITY_UPDATE_SETTINGS,
category,
settings
@@ -20,7 +20,7 @@ export default {
},
updateSetting (category, setting, value) {
- FluxDispatcher.dirtyDispatch({
+ FluxDispatcher.dispatch({
type: ActionTypes.VIZALITY_UPDATE_SETTING,
category,
setting,
@@ -29,7 +29,7 @@ export default {
},
deleteSetting (category, setting) {
- FluxDispatcher.dirtyDispatch({
+ FluxDispatcher.dispatch({
type: ActionTypes.VIZALITY_DELETE_SETTING,
category,
setting
diff --git a/renderer/src/builtins/attributes/modules/components/Anchor.js b/renderer/src/builtins/attributes/modules/components/Anchor.js
index ecf5631c..a2836a08 100644
--- a/renderer/src/builtins/attributes/modules/components/Anchor.js
+++ b/renderer/src/builtins/attributes/modules/components/Anchor.js
@@ -109,8 +109,8 @@ export default builtin => {
icon: 'PersonRemove'
});
}
- return FluxDispatcher.dirtyDispatch({
- type: $discord.constants.ActionTypes.USER_PROFILE_MODAL_OPEN,
+ return FluxDispatcher.dispatch({
+ type: 'USER_PROFILE_MODAL_OPEN',
userId
});
} catch (err) {
diff --git a/renderer/src/builtins/attributes/modules/members/Member.js b/renderer/src/builtins/attributes/modules/members/Member.js
index 749cd342..c32d8057 100644
--- a/renderer/src/builtins/attributes/modules/members/Member.js
+++ b/renderer/src/builtins/attributes/modules/members/Member.js
@@ -4,24 +4,31 @@
* @memberof Builtin.Attributes.Misc
*/
-import { getModuleByDisplayName } from '@vizality/webpack';
+import { getModule } from '@vizality/webpack';
import { patch, unpatch } from '@vizality/patcher';
export const labels = [ 'Members', 'Member' ];
export default builtin => {
- const MemberListItem = getModuleByDisplayName('MemberListItem');
- patch('vz-attributes-members-member', MemberListItem?.prototype, 'render', function (_, res) {
+ const MemberListItem = getModule([ 'AVATAR_DECORATION_PADDING' ])
+ patch('vz-attributes-members-member', MemberListItem?.default, 'type', (_, res) => {
try {
- if (!res || !this?.props?.user) return;
- const { activities } = res.props?.subText?.props;
- const { user, isOwner } = this.props;
+ if (!res || !res?.props?.user) return;
+ const { user, isOwner, activities } = res.props;
if (!user) return;
- res.props['vz-user-id'] = user.id;
- res.props['vz-activity'] = Boolean(activities?.some(activity => activity.type !== 4)) && '';
- res.props['vz-self'] = Boolean(user.email) && '';
- res.props['vz-bot'] = Boolean(user.bot) && '';
- res.props['vz-owner'] = Boolean(isOwner) && '';
+
+ const old = res.type.prototype.render
+ res.type.prototype.render = function() {
+ const res = old.apply(this, arguments)
+
+ res.props['vz-user-id'] = user.id;
+ res.props['vz-activity'] = Boolean(activities?.some(activity => activity.type !== 4)) && '';
+ res.props['vz-self'] = Boolean(user.email) && '';
+ res.props['vz-bot'] = Boolean(user.bot) && '';
+ res.props['vz-owner'] = Boolean(isOwner) && '';
+
+ return res
+ }
} catch (err) {
return builtin.error(builtin._labels.concat(labels), err);
}
diff --git a/renderer/src/builtins/attributes/modules/misc/Settings.js b/renderer/src/builtins/attributes/modules/misc/Settings.js
index 7c8c4a13..332bd2c6 100644
--- a/renderer/src/builtins/attributes/modules/misc/Settings.js
+++ b/renderer/src/builtins/attributes/modules/misc/Settings.js
@@ -40,7 +40,7 @@ export default () => {
/**
* Subscribe to Discord's user settings uppdate flux store.
*/
- FluxDispatcher?.subscribe($discord.constants.ActionTypes.USER_SETTINGS_UPDATE, handleSettingsChange);
+ FluxDispatcher?.subscribe('USER_SETTINGS_UPDATE', handleSettingsChange);
/**
* Remove attributes and unsubscribe from Flux on unload.
@@ -48,6 +48,6 @@ export default () => {
return () => {
root?.removeAttribute('vz-theme');
root?.removeAttribute('vz-mode');
- FluxDispatcher?.unsubscribe($discord.constants.ActionTypes.USER_SETTINGS_UPDATE, handleSettingsChange);
+ FluxDispatcher?.unsubscribe('USER_SETTINGS_UPDATE', handleSettingsChange);
};
};
diff --git a/renderer/src/builtins/settings/index.js b/renderer/src/builtins/settings/index.js
index c84b1206..3d454999 100644
--- a/renderer/src/builtins/settings/index.js
+++ b/renderer/src/builtins/settings/index.js
@@ -1,92 +1,18 @@
import { openModal, closeModal } from '@vizality/modal';
-import { getModuleByDisplayName, getModule, instance } from '@vizality/webpack';
+import { getModule, contextMenu } from '@vizality/webpack';
import { SettingsContextMenu } from '@vizality/components/vizality';
import { Content, Layout } from '@vizality/components/dashboard';
-import { toPlural, toTitleCase } from '@vizality/util/string';
+import { toPlural } from '@vizality/util/string';
import { Confirm, ContextMenu, Modal } from '@vizality/components';
-import { joinClassNames } from '@vizality/util/dom';
+import { joinClassNames, waitForElement } from '@vizality/util/dom';
import { patch, unpatch } from '@vizality/patcher';
import { Builtin } from '@vizality/entities';
import { Messages } from '@vizality/i18n';
import React from 'react';
+import { webFrame } from 'electron'
import SettingsPage from './components/Settings';
-/**
- * Contributed by DoggyBootsy, originally written by Strencher.
- */
-{
- const modules = Object.values(instance.m).filter(e => e.toString().search(/openContextMenuLazy[)(]/) > -1);
- const regex = [
- {
- regex: /return Promise\.all\(\[(.*?)\]\)\.then\(\D+(.+?)\)\)/,
- parse (match) {
- return {
- imports: matchAll(/\(([\de]+)\)/g, match[0]).map(e => Number(e)),
- main: match[1]
- };
- }
- },
- {
- regex: /return Promise\.resolve\(\)\.then\(\D+(.+?)\)/,
- parse (match) {
- return {
- imports: [],
- main: match[0]
- };
- }
- },
- {
- regex: /return [rn]\.e\((\d+)\)\.then\(\D+(\d+)\)\)/,
- parse (match) {
- return {
- imports: [ match[0] ],
- main: match[0]
- };
- }
- }
- ];
-
- function matchAll (regex, input, parent = false) {
- const output = [];
- let matches,
- lastIndex = 0;
- while (matches = regex.exec(input.slice(lastIndex))) {
- if (!regex.global) lastIndex += matches.index + matches[0].length;
- if (parent) output.push(matches);
- else {
- const [ , ...match ] = matches;
- output.push(match);
- }
- }
- return output;
- }
-
- const found = [];
-
- for (let i = 0; i < modules.length; i++) {
- const str = modules[i].toString();
-
- for (let i2 = 0; i2 < regex.length; i2++) {
- const { regex: reg, parse } = regex[i2];
- if (!reg.test(str)) continue;
- const result = matchAll(reg, str).map(res => ({ ...parse(res), module: modules[i], reg }));
- found.push(...result);
-
- break;
- }
- }
-
- Promise.all(found.map(item => {
- try {
- const imports = item.imports.map(i => instance.e(i));
- return Promise.all(imports).then(instance.bind(instance, item.main)).catch(() => void 0);
- } catch (error) {
- return Promise.resolve();
- }
- }));
-}
-
/**
* The settings page categories.
*/
@@ -183,22 +109,59 @@ export default class Settings extends Builtin {
));
}
+ async waitFor(filter) {
+ const exists = await getModule(filter, true, true)
+ if (exists) return exists
+ return await this.waitFor(filter)
+ }
+
async patchSettingsContextMenu () {
- const DiscordSettingsContextMenu = await getModule(m => m.default?.displayName === 'UserSettingsCogContextMenu', true);
+ const { panels } = await getModule('panels', 'downloadProgressCircle', 'hasNotice', true)
+ const { container } = await getModule('container', 'usernameContainer', 'godlike', true)
+ const { button } = await getModule('button', 'disabled', 'enabled', true)
+
+ await waitForElement(`.${panels} > .${container} .${button}:last-child`);
+ const settingsNode = webFrame.top.context.document.querySelector(`.${panels} > .${container} .${button}:last-child`);
+
+ settingsNode.__reactProps$.onContextMenu({
+ stopPropagation() {},
+ currentTarget: { contains: () => true },
+ preventDefault() {}
+ });
+ contextMenu.closeContextMenu();
+
+
+ const DiscordSettingsContextMenu = await this.waitFor(m => {
+ if (!m.default) return;
+ const string = String(m.default);
+ return string.includes('.AnalyticsLocationProvider,') && string.includes('.createElement(') && !string.includes('return function') && !m.
+ default.displayName;
+ });
+
patch('vz-settings-context-menu', DiscordSettingsContextMenu, 'default', (_, res) => {
- const items = res.props.children.find(child => Array.isArray(child));
- items.push(
- <>
-
- vizality.api.routes.navigateTo('dashboard')}
- >
- {SettingsContextMenu.type().props.children}
-
- >
- );
+ const { children } = res.props;
+ const old = children.type;
+
+ children.type = () => {
+ const result = old(children.props);
+
+ const items = result.props.children.props.children.find(child => Array.isArray(child));
+
+ items.push(
+ <>
+
+ vizality.api.routes.navigateTo('dashboard')}
+ >
+ {SettingsContextMenu.type().props.children}
+
+ >
+ );
+
+ return result;
+ };
});
}
diff --git a/renderer/src/index.js b/renderer/src/index.js
index 119c31e2..0312ac7c 100644
--- a/renderer/src/index.js
+++ b/renderer/src/index.js
@@ -6,7 +6,7 @@
import { log as _log, warn as _warn, error as _error, deprecate as _deprecate } from '@vizality/util/logger';
import { initialize as initializeWebpackModules, getModule, FluxDispatcher, getAllModules } from '@vizality/webpack';
-import { Directories, Events, Protocols, Developers } from '@vizality/constants';
+import { Directories, Events, Protocols } from '@vizality/constants';
import { resolveCompiler } from '@vizality/compilers';
import { createElement } from '@vizality/util/dom';
import { toPlural } from '@vizality/util/string';
@@ -60,7 +60,6 @@ export default class Vizality extends Updatable {
async handleConnectionOpen () {
return new Promise(resolve => {
- console.log(getAllModules()?.length);
if (getAllModules()?.length > 7000) {
return resolve();
}
@@ -93,6 +92,7 @@ export default class Vizality extends Updatable {
* @note This has to be after webpack modules have been initialized.
*/
const Flux = await getModule('Store', 'PersistedStore', true);
+
Flux.connectStoresAsync = (stores, fn) => Component =>
import('./components').AsyncComponent.from((async () => {
const awaitedStores = await Promise.all(stores);
diff --git a/renderer/src/modules/components/Anchor.jsx b/renderer/src/modules/components/Anchor.jsx
index ccb5dc43..ea4b4429 100644
--- a/renderer/src/modules/components/Anchor.jsx
+++ b/renderer/src/modules/components/Anchor.jsx
@@ -76,8 +76,8 @@ export default memo(({ onClick, href, className, userId, children, type, addonId
icon: 'PersonRemove'
});
}
- return FluxDispatcher.dirtyDispatch({
- type: $discord.constants.ActionTypes.USER_PROFILE_MODAL_OPEN,
+ return FluxDispatcher.dispatch({
+ type: 'USER_PROFILE_MODAL_OPEN',
userId
});
}
diff --git a/renderer/src/modules/components/index.js b/renderer/src/modules/components/index.js
index 3bb5717f..a4c3bb4c 100644
--- a/renderer/src/modules/components/index.js
+++ b/renderer/src/modules/components/index.js
@@ -25,7 +25,7 @@ export const ShinyButton = AsyncComponent.fromDisplayName('ShinyButton');
export const WebhookCard = AsyncComponent.fromDisplayName('WebhookCard');
export const Tooltip = AsyncComponent.fetchFromProps('TooltipContainer');
export const HelpMessage = AsyncComponent.fromDisplayName('HelpMessage');
-export const Button = AsyncComponent.fromProps(m => m.Link && m.Hovers);
+export const Button = AsyncComponent.fromProps([ 'link', 'Hovers' ]);
export const FormNotice = AsyncComponent.fromDisplayName('FormNotice');
// "count", "color", "shape", "disableColor", "className"
export const NumberBadge = AsyncComponent.fetchFromProps('NumberBadge');
@@ -65,7 +65,7 @@ export const Table = AsyncComponent.fromDisplayName('Table');
export const Image = AsyncComponent.fromDisplayName('Image');
export const Video = AsyncComponent.fromDisplayName('Video');
export const Card = AsyncComponent.fromDisplayName('Card');
-export const Text = AsyncComponent.fromDisplayName('Text');
+export const Text = AsyncComponent.fromDisplayName('LegacyText');
export const Flex = AsyncComponent.fromDisplayName('Flex');
export { default as ProgressBar } from './ProgressBar';
@@ -197,7 +197,7 @@ getModuleByDisplayName('TextInput', true, true).then(TextInput => {
this.TextInput.Sizes = TextInput.Sizes;
});
-getModuleByDisplayName('Text', true, true).then(Text => {
+getModuleByDisplayName('LegacyText', true, true).then(Text => {
this.Text.Colors = Text.Colors;
this.Text.Sizes = Text.Sizes;
});
diff --git a/renderer/src/modules/discord/constants.js b/renderer/src/modules/discord/constants.js
index 96f58dc6..00517cb3 100644
--- a/renderer/src/modules/discord/constants.js
+++ b/renderer/src/modules/discord/constants.js
@@ -24,4 +24,4 @@ export default {
}
};
-export const { ActionTypes, Permissions, Routes } = this.default;
+export const { Permissions, Routes } = this.default;
diff --git a/renderer/src/modules/discord/modal/userProfile/action/open.js b/renderer/src/modules/discord/modal/userProfile/action/open.js
index 8e36c91c..7cbc328f 100644
--- a/renderer/src/modules/discord/modal/userProfile/action/open.js
+++ b/renderer/src/modules/discord/modal/userProfile/action/open.js
@@ -1,8 +1,8 @@
// if (!userId) return;
// // @todo Use Discord module for this after it's set up.
// getModule('getUser').getUser(userId)
-// .then(() => getModule('dirtyDispatch').wait(
-// () => getModule('dirtyDispatch').dispatch({ type: constants.ActionTypes.USER_PROFILE_MODAL_OPEN, userId })))
+// .then(() => getModule('dispatch').wait(
+// () => getModule('dispatch').dispatch({ type: 'USER_PROFILE_MODAL_OPEN', userId })))
// .catch(() => vizality.api.notifications.sendToast({
// header: 'User Not Found',
// type: 'User Not Found',
diff --git a/renderer/src/modules/webpack/index.js b/renderer/src/modules/webpack/index.js
index e8b9f88d..2fc257b1 100644
--- a/renderer/src/modules/webpack/index.js
+++ b/renderer/src/modules/webpack/index.js
@@ -80,19 +80,16 @@ const _getModule = (filter, retry = false, forever = false) => {
*/
export const initialize = async () => {
/**
- * Wait until webpack is ready.
+ * If 'window.webpackChunkdiscord_app' doesn't exist create it
+ * (Discord loads modules that existed window object exists)
*/
- while (!window.webpackChunkdiscord_app) {
- await sleep(100);
- }
+ if (!window.webpackChunkdiscord_app) window.webpackChunkdiscord_app = []
- let instance;
window.webpackChunkdiscord_app.push([
- [ '_vizality' ],
- {}, exports => instance = exports
- ]);
-
- this.instance = instance;
+ [ Symbol('vizality') ],
+ {},
+ (exports) => this.instance = exports
+ ])
for (const mdl in moduleFilters) {
this[mdl] = await _getModule(moduleFilters[mdl], true);
From c8f5b7cb0301e7c5d1c2bfc58f1dd235ea1644c1 Mon Sep 17 00:00:00 2001
From: Robert Delaney <71196819+doggybootsy@users.noreply.github.com>
Date: Thu, 4 Aug 2022 18:00:00 -0700
Subject: [PATCH 2/2] Fix buttons
---
renderer/src/modules/components/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/renderer/src/modules/components/index.js b/renderer/src/modules/components/index.js
index a4c3bb4c..ca1a1254 100644
--- a/renderer/src/modules/components/index.js
+++ b/renderer/src/modules/components/index.js
@@ -25,7 +25,7 @@ export const ShinyButton = AsyncComponent.fromDisplayName('ShinyButton');
export const WebhookCard = AsyncComponent.fromDisplayName('WebhookCard');
export const Tooltip = AsyncComponent.fetchFromProps('TooltipContainer');
export const HelpMessage = AsyncComponent.fromDisplayName('HelpMessage');
-export const Button = AsyncComponent.fromProps([ 'link', 'Hovers' ]);
+export const Button = AsyncComponent.from(getModule('Link', 'Hovers', 'Sizes', true));
export const FormNotice = AsyncComponent.fromDisplayName('FormNotice');
// "count", "color", "shape", "disableColor", "className"
export const NumberBadge = AsyncComponent.fetchFromProps('NumberBadge');