mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-30 23:27:55 -05:00
Rework verified social links badge
This commit is contained in:
@@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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">
|
||||
|
||||
5
changelog/2026-09-21-social-links-widget-names.md
Normal file
5
changelog/2026-09-21-social-links-widget-names.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
navItem: u
|
||||
type: feature
|
||||
---
|
||||
Verified social links on your profile now show your account name on each platform
|
||||
Reference in New Issue
Block a user