From a3c64d90c3b9ce278b15d9c90c63b5d242d6c85d Mon Sep 17 00:00:00 2001 From: u32 Date: Thu, 8 Jan 2026 15:11:47 +0000 Subject: [PATCH] Fix vencord badges not showing if user has no Discord badges (#3874) Co-authored-by: Vendicated --- src/api/Badges.ts | 2 +- src/plugins/_api/badges/index.tsx | 18 ++-- .../platformIndicators/icons/desktopIcon.svg | 3 - .../platformIndicators/icons/embeddedIcon.svg | 3 - .../platformIndicators/icons/mobileIcon.svg | 3 - .../platformIndicators/icons/webIcon.svg | 3 - src/plugins/platformIndicators/index.tsx | 85 +++++++------------ 7 files changed, 41 insertions(+), 76 deletions(-) delete mode 100644 src/plugins/platformIndicators/icons/desktopIcon.svg delete mode 100644 src/plugins/platformIndicators/icons/embeddedIcon.svg delete mode 100644 src/plugins/platformIndicators/icons/mobileIcon.svg delete mode 100644 src/plugins/platformIndicators/icons/webIcon.svg diff --git a/src/api/Badges.ts b/src/api/Badges.ts index c5923cf6c..1bcdd268b 100644 --- a/src/api/Badges.ts +++ b/src/api/Badges.ts @@ -48,7 +48,7 @@ export interface ProfileBadge { /** * Allows dynamically returning multiple badges. - * May call hooks but then you must not use shouldShow + * Must not call hooks */ getBadges?(userInfo: BadgeUserArgs): ProfileBadge[]; } diff --git a/src/plugins/_api/badges/index.tsx b/src/plugins/_api/badges/index.tsx index 7095ee731..8d764a2b4 100644 --- a/src/plugins/_api/badges/index.tsx +++ b/src/plugins/_api/badges/index.tsx @@ -90,16 +90,12 @@ export default definePlugin({ { find: "#{intl::PROFILE_USER_BADGES}", replacement: [ - { - match: /(?<=\{[^}]*?)badges:\i(?=[^}]*?}=(\i))/, - replace: "_$&=$self.useBadges($1.displayProfile).concat($1.badges)" - }, { match: /alt:" ","aria-hidden":!0,src:.{0,50}(\i).iconSrc/, replace: "...$1.props,$&" }, { - match: /(?<="aria-label":(\i)\.description,.{0,200}?)children:/g, + match: /(?<=forceOpen:.{0,40}?\i\((\i)\.id\).{0,100}?)children:/, replace: "children:$1.component?$self.renderBadgeComponent({...$1}) :" }, // handle onClick and onContextMenu @@ -108,6 +104,13 @@ export default definePlugin({ replace: "...$self.getBadgeMouseEventHandlers($1),$&" } ] + }, + { + find: "getLegacyUsername(){", + replacement: { + match: /getBadges\(\)\{.{0,100}?return\[/, + replace: "$&...$self.getBadges(this)," + } } ], @@ -140,14 +143,13 @@ export default definePlugin({ clearInterval(intervalId); }, - // doesn't use hooks itself, but some plugins might do so in their getBadges function - useBadges(profile: { userId: string; guildId: string; }) { + getBadges(profile: { userId: string; guildId: string; }) { if (!profile) return []; try { return _getBadges(profile); } catch (e) { - new Logger("BadgeAPI#useBadges").error(e); + new Logger("BadgeAPI#getBadges").error(e); return []; } }, diff --git a/src/plugins/platformIndicators/icons/desktopIcon.svg b/src/plugins/platformIndicators/icons/desktopIcon.svg deleted file mode 100644 index df7ac3312..000000000 --- a/src/plugins/platformIndicators/icons/desktopIcon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/plugins/platformIndicators/icons/embeddedIcon.svg b/src/plugins/platformIndicators/icons/embeddedIcon.svg deleted file mode 100644 index ce6f62ddb..000000000 --- a/src/plugins/platformIndicators/icons/embeddedIcon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/plugins/platformIndicators/icons/mobileIcon.svg b/src/plugins/platformIndicators/icons/mobileIcon.svg deleted file mode 100644 index 28b23a522..000000000 --- a/src/plugins/platformIndicators/icons/mobileIcon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/plugins/platformIndicators/icons/webIcon.svg b/src/plugins/platformIndicators/icons/webIcon.svg deleted file mode 100644 index 82627ca90..000000000 --- a/src/plugins/platformIndicators/icons/webIcon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/plugins/platformIndicators/index.tsx b/src/plugins/platformIndicators/index.tsx index def3e5c94..8c6ba66d8 100644 --- a/src/plugins/platformIndicators/index.tsx +++ b/src/plugins/platformIndicators/index.tsx @@ -27,11 +27,6 @@ import definePlugin, { OptionType } from "@utils/types"; import { DiscordPlatform, OnlineStatus, User } from "@vencord/discord-types"; import { filters, findStoreLazy, mapMangledModuleLazy } from "@webpack"; import { AuthenticationStore, PresenceStore, Tooltip, UserStore, useStateFromStores } from "@webpack/common"; -import desktopIcon from "file://icons/desktopIcon.svg?minify"; -import embeddedIcon from "file://icons/embeddedIcon.svg?minify"; -import mobileIcon from "file://icons/mobileIcon.svg?minify"; -import webIcon from "file://icons/webIcon.svg?minify"; -import type { JSX } from "react"; export interface Session { sessionId: string; @@ -51,41 +46,30 @@ const { useStatusFillColor } = mapMangledModuleLazy(".concat(.5625*", { useStatusFillColor: filters.byCode(".hex") }); -function Icon(svg: string, size = 20) { +function Icon(path: string, opts?: { viewBox?: string; width?: number; height?: number; }) { return ({ color, tooltip, small }: { color: string; tooltip: string; small: boolean; }) => ( - + {tooltipProps => ( - + height={(opts?.height ?? 20) - (small ? 3 : 0)} + width={(opts?.width ?? 20) - (small ? 3 : 0)} + viewBox={opts?.viewBox ?? "0 0 24 24"} + fill={color} + > + + )} ); } -type IconData = { - svg: string, - size: number, - component: (props: { color: string, tooltip: string, small: boolean; }) => JSX.Element; -}; - -const Icons: Record = { - desktop: iconData(desktopIcon), - web: iconData(webIcon), - mobile: iconData(mobileIcon), - embedded: iconData(embeddedIcon), -}; - -function iconData(svg: string, size: number = 20): IconData { - return { - svg, - size, - component: Icon(svg, size), - }; -} +const Icons = { + desktop: Icon("M4 2.5c-1.103 0-2 .897-2 2v11c0 1.104.897 2 2 2h7v2H7v2h10v-2h-4v-2h7c1.103 0 2-.896 2-2v-11c0-1.103-.897-2-2-2H4Zm16 2v9H4v-9h16Z"), + web: Icon("M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2Zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93Zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39Z"), + mobile: Icon("M 187 0 L 813 0 C 916.277 0 1000 83.723 1000 187 L 1000 1313 C 1000 1416.277 916.277 1500 813 1500 L 187 1500 C 83.723 1500 0 1416.277 0 1313 L 0 187 C 0 83.723 83.723 0 187 0 Z M 125 1000 L 875 1000 L 875 250 L 125 250 Z M 500 1125 C 430.964 1125 375 1180.964 375 1250 C 375 1319.036 430.964 1375 500 1375 C 569.036 1375 625 1319.036 625 1250 C 625 1180.964 569.036 1125 500 1125 Z", { viewBox: "0 0 1000 1500", height: 17, width: 17 }), + embedded: Icon("M14.8 2.7 9 3.1V47h3.3c1.7 0 6.2.3 10 .7l6.7.6V2l-4.2.2c-2.4.1-6.9.3-10 .5zm1.8 6.4c1 1.7-1.3 3.6-2.7 2.2C12.7 10.1 13.5 8 15 8c.5 0 1.2.5 1.6 1.1zM16 33c0 6-.4 10-1 10s-1-4-1-10 .4-10 1-10 1 4 1 10zm15-8v23.3l3.8-.7c2-.3 4.7-.6 6-.6H43V3h-2.2c-1.3 0-4-.3-6-.6L31 1.7V25z", { viewBox: "0 0 50 50" }), +} satisfies Record; function getPlatformTooltip(platform: DiscordPlatform): string { return platform === "embedded" @@ -96,7 +80,7 @@ function getPlatformTooltip(platform: DiscordPlatform): string { const PlatformIcon = ({ platform, status, small }: { platform: DiscordPlatform, status: OnlineStatus; small: boolean; }) => { const tooltip = getPlatformTooltip(platform as DiscordPlatform); - const Icon = (Icons[platform] ?? Icons.desktop).component; + const Icon = Icons[platform] ?? Icons.desktop; return ; }; @@ -126,14 +110,6 @@ function ensureOwnStatus(user: User) { } function getBadges({ userId }: BadgeUserArgs): ProfileBadge[] { - const colorMap = { - online: useStatusFillColor("online"), - idle: useStatusFillColor("idle"), - dnd: useStatusFillColor("dnd"), - offline: useStatusFillColor("offline"), - streaming: useStatusFillColor("streaming"), - }; - const user = UserStore.getUser(userId); if (!user || user.bot) return []; @@ -143,20 +119,19 @@ function getBadges({ userId }: BadgeUserArgs): ProfileBadge[] { const status = PresenceStore.getClientStatus(user.id); if (!status) return []; - return Object.entries(status).map(([platform, status]) => { - const tooltip = getPlatformTooltip(platform as DiscordPlatform); - - const icon = Icons[platform as DiscordPlatform] ?? Icons.desktop; - - return { - description: tooltip, - iconSrc: "data:image/svg+xml;utf8," + encodeURIComponent(icon.svg.replace("#123456", colorMap[status] ?? colorMap.offline)), - props: { - style: { width: icon.size, height: icon.size }, - }, - key: `vc-platform-indicator-${platform}`, - } satisfies ProfileBadge; - }); + return Object.entries(status).map(([platform, status]) => ({ + key: `vc-platform-indicator-${platform}`, + component: () => ( + + + + ), + })); } const PlatformIndicator = ({ user, small = false }: { user: User; small?: boolean; }) => {