/* * Vencord, a Discord client mod * Copyright (c) 2024 Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ import "./styles.css"; import { definePluginSettings } from "@api/Settings"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; import { GuildStore, SelectedGuildStore, useState } from "@webpack/common"; import { User } from "discord-types/general"; const settings = definePluginSettings({ showAtSymbol: { type: OptionType.BOOLEAN, description: "Whether the the @ symbol should be displayed on user mentions", default: true } }); function DefaultRoleIcon() { return ( ); } export default definePlugin({ name: "MentionAvatars", description: "Shows user avatars and role icons inside mentions", authors: [Devs.Ven, Devs.SerStars], patches: [{ find: ".USER_MENTION)", replacement: { match: /children:"@"\.concat\((null!=\i\?\i:\i)\)(?<=\.useName\((\i)\).+?)/, replace: "children:$self.renderUsername({username:$1,user:$2})" } }, { find: ".ROLE_MENTION)", replacement: { match: /children:\[\i&&.{0,50}\.RoleDot.{0,300},\i(?=\])/, replace: "$&,$self.renderRoleIcon(arguments[0])" } }], settings, renderUsername: ErrorBoundary.wrap((props: { user: User, username: string; }) => { const { user, username } = props; const [isHovering, setIsHovering] = useState(false); if (!user) return <>{getUsernameString(username)}; return ( setIsHovering(true)} onMouseLeave={() => setIsHovering(false)} > {getUsernameString(username)} ); }, { noop: true }), renderRoleIcon: ErrorBoundary.wrap(({ roleId, guildId }: { roleId: string, guildId: string; }) => { // Discord uses Role Mentions for uncached users because .... idk if (!roleId) return null; const role = GuildStore.getRole(guildId, roleId); if (!role?.icon) return ; return ( ); }), }); function getUsernameString(username: string) { return settings.store.showAtSymbol ? `@${username}` : username; }