import './discordstatus.css'; import { useEffect, useState } from "react"; interface LanyardResponse { success: boolean; data: LanyardData; } interface LanyardData { discord_status: 'online' | 'idle' | 'dnd' | 'offline'; activities: DiscordActivity[]; discord_user: DiscordUser; active_on_discord_web: boolean; active_on_discord_desktop: boolean; active_on_discord_mobile: boolean; active_on_discord_embedded: boolean; active_on_discord_vr: boolean; listening_to_spotify: boolean; spotify: SpotifyData | null; kv: Record; } interface SpotifyData { album: string; album_art_url: string; artist: string; song: string; track_id: string; timestamps: { start: number; end: number; }; } interface DiscordUser { id: string; username: string; discriminator: string; global_name: string; display_name: string; avatar: string; bot: boolean; public_flags: number; avatar_decoration_data: null | any; collectibles?: { nameplate?: { asset: string; expires_at: string | null; label: string; palette: string; sku_id: string; }; }; display_name_styles?: { colors: any[]; effect_id: number; font_id: number; }; primary_guild?: { badge: null | any; identity_enabled: boolean; identity_guild_id: null | string; tag: null | string; }; } interface DiscordActivity { id: string; name: string; type: number; session_id?: string; created_at: number; state?: string; details?: string; timestamps?: { start?: number; end?: number; }; assets?: { large_image?: string; large_text?: string; small_image?: string; small_text?: string; }; emoji?: { name: string; id?: string; animated?: boolean; }; application_id?: string; flags?: number; platform?: string; sync_id?: string; content_classification?: { data: null | any; loaded: boolean; }; } function resolveDiscordAsset(applicationId: string | undefined, image: string | undefined): string { if (!image) return ""; if (image.startsWith("mp:external/")) { const httpsIndex = image.indexOf("/https/"); if (httpsIndex !== -1) { return `https://${image.slice(httpsIndex + "/https/".length)}`; } } if (image.startsWith("spotify:")) return ""; if (applicationId && image) return `https://cdn.discordapp.com/app-assets/${applicationId}/${image}.png`; return image; } export interface DiscordStatusParams { userId: string } const STATUS_LABELS: Record = { online: 'online', idle: 'away', dnd: 'busy', offline: 'offline' }; export function DiscordStatus({ userId }: DiscordStatusParams) { const [presence, setPresence] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { async function fetchRichPresence() { try { const response = await fetch(`https://api.lanyard.rest/v1/users/${userId}`); const json: LanyardResponse = await response.json(); if (json.success) { setPresence(json.data); } } catch (error) { console.error("Failed to fetch Lanyard presence:", error); } finally { setLoading(false); } } fetchRichPresence(); const interval = setInterval(fetchRichPresence, 30000); return () => clearInterval(interval); }, [userId]); if (loading) return

loading status...

; if (!presence) return

offline

; const customActivity = presence.activities.find(act => act.id === "custom"); const customStatusText = customActivity ? `${customActivity.emoji?.name || ''} ${customActivity.state || ''}`.trim() : null; const gameActivity = presence.activities .filter(act => act.type === 0) .sort((a, b) => (b.assets ? 1 : 0) - (a.assets ? 1 : 0))[0] as DiscordActivity | undefined; const isListeningToSpotify = presence.listening_to_spotify && presence.spotify; let primaryActivity = null; let activityText = ""; let activityImage = ""; if (gameActivity) { primaryActivity = gameActivity; activityText = `playing: ${gameActivity.name.toLowerCase()}`; if (gameActivity.details) activityText += ` • ${gameActivity.details}`; activityImage = gameActivity.assets ? resolveDiscordAsset(gameActivity.assets.small_image || gameActivity.assets.large_image) : ""; } else if (isListeningToSpotify && presence.spotify) { primaryActivity = { name: "Spotify" } as DiscordActivity; activityText = `listening to: ${presence.spotify.song} • ${presence.spotify.artist}`; activityImage = presence.spotify.album_art_url || ""; } return (
Discord avatar
{primaryActivity ? ( <>{activityText} ) : ( <>currently: {STATUS_LABELS[presence.discord_status]} )} {customStatusText && ( {customStatusText} )}
{activityImage && primaryActivity && ( {primaryActivity.name} )}
); }