Better support with Tether
All checks were successful
Deploy Site / docker (ubuntu-latest, 2.44.0) (push) Successful in 1m51s

This commit is contained in:
Braydon 2024-09-10 16:25:39 -04:00
parent 33ff9b81e2
commit 1180e9c8aa
3 changed files with 67 additions and 71 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -26,7 +26,7 @@
"sharp": "^0.33.5", "sharp": "^0.33.5",
"tailwind-merge": "^2.5.2", "tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"use-tether": "^1.0.0" "use-tether": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"typescript": "^5", "typescript": "^5",

View File

@ -1,7 +1,12 @@
"use client"; "use client";
import { ReactElement, useEffect, useState } from "react"; import { ReactElement, useEffect, useState } from "react";
import { DiscordUser, SpotifyActivity, useTetherWS } from "use-tether"; import {
DiscordUser,
SpotifyActivity,
UserBadge,
useTetherWS,
} from "use-tether";
import Image from "next/image"; import Image from "next/image";
import { cn, truncateText } from "@/lib/utils"; import { cn, truncateText } from "@/lib/utils";
import SimpleTooltip from "@/components/ui/simple-tooltip"; import SimpleTooltip from "@/components/ui/simple-tooltip";
@ -15,31 +20,6 @@ const statusColors = {
OFFLINE: "bg-zinc-500", OFFLINE: "bg-zinc-500",
}; };
const userBadges = {
// Nitro
"https://cdn.discordapp.com/badge-icons/2ba85e8026a8614b640c2837bcdfe21b.png":
{
name: "Nitro Subscriber",
predicate: (discordUser: DiscordUser) => true, // TODO: Add Nitro predicate
},
// Early Supporter
"https://cdn.discordapp.com/badge-icons/7060786766c9c840eb3019e725d2b358.png":
{
name: "Early Supporter",
predicate: (discordUser: DiscordUser) =>
discordUser.flags.list.includes("EARLY_SUPPORTER"),
},
// Active Developer
"https://cdn.discordapp.com/badge-icons/6bdc42827a38498929a4920da12695d9.png":
{
name: "Active Developer",
predicate: (discordUser: DiscordUser) =>
discordUser.flags.list.includes("ACTIVE_DEVELOPER"),
},
};
const DiscordStatus = (): ReactElement | undefined => { const DiscordStatus = (): ReactElement | undefined => {
const discordUser: DiscordUser | undefined = const discordUser: DiscordUser | undefined =
useTetherWS("504147739131641857"); useTetherWS("504147739131641857");
@ -49,14 +29,14 @@ const DiscordStatus = (): ReactElement | undefined => {
return ( return (
<div className="flex justify-center select-none"> <div className="flex justify-center select-none">
<div className="flex flex-col bg-zinc-300 dark:bg-zinc-900 rounded-xl"> <div className="flex flex-col bg-zinc-300 dark:bg-zinc-900 rounded-xl">
<BannerAvatar user={discordUser} /> <BannerAvatar discordUser={discordUser} />
<div className="px-3 pt-1.5 py-2.5 flex flex-col"> <div className="px-3 pt-1.5 py-2.5 flex flex-col">
<div className="ml-[5.65rem] flex items-start"> <div className="ml-[5.65rem] flex items-start">
<Bio bio="7th ward" /> {/* TODO: Add bio */} {discordUser.bio && <Bio bio={discordUser.bio} />}
<Badges discordUser={discordUser} /> <Badges discordUser={discordUser} />
</div> </div>
<div className="mt-3"> <div className={discordUser.banner ? "mt-3" : "mt-6"}>
<Username discordUser={discordUser} /> <Username discordUser={discordUser} />
{/* Activity */} {/* Activity */}
@ -74,34 +54,47 @@ const DiscordStatus = (): ReactElement | undefined => {
); );
}; };
const BannerAvatar = ({ user }: { user: DiscordUser }): ReactElement => ( const BannerAvatar = ({
<div className="relative pointer-events-none"> discordUser,
{user.banner && ( }: {
<Image discordUser: DiscordUser;
className="border-2 border-zinc-300 dark:border-zinc-900 rounded-t-xl" }): ReactElement => {
src={user.banner.url} const bannerClasses =
alt={`${user.username}'s Banner`} "border-2 border-zinc-300 dark:border-zinc-900 rounded-t-xl";
width={300} return (
height={300} <div className="relative pointer-events-none">
/> {discordUser.banner ? (
)} <Image
<div className="relative"> className={bannerClasses}
<Image src={discordUser.banner.url}
className="absolute left-2 -bottom-12 border-[5px] border-zinc-300 dark:border-zinc-900 rounded-full" alt={`${discordUser.username}'s Banner`}
src={user.avatar.url} width={300}
alt={`${user.username}'s Avatar`} height={300}
width={96} />
height={96} ) : (
/> <div
<div className={cn("w-[300px] h-[107px]", bannerClasses)}
className={cn( style={{ background: discordUser.bannerColor }}
"absolute left-[4.5rem] -bottom-12 w-7 h-7 border-[5px] border-zinc-300 dark:border-zinc-900 rounded-full", />
statusColors[user.onlineStatus] )}
)} <div className="relative">
/> <Image
className="absolute left-2 -bottom-12 border-[5px] border-zinc-300 dark:border-zinc-900 rounded-full"
src={discordUser.avatar.url}
alt={`${discordUser.username}'s Avatar`}
width={96}
height={96}
/>
<div
className={cn(
"absolute left-[4.5rem] -bottom-12 w-7 h-7 border-[5px] border-zinc-300 dark:border-zinc-900 rounded-full",
statusColors[discordUser.onlineStatus]
)}
/>
</div>
</div> </div>
</div> );
); };
const Bio = ({ bio }: { bio: string }): ReactElement => ( const Bio = ({ bio }: { bio: string }): ReactElement => (
<SimpleTooltip content={bio}> <SimpleTooltip content={bio}>
@ -116,20 +109,23 @@ const Badges = ({
}: { }: {
discordUser: DiscordUser; discordUser: DiscordUser;
}): ReactElement => ( }): ReactElement => (
<div className="ml-auto flex gap-1"> <div
{Object.entries(userBadges) className={cn(
.filter(([_, badge]) => badge.predicate(discordUser)) "ml-auto flex flex-wrap gap-1 justify-end",
.map(([badgeIcon, badge], index) => ( discordUser.badges.length > 4 && "max-w-[4.75rem]"
<SimpleTooltip key={index} content={badge.name}> )}
<Image >
src={badgeIcon} {discordUser.badges.map((badge: UserBadge, index: number) => (
alt="Discord Profile Badge" <SimpleTooltip key={index} content={badge.description}>
width={22} <Image
height={22} src={badge.icon.url}
draggable={false} alt="Discord Profile Badge"
/> width={22}
</SimpleTooltip> height={22}
))} draggable={false}
/>
</SimpleTooltip>
))}
</div> </div>
); );