Initial commit

This commit is contained in:
hibna
2026-04-25 23:58:58 +03:00
commit 9d06660901
13 changed files with 528 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
{
"id": "spotify",
"name": "Spotify Web",
"description": "Reflects what you're listening to on open.spotify.com.",
"version": "1.0.0",
"author": "hibna",
"match": ["https://open.spotify.com/*"],
"tickInterval": 1500,
"sdkVersion": "^0.1.0"
}
+51
View File
@@ -0,0 +1,51 @@
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,
});
},
});
+13
View File
@@ -0,0 +1,13 @@
{
"id": "youtube",
"name": "YouTube",
"description": "Shows the video you're watching on YouTube as a Source rich presence.",
"version": "1.0.0",
"author": "hibna",
"match": [
"https://www.youtube.com/*",
"https://music.youtube.com/*"
],
"tickInterval": 1000,
"sdkVersion": "^0.1.0"
}
+69
View File
@@ -0,0 +1,69 @@
import { ActivityType, definePresence } from "@source/presence-sdk";
function findVideo(): HTMLVideoElement | null {
return document.querySelector<HTMLVideoElement>("video.html5-main-video, video");
}
function readTitle(): string | null {
const titleNode =
document.querySelector<HTMLElement>("h1.ytd-watch-metadata yt-formatted-string") ??
document.querySelector<HTMLElement>("h1.title yt-formatted-string");
const text = titleNode?.textContent?.trim();
if (text) return text;
const fallback = document.title.replace(/\s*-\s*YouTube\s*$/i, "").trim();
return fallback.length > 0 ? fallback : null;
}
function readChannel(): string | null {
const node =
document.querySelector<HTMLElement>("ytd-channel-name #text a") ??
document.querySelector<HTMLElement>("#owner #channel-name a");
return node?.textContent?.trim() ?? null;
}
export default definePresence({
match: ["https://www.youtube.com/*", "https://music.youtube.com/*"],
tickInterval: 1000,
tick(ctx) {
const video = findVideo();
const isMusic = location.hostname === "music.youtube.com";
if (location.pathname === "/" || location.pathname === "/feed/subscriptions") {
ctx.setActivity({
type: ActivityType.WATCHING,
name: isMusic ? "YouTube Music" : "YouTube",
details: "Browsing",
});
return;
}
if (!video) {
ctx.setActivity({
type: ActivityType.WATCHING,
name: isMusic ? "YouTube Music" : "YouTube",
details: document.title.slice(0, 128),
});
return;
}
const title = readTitle();
if (!title) {
ctx.clear();
return;
}
const channel = readChannel();
const paused = video.paused;
const liveBadge = document.querySelector(".ytp-live") !== null;
ctx.setActivity({
type: isMusic ? ActivityType.LISTENING : ActivityType.WATCHING,
name: isMusic ? "YouTube Music" : "YouTube",
details: title,
state: channel ? `${paused ? "Paused" : liveBadge ? "Live" : "Playing"} · ${channel}` : paused ? "Paused" : liveBadge ? "Live" : "Playing",
url: location.href,
startedAt: paused || liveBadge ? null : Date.now() - Math.floor(video.currentTime * 1000),
endsAt: paused || liveBadge || !Number.isFinite(video.duration) ? null : Date.now() + Math.floor((video.duration - video.currentTime) * 1000),
});
},
});