Plugin
IrcColors
Makes username colors in chat unique, like in IRC clients
1
import { definePluginSettings } from "@api/Settings";2
import { hash as h64 } from "@intrnl/xxhash64";3
import { Devs } from "@utils/constants";4
import definePlugin, { OptionType } from "@utils/types";5
import { useMemo } from "@webpack/common";6
7
// Calculate a CSS color string based on the user ID8
function calculateNameColorForUser(id?: string) {9
const { lightness } = settings.use(["lightness"]);10
const idHash = useMemo(() => id ? h64(id) : null, [id]);11
12
return idHash && `hsl(${idHash % 360n}, 100%, ${lightness}%)`;13
}14
15
const settings = definePluginSettings({16
lightness: {17
description: "Lightness, in %. Change if the colors are too light or too dark",18
type: OptionType.NUMBER,19
default: 70,20
},21
memberListColors: {22
description: "Replace role colors in the member list",23
restartNeeded: true,24
type: OptionType.BOOLEAN,25
default: true26
},27
applyColorOnlyToUsersWithoutColor: {28
description: "Apply colors only to users who don039;t have a predefined color",29
restartNeeded: false,30
type: OptionType.BOOLEAN,31
default: false32
},33
applyColorOnlyInDms: {34
displayName: "Apply Color Only In DMs",35
description: "Apply colors only in direct messages; do not apply colors in servers.",36
restartNeeded: false,37
type: OptionType.BOOLEAN,38
default: false39
}40
});41
42
export default definePlugin({43
name: "IrcColors",44
description: "Makes username colors in chat unique, like in IRC clients",45
tags: ["Appearance", "Customisation"],46
authors: [Devs.Grzesiek11, Devs.jamesbt365],47
settings,48
49
patches: [50
{51
find: 039;="SYSTEM_TAG"039;,52
replacement: {53
// Override colorString with our custom color and disable gradients if applying the custom color.54
match: /(?<=colorString:\i,colorStrings:\i,colorRoleName:\i.*?}=)(\i),/,55
replace: "$self.wrapMessageColorProps($1, arguments[0]),"56
}57
},58
{59
find: "#{intl::GUILD_OWNER}),children:",60
replacement: {61
match: /(?<=roleName:\i,)colorString:/,62
replace: "colorString:$self.calculateNameColorForListContext(arguments[0]),originalColor:"63
},64
predicate: () => settings.store.memberListColors65
}66
],67
68
wrapMessageColorProps(colorProps: { colorString: string, colorStrings?: Record<"primaryColor" | "secondaryColor" | "tertiaryColor", string>; }, context: any) {69
try {70
const colorString = this.calculateNameColorForMessageContext(context);71
if (colorString === colorProps.colorString) {72
return colorProps;73
}74
75
return {76
...colorProps,77
colorString,78
colorStrings: colorProps.colorStrings && {79
primaryColor: colorString,80
secondaryColor: undefined,81
tertiaryColor: undefined82
}83
};84
} catch (e) {85
console.error("Failed to calculate message color strings:", e);86
return colorProps;87
}88
},89
90
calculateNameColorForMessageContext(context: any) {91
const userId: string | undefined = context?.message?.author?.id;92
const colorString = context?.author?.colorString;93
const color = calculateNameColorForUser(userId);94
95
// Color preview in role settings96
if (context?.message?.channel_id === "1337" && userId === "313337")97
return colorString;98
99
if (settings.store.applyColorOnlyInDms && !context?.channel?.isPrivate()) {100
return colorString;101
}102
103
return (!settings.store.applyColorOnlyToUsersWithoutColor || !colorString)104
? color105
: colorString;106
},107
108
calculateNameColorForListContext(context: any) {109
try {110
const id = context?.user?.id;111
const colorString = context?.colorString;112
const color = calculateNameColorForUser(id);113
114
if (settings.store.applyColorOnlyInDms && context?.guildId !== undefined) {115
return colorString;116
}117
118
return (!settings.store.applyColorOnlyToUsersWithoutColor || !colorString)119
? color120
: colorString;121
} catch (e) {122
console.error("Failed to calculate name color for list context:", e);123
}124
}125
});126