feat: add spotify status
This commit is contained in:
@@ -17,10 +17,22 @@ interface LanyardData {
|
|||||||
active_on_discord_embedded: boolean;
|
active_on_discord_embedded: boolean;
|
||||||
active_on_discord_vr: boolean;
|
active_on_discord_vr: boolean;
|
||||||
listening_to_spotify: boolean;
|
listening_to_spotify: boolean;
|
||||||
spotify: null | Record<string, any>;
|
spotify: SpotifyData | null;
|
||||||
kv: Record<string, string>;
|
kv: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SpotifyData {
|
||||||
|
album: string;
|
||||||
|
album_art_url: string;
|
||||||
|
artist: string;
|
||||||
|
song: string;
|
||||||
|
track_id: string;
|
||||||
|
timestamps: {
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
interface DiscordUser {
|
interface DiscordUser {
|
||||||
id: string;
|
id: string;
|
||||||
username: string;
|
username: string;
|
||||||
@@ -31,9 +43,26 @@ interface DiscordUser {
|
|||||||
bot: boolean;
|
bot: boolean;
|
||||||
public_flags: number;
|
public_flags: number;
|
||||||
avatar_decoration_data: null | any;
|
avatar_decoration_data: null | any;
|
||||||
collectibles?: Record<string, any>;
|
collectibles?: {
|
||||||
display_name_styles?: Record<string, any>;
|
nameplate?: {
|
||||||
primary_guild?: Record<string, any>;
|
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 {
|
interface DiscordActivity {
|
||||||
@@ -62,6 +91,11 @@ interface DiscordActivity {
|
|||||||
application_id?: string;
|
application_id?: string;
|
||||||
flags?: number;
|
flags?: number;
|
||||||
platform?: string;
|
platform?: string;
|
||||||
|
sync_id?: string;
|
||||||
|
content_classification?: {
|
||||||
|
data: null | any;
|
||||||
|
loaded: boolean;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveDiscordAsset(image: string | undefined): string {
|
function resolveDiscordAsset(image: string | undefined): string {
|
||||||
@@ -113,15 +147,13 @@ export function DiscordStatus({ userId }: DiscordStatusParams) {
|
|||||||
fetchRichPresence();
|
fetchRichPresence();
|
||||||
const interval = setInterval(fetchRichPresence, 30000);
|
const interval = setInterval(fetchRichPresence, 30000);
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, []);
|
}, [userId]);
|
||||||
|
|
||||||
if (loading) {
|
if (loading)
|
||||||
return <p style={{ fontSize: '0.75rem', fontStyle: 'italic', color: 'var(--text-dim)' }}>loading status...</p>;
|
return <p style={{ fontSize: '0.75rem', fontStyle: 'italic', color: 'var(--text-dim)' }}>loading status...</p>;
|
||||||
}
|
|
||||||
|
|
||||||
if (!presence) {
|
if (!presence)
|
||||||
return <p style={{ fontSize: '0.75rem', fontStyle: 'italic', color: 'var(--text-dim)' }}>offline</p>;
|
return <p style={{ fontSize: '0.75rem', fontStyle: 'italic', color: 'var(--text-dim)' }}>offline</p>;
|
||||||
}
|
|
||||||
|
|
||||||
const customActivity = presence.activities.find(act => act.id === "custom");
|
const customActivity = presence.activities.find(act => act.id === "custom");
|
||||||
const customStatusText = customActivity
|
const customStatusText = customActivity
|
||||||
@@ -132,9 +164,28 @@ export function DiscordStatus({ userId }: DiscordStatusParams) {
|
|||||||
.filter(act => act.type === 0)
|
.filter(act => act.type === 0)
|
||||||
.sort((a, b) => (b.assets ? 1 : 0) - (a.assets ? 1 : 0))[0] as DiscordActivity | undefined;
|
.sort((a, b) => (b.assets ? 1 : 0) - (a.assets ? 1 : 0))[0] as DiscordActivity | undefined;
|
||||||
|
|
||||||
const gameImage = gameActivity?.assets
|
const isListeningToSpotify = presence.listening_to_spotify && presence.spotify;
|
||||||
? resolveDiscordAsset(gameActivity.assets.small_image || gameActivity.assets.large_image)
|
|
||||||
: "";
|
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 (
|
return (
|
||||||
<div className="discord-status-compact">
|
<div className="discord-status-compact">
|
||||||
@@ -149,14 +200,10 @@ export function DiscordStatus({ userId }: DiscordStatusParams) {
|
|||||||
|
|
||||||
<div className="status-details">
|
<div className="status-details">
|
||||||
<span className="status-text">
|
<span className="status-text">
|
||||||
{gameActivity ? (
|
{primaryActivity ? (
|
||||||
<>
|
<>{activityText}</>
|
||||||
playing: <em>{gameActivity.name.toLowerCase()}</em>
|
|
||||||
</>
|
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>currently: <em>{STATUS_LABELS[presence.discord_status]}</em></>
|
||||||
currently: <em>{STATUS_LABELS[presence.discord_status]}</em>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@@ -167,13 +214,13 @@ export function DiscordStatus({ userId }: DiscordStatusParams) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{gameImage && gameActivity && (
|
{activityImage && primaryActivity && (
|
||||||
<img
|
<img
|
||||||
src={gameImage}
|
src={activityImage}
|
||||||
alt={gameActivity.name}
|
alt={primaryActivity.name}
|
||||||
className="game-icon"
|
className="game-icon"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user