From 5de20ab30a8630516512029ea4643252a742e6ea Mon Sep 17 00:00:00 2001 From: Inrixia Date: Wed, 26 Jun 2024 04:25:18 +1200 Subject: [PATCH] DiscordRPC - Native Working --- .../{DiscordRPC.ts => DiscordRPC.native.ts} | 0 plugins/DiscordRPC/src/index.ts | 71 +++---------------- plugins/DiscordRPC/src/updateRPC.native.ts | 51 +++++++++++++ 3 files changed, 60 insertions(+), 62 deletions(-) rename plugins/DiscordRPC/src/{DiscordRPC.ts => DiscordRPC.native.ts} (100%) create mode 100644 plugins/DiscordRPC/src/updateRPC.native.ts diff --git a/plugins/DiscordRPC/src/DiscordRPC.ts b/plugins/DiscordRPC/src/DiscordRPC.native.ts similarity index 100% rename from plugins/DiscordRPC/src/DiscordRPC.ts rename to plugins/DiscordRPC/src/DiscordRPC.native.ts diff --git a/plugins/DiscordRPC/src/index.ts b/plugins/DiscordRPC/src/index.ts index 85e4f13..129fbed 100644 --- a/plugins/DiscordRPC/src/index.ts +++ b/plugins/DiscordRPC/src/index.ts @@ -1,25 +1,13 @@ -import { store, intercept } from "@neptune"; -import { getMediaURLFromID } from "@neptune/utils"; -import { Presence } from "discord-rpc"; +import { intercept } from "@neptune"; import { html } from "@neptune/voby"; -import { DiscordRPC } from "./DiscordRPC"; - // @ts-expect-error Types dont include @plugin import { storage } from "@plugin"; -import { MediaItem } from "neptune-types/tidal"; import { SwitchSetting } from "@inrixia/lib/components/SwitchSetting"; import getPlaybackControl from "@inrixia/lib/getPlaybackControl"; import { TrackItemCache } from "@inrixia/lib/Caches/TrackItemCache"; - -const rpcClient = new DiscordRPC("1130698654987067493"); - -const STR_MAX_LEN = 127; -const formatLongString = (s?: string) => { - if (s === undefined) return ""; - return s.length >= STR_MAX_LEN ? s.slice(0, STR_MAX_LEN - 3) + "..." : s; -}; +import { updateRPC } from "./updateRPC.native"; enum AudioQuality { HiRes = "HI_RES_LOSSLESS", @@ -42,63 +30,22 @@ interface PlaybackContext { playbackSessionId: string; sampleRate: number | null; } -const unloadTimeUpdate = intercept("playbackControls/TIME_UPDATE", ([current]) => { - updateRPC(current); +export const onUnload = intercept("playbackControls/TIME_UPDATE", ([current]) => { + onTimeUpdate(); }); - -const updateRPC = async (currentTime?: number) => { +const onTimeUpdate = async () => { const { playbackContext, playbackState, latestCurrentTime } = getPlaybackControl(); - currentTime ??= latestCurrentTime; + if (playbackState === undefined || latestCurrentTime === undefined || playbackContext === undefined) return; - const mediaItemId = (playbackContext)?.actualProductId; + const mediaItemId = playbackContext.actualProductId; if (mediaItemId === undefined) return; const currentlyPlaying = await TrackItemCache.ensure(mediaItemId); if (currentlyPlaying === undefined) return; - const _rpcClient = await rpcClient.ensureRPC().catch((err) => console.error("Failed to connect to DiscordRPC", err)); - if (_rpcClient === undefined) return; - - const activityState: Presence = { - buttons: [], - }; - if (currentlyPlaying.url) activityState.buttons?.push({ url: currentlyPlaying.url, label: "Play on Tidal" }); - - // Pause indicator - if (playbackState === "NOT_PLAYING") { - if (storage.keepRpcOnPause === false) return _rpcClient.clearActivity(); - activityState.smallImageKey = "paused-icon"; - activityState.smallImageText = "Paused"; - } else if (currentlyPlaying.duration !== undefined && currentTime !== undefined) { - // Playback/Time - activityState.startTimestamp = Math.floor(Date.now() / 1000); - activityState.endTimestamp = Math.floor((Date.now() + (currentlyPlaying.duration - currentTime) * 1000) / 1000); - } - - // Album - if (currentlyPlaying.album !== undefined) { - activityState.largeImageKey = getMediaURLFromID(currentlyPlaying.album.cover); - activityState.largeImageText = formatLongString(currentlyPlaying.album.title); - } - - // Title/Artist - const artist = `by ${currentlyPlaying?.artist?.name ?? currentlyPlaying.artists?.[0]?.name ?? "Unknown Artist"}`; - const desc = `${currentlyPlaying.title} ${artist}`; - if (desc.length >= 32) { - activityState.details = formatLongString(currentlyPlaying.title); - activityState.state = formatLongString(artist); - } else { - activityState.details = formatLongString(desc); - } - - return _rpcClient.setActivity(activityState); + updateRPC(currentlyPlaying, playbackState, latestCurrentTime, storage.keepRpcOnPause); }; - -export async function onUnload() { - unloadTimeUpdate(); - await rpcClient.cleanp(); -} -updateRPC(); +onTimeUpdate(); storage.keepRpcOnPause ??= false; export function Settings() { diff --git a/plugins/DiscordRPC/src/updateRPC.native.ts b/plugins/DiscordRPC/src/updateRPC.native.ts new file mode 100644 index 0000000..488e981 --- /dev/null +++ b/plugins/DiscordRPC/src/updateRPC.native.ts @@ -0,0 +1,51 @@ +import { Presence } from "discord-rpc"; +import { DiscordRPC } from "./DiscordRPC.native"; +import { PlaybackState, TrackItem } from "neptune-types/tidal"; + +const rpcClient = new DiscordRPC("1130698654987067493"); + +const STR_MAX_LEN = 127; +const formatLongString = (s?: string) => { + if (s === undefined) return ""; + return s.length >= STR_MAX_LEN ? s.slice(0, STR_MAX_LEN - 3) + "..." : s; +}; +const getMediaURLFromID = (id?: string, path = "/1280x1280.jpg") => (id ? "https://resources.tidal.com/images/" + id.split("-").join("/") + path : undefined); + +export const updateRPC = async (currentlyPlaying: TrackItem, playbackState: PlaybackState, currentTime: number, keepRpcOnPause: boolean) => { + const _rpcClient = await rpcClient.ensureRPC().catch((err) => console.error("Failed to connect to DiscordRPC", err)); + if (_rpcClient === undefined) return; + + const activityState: Presence = { + buttons: [], + }; + if (currentlyPlaying.url) activityState.buttons?.push({ url: currentlyPlaying.url, label: "Play on Tidal" }); + + // Pause indicator + if (playbackState === "NOT_PLAYING") { + if (keepRpcOnPause === false) return _rpcClient.clearActivity(); + activityState.smallImageKey = "paused-icon"; + activityState.smallImageText = "Paused"; + } else if (currentlyPlaying.duration !== undefined && currentTime !== undefined) { + // Playback/Time + activityState.startTimestamp = Math.floor(Date.now() / 1000); + activityState.endTimestamp = Math.floor((Date.now() + (currentlyPlaying.duration - currentTime) * 1000) / 1000); + } + + // Album + if (currentlyPlaying.album !== undefined) { + activityState.largeImageKey = getMediaURLFromID(currentlyPlaying.album.cover); + activityState.largeImageText = formatLongString(currentlyPlaying.album.title); + } + + // Title/Artist + const artist = `by ${currentlyPlaying?.artist?.name ?? currentlyPlaying.artists?.[0]?.name ?? "Unknown Artist"}`; + const desc = `${currentlyPlaying.title} ${artist}`; + if (desc.length >= 32) { + activityState.details = formatLongString(currentlyPlaying.title); + activityState.state = formatLongString(artist); + } else { + activityState.details = formatLongString(desc); + } + + return _rpcClient.setActivity(activityState); +};