Plugin

ThemeAttributes

Adds data attributes to various elements for theming purposes

Appearance Customisation
index.ts
Download

Source

src/plugins/themeAttributes/index.ts
1import { Devs } from "@utils/constants";
2import { Logger } from "@utils/Logger";
3import definePlugin from "@utils/types";
4import { Message } from "@vencord/discord-types";
5import { UserStore } from "@webpack/common";
6
7
8export default definePlugin({
9 name: "ThemeAttributes",
10 description: "Adds data attributes to various elements for theming purposes",
11 tags: ["Appearance", "Customisation"],
12 authors: [Devs.Ven, Devs.Board],
13
14 patches: [
15 // Add data-tab-id to all tab bar items
16 // This for examples applies to the User and Server settings sidebars
17 {
18 find: ".tabBarRef",
19 replacement: {
20 match: /style:this\.getStyle\(\),role:\i/,
21 replace: "$&,'data-tab-id':this?.props?.id"
22 }
23 },
24
25 // Add data-author-id and data-is-self to all messages
26 {
27 find: "Message must not be a thread starter message",
28 replacement: {
29 match: /"aria-setsize":-1,(?=.{0,150}?#{intl::MESSAGE_A11Y_ROLE_DESCRIPTION})/,
30 replace: "...$self.getMessageProps(arguments[0]),$&"
31 }
32 },
33
34 // add --avatar-url-<resolution> css variable to avatar img elements
35 // popout profiles
36 {
37 find: "#{intl::LABEL_WITH_ONLINE_STATUS}",
38 replacement: [
39 {
40 match: /src:(\i)\?\?void 0.{1,50}"aria-hidden":!0/,
41 replace: "$&,style:$self.getAvatarStyles($1)"
42 }
43 ]
44 },
45 // chat avatars
46 {
47 find: "showCommunicationDisabledStyles",
48 replacement: {
49 match: /src:(\i),"aria-hidden":!0/,
50 replace: "$&,style:$self.getAvatarStyles($1)"
51 }
52 }
53 ],
54
55 getAvatarStyles(src: string | null) {
56 if (typeof src !== "string" || src.startsWith("data:")) return {};
57
58 return Object.fromEntries(
59 [128, 256, 512, 1024, 2048, 4096].map(size => [
60 `--avatar-url-${size}`,
61 `url(${src.replace(/\d+$/, String(size))})`
62 ])
63 );
64 },
65
66 getMessageProps(props: { message: Message; }) {
67 try {
68 const author = props.message?.author;
69 const authorId = author?.id;
70 return {
71 "data-author-id": authorId,
72 "data-author-username": author?.username,
73 "data-is-self": authorId && authorId === UserStore.getCurrentUser()?.id,
74 };
75 } catch (e) {
76 new Logger("ThemeAttributes").error("Error in getMessageProps", e);
77 return {};
78 }
79 }
80});
81