Add extra classes to messages, channel members and channels
This commit is contained in:
parent
ee0b13dab2
commit
2c38433a2b
|
@ -1,6 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* BetterDiscord React Component Manipulations
|
* BetterDiscord React Component Manipulations
|
||||||
* original concept and some code by samogot - https://github.com/samogot / https://github.com/samogot/betterdiscord-plugins/tree/master/v2/1Lib%20Discord%20Internals
|
* Original concept and some code by samogot - https://github.com/samogot / https://github.com/samogot/betterdiscord-plugins/tree/master/v2/1Lib%20Discord%20Internals
|
||||||
|
*
|
||||||
* Copyright (c) 2015-present JsSucks - https://github.com/JsSucks
|
* Copyright (c) 2015-present JsSucks - https://github.com/JsSucks
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* https://github.com/JsSucks - https://betterdiscord.net
|
* https://github.com/JsSucks - https://betterdiscord.net
|
||||||
|
@ -9,7 +10,6 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EmoteModule } from 'builtin';
|
|
||||||
import { Reflection } from 'ui';
|
import { Reflection } from 'ui';
|
||||||
import { Filters, ClientLogger as Logger } from 'common';
|
import { Filters, ClientLogger as Logger } from 'common';
|
||||||
import { MonkeyPatch, Patcher } from './patcher';
|
import { MonkeyPatch, Patcher } from './patcher';
|
||||||
|
@ -167,21 +167,9 @@ export { Helpers as ReactHelpers };
|
||||||
|
|
||||||
class ReactComponent {
|
class ReactComponent {
|
||||||
constructor(id, component, retVal) {
|
constructor(id, component, retVal) {
|
||||||
this._id = id;
|
this.id = id;
|
||||||
this._component = component;
|
this.component = component;
|
||||||
this._retVal = retVal;
|
this.retVal = retVal;
|
||||||
}
|
|
||||||
|
|
||||||
get id() {
|
|
||||||
return this._id;
|
|
||||||
}
|
|
||||||
|
|
||||||
get component() {
|
|
||||||
return this._component;
|
|
||||||
}
|
|
||||||
|
|
||||||
get retVal() {
|
|
||||||
return this._retVal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +198,13 @@ export class ReactComponents {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a component from the components array or by waiting for it to be mounted.
|
||||||
|
* @param {String} name The component's name
|
||||||
|
* @param {Object} important An object containing a selector to look for
|
||||||
|
* @param {Function} filter A function to filter components if a single element is rendered by multiple components
|
||||||
|
* @return {Promise => ReactComponent}
|
||||||
|
*/
|
||||||
static async getComponent(name, important, filter) {
|
static async getComponent(name, important, filter) {
|
||||||
const have = this.components.find(c => c.id === name);
|
const have = this.components.find(c => c.id === name);
|
||||||
if (have) return have;
|
if (have) return have;
|
||||||
|
@ -220,19 +215,21 @@ export class ReactComponents {
|
||||||
clearInterval(importantInterval);
|
clearInterval(importantInterval);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const select = document.querySelector(important.selector);
|
|
||||||
if (!select) return;
|
const element = document.querySelector(important.selector);
|
||||||
const reflect = Reflection(select);
|
if (!element) return;
|
||||||
|
|
||||||
|
clearInterval(importantInterval);
|
||||||
|
const reflect = Reflection(element);
|
||||||
const component = filter ? reflect.components.find(filter) || reflect.component : reflect.component;
|
const component = filter ? reflect.components.find(filter) || reflect.component : reflect.component;
|
||||||
if (!component) {
|
if (!component) {
|
||||||
clearInterval(importantInterval);
|
Logger.error('ReactComponents', [`FAILED TO GET IMPORTANT COMPONENT ${name} WITH REFLECTION FROM`, element]);
|
||||||
Logger.error('ReactComponents', [`FAILED TO GET IMPORTANT COMPONENT ${name} WITH REFLECTION FROM`, select]);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!component.displayName) component.displayName = name;
|
if (!component.displayName) component.displayName = name;
|
||||||
Logger.info('ReactComponents', [`Found important component ${name} with reflection`, reflect]);
|
Logger.info('ReactComponents', [`Found important component ${name} with reflection`, reflect]);
|
||||||
this.push(component);
|
this.push(component);
|
||||||
clearInterval(importantInterval);
|
|
||||||
}, 50);
|
}, 50);
|
||||||
}
|
}
|
||||||
let listener = this.listeners.find(l => l.id === name);
|
let listener = this.listeners.find(l => l.id === name);
|
||||||
|
@ -304,6 +301,7 @@ export class ReactAutoPatcher {
|
||||||
|
|
||||||
static async patchMessage() {
|
static async patchMessage() {
|
||||||
this.Message = await ReactComponents.getComponent('Message', { selector: '.message' });
|
this.Message = await ReactComponents.getComponent('Message', { selector: '.message' });
|
||||||
|
|
||||||
this.unpatchMessageRender = MonkeyPatch('BD:ReactComponents', this.Message.component.prototype).after('render', (component, args, retVal) => {
|
this.unpatchMessageRender = MonkeyPatch('BD:ReactComponents', this.Message.component.prototype).after('render', (component, args, retVal) => {
|
||||||
const { message, jumpSequenceId, canFlash } = component.props;
|
const { message, jumpSequenceId, canFlash } = component.props;
|
||||||
const { id, colorString, bot, author, attachments, embeds } = message;
|
const { id, colorString, bot, author, attachments, embeds } = message;
|
||||||
|
@ -324,11 +322,16 @@ export class ReactAutoPatcher {
|
||||||
|
|
||||||
static async patchMessageGroup() {
|
static async patchMessageGroup() {
|
||||||
this.MessageGroup = await ReactComponents.getComponent('MessageGroup', { selector: '.message-group' });
|
this.MessageGroup = await ReactComponents.getComponent('MessageGroup', { selector: '.message-group' });
|
||||||
|
|
||||||
this.unpatchMessageGroupRender = MonkeyPatch('BD:ReactComponents', this.MessageGroup.component.prototype).after('render', (component, args, retVal) => {
|
this.unpatchMessageGroupRender = MonkeyPatch('BD:ReactComponents', this.MessageGroup.component.prototype).after('render', (component, args, retVal) => {
|
||||||
const { author, type } = component.props.messages[0];
|
const { author, type } = component.props.messages[0];
|
||||||
retVal.props['data-author-id'] = author.id;
|
retVal.props['data-author-id'] = author.id;
|
||||||
if (author.id === DiscordApi.currentUser.id) retVal.props.className += ' bd-isCurrentUser';
|
if (author.id === DiscordApi.currentUser.id) retVal.props.className += ' bd-isCurrentUser';
|
||||||
if (type !== 0) retVal.props.className += ' bd-isSystemMessage';
|
if (type !== 0) retVal.props.className += ' bd-isSystemMessage';
|
||||||
|
|
||||||
|
const dapiMessage = DiscordApi.Message.from(component.props.messages[0]);
|
||||||
|
if (dapiMessage.guild && author.id === dapiMessage.guild.ownerId) retVal.props.className += ' bd-isGuildOwner';
|
||||||
|
if (dapiMessage.guild && dapiMessage.guild.isMember(author.id)) retVal.props.className += ' bd-isGuildMember';
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const e of document.querySelectorAll('.message-group')) {
|
for (const e of document.querySelectorAll('.message-group')) {
|
||||||
|
@ -338,13 +341,15 @@ export class ReactAutoPatcher {
|
||||||
|
|
||||||
static async patchChannelMember() {
|
static async patchChannelMember() {
|
||||||
const selector = '.' + WebpackModules.getModuleByProps(['member', 'memberInner', 'activity']).member;
|
const selector = '.' + WebpackModules.getModuleByProps(['member', 'memberInner', 'activity']).member;
|
||||||
|
|
||||||
this.ChannelMember = await ReactComponents.getComponent('ChannelMember', { selector }, m => m.prototype.renderActivity);
|
this.ChannelMember = await ReactComponents.getComponent('ChannelMember', { selector }, m => m.prototype.renderActivity);
|
||||||
|
|
||||||
this.unpatchChannelMemberRender = MonkeyPatch('BD:ReactComponents', this.ChannelMember.component.prototype).after('render', (component, args, retVal) => {
|
this.unpatchChannelMemberRender = MonkeyPatch('BD:ReactComponents', this.ChannelMember.component.prototype).after('render', (component, args, retVal) => {
|
||||||
if (!retVal.props || !retVal.props.children) return;
|
if (!retVal.props || !retVal.props.children) return;
|
||||||
const user = Helpers.findProp(component, 'user');
|
const user = Helpers.findProp(component, 'user');
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
retVal.props['data-user-id'] = user.id;
|
retVal.props['data-user-id'] = user.id;
|
||||||
|
retVal.props['data-colourstring'] = component.props.colorString;
|
||||||
|
if (component.props.isOwner) retVal.props.className += ' bd-isGuildOwner';
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const e of document.querySelectorAll(selector)) {
|
for (const e of document.querySelectorAll(selector)) {
|
||||||
|
@ -354,6 +359,7 @@ export class ReactAutoPatcher {
|
||||||
|
|
||||||
static async patchGuild() {
|
static async patchGuild() {
|
||||||
this.Guild = await ReactComponents.getComponent('Guild');
|
this.Guild = await ReactComponents.getComponent('Guild');
|
||||||
|
|
||||||
this.unpatchGuild = MonkeyPatch('BD:ReactComponents', this.Guild.component.prototype).after('render', (component, args, retVal) => {
|
this.unpatchGuild = MonkeyPatch('BD:ReactComponents', this.Guild.component.prototype).after('render', (component, args, retVal) => {
|
||||||
const { guild } = component.props;
|
const { guild } = component.props;
|
||||||
if (!guild) return;
|
if (!guild) return;
|
||||||
|
@ -368,11 +374,15 @@ export class ReactAutoPatcher {
|
||||||
|
|
||||||
static async patchChannel() {
|
static async patchChannel() {
|
||||||
this.Channel = await ReactComponents.getComponent('Channel', {selector: '.chat'});
|
this.Channel = await ReactComponents.getComponent('Channel', {selector: '.chat'});
|
||||||
|
|
||||||
this.unpatchChannel = MonkeyPatch('BD:ReactComponents', this.Channel.component.prototype).after('render', (component, args, retVal) => {
|
this.unpatchChannel = MonkeyPatch('BD:ReactComponents', this.Channel.component.prototype).after('render', (component, args, retVal) => {
|
||||||
const channel = component.props.channel || component.state.channel;
|
const channel = component.props.channel || component.state.channel;
|
||||||
if (!channel) return;
|
if (!channel) return;
|
||||||
retVal.props['data-channel-id'] = channel.id;
|
retVal.props['data-channel-id'] = channel.id;
|
||||||
retVal.props['data-channel-name'] = channel.name;
|
retVal.props['data-channel-name'] = channel.name;
|
||||||
|
if ([0, 2, 4].includes(channel.type)) retVal.props.className += ' bd-isGuildChannel';
|
||||||
|
if ([1, 3].includes(channel.type)) retVal.props.className += ' bd-isPrivateChannel';
|
||||||
|
if (channel.type === 3) retVal.props.className += ' bd-isGroupChannel';
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const e of document.querySelectorAll('.chat')) {
|
for (const e of document.querySelectorAll('.chat')) {
|
||||||
|
@ -382,13 +392,16 @@ export class ReactAutoPatcher {
|
||||||
|
|
||||||
static async patchChannelList() {
|
static async patchChannelList() {
|
||||||
const selector = '.' + WebpackModules.getModuleByProps(['containerDefault', 'actionIcon']).containerDefault;
|
const selector = '.' + WebpackModules.getModuleByProps(['containerDefault', 'actionIcon']).containerDefault;
|
||||||
|
|
||||||
this.GuildChannel = await ReactComponents.getComponent('GuildChannel', { selector: '.containerDefault-1ZnADq' });
|
this.GuildChannel = await ReactComponents.getComponent('GuildChannel', { selector: '.containerDefault-1ZnADq' });
|
||||||
|
|
||||||
this.unpatchGuildChannel = MonkeyPatch('BD:ReactComponents', this.GuildChannel.component.prototype).after('render', (component, args, retVal) => {
|
this.unpatchGuildChannel = MonkeyPatch('BD:ReactComponents', this.GuildChannel.component.prototype).after('render', (component, args, retVal) => {
|
||||||
const { channel } = component.props;
|
const { channel } = component.props;
|
||||||
if (!channel) return;
|
if (!channel) return;
|
||||||
retVal.props['data-channel-id'] = channel.id;
|
retVal.props['data-channel-id'] = channel.id;
|
||||||
retVal.props['data-channel-name'] = channel.name;
|
retVal.props['data-channel-name'] = channel.name;
|
||||||
|
if ([0, 2, 4].includes(channel.type)) retVal.props.className += ' bd-isGuildChannel';
|
||||||
|
if ([1, 3].includes(channel.type)) retVal.props.className += ' bd-isPrivateChannel';
|
||||||
|
if (channel.type === 3) retVal.props.className += ' bd-isGroupChannel';
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const e of document.querySelectorAll(selector)) {
|
for (const e of document.querySelectorAll(selector)) {
|
||||||
|
@ -398,8 +411,8 @@ export class ReactAutoPatcher {
|
||||||
|
|
||||||
static async patchUserProfileModal() {
|
static async patchUserProfileModal() {
|
||||||
const selector = '.' + WebpackModules.getModuleByProps(['root', 'topSectionNormal']).root;
|
const selector = '.' + WebpackModules.getModuleByProps(['root', 'topSectionNormal']).root;
|
||||||
|
|
||||||
this.UserProfileModal = await ReactComponents.getComponent('UserProfileModal', { selector }, Filters.byPrototypeFields(['renderHeader', 'renderBadges']));
|
this.UserProfileModal = await ReactComponents.getComponent('UserProfileModal', { selector }, Filters.byPrototypeFields(['renderHeader', 'renderBadges']));
|
||||||
|
|
||||||
this.unpatchUserProfileModal = MonkeyPatch('BD:ReactComponents', this.UserProfileModal.component.prototype).after('render', (component, args, retVal) => {
|
this.unpatchUserProfileModal = MonkeyPatch('BD:ReactComponents', this.UserProfileModal.component.prototype).after('render', (component, args, retVal) => {
|
||||||
const { user } = component.props;
|
const { user } = component.props;
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
|
@ -415,8 +428,8 @@ export class ReactAutoPatcher {
|
||||||
|
|
||||||
static async patchUserPopout() {
|
static async patchUserPopout() {
|
||||||
const selector = '.' + WebpackModules.getModuleByProps(['userPopout', 'headerNormal']).userPopout;
|
const selector = '.' + WebpackModules.getModuleByProps(['userPopout', 'headerNormal']).userPopout;
|
||||||
|
|
||||||
this.UserPopout = await ReactComponents.getComponent('UserPopout', { selector });
|
this.UserPopout = await ReactComponents.getComponent('UserPopout', { selector });
|
||||||
|
|
||||||
this.unpatchUserPopout = MonkeyPatch('BD:ReactComponents', this.UserPopout.component.prototype).after('render', (component, args, retVal) => {
|
this.unpatchUserPopout = MonkeyPatch('BD:ReactComponents', this.UserPopout.component.prototype).after('render', (component, args, retVal) => {
|
||||||
const { user, guild, guildMember } = component.props;
|
const { user, guild, guildMember } = component.props;
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
|
|
Loading…
Reference in New Issue