52 lines
1.6 KiB
TypeScript
52 lines
1.6 KiB
TypeScript
import { ActivityType, definePresence } from "@source/presence-sdk";
|
|
|
|
function readNowPlayingTitle(): string | null {
|
|
return (
|
|
document
|
|
.querySelector<HTMLElement>('[data-testid="now-playing-widget"] [data-testid="context-item-info-title"]')
|
|
?.textContent?.trim() ?? null
|
|
);
|
|
}
|
|
|
|
function readArtist(): string | null {
|
|
const artistNodes = document.querySelectorAll<HTMLElement>(
|
|
'[data-testid="now-playing-widget"] [data-testid="context-item-info-artist"]',
|
|
);
|
|
if (artistNodes.length === 0) return null;
|
|
return Array.from(artistNodes).map((n) => n.textContent?.trim()).filter(Boolean).join(", ") || null;
|
|
}
|
|
|
|
function readPlayState(): "playing" | "paused" {
|
|
const button = document.querySelector<HTMLButtonElement>(
|
|
'[data-testid="control-button-playpause"]',
|
|
);
|
|
const label = button?.getAttribute("aria-label")?.toLowerCase() ?? "";
|
|
if (label.includes("pause")) return "playing";
|
|
return "paused";
|
|
}
|
|
|
|
export default definePresence({
|
|
match: ["https://open.spotify.com/*"],
|
|
tickInterval: 1500,
|
|
tick(ctx) {
|
|
const title = readNowPlayingTitle();
|
|
if (!title) {
|
|
ctx.setActivity({
|
|
type: ActivityType.LISTENING,
|
|
name: "Spotify",
|
|
details: "Browsing",
|
|
});
|
|
return;
|
|
}
|
|
const artist = readArtist();
|
|
const state = readPlayState();
|
|
ctx.setActivity({
|
|
type: ActivityType.LISTENING,
|
|
name: "Spotify",
|
|
details: title,
|
|
state: artist ? `${state === "playing" ? "Playing" : "Paused"} · ${artist}` : state === "playing" ? "Playing" : "Paused",
|
|
url: location.href,
|
|
});
|
|
},
|
|
});
|