267 lines
18 KiB
JavaScript
267 lines
18 KiB
JavaScript
//META{"name":"BetterRoleColors","displayName":"BetterRoleColors","website":"https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/BetterRoleColors","source":"https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/BetterRoleColors/BetterRoleColors.plugin.js"}*//
|
|
|
|
var BetterRoleColors = (() => {
|
|
const config = {"info":{"name":"BetterRoleColors","authors":[{"name":"Zerebos","discord_id":"249746236008169473","github_username":"rauenzi","twitter_username":"ZackRauen"}],"version":"0.7.6","description":"Adds server-based role colors to typing, voice, popouts, modals and more! Support Server: bit.ly/ZeresServer","github":"https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/BetterRoleColors","github_raw":"https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/BetterRoleColors/BetterRoleColors.plugin.js"},"defaultConfig":[{"type":"category","id":"modules","name":"Module Settings","collapsible":true,"shown":true,"settings":[{"type":"switch","id":"typing","name":"Typing","note":"Toggles colorizing of typing notifications.","value":true},{"type":"switch","id":"voice","name":"Voice","note":"Toggles colorizing of voice users.","value":true},{"type":"switch","id":"mentions","name":"Mentions","note":"Toggles colorizing of user mentions in chat.","value":true},{"type":"switch","id":"botTags","name":"Bot Tags","note":"Toggles coloring the background of bot tags to match role.","value":true},{"type":"switch","id":"memberList","name":"Memberlist Headers","note":"Toggles coloring role names in the member list.","value":true}]},{"type":"category","id":"popouts","name":"Popout Options","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"username","name":"Username","note":"Toggles coloring on the username in popouts.","value":false},{"type":"switch","id":"discriminator","name":"Discriminator","note":"Toggles coloring on the discriminator in popouts.","value":false},{"type":"switch","id":"nickname","name":"Nickname","note":"Toggles coloring on the nickname in popouts.","value":true},{"type":"switch","id":"fallback","name":"Enable Fallback","note":"If nickname is on and username is off, enabling this will automatically color the username.","value":true}]},{"type":"category","id":"modals","name":"Modal Options","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"username","name":"Username","note":"Toggles coloring on the username in modals.","value":true},{"type":"switch","id":"discriminator","name":"Discriminator","note":"Toggles coloring on the discriminator in modals.","value":false}]},{"type":"category","id":"auditLog","name":"Audit Log Options","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"username","name":"Username","note":"Toggles coloring on the username in audit log.","value":true},{"type":"switch","id":"discriminator","name":"Discriminator","note":"Toggles coloring on the discriminator in audit log.","value":false}]},{"type":"category","id":"account","name":"Account Details Options","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"username","name":"Username","note":"Toggles coloring on the username in account details.","value":true},{"type":"switch","id":"discriminator","name":"Discriminator","note":"Toggles coloring on the discriminator in account details.","value":false}]},{"type":"category","id":"mentions","name":"Mention Options","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"changeOnHover","name":"Hover Color","note":"Turning this on adjusts the color on hover to match role color, having it off defers to your theme.","value":true}]}],"changelog":[{"title":"What's New?","items":["Role headers in the memberlist now match the role color! (You can turn this off in settings)"]}],"main":"index.js"};
|
|
|
|
return !global.ZeresPluginLibrary ? class {
|
|
getName() {return config.info.name;}
|
|
getAuthor() {return config.info.authors.map(a => a.name).join(", ");}
|
|
getDescription() {return config.info.description;}
|
|
getVersion() {return config.info.version;}
|
|
load() {window.BdApi.alert("Library Missing",`The library plugin needed for ${config.info.name} is missing.<br /><br /> <a href="https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js" target="_blank">Click here to download the library!</a>`);}
|
|
start() {}
|
|
stop() {}
|
|
} : (([Plugin, Api]) => {
|
|
const plugin = (Plugin, Api) => {
|
|
const {DiscordSelectors, WebpackModules, DiscordModules, PluginUtilities, Patcher, ColorConverter, ReactTools} = Api;
|
|
|
|
const ReactDOM = DiscordModules.ReactDOM;
|
|
const GuildMemberStore = DiscordModules.GuildMemberStore;
|
|
const SelectedGuildStore = DiscordModules.SelectedGuildStore;
|
|
const UserStore = DiscordModules.UserStore;
|
|
const RelationshipStore = DiscordModules.RelationshipStore;
|
|
const PopoutWrapper = WebpackModules.getByProps("Positions", "Animations");
|
|
const VoiceUser = WebpackModules.find(m => typeof(m) === "function" && m.List);
|
|
const UserPopout = DiscordModules.UserPopout;
|
|
const UserModal = DiscordModules.UserProfileModal;
|
|
const AuditLogItem = WebpackModules.getByPrototypes("renderPermissionUpdate");
|
|
const TypingUsers = WebpackModules.findByDisplayName("FluxContainer(TypingUsers)");
|
|
|
|
return class BetterRoleColors extends Plugin {
|
|
|
|
constructor() {
|
|
super();
|
|
this.cancels = [];
|
|
}
|
|
|
|
onStart() {
|
|
this.patchVoiceUsers();
|
|
this.patchMentions();
|
|
this.patchAccountDetails();
|
|
this.patchUserPopouts();
|
|
this.patchUserModals();
|
|
this.patchAuditLog();
|
|
this.patchTypingUsers();
|
|
this.patchMemberList();
|
|
}
|
|
|
|
onStop() {
|
|
Patcher.unpatchAll();
|
|
for (const cancel of this.cancels) cancel();
|
|
}
|
|
|
|
getSettingsPanel() {
|
|
return this.buildSettingsPanel().getElement();
|
|
}
|
|
|
|
patchAccountDetails() {
|
|
const colorize = () => {
|
|
if (!this.settings.account.username && !this.settings.account.discriminator) return;
|
|
const account = document.querySelector(DiscordSelectors.AccountDetails.accountDetails);
|
|
if (!account) return;
|
|
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), UserStore.getCurrentUser().id);
|
|
const color = member && member.colorString ? member.colorString : "";
|
|
if (this.settings.account.username) account.querySelector(".username").style.setProperty("color", color, "important");
|
|
if (this.settings.account.discriminator) {
|
|
account.querySelector(".discriminator").style.setProperty("color", color, "important");
|
|
account.querySelector(".discriminator").style.setProperty("opacity", "1");
|
|
}
|
|
};
|
|
PluginUtilities.addOnSwitchListener(colorize);
|
|
this.cancels.push(() => {
|
|
PluginUtilities.removeOnSwitchListener(colorize);
|
|
const account = document.querySelector(DiscordSelectors.AccountDetails.accountDetails);
|
|
account.querySelector(".username").style.setProperty("color", "");
|
|
account.querySelector(".discriminator").style.setProperty("color", "");
|
|
account.querySelector(".discriminator").style.setProperty("opacity", "");
|
|
});
|
|
colorize();
|
|
}
|
|
|
|
filterTypingUsers(typingUsers) {
|
|
if (!typingUsers) return [];
|
|
return Object.keys(typingUsers).filter((e) => {
|
|
return e != UserStore.getCurrentUser().id;
|
|
}).filter((e) => {
|
|
return !RelationshipStore.isBlocked(e);
|
|
}).map((e) => {
|
|
return UserStore.getUser(e);
|
|
}).filter(function(e) {
|
|
return e != null;
|
|
});
|
|
}
|
|
|
|
patchTypingUsers() {
|
|
const brc = this;
|
|
Patcher.after(TypingUsers.prototype, "componentDidUpdate", (thisObject) => {
|
|
if (!brc.settings.modules.typing) return;
|
|
setImmediate(() => {
|
|
const typingUsers = this.filterTypingUsers(Object.assign({}, thisObject.state.typingUsers));
|
|
document.querySelectorAll(DiscordSelectors.Typing.typing.descend("strong")).forEach((elem, index) => {
|
|
if (!typingUsers[index]) return;
|
|
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), typingUsers[index].id);
|
|
if (!member) return;
|
|
elem.style.setProperty("color", member.colorString ? member.colorString : "");
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
patchVoiceUsers() {
|
|
const brc = this;
|
|
const voiceUserMount = function() {
|
|
if (!brc.settings.modules.voice) return;
|
|
if (!this || !this.props || !this.props.user) return;
|
|
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), this.props.user.id);
|
|
if (!member || !member.colorString) return;
|
|
const elem = ReactDOM.findDOMNode(this);
|
|
elem.querySelector("[class*=\"name\"]").style.setProperty("color", member.colorString);
|
|
};
|
|
|
|
Patcher.after(VoiceUser.prototype, "componentDidMount", (thisObject) => {
|
|
const bound = voiceUserMount.bind(thisObject); bound();
|
|
});
|
|
}
|
|
|
|
patchMentions() {
|
|
const brc = this;
|
|
const mentionMount = function() {
|
|
if (!brc.settings.modules.mentions) return;
|
|
if (!this || !this.props || !this.props.children || !this.props.children.props || this.props.children.props.className != "mention") return;
|
|
const props = this.props.render().props;
|
|
if (!props || !props.user) return;
|
|
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), props.user.id);
|
|
if (!member || !member.colorString) return;
|
|
const elem = ReactDOM.findDOMNode(this);
|
|
elem.style.setProperty("color", member.colorString, "important");
|
|
elem.style.setProperty("background", ColorConverter.rgbToAlpha(member.colorString,0.1), "important");
|
|
|
|
if (!brc.settings.mentions.changeOnHover) return;
|
|
elem.addEventListener("mouseenter", (e) =>{
|
|
e.target.style.setProperty("color", "#FFFFFF", "important");
|
|
e.target.style.setProperty("background", ColorConverter.rgbToAlpha(member.colorString,0.7), "important");
|
|
});
|
|
elem.addEventListener("mouseleave", (e) => {
|
|
e.target.style.setProperty("color", member.colorString, "important");
|
|
e.target.style.setProperty("background", ColorConverter.rgbToAlpha(member.colorString,0.1), "important");
|
|
});
|
|
};
|
|
|
|
Patcher.after(PopoutWrapper.prototype, "componentDidMount", (thisObject) => {
|
|
const bound = mentionMount.bind(thisObject); bound();
|
|
});
|
|
}
|
|
|
|
patchUserPopouts() {
|
|
const brc = this;
|
|
const popoutMount = function() {
|
|
if (!brc.settings.popouts.username && !brc.settings.popouts.discriminator && !brc.settings.popouts.nickname) return;
|
|
if (!this || !this.props || !this.props.user) return;
|
|
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), this.props.user.id);
|
|
if (!member || !member.colorString) return;
|
|
const elem = ReactDOM.findDOMNode(this);
|
|
const hasNickname = Boolean(this.state.nickname);
|
|
if (brc.settings.popouts.username || (!hasNickname && brc.settings.popouts.fallback)) elem.querySelector(".username").style.setProperty("color", member.colorString, "important");
|
|
if (brc.settings.popouts.discriminator) elem.querySelector(".discriminator").style.setProperty("color", member.colorString, "important");
|
|
if (brc.settings.popouts.nickname && hasNickname) elem.querySelector(DiscordSelectors.UserPopout.headerName).style.setProperty("color", member.colorString, "important");
|
|
};
|
|
|
|
Patcher.after(UserPopout.prototype, "componentDidMount", (thisObject) => {
|
|
const bound = popoutMount.bind(thisObject); bound();
|
|
});
|
|
}
|
|
|
|
patchUserModals() {
|
|
const brc = this;
|
|
const modalMount = function() {
|
|
if (!brc.settings.modals.username && !brc.settings.modals.discriminator) return;
|
|
if (!this || !this.props || !this.props.user) return;
|
|
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), this.props.user.id);
|
|
if (!member || !member.colorString) return;
|
|
const elem = ReactDOM.findDOMNode(this);
|
|
if (brc.settings.modals.username) elem.querySelector(".username").style.setProperty("color", member.colorString, "important");
|
|
if (brc.settings.modals.discriminator) elem.querySelector(".discriminator").style.setProperty("color", member.colorString, "important");
|
|
};
|
|
|
|
Patcher.after(UserModal.prototype, "componentDidMount", (thisObject) => {
|
|
const bound = modalMount.bind(thisObject); bound();
|
|
});
|
|
}
|
|
|
|
patchAuditLog() {
|
|
const brc = this;
|
|
const auditlogMount = function() {
|
|
if (!brc.settings.auditLog.username && !brc.settings.auditLog.discriminator) return;
|
|
if (!this || !this.props || !this.props.log || !this.props.log.user) return;
|
|
|
|
const elem = ReactDOM.findDOMNode(this);
|
|
const hooks = elem.querySelectorAll(DiscordSelectors.AuditLog.userHook);
|
|
const member = GuildMemberStore.getMember(this._reactInternalFiber.return.memoizedProps.guildId, this.props.log.user.id);
|
|
if (member && member.colorString) {
|
|
if (member.colorString && brc.settings.auditLog.username) hooks[0].children[0].style.color = member.colorString;
|
|
if (member.colorString && brc.settings.auditLog.discriminator) { hooks[0].querySelector(DiscordSelectors.AuditLog.discrim).style.color = member.colorString;hooks[0].querySelector(DiscordSelectors.AuditLog.discrim).style.opacity = 1;}
|
|
}
|
|
|
|
if (hooks.length < 2 || this.props.log.targetType != "USER") return;
|
|
const member2 = GuildMemberStore.getMember(this._reactInternalFiber.return.memoizedProps.guildId, this.props.log.target.id);
|
|
if (!member2 || !member2.colorString) return;
|
|
if (brc.settings.auditLog.username) hooks[1].children[0].style.color = member2.colorString;
|
|
if (brc.settings.auditLog.discriminator) { hooks[1].querySelector(DiscordSelectors.AuditLog.discrim).style.color = member2.colorString;hooks[1].querySelector(DiscordSelectors.AuditLog.discrim).style.opacity = 1;}
|
|
};
|
|
|
|
Patcher.after(AuditLogItem.prototype, "componentDidMount", (thisObject) => {
|
|
const bound = auditlogMount.bind(thisObject); bound();
|
|
});
|
|
}
|
|
|
|
getMemberGroup() {
|
|
return new Promise(resolve => {
|
|
const memberList = document.querySelector(DiscordSelectors.MemberList.membersWrap);
|
|
if (memberList) {resolve(ReactTools.getOwnerInstance(memberList, {include: ["ChannelMembers"]}).constructor);}
|
|
else {
|
|
const channel = WebpackModules.find(m => m.prototype && m.prototype.renderEmptyChannel);
|
|
const unpatch = Patcher.before(channel.prototype, "componentDidUpdate", (t) => {
|
|
const elem = DiscordModules.ReactDOM.findDOMNode(t);
|
|
if (!elem) return;
|
|
const memberList = elem.querySelector(DiscordSelectors.MemberList.membersWrap);
|
|
if (!memberList) return;
|
|
unpatch();
|
|
resolve(ReactTools.getOwnerInstance(memberList, {include: ["ChannelMembers"]}).constructor);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
forceUpdateMemberList() {
|
|
const memberList = document.querySelector(DiscordSelectors.MemberList.membersWrap);
|
|
if (memberList) ReactTools.getOwnerInstance(memberList, {include: ["ChannelMembers"]}).forceUpdate();
|
|
}
|
|
|
|
async patchMemberList() {
|
|
const MemberList = await this.getMemberGroup();
|
|
Patcher.after(MemberList.prototype, "render", (memberList) => {
|
|
if (memberList.renderSection.__patched) return;
|
|
Patcher.after(memberList, "renderSection", (_, __, section) => {
|
|
if (!this.settings.modules.memberList) return;
|
|
const guild = DiscordModules.GuildStore.getGuild(memberList.props.channel.guild_id);
|
|
if (!guild) return;
|
|
const roleColor = guild.roles[section.props.id] ? guild.roles[section.props.id].colorString : "";
|
|
if (!roleColor) return;
|
|
const originalType = section.type;
|
|
section.type = function() {
|
|
const label = originalType(...arguments);
|
|
label.props.style = {color: roleColor};
|
|
return label;
|
|
};
|
|
return section;
|
|
});
|
|
memberList.renderSection.__patched = true;
|
|
});
|
|
this.forceUpdateMemberList();
|
|
}
|
|
|
|
};
|
|
};
|
|
return plugin(Plugin, Api);
|
|
})(global.ZeresPluginLibrary.buildPlugin(config));
|
|
})(); |