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