From 43359d771cf998f713550eafa0b02068dda98ae6 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Thu, 8 Mar 2018 10:40:29 +0200 Subject: [PATCH] add automa, new functions to ui and base reflection --- client/src/ui/automanip.js | 80 +++++++++++++++++++++++++++++++++++++ client/src/ui/bdui.js | 2 + client/src/ui/dom.js | 6 +++ client/src/ui/reflection.js | 56 ++++++++++++++++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 client/src/ui/automanip.js create mode 100644 client/src/ui/reflection.js diff --git a/client/src/ui/automanip.js b/client/src/ui/automanip.js new file mode 100644 index 00000000..1f2db70f --- /dev/null +++ b/client/src/ui/automanip.js @@ -0,0 +1,80 @@ +/** + * BetterDiscord Automated DOM Manipulations + * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks + * All rights reserved. + * https://betterdiscord.net + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. +*/ + +import { Events, WebpackModules } from 'modules'; +import Reflection from './reflection'; +import DOM from './dom'; + +class TempApi { + static get currentGuildId() { + try { + return WebpackModules.getModuleByName('SelectedGuildStore').getGuildId(); + } catch (err) { + return 0; + } + } + static get currentChannelId() { + try { + return WebpackModules.getModuleByName('SelectedChannelStore').getChannelId(); + } catch (err) { + return 0; + } + } + static get currentUserId() { + try { + return WebpackModules.getModuleByName('UserStore').getCurrentUser().id; + } catch (err) { + return 0; + } + } +} + +export default class { + + constructor() { + Events.on('server-switch', e => { + try { + this.appMount.setAttribute('guild-id', TempApi.currentGuildId); + this.appMount.setAttribute('channel-id', TempApi.currentChannelId); + this.setIds(); + } catch (err) { + console.log(err); + } + }); + Events.on('channel-switch', e => { + try { + this.appMount.setAttribute('guild-id', TempApi.currentGuildId); + this.appMount.setAttribute('channel-id', TempApi.currentChannelId); + this.setIds(); + } catch (err) { + console.log(err); + } + }); + } + + setIds() { + for (let msg of document.querySelectorAll('.message')) { + if (msg.hasAttribute('message-id')) continue; + const message = Reflection.findProp(msg, 'message'); + if (!message) continue; + const { id, author } = message; + if (!id || !author) continue; + const currentUser = author.id === TempApi.currentUserId; + DOM.setAttributes(msg, [{ name: 'message-id', value: message.id }]); + const msgGroup = msg.closest('.message-group'); + if (!msgGroup) continue; + DOM.setAttributes(msgGroup, [{ name: 'author-id', value: author.id }, { name: 'author-is-currentuser', value: currentUser }]); + } + } + + get appMount() { + return document.getElementById('app-mount'); + } +} diff --git a/client/src/ui/bdui.js b/client/src/ui/bdui.js index 44341cc7..b8cacb09 100644 --- a/client/src/ui/bdui.js +++ b/client/src/ui/bdui.js @@ -14,10 +14,12 @@ import { BdSettingsWrapper } from './components'; import BdModals from './components/bd/BdModals.vue'; import { Events, WebpackModules } from 'modules'; import { Utils } from 'common'; +import AutoManip from './automanip'; export default class { static initUiEvents() { + this.autoManip = new AutoManip(); const defer = setInterval(() => { if (!this.profilePopupModule) return; clearInterval(defer); diff --git a/client/src/ui/dom.js b/client/src/ui/dom.js index c73904d2..55a0d179 100644 --- a/client/src/ui/dom.js +++ b/client/src/ui/dom.js @@ -158,4 +158,10 @@ export default class DOM { style.appendChild(document.createTextNode(css)); return style; } + + static setAttributes(node, attributes) { + for (let attribute of attributes) { + node.setAttribute(attribute.name, attribute.value); + } + } } diff --git a/client/src/ui/reflection.js b/client/src/ui/reflection.js new file mode 100644 index 00000000..9410f256 --- /dev/null +++ b/client/src/ui/reflection.js @@ -0,0 +1,56 @@ +/** + * BetterDiscord Reflection Module + * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks + * All rights reserved. + * https://betterdiscord.net + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. +*/ + +export default class { + static reactInternalInstance(node) { + if (!Object.keys(node) || !Object.keys(node).length) return null; + const riiKey = Object.keys(node).find(k => k.startsWith('__reactInternalInstance')); + return riiKey ? node[riiKey] : null; + } + + static findProp(node, prop) { + const ii = this.reactInternalInstance(node); + if (!ii) return null; + const fir = this.findInReturn(ii, prop); + if (fir) return fir; + return null; + } + + static findInReturn(internalInstance, prop) { + const r = internalInstance.return; + if (!r) return null; + const find = this.findMemoizedProp(r, prop); + if (find) return find; + return this.findMemoizedState(r, prop); + } + + static findMemoizedProp(obj, prop) { + if (!obj.hasOwnProperty('memoizedProps')) return null; + obj = obj.memoizedProps; + return this.findPropIn(obj, prop); + } + + static findMemoizedState(obj, prop) { + if (!obj.hasOwnProperty('memoizedState')) return null; + obj = obj.memoizedState; + return this.findPropIn(obj, prop); + } + + static findPropIn(obj, prop) { + if (obj && !(obj instanceof Array) && obj instanceof Object && obj.hasOwnProperty(prop)) return obj[prop]; + if (obj && obj instanceof Array) { + const found = obj.find(mp => { + if (mp.props && mp.props.hasOwnProperty(prop)) return true; + }); + if (found) return found; + } + return null; + } +}