From 5ed34c149abbe53264dfeca62f068dec803e4d72 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 17 Mar 2018 18:35:09 -0300 Subject: [PATCH] Initial force update through reflection --- client/src/builtin/EmoteModule.js | 10 +++++++--- client/src/modules/reactcomponents.js | 19 +++++++++++++------ client/src/ui/reflection.js | 20 ++++++++++++++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/client/src/builtin/EmoteModule.js b/client/src/builtin/EmoteModule.js index d007908e..0a02c41a 100644 --- a/client/src/builtin/EmoteModule.js +++ b/client/src/builtin/EmoteModule.js @@ -9,7 +9,7 @@ */ import { FileUtils, ClientLogger as Logger } from 'common'; import { Events, Globals, WebpackModules, ReactComponents, MonkeyPatch } from 'modules'; -import { DOM, VueInjector } from 'ui'; +import { DOM, VueInjector, Reflection } from 'ui'; import EmoteComponent from './EmoteComponent.vue'; let emotes = null; const emotesEnabled = true; @@ -105,12 +105,16 @@ export default class { Logger.err('EmoteModule', err); } }); - this.unpatchMount = MonkeyPatch('BD:EmoteModule', Message.component.prototype).after('componentDidMount', (component, args) => { + for (const message of document.querySelectorAll('.message')) { + Reflection(message).forceUpdate(); + } + this.injectAll(); + this.unpatchMount = MonkeyPatch('BD:EmoteModule', Message.component.prototype).after('componentDidMount', component => { const element = this.ReactDOM.findDOMNode(component); if (!element) return; this.injectEmotes(element); }); - this.unpatchUpdate = MonkeyPatch('BD:EmoteModule', Message.component.prototype).after('componentDidUpdate', (component, args) => { + this.unpatchUpdate = MonkeyPatch('BD:EmoteModule', Message.component.prototype).after('componentDidUpdate', component => { const element = this.ReactDOM.findDOMNode(component); if (!element) return; this.injectEmotes(element); diff --git a/client/src/modules/reactcomponents.js b/client/src/modules/reactcomponents.js index 58bfb643..c0ed473c 100644 --- a/client/src/modules/reactcomponents.js +++ b/client/src/modules/reactcomponents.js @@ -272,12 +272,13 @@ export class ReactAutoPatcher { } static async patchComponents() { - this.patchMessage(); - this.patchMessageGroup(); - this.patchChannelMember(); - this.patchGuild(); - this.patchChannel(); - this.patchChannelList(); + await this.patchMessage(); + await this.patchMessageGroup(); + await this.patchChannelMember(); + await this.patchGuild(); + await this.patchChannel(); + await this.patchChannelList(); + this.forceUpdate(); } static async patchMessage() { @@ -344,4 +345,10 @@ export class ReactAutoPatcher { retVal.props['data-channel-name'] = channel.name; }); } + + static forceUpdate() { + for (const e of document.querySelectorAll('.message,.message-group,.guild,.containerDefault-7RImuF,.channel-members .member')) { + Reflection(e).forceUpdate(); + } + } } diff --git a/client/src/ui/reflection.js b/client/src/ui/reflection.js index 8a811171..bcc95ff5 100644 --- a/client/src/ui/reflection.js +++ b/client/src/ui/reflection.js @@ -89,6 +89,14 @@ class Reflection { } } + static getStateNode(node) { + try { + return this.reactInternalInstance(node).return.stateNode; + } catch (err) { + return null; + } + } + static getComponent(node, first = true) { // IMPORTANT TODO Currently only checks the first found component. For example channel-member will not return the correct component try { @@ -121,12 +129,24 @@ export default function (node) { get state() { return Reflection.getState(this.node); } + get stateNode() { + return Reflection.getStateNode(this.node); + } get reactInternalInstance() { return Reflection.reactInternalInstance(this.node); } get component() { return Reflection.getComponent(this.node); } + forceUpdate() { + try { + const stateNode = Reflection.getStateNode(this.node); + if (!stateNode || !stateNode.forceUpdate) return; + stateNode.forceUpdate(); + } catch (err) { + Logger.err('Reflection', err); + } + } prop(propName) { const split = propName.split('.'); const first = Reflection.findProp(this.node, split[0]);