diff --git a/src/plugins/moreUserTags/index.tsx b/src/plugins/moreUserTags/index.tsx
index 8029b483..69308942 100644
--- a/src/plugins/moreUserTags/index.tsx
+++ b/src/plugins/moreUserTags/index.tsx
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
+import "./style.css";
+
import { definePluginSettings } from "@api/Settings";
import { Flex } from "@components/Flex";
import { Devs } from "@utils/constants";
@@ -23,7 +25,7 @@ import { getIntlMessage } from "@utils/discord";
import { Margins } from "@utils/margins";
import definePlugin, { OptionType } from "@utils/types";
import { findByCodeLazy, findLazy } from "@webpack";
-import { Card, ChannelStore, Forms, GuildStore, PermissionsBits, Switch, TextInput, Tooltip } from "@webpack/common";
+import { Card, ChannelStore, Forms, GuildMemberStore, GuildStore, PermissionsBits, Switch, TextInput, Tooltip } from "@webpack/common";
import type { Permissions, RC } from "@webpack/types";
import type { Channel, Guild, Message, User } from "discord-types/general";
@@ -108,6 +110,16 @@ const defaultSettings = Object.fromEntries(
tags.map(({ name, displayName }) => [name, { text: displayName, showInChat: true, showInNotChat: true }])
) as TagSettings;
+// From https://gist.github.com/StevenBlack/960189
+export function getContrastYIQ(hexColor: string | undefined): "#000" | "#fff" | undefined {
+ if (!hexColor) return;
+ const r = parseInt(hexColor.substring(1, 3), 16);
+ const g = parseInt(hexColor.substring(3, 5), 16);
+ const b = parseInt(hexColor.substring(5, 7), 16);
+ const yiq = (r * 299 + g * 587 + b * 114) / 1000;
+ return yiq >= 128 ? "#000" : "#fff";
+}
+
function SettingsComponent() {
const tagSettings = settings.store.tagSettings ??= defaultSettings;
@@ -166,6 +178,10 @@ const settings = definePluginSettings({
description: "Only show extra tags for bots / Hide [BOT] text",
type: OptionType.BOOLEAN
},
+ useRoleColors: {
+ description: "Use the user's role color instead of the default color",
+ type: OptionType.BOOLEAN
+ },
tagSettings: {
type: OptionType.COMPONENT,
component: SettingsComponent,
@@ -190,6 +206,11 @@ export default definePlugin({
{
find: "#{intl::DISCORD_SYSTEM_MESSAGE_BOT_TAG_TOOLTIP_OFFICIAL}",
replacement: [
+ // Grab the colors from the params using the custom params
+ {
+ match: /type:\i=\i\.\i\.BOT/,
+ replace: "$&,moreTags_bgColor:moreTags_bgColor,moreTags_fgColor:moreTags_fgColor"
+ },
// make the tag show the right text
{
match: /(switch\((\i)\){.+?)case (\i(?:\.\i)?)\.BOT:default:(\i)=(.{0,40}#{intl::APP_TAG}\))/,
@@ -202,27 +223,34 @@ export default definePlugin({
replace: "$1=$self.isOPTag($2)"
},
// add HTML data attributes (for easier theming)
+ // also set the colors
{
match: /.botText,children:(\i)}\)]/,
- replace: "$&,'data-tag':$1.toLowerCase()"
+ replace: "$&,'data-tag':$1.toLowerCase(),style:{'background-color':moreTags_bgColor,'color':moreTags_fgColor},'data-moreTags-darkFg':moreTags_fgColor?.includes('0')"
}
],
},
// in messages
{
find: ".Types.ORIGINAL_POSTER",
- replacement: {
- match: /;return\((\(null==\i\?void 0:\i\.isSystemDM\(\).+?.Types.ORIGINAL_POSTER\)),null==(\i)\)/,
- replace: ";$1;$2=$self.getTag({...arguments[0],origType:$2,location:'chat'});return $2 == null"
- }
+ replacement: [
+ // Pass the tag's colors and type to the next function
+ {
+ match: /;return\((\(null==\i\?void 0:\i\.isSystemDM\(\).+?.Types.ORIGINAL_POSTER\)),null==(\i)\)\?null:\(0,(\i)\.jsx\)\((\i).(\i),{/,
+ replace: ";$1;$2=$self.getTag({...arguments[0],origType:$2,location:'chat'});return $2 == null?null:(0,$3.jsx)($4.$5,{...$self.getTagColors({...arguments[0],tagType:$2,location:'chat'}),"
+ }
+ ]
},
// in the member list
{
find: "#{intl::GUILD_OWNER}),children:",
- replacement: {
- match: /(?\i)=\(null==.{0,100}\.BOT;return null!=(?\i)&&\i\.bot/,
- replace: "$ = $self.getTag({user: $, channel: arguments[0].channel, origType: $.bot ? 0 : null, location: 'not-chat' }); return typeof $ === 'number'"
- }
+ replacement: [
+ // Pass the tag's colors and type to the next function
+ {
+ match: /(?\i)=\(null==.{0,100}\.BOT;return null!=(?\i)&&\i\.bot\?\(0,(?\i)\.jsx\)\((?\i)\.(?\i),{/,
+ replace: "$ = $self.getTag({user: $, channel: arguments[0].channel, origType: $.bot ? 0 : null, location: 'not-chat' }); return typeof $ === 'number'?(0,$.jsx)($.$,{...$self.getTagColors({...arguments[0],tagType:$,location:'not-chat'}),"
+ }
+ ]
},
// pass channel id down props to be used in profiles
{
@@ -249,12 +277,41 @@ export default definePlugin({
// it's either this or extremely long lookbehind
match: /user:\i,nick:\i,/,
replace: "$&moreTags_channelId,"
- }, {
+ },
+ {
+ // Get the tag type and tag colors so that they can be distributed
+ match: /(,\i=\i\.isPomelo\(\)\|\|\i;)(.+?botType:(\i),botVerified:(\i),(?!discriminatorClass:)(?<=user:(\i).+?))/,
+ replace: "$1let moreTags_tagType=$self.getTag({user:$5,channelId:moreTags_channelId,origType:$3,location:'not-chat'});let moreTags_tagColors=$self.getTagColors({user:$5,channelId:moreTags_channelId,tagType:moreTags_tagType,location:'not-chat'});$2"
+ },
+ {
match: /,botType:(\i),botVerified:(\i),(?!discriminatorClass:)(?<=user:(\i).+?)/g,
- replace: ",botType:$self.getTag({user:$3,channelId:moreTags_channelId,origType:$1,location:'not-chat'}),botVerified:$2,"
+ replace: ",botType:moreTags_tagType,...moreTags_tagColors,"
+ }, {
+ // Get the parameters from the function that were passed in previously
+ // because Discord needs to make it hard on us
+ match: /,botClass:\i,showStreamerModeTooltip:\i/,
+ replace: "$&,moreTags_bgColor:moreTags_bgColor,moreTags_fgColor:moreTags_fgColor"
+ }, {
+ // Finally pass the color information into the renderer
+ match: /\.jsx\)\(\i\.\i,{type:\i,/,
+ replace: "$&moreTags_bgColor,moreTags_fgColor,"
}
]
},
+ // Colors need to be passed down through this random module.
+ // If there's a way to bypass this module without modifying discord's random variables (We don't want to break stuff) leave a PR (or comment if an existing one is open)
+ {
+ find: ",invertBotTagColor:",
+ replacement: [
+ {
+ match: /,invertBotTagColor:\i/,
+ replace: "$&,moreTags_bgColor:moreTags_bgColor,moreTags_fgColor:moreTags_fgColor"
+ }, {
+ match: /verified:\i,useRemSizes:\i/,
+ replace: "$&,moreTags_bgColor,moreTags_fgColor"
+ }
+ ]
+ }
],
start() {
@@ -316,6 +373,31 @@ export default definePlugin({
}
},
+
+ getTagColors({
+ user, channelId, channel, location, tagType
+ }: {
+ user: User,
+ channel?: Channel,
+ channelId?: string;
+ location: "chat" | "not-chat";
+ tagType: number;
+ }): {
+ moreTags_bgColor: string,
+ moreTags_fgColor: string;
+ } {
+ const passedTagName = Object.keys(Tag.Types).find(k => Tag.Types[k] === tagType);
+ const [tagName, variant] = passedTagName?.split("-") ?? [null, null];
+ if (!settings.store.useRoleColors || !tagType || !tagName || (location === "chat" && !settings.store.tagSettings[tagName]?.showInChat) || (location === "not-chat" && !settings.store.tagSettings[tagName]?.showInNotChat) || (user.bot && settings.store.dontShowForBots)) {
+ return { moreTags_bgColor: "", moreTags_fgColor: "" };
+ }
+ if (!channel && channelId) channel = ChannelStore.getChannel(channelId);
+ const member = channel?.guild_id != null ? GuildMemberStore.getMember(channel?.guild_id, user.id) : null;
+ const colorString = member?.colorString;
+ const fgColorString = colorString != null ? getContrastYIQ(colorString) : null;
+ return { moreTags_bgColor: colorString ?? "", moreTags_fgColor: fgColorString ?? "" };
+ },
+
getTag({
message, user, channelId, origType, location, channel
}: {
@@ -342,8 +424,8 @@ export default definePlugin({
const perms = this.getPermissions(user, channel);
for (const tag of tags) {
- if (location === "chat" && !settings.tagSettings[tag.name].showInChat) continue;
- if (location === "not-chat" && !settings.tagSettings[tag.name].showInNotChat) continue;
+ if (location === "chat" && !settings.tagSettings[tag.name]?.showInChat) continue;
+ if (location === "not-chat" && !settings.tagSettings[tag.name]?.showInNotChat) continue;
// If the owner tag is disabled, and the user is the owner of the guild,
// avoid adding other tags because the owner will always match the condition for them
diff --git a/src/plugins/moreUserTags/style.css b/src/plugins/moreUserTags/style.css
new file mode 100644
index 00000000..234d6c37
--- /dev/null
+++ b/src/plugins/moreUserTags/style.css
@@ -0,0 +1,7 @@
+span[class*="botTagCozy"][data-moreTags-darkFg="true"]>svg>path {
+ fill: #000;
+}
+
+span[class*="botTagCozy"][data-moreTags-darkFg="false"]>svg>path {
+ fill: #fff;
+}
diff --git a/src/utils/constants.ts b/src/utils/constants.ts
index 6b2ca504..9c64830e 100644
--- a/src/utils/constants.ts
+++ b/src/utils/constants.ts
@@ -971,6 +971,10 @@ export const EquicordDevs = Object.freeze({
voidbbg: {
name: "voidbbg",
id: 117126234588184582n
+ },
+ OIRNOIR: {
+ name: "OIRNOIR",
+ id: 720842469024989195n
}
} satisfies Record);