diff --git a/src/components/BentoDiscord.tsx b/src/components/BentoDiscord.tsx new file mode 100644 index 0000000..e1005e3 --- /dev/null +++ b/src/components/BentoDiscord.tsx @@ -0,0 +1,241 @@ +import { useEffect, useState } from "react"; +import { Skeleton } from "./ui/skeleton"; +import { MoveUpRight } from "lucide-react"; + +interface DiscordUser { + id: string; + username: string; + discriminator: string; + avatar: string; + global_name: string | null; +} + +interface DiscordActivity { + id: string; + name: string; + type: number; + state?: string; + details?: string; + timestamps?: { + start?: number; + end?: number; + }; + assets?: { + large_image?: string; + large_text?: string; + small_image?: string; + small_text?: string; + }; + application_id?: string; +} + +interface LanyardData { + discord_user: DiscordUser; + discord_status: "online" | "idle" | "dnd" | "offline"; + activities: DiscordActivity[]; + listening_to_spotify: boolean; + spotify?: { + track_id: string; + timestamps: { + start: number; + end: number; + }; + song: string; + artist: string; + album_art_url: string; + album: string; + }; +} + +interface LanyardResponse { + success: boolean; + data: LanyardData; +} + +export default function BentoDiscord() { + const [discordData, setDiscordData] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + + useEffect(() => { + const fetchDiscordData = async () => { + try { + const response = await fetch(`https://api.lanyard.rest/v1/users/703974042700611634`); + const data: LanyardResponse = await response.json(); + + if (data.success) { + setDiscordData(data.data); + } + setIsLoading(false); + } catch (error) { + console.error('Error fetching Discord data:', error); + setIsLoading(false); + } + }; + + fetchDiscordData(); + + // Update every 30 seconds + const interval = setInterval(fetchDiscordData, 30000); + return () => clearInterval(interval); + }, []); + + const getStatusColor = (status: string) => { + switch (status) { + case "online": return "bg-green-500"; + case "idle": return "bg-yellow-500"; + case "dnd": return "bg-red-500"; + default: return "bg-gray-500"; + } + }; + + const getStatusText = (status: string) => { + switch (status) { + case "online": return "Online"; + case "idle": return "Away"; + case "dnd": return "Do Not Disturb"; + default: return "Offline"; + } + }; + + const getAvatarUrl = (user: DiscordUser) => { + return `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png?size=128`; + }; + + const getMainActivity = (activities: DiscordActivity[]) => { + return activities.find(activity => activity.type !== 4 && activity.name !== "Spotify") || activities[0]; + }; + + if (isLoading) { + return ( +
+ {/* Background Pattern */} +
+
+
+ + {/* Discord Logo */} +
+ + + +
+ +
+ {/* Header Skeleton */} +
+ + +
+ + {/* Profile Skeleton */} +
+
+ + +
+ +
+ + + +
+
+ + {/* Footer Skeleton */} +
+ + +
+
+
+ ); + } + + if (!discordData) return

Something absolutely horrible has gone wrong

; + + const mainActivity = getMainActivity(discordData.activities); + const displayName = discordData.discord_user.global_name || discordData.discord_user.username; + + return ( +
+ {/* Background Pattern */} +
+
+
+ + {/* Discord Logo */} +
+ + + +
+ +
+ {/* Header */} +
+
+ + {getStatusText(discordData.discord_status).toUpperCase()} + +
+ + {/* Profile Info */} +
+
+ Discord avatar +
+
+ +
+

+ {displayName} +

+ {mainActivity ? ( + <> +

+ {mainActivity.name} +

+ {mainActivity.details && ( +

+ {mainActivity.details} +

+ )} + + ) : ( +

+ @{discordData.discord_user.username} +

+ )} +
+
+ + {/* Footer */} +
+
+
+
+
+
+ + + + +
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/index.astro b/src/pages/index.astro index 182d49f..25eab6a 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,6 +1,7 @@ --- import BentoSpotify from '@/components/BentoSpotify' import BentoWeather from '@/components/BentoWeather' +import BentoDiscord from '@/components/BentoDiscord' import Link from '@/components/Link.astro' import PageHead from '@/components/PageHead.astro' import { Badge } from '@/components/ui/badge' @@ -109,7 +110,9 @@ const allPosts = await getRecentPosts(2) -
Discord
+
+ +