Fix vencord badges not showing if user has no Discord badges (#3874)
Co-authored-by: Vendicated <vendicated@riseup.net>
This commit is contained in:
parent
b4eff3b62b
commit
a3c64d90c3
7 changed files with 41 additions and 76 deletions
|
|
@ -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[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 [];
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
<svg height="20" width="20" viewBox="0 0 24 24" fill="#123456" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="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" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 254 B |
|
|
@ -1,3 +0,0 @@
|
|||
<svg height="20" width="20" viewBox="0 0 50 50" fill="#123456" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="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" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 395 B |
|
|
@ -1,3 +0,0 @@
|
|||
<svg height="17" width="17" viewBox="0 0 1000 1500" fill="#123456" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="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" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 510 B |
|
|
@ -1,3 +0,0 @@
|
|||
<svg height="20" width="20" viewBox="0 0 24 24" fill="#123456" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="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" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 424 B |
|
|
@ -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; }) => (
|
||||
<Tooltip text={tooltip} >
|
||||
<Tooltip text={tooltip}>
|
||||
{tooltipProps => (
|
||||
<img
|
||||
<svg
|
||||
{...tooltipProps}
|
||||
src={"data:image/svg+xml;utf8," + encodeURIComponent(svg.replace("#123456", color))}
|
||||
height={size - (small ? 3 : 0)}
|
||||
width={size - (small ? 3 : 0)}
|
||||
/>
|
||||
height={(opts?.height ?? 20) - (small ? 3 : 0)}
|
||||
width={(opts?.width ?? 20) - (small ? 3 : 0)}
|
||||
viewBox={opts?.viewBox ?? "0 0 24 24"}
|
||||
fill={color}
|
||||
>
|
||||
<path d={path} />
|
||||
</svg>
|
||||
)}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
type IconData = {
|
||||
svg: string,
|
||||
size: number,
|
||||
component: (props: { color: string, tooltip: string, small: boolean; }) => JSX.Element;
|
||||
};
|
||||
|
||||
const Icons: Record<DiscordPlatform, IconData> = {
|
||||
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<DiscordPlatform, any>;
|
||||
|
||||
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 <Icon color={useStatusFillColor(status)} tooltip={tooltip} small={small} />;
|
||||
};
|
||||
|
|
@ -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: () => (
|
||||
<span className="vc-platform-indicator">
|
||||
<PlatformIcon
|
||||
key={platform}
|
||||
platform={platform as DiscordPlatform}
|
||||
status={status}
|
||||
small={false}
|
||||
/>
|
||||
</span>
|
||||
),
|
||||
}));
|
||||
}
|
||||
|
||||
const PlatformIndicator = ({ user, small = false }: { user: User; small?: boolean; }) => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue