Merge pull request #201 from samuelthomas2774/channel-components

Channel components
This commit is contained in:
Alexei Stukov 2018-08-07 06:16:35 +03:00 committed by GitHub
commit a805c8f75a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 67 additions and 29 deletions

View File

@ -233,14 +233,25 @@ export class ReactComponents {
return;
}
const element = document.querySelector(important.selector);
if (!element) return;
const elements = document.querySelectorAll(important.selector);
if (!elements.length) return;
let component, reflect;
for (let element of elements) {
reflect = Reflection(element);
component = filter ? reflect.components.find(filter) : reflect.component;
if (component) break;
}
if (!component && filter) {
Logger.log('ReactComponents', ['Found elements matching the query selector but no components passed the filter']);
return;
}
DOM.observer.unsubscribe(observerSubscription);
const reflect = Reflection(element);
const component = filter ? reflect.components.find(filter) : reflect.component;
if (!component) {
Logger.err('ReactComponents', [`FAILED TO GET IMPORTANT COMPONENT ${name} WITH REFLECTION FROM`, element]);
Logger.err('ReactComponents', [`FAILED TO GET IMPORTANT COMPONENT ${name} WITH REFLECTION FROM`, elements]);
return;
}
@ -250,7 +261,7 @@ export class ReactComponents {
this.push(component, undefined, important);
};
const observerSubscription = DOM.observer.subscribeToQuerySelector(callback, important.selector);
const observerSubscription = DOM.observer.subscribeToQuerySelector(callback, important.selector, null, true);
setTimeout(callback, 0);
}
@ -298,7 +309,7 @@ export class ReactComponents {
export class ReactAutoPatcher {
/**
* Wait for React to be loaded and patch it's createElement to store all unknown components.
* Also patches of some known components.
* Also patches some known components.
*/
static async autoPatch() {
const React = await WebpackModules.waitForModuleByName('React');
@ -312,16 +323,8 @@ export class ReactAutoPatcher {
* Patches a few known components.
*/
static patchComponents() {
return Promise.all([
this.patchMessage(),
this.patchMessageGroup(),
this.patchChannelMember(),
this.patchGuild(),
this.patchChannel(),
this.patchChannelList(),
this.patchUserProfileModal(),
this.patchUserPopout()
]);
const componentPatchFunctions = Object.getOwnPropertyNames(this).filter(p => p.startsWith('patch') && p !== 'patchComponents');
return Promise.all(componentPatchFunctions.map(p => this[p].call(this)));
}
static async patchMessage() {
@ -396,6 +399,9 @@ export class ReactAutoPatcher {
this.Guild.forceUpdateAll();
}
/**
* The Channel component contains the header, message scroller, message form and member list.
*/
static async patchChannel() {
const selector = '.chat';
this.Channel = await ReactComponents.getComponent('Channel', {selector});
@ -413,21 +419,53 @@ export class ReactAutoPatcher {
this.Channel.forceUpdateAll();
}
static async patchChannelList() {
/**
* The GuildTextChannel component represents a text channel in the guild channel list.
*/
static async patchGuildTextChannel() {
const selector = '.' + WebpackModules.getClassName('containerDefault', 'actionIcon');
this.GuildChannel = await ReactComponents.getComponent('GuildChannel', {selector});
this.GuildTextChannel = await ReactComponents.getComponent('GuildTextChannel', {selector}, c => c.prototype.renderMentionBadge);
this.unpatchGuildChannel = MonkeyPatch('BD:ReactComponents', this.GuildChannel.component.prototype).after('render', (component, args, retVal) => {
const { channel } = component.props;
if (!channel) return;
retVal.props['data-channel-id'] = channel.id;
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';
});
this.unpatchGuildTextChannel = MonkeyPatch('BD:ReactComponents', this.GuildTextChannel.component.prototype).after('render', this._afterChannelRender);
this.GuildChannel.forceUpdateAll();
this.GuildTextChannel.forceUpdateAll();
}
/**
* The GuildVoiceChannel component represents a voice channel in the guild channel list.
*/
static async patchGuildVoiceChannel() {
const selector = '.' + WebpackModules.getClassName('containerDefault', 'actionIcon');
this.GuildVoiceChannel = await ReactComponents.getComponent('GuildVoiceChannel', {selector}, c => c.prototype.handleVoiceConnect);
this.unpatchGuildVoiceChannel = MonkeyPatch('BD:ReactComponents', this.GuildVoiceChannel.component.prototype).after('render', this._afterChannelRender);
this.GuildVoiceChannel.forceUpdateAll();
}
/**
* The DirectMessage component represents a channel in the direct messages list.
*/
static async patchDirectMessage() {
const selector = '.channel.private';
this.DirectMessage = await ReactComponents.getComponent('DirectMessage', {selector}, c => c.prototype.renderAvatar);
this.unpatchDirectMessage = MonkeyPatch('BD:ReactComponents', this.DirectMessage.component.prototype).after('render', this._afterChannelRender);
this.DirectMessage.forceUpdateAll();
}
static _afterChannelRender(component, args, retVal) {
const { channel } = component.props;
if (!channel) return;
retVal.props['data-channel-id'] = channel.id;
retVal.props['data-channel-name'] = channel.name;
if ([0, 2, 4].includes(channel.type)) retVal.props.className += ' bd-isGuildChannel';
if (channel.type === 2) retVal.props.className += ' bd-isVoiceChannel';
// if (channel.type === 4) retVal.props.className += ' bd-isChannelCategory';
if ([1, 3].includes(channel.type)) retVal.props.className += ' bd-isPrivateChannel';
if (channel.type === 3) retVal.props.className += ' bd-isGroupChannel';
}
static async patchUserProfileModal() {