Rework verified social links badge

This commit is contained in:
Kalle
2026-09-21 08:03:57 +03:00
parent fa6deebc37
commit 807ab2eb96
4 changed files with 121 additions and 50 deletions

View File

@@ -1525,24 +1525,45 @@ export async function findSocialLinksByUserId(userId: number) {
if (!user) return [];
const links: Array<
| { type: "url"; value: string }
| { type: "popover"; platform: "discord"; value: string }
| {
type: "url";
platform: "twitch" | "youtube" | "bsky";
/** Account name on the platform, null if only an id is known */
name: string | null;
url: string;
}
| { type: "text"; platform: "discord"; name: string }
> = [];
if (user.twitch) {
links.push({ type: "url", value: twitchUrl(user.twitch) });
links.push({
type: "url",
platform: "twitch",
name: user.twitch,
url: twitchUrl(user.twitch),
});
}
if (user.youtubeId) {
links.push({ type: "url", value: youtubeUrl(user.youtubeId) });
links.push({
type: "url",
platform: "youtube",
name: null,
url: youtubeUrl(user.youtubeId),
});
}
if (user.bsky) {
links.push({ type: "url", value: bskyUrl(user.bsky) });
links.push({
type: "url",
platform: "bsky",
name: user.bsky,
url: bskyUrl(user.bsky),
});
}
if (user.discordUniqueName) {
links.push({
type: "popover",
type: "text",
platform: "discord",
value: user.discordUniqueName,
name: user.discordUniqueName,
});
}

View File

@@ -310,11 +310,44 @@
}
}
.socialLinksIcons {
.socialLinksList {
display: flex;
gap: var(--s-2);
justify-content: center;
flex-wrap: wrap;
flex-direction: column;
gap: var(--s-1);
}
.socialLinkIconCircle {
border-radius: var(--radius-full);
padding: 0;
width: 24px;
height: 24px;
& svg {
width: 14px;
height: 14px;
}
}
.linkRow {
display: flex;
align-items: center;
justify-content: flex-start;
gap: var(--s-1-5);
width: 100%;
height: auto;
padding: var(--s-0-5) var(--s-1);
border-radius: var(--radius-field);
color: var(--color-text);
font-size: var(--font-sm);
font-weight: var(--weight-body);
&:is(a, button):hover {
background-color: var(--color-bg-high);
}
}
.socialLinkName {
overflow-wrap: anywhere;
}
.gameBadgeGrid {
@@ -337,16 +370,7 @@
.friendsList {
display: flex;
flex-direction: column;
gap: var(--s-2);
}
.friendLink {
padding: var(--s-0-5) var(--s-1);
border-radius: var(--radius-field);
&:hover {
background-color: var(--color-bg-higher);
}
gap: var(--s-1);
}
.mapModePreferences {

View File

@@ -830,6 +830,28 @@ const urlToIcon = (url: string) => {
return <LinkIcon />;
};
const SOCIAL_PLATFORM_FALLBACK_NAMES = {
twitch: "Twitch",
youtube: "YouTube",
bsky: "Bluesky",
discord: "Discord",
} as const;
const platformToIcon = (
platform: "twitch" | "youtube" | "bsky" | "discord",
) => {
switch (platform) {
case "twitch":
return <TwitchIcon />;
case "youtube":
return <YouTubeIcon />;
case "bsky":
return <BskyIcon />;
case "discord":
return <DiscordIcon />;
}
};
function SocialLinksWidget({
data,
}: {
@@ -838,43 +860,42 @@ function SocialLinksWidget({
if (data.length === 0) return null;
return (
<div className={styles.socialLinksIcons}>
{data.map((link, i) => {
if (link.type === "popover") {
return (
<SendouPopover
key={i}
trigger={
<SendouButton
variant="minimal"
className={clsx(
styles.socialLinkIconContainer,
styles.discord,
)}
>
{link.platform === "discord" ? <DiscordIcon /> : null}
</SendouButton>
}
<div className={styles.socialLinksList}>
{data.map((link) => {
const content = (
<>
<div
className={clsx(
styles.socialLinkIconContainer,
styles.socialLinkIconCircle,
styles[link.platform],
)}
>
{link.value}
</SendouPopover>
{platformToIcon(link.platform)}
</div>
<span className={styles.socialLinkName}>
{link.name ?? SOCIAL_PLATFORM_FALLBACK_NAMES[link.platform]}
</span>
</>
);
if (link.type === "text") {
return (
<div key={link.platform} className={styles.linkRow}>
{content}
</div>
);
}
const type = urlToLinkType(link.value);
return (
<a
key={i}
href={link.value}
key={link.platform}
href={link.url}
target="_blank"
rel="noreferrer"
className={clsx(styles.socialLinkIconContainer, {
[styles.twitch]: type === "twitch",
[styles.youtube]: type === "youtube",
[styles.bsky]: type === "bsky",
})}
className={styles.linkRow}
>
{urlToIcon(link.value)}
{content}
</a>
);
})}
@@ -962,7 +983,7 @@ function FriendsWidget({
return (
<div className={styles.friendsList}>
{itemsToDisplay.map((friend) => (
<UserLink key={friend.id} user={friend} className={styles.friendLink} />
<UserLink key={friend.id} user={friend} className={styles.linkRow} />
))}
{!everythingVisible ? (
<div className="mt-4">

View File

@@ -0,0 +1,5 @@
---
navItem: u
type: feature
---
Verified social links on your profile now show your account name on each platform