From 1a0c15e17fd79202fd4144077ae8a3a28d464c11 Mon Sep 17 00:00:00 2001 From: 3top1a <3top1a.official@gmail.com> Date: Wed, 16 Oct 2024 20:37:47 +0200 Subject: [PATCH 01/13] Maybe? Can't build --- package-lock.json | 33 +++++++++++--------------------- package.json | 5 ++--- src/scripts/discord.ts | 12 +++++++----- src/types/discord-rpc.d.ts | 39 ++++++++++++++++++++++++++++++++++++++ tsconfig.json | 1 + 5 files changed, 60 insertions(+), 30 deletions(-) create mode 100644 src/types/discord-rpc.d.ts diff --git a/package-lock.json b/package-lock.json index 67ba00ea0..b19fbb505 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@types/swagger-jsdoc": "^6.0.4", "axios": "^1.7.7", "cors": "^2.8.5", - "discord-rpc": "^4.0.1", + "discord-rpc": "github:sKiLdUsT/RPC#types", "electron-store": "^8.2.0", "express": "^4.21.1", "hotkeys-js": "^3.13.7", @@ -25,7 +25,6 @@ "devDependencies": { "@mastermindzh/prettier-config": "^1.0.0", "@types/cors": "^2.8.17", - "@types/discord-rpc": "^4.0.8", "@types/express": "^4.17.21", "@types/node": "^20.14.10", "@types/request": "^2.48.12", @@ -33,7 +32,7 @@ "@typescript-eslint/eslint-plugin": "^7.16.0", "@typescript-eslint/parser": "^7.15.0", "copyfiles": "^2.4.1", - "electron": "git+https://github.com/castlabs/electron-releases#v31.1.0+wvcus", + "electron": "git+https://github.com/castlabs/electron-releases#v33.1.0+wvcus", "electron-builder": "~24.9.4", "eslint": "^8.57.0", "js-yaml": "^4.1.0", @@ -1230,21 +1229,6 @@ "@types/ms": "*" } }, - "node_modules/@types/discord-rpc": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/discord-rpc/-/discord-rpc-4.0.8.tgz", - "integrity": "sha512-1tZf217Natkj+TziNXRRLwNmdm5GNa1bnrQr8VWowquo/Su5hMjdhobj8URxW1COMk2da28XCU1ahsYCAlxirA==", - "dev": true, - "dependencies": { - "@types/events": "*" - } - }, - "node_modules/@types/events": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.3.tgz", - "integrity": "sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g==", - "dev": true - }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", @@ -3382,8 +3366,8 @@ }, "node_modules/discord-rpc": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/discord-rpc/-/discord-rpc-4.0.1.tgz", - "integrity": "sha512-HOvHpbq5STRZJjQIBzwoKnQ0jHplbEWFWlPDwXXKm/bILh4nzjcg7mNqll0UY7RsjFoaXA7e/oYb/4lvpda2zA==", + "resolved": "git+ssh://git@github.com/sKiLdUsT/RPC.git#1c5b6842fa586a1b7b339a50fa5ec1c4cf6c8867", + "license": "MIT", "dependencies": { "node-fetch": "^2.6.1", "ws": "^7.3.1" @@ -6152,6 +6136,7 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -8532,7 +8517,8 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" }, "node_modules/truncate-utf8-bytes": { "version": "1.0.2", @@ -8819,12 +8805,14 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -8903,6 +8891,7 @@ "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", "engines": { "node": ">=8.3.0" }, diff --git a/package.json b/package.json index 2aa8b87cd..a79097b7e 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@types/swagger-jsdoc": "^6.0.4", "axios": "^1.7.7", "cors": "^2.8.5", - "discord-rpc": "^4.0.1", + "discord-rpc": "github:sKiLdUsT/RPC#types", "electron-store": "^8.2.0", "express": "^4.21.1", "hotkeys-js": "^3.13.7", @@ -56,7 +56,6 @@ "devDependencies": { "@mastermindzh/prettier-config": "^1.0.0", "@types/cors": "^2.8.17", - "@types/discord-rpc": "^4.0.8", "@types/express": "^4.17.21", "@types/node": "^20.14.10", "@types/request": "^2.48.12", @@ -64,7 +63,7 @@ "@typescript-eslint/eslint-plugin": "^7.16.0", "@typescript-eslint/parser": "^7.15.0", "copyfiles": "^2.4.1", - "electron": "git+https://github.com/castlabs/electron-releases#v31.1.0+wvcus", + "electron": "git+https://github.com/castlabs/electron-releases#v32.0.0+wvcus", "electron-builder": "~24.9.4", "eslint": "^8.57.0", "js-yaml": "^4.1.0", diff --git a/src/scripts/discord.ts b/src/scripts/discord.ts index 4a162a6dc..6fc06e2e1 100644 --- a/src/scripts/discord.ts +++ b/src/scripts/discord.ts @@ -1,4 +1,4 @@ -import { Client, Presence } from "discord-rpc"; +import * as DRPC from "discord-rpc"; import { app, ipcMain } from "electron"; import { globalEvents } from "../constants/globalEvents"; import { settings } from "../constants/settings"; @@ -10,7 +10,7 @@ import { settingsStore } from "./settings"; const clientId = "833617820704440341"; -export let rpc: Client; +export let rpc: DRPC.Client; const observer = () => { if (rpc) { @@ -33,8 +33,10 @@ const updateActivity = () => { } }; -const getActivity = (): Presence => { - const presence: Presence = { ...defaultPresence }; +const getActivity = (): DRPC.Presence => { + const presence: DRPC.Presence = { ...defaultPresence }; + + presence.type = DRPC.ActivityTypes.LISTENING if (mediaInfo.status === MediaStatus.paused) { presence.details = @@ -110,7 +112,7 @@ const getActivity = (): Presence => { * Set up the discord rpc and listen on globalEvents.updateInfo */ export const initRPC = () => { - rpc = new Client({ transport: "ipc" }); + rpc = new DRPC.Client({ transport: "ipc" }); rpc.login({ clientId }).then( () => { rpc.on("ready", () => { diff --git a/src/types/discord-rpc.d.ts b/src/types/discord-rpc.d.ts new file mode 100644 index 000000000..e66c00c9c --- /dev/null +++ b/src/types/discord-rpc.d.ts @@ -0,0 +1,39 @@ +declare module 'discord-rpc' { + export class Client { + constructor(options: { transport: 'ipc' }); + on(event: string, listener: (...args: any[]) => void): this; + login(options: { clientId: string }): Promise; + setActivity(presence: Presence): Promise; + clearActivity(): Promise; + destroy(): Promise; + } + + export interface Presence { + state?: string; + details?: string; + startTimestamp?: number; + endTimestamp?: number; + largeImageKey?: string; + largeImageText?: string; + smallImageKey?: string; + smallImageText?: string; + partyId?: string; + partySize?: number; + partyMax?: number; + matchSecret?: string; + spectateSecret?: string; + joinSecret?: string; + instance?: boolean; + type?: number; + buttons?: Array<{ label: string; url: string }>; + } + + export const ActivityTypes: { + PLAYING: 0, + STREAMING: 1, + LISTENING: 2, + WATCHING: 3, + CUSTOM: 4, + COMPETING: 5 + }; +} diff --git a/tsconfig.json b/tsconfig.json index 89364cb32..5440346ab 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "resolveJsonModule": true, "esModuleInterop": true, "baseUrl": ".", + "allowSyntheticDefaultImports": true, "paths": { "*": ["node_modules/*"] } From b1830f56842c32d6ef4e1ac334e12ecac1da4271 Mon Sep 17 00:00:00 2001 From: 3top1a <3top1a.official@gmail.com> Date: Thu, 17 Oct 2024 20:16:22 +0200 Subject: [PATCH 02/13] Fixed impl --- package-lock.json | 2 +- src/scripts/discord.ts | 20 ++++++++++++-------- src/scripts/settings.ts | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index b19fbb505..64263a787 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "@typescript-eslint/eslint-plugin": "^7.16.0", "@typescript-eslint/parser": "^7.15.0", "copyfiles": "^2.4.1", - "electron": "git+https://github.com/castlabs/electron-releases#v33.1.0+wvcus", + "electron": "git+https://github.com/castlabs/electron-releases#v32.0.0+wvcus", "electron-builder": "~24.9.4", "eslint": "^8.57.0", "js-yaml": "^4.1.0", diff --git a/src/scripts/discord.ts b/src/scripts/discord.ts index 6fc06e2e1..a61c40b0a 100644 --- a/src/scripts/discord.ts +++ b/src/scripts/discord.ts @@ -12,6 +12,8 @@ const clientId = "833617820704440341"; export let rpc: DRPC.Client; +const ACTIVITY_LISTENING = 2; + const observer = () => { if (rpc) { updateActivity(); @@ -20,7 +22,7 @@ const observer = () => { const defaultPresence = { largeImageKey: "tidal-hifi-icon", - largeImageText: `TIDAL Hi-Fi ${app.getVersion()}`, + largeImageText: `Tidal`, instance: false, }; @@ -36,7 +38,7 @@ const updateActivity = () => { const getActivity = (): DRPC.Presence => { const presence: DRPC.Presence = { ...defaultPresence }; - presence.type = DRPC.ActivityTypes.LISTENING + presence.type = ACTIVITY_LISTENING; if (mediaInfo.status === MediaStatus.paused) { presence.details = @@ -52,13 +54,14 @@ const getActivity = (): DRPC.Presence => { settingsStore.get(settings.discord.usingText) ?? "Playing media on TIDAL"; } } + return presence; function getFromStore() { const includeTimestamps = settingsStore.get(settings.discord.includeTimestamps) ?? true; const detailsPrefix = - settingsStore.get(settings.discord.detailsPrefix) ?? "Listening to "; + settingsStore.get(settings.discord.detailsPrefix) ?? ""; const buttonText = settingsStore.get(settings.discord.buttonText) ?? "Play on TIDAL"; @@ -100,12 +103,13 @@ const getActivity = (): DRPC.Presence => { const currentSeconds = convertDurationToSeconds(mediaInfo.current); const durationSeconds = convertDurationToSeconds(mediaInfo.duration); const date = new Date(); - const now = (date.getTime() / 1000) | 0; - const remaining = date.setSeconds(date.getSeconds() + (durationSeconds - currentSeconds)); - presence.startTimestamp = now; - presence.endTimestamp = remaining; + const now = Math.floor(date.getTime() / 1000); + const startTimestamp = now - currentSeconds; + const endTimestamp = startTimestamp + durationSeconds; + presence.startTimestamp = startTimestamp; + presence.endTimestamp = endTimestamp; } - } + } }; /** diff --git a/src/scripts/settings.ts b/src/scripts/settings.ts index 4e5323abc..8e7b2960f 100644 --- a/src/scripts/settings.ts +++ b/src/scripts/settings.ts @@ -47,7 +47,7 @@ export const settingsStore = new Store({ idleText: "Browsing Tidal", usingText: "Playing media on TIDAL", includeTimestamps: true, - detailsPrefix: "Listening to ", + detailsPrefix: "", buttonText: "Play on Tidal", }, ListenBrainz: { From 3dc42eceb067f56de7a645af7ae2526ac84f8f43 Mon Sep 17 00:00:00 2001 From: 3top1a <3top1a.official@gmail.com> Date: Thu, 17 Oct 2024 20:47:40 +0200 Subject: [PATCH 03/13] Reverted bad changes --- src/scripts/discord.ts | 4 ++-- src/scripts/settings.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scripts/discord.ts b/src/scripts/discord.ts index a61c40b0a..d092e24bf 100644 --- a/src/scripts/discord.ts +++ b/src/scripts/discord.ts @@ -22,7 +22,7 @@ const observer = () => { const defaultPresence = { largeImageKey: "tidal-hifi-icon", - largeImageText: `Tidal`, + largeImageText: `TIDAL Hi-Fi ${app.getVersion()}`, instance: false, }; @@ -61,7 +61,7 @@ const getActivity = (): DRPC.Presence => { const includeTimestamps = settingsStore.get(settings.discord.includeTimestamps) ?? true; const detailsPrefix = - settingsStore.get(settings.discord.detailsPrefix) ?? ""; + settingsStore.get(settings.discord.detailsPrefix) ?? "Listening to "; const buttonText = settingsStore.get(settings.discord.buttonText) ?? "Play on TIDAL"; diff --git a/src/scripts/settings.ts b/src/scripts/settings.ts index 8e7b2960f..4e5323abc 100644 --- a/src/scripts/settings.ts +++ b/src/scripts/settings.ts @@ -47,7 +47,7 @@ export const settingsStore = new Store({ idleText: "Browsing Tidal", usingText: "Playing media on TIDAL", includeTimestamps: true, - detailsPrefix: "", + detailsPrefix: "Listening to ", buttonText: "Play on Tidal", }, ListenBrainz: { From 21edcd6ad5e4d88b4a54bf653e5275b8ce97c55d Mon Sep 17 00:00:00 2001 From: 3top1a <3top1a.official@gmail.com> Date: Thu, 17 Oct 2024 20:51:23 +0200 Subject: [PATCH 04/13] reverted more ugly/unnecessary changes --- package-lock.json | 2 +- package.json | 2 +- src/scripts/discord.ts | 2 +- tsconfig.json | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 64263a787..85d174f37 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "@typescript-eslint/eslint-plugin": "^7.16.0", "@typescript-eslint/parser": "^7.15.0", "copyfiles": "^2.4.1", - "electron": "git+https://github.com/castlabs/electron-releases#v32.0.0+wvcus", + "electron": "git+https://github.com/castlabs/electron-releases#v31.1.0+wvcus", "electron-builder": "~24.9.4", "eslint": "^8.57.0", "js-yaml": "^4.1.0", diff --git a/package.json b/package.json index a79097b7e..9bd83dbec 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@typescript-eslint/eslint-plugin": "^7.16.0", "@typescript-eslint/parser": "^7.15.0", "copyfiles": "^2.4.1", - "electron": "git+https://github.com/castlabs/electron-releases#v32.0.0+wvcus", + "electron": "git+https://github.com/castlabs/electron-releases#v31.1.0+wvcus", "electron-builder": "~24.9.4", "eslint": "^8.57.0", "js-yaml": "^4.1.0", diff --git a/src/scripts/discord.ts b/src/scripts/discord.ts index d092e24bf..c9c058e37 100644 --- a/src/scripts/discord.ts +++ b/src/scripts/discord.ts @@ -109,7 +109,7 @@ const getActivity = (): DRPC.Presence => { presence.startTimestamp = startTimestamp; presence.endTimestamp = endTimestamp; } - } + } }; /** diff --git a/tsconfig.json b/tsconfig.json index 5440346ab..89364cb32 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,6 @@ "resolveJsonModule": true, "esModuleInterop": true, "baseUrl": ".", - "allowSyntheticDefaultImports": true, "paths": { "*": ["node_modules/*"] } From cb8667bd41c1f4c0068b82012ecfaf3122941bc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dar=C3=ADo=20Marmie?= Date: Mon, 21 Oct 2024 18:14:28 -0300 Subject: [PATCH 05/13] feat: Added ability to keep a static window title. --- src/constants/settings.ts | 1 + src/pages/settings/preload.ts | 4 ++++ src/pages/settings/settings.html | 10 ++++++++++ src/preload.ts | 4 +++- src/scripts/settings.ts | 9 +++++---- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/constants/settings.ts b/src/constants/settings.ts index 78fce85b2..31591179f 100644 --- a/src/constants/settings.ts +++ b/src/constants/settings.ts @@ -57,6 +57,7 @@ export const settings = { skippedArtists: "skippedArtists", theme: "theme", trayIcon: "trayIcon", + staticWindowTitle: "staticWindowTitle", updateFrequency: "updateFrequency", windowBounds: { root: "windowBounds", diff --git a/src/pages/settings/preload.ts b/src/pages/settings/preload.ts index 498988ba1..53286e1b5 100644 --- a/src/pages/settings/preload.ts +++ b/src/pages/settings/preload.ts @@ -48,6 +48,7 @@ let adBlock: HTMLInputElement, skippedArtists: HTMLInputElement, theme: HTMLSelectElement, trayIcon: HTMLInputElement, + staticWindowTitle: HTMLInputElement, updateFrequency: HTMLInputElement, enableListenBrainz: HTMLInputElement, ListenBrainzAPI: HTMLInputElement, @@ -143,6 +144,7 @@ function refreshSettings() { theme.value = settingsStore.get(settings.theme); skippedArtists.value = settingsStore.get(settings.skippedArtists).join("\n"); trayIcon.checked = settingsStore.get(settings.trayIcon); + staticWindowTitle.checked = settingsStore.get(settings.staticWindowTitle); updateFrequency.value = settingsStore.get(settings.updateFrequency); enableListenBrainz.checked = settingsStore.get(settings.ListenBrainz.enabled); ListenBrainzAPI.value = settingsStore.get(settings.ListenBrainz.api); @@ -259,6 +261,7 @@ window.addEventListener("DOMContentLoaded", () => { port = get("port"); theme = get("themesList"); trayIcon = get("trayIcon"); + staticWindowTitle = get("staticWindowTitle"); skipArtists = get("skipArtists"); skippedArtists = get("skippedArtists"); singleInstance = get("singleInstance"); @@ -298,6 +301,7 @@ window.addEventListener("DOMContentLoaded", () => { addInputListener(singleInstance, settings.singleInstance); addSelectListener(theme, settings.theme); addInputListener(trayIcon, settings.trayIcon); + addInputListener(staticWindowTitle, settings.staticWindowTitle); addInputListener(updateFrequency, settings.updateFrequency); addInputListener( enableListenBrainz, diff --git a/src/pages/settings/settings.html b/src/pages/settings/settings.html index 30e839bdc..f0b0dfb79 100644 --- a/src/pages/settings/settings.html +++ b/src/pages/settings/settings.html @@ -106,6 +106,16 @@

Tray icon

+
+
+

Static Window Title

+

Makes the window title "TIDAL Hi-Fi" instead of changing to the currently playing song.

+
+ +

Minimize on Close

diff --git a/src/preload.ts b/src/preload.ts index 814044ba9..bfd472d09 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -550,6 +550,7 @@ setInterval(function () { const artistsArray = elements.getArtistsArray(); const artistsString = elements.getArtistsString(artistsArray); const songDashArtistTitle = `${title} - ${artistsString}`; + const staticTitle = "TIDAL Hi-Fi" const titleOrArtistsChanged = currentSong !== songDashArtistTitle; const current = elements.getText("current"); const currentStatus = getCurrentlyPlayingStatus(); @@ -594,7 +595,8 @@ setInterval(function () { }; // update title, url and play info with new info - setTitle(songDashArtistTitle); + if(settingsStore.get(settings.staticWindowTitle)) setTitle(staticTitle) + else setTitle(songDashArtistTitle); getTrackURL(); currentSong = songDashArtistTitle; currentPlayStatus = currentStatus; diff --git a/src/scripts/settings.ts b/src/scripts/settings.ts index 4e5323abc..7416b1f70 100644 --- a/src/scripts/settings.ts +++ b/src/scripts/settings.ts @@ -71,6 +71,7 @@ export const settingsStore = new Store({ skippedArtists: [""], theme: "none", trayIcon: true, + staticWindowTitle: false, updateFrequency: 500, windowBounds: { width: 800, height: 600 }, }, @@ -127,7 +128,7 @@ const settingsModule = { settingsWindow, }; -export const createSettingsWindow = function () { +export const createSettingsWindow = function() { settingsWindow = new BrowserWindow({ width: 650, height: 700, @@ -159,7 +160,7 @@ export const createSettingsWindow = function () { settingsModule.settingsWindow = settingsWindow; }; -export const showSettingsWindow = function (tab = "general") { +export const showSettingsWindow = function(tab = "general") { if (!settingsWindow) { console.log("Settings window is not initialized. Attempting to create it."); createSettingsWindow(); @@ -170,11 +171,11 @@ export const showSettingsWindow = function (tab = "general") { settingsWindow.webContents.send("refreshData"); settingsWindow.show(); }; -export const hideSettingsWindow = function () { +export const hideSettingsWindow = function() { settingsWindow.hide(); }; -export const closeSettingsWindow = function () { +export const closeSettingsWindow = function() { settingsWindow = null; }; From f832bd27122f7336536a43faf0a88db3ea2ea133 Mon Sep 17 00:00:00 2001 From: 3top1a <3top1a.official@gmail.com> Date: Tue, 22 Oct 2024 17:20:06 +0200 Subject: [PATCH 06/13] replaced discord rpc library --- package-lock.json | 233 +++++++++++++++++++++++-------------- package.json | 2 +- src/scripts/discord.ts | 24 ++-- src/types/discord-rpc.d.ts | 39 ------- 4 files changed, 159 insertions(+), 139 deletions(-) delete mode 100644 src/types/discord-rpc.d.ts diff --git a/package-lock.json b/package-lock.json index 85d174f37..039b3fda2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,9 @@ "dependencies": { "@electron/remote": "^2.1.2", "@types/swagger-jsdoc": "^6.0.4", + "@xhayper/discord-rpc": "^1.2.0", "axios": "^1.7.7", "cors": "^2.8.5", - "discord-rpc": "github:sKiLdUsT/RPC#types", "electron-store": "^8.2.0", "express": "^4.21.1", "hotkeys-js": "^3.13.7", @@ -401,6 +401,59 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/@discordjs/collection": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz", + "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/rest": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.4.0.tgz", + "integrity": "sha512-Xb2irDqNcq+O8F0/k/NaDp7+t091p+acb51iA4bCKfIn+WFWd6HrNvcsSbMMxIR9NjcMZS6NReTKygqiQN+ntw==", + "license": "Apache-2.0", + "dependencies": { + "@discordjs/collection": "^2.1.1", + "@discordjs/util": "^1.1.1", + "@sapphire/async-queue": "^1.5.3", + "@sapphire/snowflake": "^3.5.3", + "@vladfrangu/async_event_emitter": "^2.4.6", + "discord-api-types": "0.37.97", + "magic-bytes.js": "^1.10.0", + "tslib": "^2.6.3", + "undici": "6.19.8" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/rest/node_modules/discord-api-types": { + "version": "0.37.97", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.97.tgz", + "integrity": "sha512-No1BXPcVkyVD4ZVmbNgDKaBoqgeQ+FJpzZ8wqHkfmBnTZig1FcH3iPPersiK1TUIAzgClh2IvOuVUYfcWLQAOA==", + "license": "MIT" + }, + "node_modules/@discordjs/util": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.1.1.tgz", + "integrity": "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, "node_modules/@dual-bundle/import-meta-resolve": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", @@ -1114,6 +1167,26 @@ "node": ">=14" } }, + "node_modules/@sapphire/async-queue": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.3.tgz", + "integrity": "sha512-x7zadcfJGxFka1Q3f8gCts1F0xMwCKbZweM85xECGI0hBTeIZJGGCrHgLggihBoprlQ/hBmDR5LKfIPqnmHM3w==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@sapphire/snowflake": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz", + "integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -1802,6 +1875,52 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@vladfrangu/async_event_emitter": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.6.tgz", + "integrity": "sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@xhayper/discord-rpc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xhayper/discord-rpc/-/discord-rpc-1.2.0.tgz", + "integrity": "sha512-cKjs9TKzN/7JoozijjszQjUEK1qnLHpEvcJQ2OGFBZjymUzIOH7l14KUu7TQtaIEk0Aw9Bx2w7TfQ0O6tp5mCw==", + "license": "ISC", + "dependencies": { + "@discordjs/rest": "^2.3.0", + "@vladfrangu/async_event_emitter": "^2.4.4", + "discord-api-types": "^0.37.93", + "ws": "^8.18.0" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@xhayper/discord-rpc/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", @@ -3364,17 +3483,11 @@ "node": ">=8" } }, - "node_modules/discord-rpc": { - "version": "4.0.1", - "resolved": "git+ssh://git@github.com/sKiLdUsT/RPC.git#1c5b6842fa586a1b7b339a50fa5ec1c4cf6c8867", - "license": "MIT", - "dependencies": { - "node-fetch": "^2.6.1", - "ws": "^7.3.1" - }, - "optionalDependencies": { - "register-scheme": "github:devsnek/node-register-scheme" - } + "node_modules/discord-api-types": { + "version": "0.37.103", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.103.tgz", + "integrity": "sha512-r+qitxXKe2l6KFw5odPdZSSqdEou+7eNC7BfbZ7mny5Me/K06wCTeKUMVeH/YsI9+4QQudskeQ307kr/7ppQ1A==", + "license": "MIT" }, "node_modules/dmg-builder": { "version": "24.9.4", @@ -5758,6 +5871,12 @@ "node": ">=10" } }, + "node_modules/magic-bytes.js": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz", + "integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==", + "license": "MIT" + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -6124,6 +6243,7 @@ "version": "1.7.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, "optional": true }, "node_modules/node-cleanup": { @@ -6132,26 +6252,6 @@ "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==", "dev": true }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/nodemon": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", @@ -7119,17 +7219,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/register-scheme": { - "version": "0.0.2", - "resolved": "git+ssh://git@github.com/devsnek/node-register-scheme.git#e7cc9a63a1f512565da44cb57316d9fb10750e17", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bindings": "^1.3.0", - "node-addon-api": "^1.3.0" - } - }, "node_modules/remarkable": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-1.7.4.tgz", @@ -8514,12 +8603,6 @@ "node": ">=0.8" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, "node_modules/truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", @@ -8609,6 +8692,12 @@ "typescript": "*" } }, + "node_modules/tslib": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "license": "0BSD" + }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -8686,6 +8775,15 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "node_modules/undici": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", + "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -8802,22 +8900,6 @@ "license": "MIT", "optional": true }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -8887,27 +8969,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/xml2js": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", diff --git a/package.json b/package.json index 9bd83dbec..0ca96ffed 100644 --- a/package.json +++ b/package.json @@ -42,9 +42,9 @@ "dependencies": { "@electron/remote": "^2.1.2", "@types/swagger-jsdoc": "^6.0.4", + "@xhayper/discord-rpc": "^1.2.0", "axios": "^1.7.7", "cors": "^2.8.5", - "discord-rpc": "github:sKiLdUsT/RPC#types", "electron-store": "^8.2.0", "express": "^4.21.1", "hotkeys-js": "^3.13.7", diff --git a/src/scripts/discord.ts b/src/scripts/discord.ts index c9c058e37..c89dddec2 100644 --- a/src/scripts/discord.ts +++ b/src/scripts/discord.ts @@ -1,4 +1,4 @@ -import * as DRPC from "discord-rpc"; +import { Client, SetActivity } from "@xhayper/discord-rpc"; import { app, ipcMain } from "electron"; import { globalEvents } from "../constants/globalEvents"; import { settings } from "../constants/settings"; @@ -10,7 +10,7 @@ import { settingsStore } from "./settings"; const clientId = "833617820704440341"; -export let rpc: DRPC.Client; +export let rpc: Client; const ACTIVITY_LISTENING = 2; @@ -29,14 +29,14 @@ const defaultPresence = { const updateActivity = () => { const showIdle = settingsStore.get(settings.discord.showIdle) ?? true; if (mediaInfo.status === MediaStatus.paused && !showIdle) { - rpc.clearActivity(); + rpc.user?.clearActivity(); } else { - rpc.setActivity(getActivity()); + rpc.user?.setActivity(getActivity()); } }; -const getActivity = (): DRPC.Presence => { - const presence: DRPC.Presence = { ...defaultPresence }; +const getActivity = (): SetActivity => { + const presence: SetActivity = { ...defaultPresence }; presence.type = ACTIVITY_LISTENING; @@ -104,10 +104,8 @@ const getActivity = (): DRPC.Presence => { const durationSeconds = convertDurationToSeconds(mediaInfo.duration); const date = new Date(); const now = Math.floor(date.getTime() / 1000); - const startTimestamp = now - currentSeconds; - const endTimestamp = startTimestamp + durationSeconds; - presence.startTimestamp = startTimestamp; - presence.endTimestamp = endTimestamp; + presence.startTimestamp = now - currentSeconds; + presence.endTimestamp = presence.startTimestamp + durationSeconds; } } }; @@ -116,8 +114,8 @@ const getActivity = (): DRPC.Presence => { * Set up the discord rpc and listen on globalEvents.updateInfo */ export const initRPC = () => { - rpc = new DRPC.Client({ transport: "ipc" }); - rpc.login({ clientId }).then( + rpc = new Client({ transport: {type: "ipc"}, clientId }); + rpc.login().then( () => { rpc.on("ready", () => { updateActivity(); @@ -139,7 +137,7 @@ export const initRPC = () => { */ export const unRPC = () => { if (rpc) { - rpc.clearActivity(); + rpc.user?.clearActivity(); rpc.destroy(); rpc = null; ipcMain.removeListener(globalEvents.updateInfo, observer); diff --git a/src/types/discord-rpc.d.ts b/src/types/discord-rpc.d.ts deleted file mode 100644 index e66c00c9c..000000000 --- a/src/types/discord-rpc.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -declare module 'discord-rpc' { - export class Client { - constructor(options: { transport: 'ipc' }); - on(event: string, listener: (...args: any[]) => void): this; - login(options: { clientId: string }): Promise; - setActivity(presence: Presence): Promise; - clearActivity(): Promise; - destroy(): Promise; - } - - export interface Presence { - state?: string; - details?: string; - startTimestamp?: number; - endTimestamp?: number; - largeImageKey?: string; - largeImageText?: string; - smallImageKey?: string; - smallImageText?: string; - partyId?: string; - partySize?: number; - partyMax?: number; - matchSecret?: string; - spectateSecret?: string; - joinSecret?: string; - instance?: boolean; - type?: number; - buttons?: Array<{ label: string; url: string }>; - } - - export const ActivityTypes: { - PLAYING: 0, - STREAMING: 1, - LISTENING: 2, - WATCHING: 3, - CUSTOM: 4, - COMPETING: 5 - }; -} From f96cf2e8da04bef428258de1cb23d4ad0619d5ac Mon Sep 17 00:00:00 2001 From: 3top1a <3top1a.official@gmail.com> Date: Tue, 22 Oct 2024 22:27:29 +0200 Subject: [PATCH 07/13] Removed redundant RPC settings --- src/constants/settings.ts | 3 -- src/pages/settings/preload.ts | 35 +--------------- src/pages/settings/settings.html | 68 ++------------------------------ src/scripts/discord.ts | 57 ++++++-------------------- src/scripts/settings.ts | 16 +------- 5 files changed, 17 insertions(+), 162 deletions(-) diff --git a/src/constants/settings.ts b/src/constants/settings.ts index 78fce85b2..716441daf 100644 --- a/src/constants/settings.ts +++ b/src/constants/settings.ts @@ -27,10 +27,7 @@ export const settings = { enableDiscord: "enableDiscord", discord: { detailsPrefix: "discord.detailsPrefix", - buttonText: "discord.buttonText", includeTimestamps: "discord.includeTimestamps", - showSong: "discord.showSong", - showIdle: "discord.showIdle", idleText: "discord.idleText", usingText: "discord.usingText", }, diff --git a/src/pages/settings/preload.ts b/src/pages/settings/preload.ts index 498988ba1..0a82cf060 100644 --- a/src/pages/settings/preload.ts +++ b/src/pages/settings/preload.ts @@ -20,11 +20,6 @@ const switchesWithSettings = { classToHide: "discord_options", settingsKey: settings.enableDiscord, }, - discord_show_song: { - switch: "discord_show_song", - classToHide: "discord_show_song_options", - settingsKey: settings.discord.showSong, - }, }; let adBlock: HTMLInputElement, @@ -54,13 +49,7 @@ let adBlock: HTMLInputElement, ListenBrainzToken: HTMLInputElement, listenbrainz_delay: HTMLInputElement, enableWaylandSupport: HTMLInputElement, - discord_details_prefix: HTMLInputElement, - discord_include_timestamps: HTMLInputElement, - discord_button_text: HTMLInputElement, - discord_show_song: HTMLInputElement, - discord_show_idle: HTMLInputElement, - discord_idle_text: HTMLInputElement, - discord_using_text: HTMLInputElement; + discord_details_prefix: HTMLInputElement addCustomCss(app); @@ -149,12 +138,6 @@ function refreshSettings() { ListenBrainzToken.value = settingsStore.get(settings.ListenBrainz.token); listenbrainz_delay.value = settingsStore.get(settings.ListenBrainz.delay); discord_details_prefix.value = settingsStore.get(settings.discord.detailsPrefix); - discord_include_timestamps.checked = settingsStore.get(settings.discord.includeTimestamps); - discord_button_text.value = settingsStore.get(settings.discord.buttonText); - discord_show_song.checked = settingsStore.get(settings.discord.showSong); - discord_show_idle.checked = settingsStore.get(settings.discord.showIdle); - discord_idle_text.value = settingsStore.get(settings.discord.idleText); - discord_using_text.value = settingsStore.get(settings.discord.usingText); // set state of all switches with additional settings Object.values(switchesWithSettings).forEach((settingSwitch) => { @@ -267,13 +250,7 @@ window.addEventListener("DOMContentLoaded", () => { ListenBrainzAPI = get("ListenBrainzAPI"); ListenBrainzToken = get("ListenBrainzToken"); discord_details_prefix = get("discord_details_prefix"); - discord_include_timestamps = get("discord_include_timestamps"); listenbrainz_delay = get("listenbrainz_delay"); - discord_button_text = get("discord_button_text"); - discord_show_song = get("discord_show_song"); - discord_show_idle = get("discord_show_idle"); - discord_using_text = get("discord_using_text"); - discord_idle_text = get("discord_idle_text"); refreshSettings(); addInputListener(adBlock, settings.adBlock); @@ -308,14 +285,4 @@ window.addEventListener("DOMContentLoaded", () => { addInputListener(ListenBrainzToken, settings.ListenBrainz.token); addInputListener(listenbrainz_delay, settings.ListenBrainz.delay); addInputListener(discord_details_prefix, settings.discord.detailsPrefix); - addInputListener(discord_include_timestamps, settings.discord.includeTimestamps); - addInputListener(discord_button_text, settings.discord.buttonText); - addInputListener( - discord_show_song, - settings.discord.showSong, - switchesWithSettings.discord_show_song - ); - addInputListener(discord_show_idle, settings.discord.showIdle); - addInputListener(discord_idle_text, settings.discord.idleText); - addInputListener(discord_using_text, settings.discord.usingText); }); diff --git a/src/pages/settings/settings.html b/src/pages/settings/settings.html index 30e839bdc..bae3aa231 100644 --- a/src/pages/settings/settings.html +++ b/src/pages/settings/settings.html @@ -226,75 +226,13 @@

Discord RPC

- -
-
-

Show Idle Text

-

Should the idle text be shown when idle?

-
- -
- -
-
-

Idle Text

-

The text displayed on Discord's rich presence while idling in the app.

- -
-
- -
-
-

Using Tidal Text

-

The text displayed on Discord's rich presence while "showSong" is turned off

- -
-
-
-

Show media

-

Show the current media in the Discord client

-
- -
- - -
diff --git a/src/scripts/discord.ts b/src/scripts/discord.ts index c89dddec2..10c25d3fb 100644 --- a/src/scripts/discord.ts +++ b/src/scripts/discord.ts @@ -21,14 +21,14 @@ const observer = () => { }; const defaultPresence = { - largeImageKey: "tidal-hifi-icon", - largeImageText: `TIDAL Hi-Fi ${app.getVersion()}`, + smallImageKey: "tidal-hifi-icon", + smallImageText: `TIDAL Hi-Fi ${app.getVersion()}`, instance: false, + type: ACTIVITY_LISTENING }; const updateActivity = () => { - const showIdle = settingsStore.get(settings.discord.showIdle) ?? true; - if (mediaInfo.status === MediaStatus.paused && !showIdle) { + if (mediaInfo.status === MediaStatus.paused) { rpc.user?.clearActivity(); } else { rpc.user?.setActivity(getActivity()); @@ -38,36 +38,11 @@ const updateActivity = () => { const getActivity = (): SetActivity => { const presence: SetActivity = { ...defaultPresence }; - presence.type = ACTIVITY_LISTENING; - - if (mediaInfo.status === MediaStatus.paused) { - presence.details = - settingsStore.get(settings.discord.idleText) ?? "Browsing Tidal"; - } else { - const showSong = settingsStore.get(settings.discord.showSong) ?? false; - if (showSong) { - const { includeTimestamps, detailsPrefix, buttonText } = getFromStore(); - includeTimeStamps(includeTimestamps); - setPresenceFromMediaInfo(detailsPrefix, buttonText); - } else { - presence.details = - settingsStore.get(settings.discord.usingText) ?? "Playing media on TIDAL"; - } - } + includeTimeStamps(); + setPresenceFromMediaInfo(); return presence; - function getFromStore() { - const includeTimestamps = - settingsStore.get(settings.discord.includeTimestamps) ?? true; - const detailsPrefix = - settingsStore.get(settings.discord.detailsPrefix) ?? "Listening to "; - const buttonText = - settingsStore.get(settings.discord.buttonText) ?? "Play on TIDAL"; - - return { includeTimestamps, detailsPrefix, buttonText }; - } - /** * Pad a string using spaces to at least 2 characters * @param input string to pad with 2 characters @@ -77,36 +52,28 @@ const getActivity = (): SetActivity => { return input.padEnd(2, " "); } - function setPresenceFromMediaInfo(detailsPrefix: string, buttonText: string) { + function setPresenceFromMediaInfo() { // discord requires a minimum of 2 characters const title = pad(mediaInfo.title); const album = pad(mediaInfo.album); const artists = pad(mediaInfo.artists); + const detailsPrefix = settingsStore.get(settings.discord.detailsPrefix) ?? "Listening to "; + presence.details = `${detailsPrefix}${title}`; + presence.state = artists ? artists : "unknown artist(s)"; if (mediaInfo.url) { - presence.details = `${detailsPrefix}${title}`; - presence.state = artists ? artists : "unknown artist(s)"; presence.largeImageKey = mediaInfo.image; - if (album) { - presence.largeImageText = album; - } - - presence.buttons = [{ label: buttonText, url: mediaInfo.url }]; - } else { - presence.details = `Watching ${title}`; - presence.state = artists; + if (album) presence.largeImageText = album; } } - function includeTimeStamps(includeTimestamps: boolean) { - if (includeTimestamps) { + function includeTimeStamps() { const currentSeconds = convertDurationToSeconds(mediaInfo.current); const durationSeconds = convertDurationToSeconds(mediaInfo.duration); const date = new Date(); const now = Math.floor(date.getTime() / 1000); presence.startTimestamp = now - currentSeconds; presence.endTimestamp = presence.startTimestamp + durationSeconds; - } } }; diff --git a/src/scripts/settings.ts b/src/scripts/settings.ts index 4e5323abc..a4742b8f1 100644 --- a/src/scripts/settings.ts +++ b/src/scripts/settings.ts @@ -42,13 +42,10 @@ export const settingsStore = new Store({ enableCustomHotkeys: false, enableDiscord: false, discord: { - showSong: true, - showIdle: true, idleText: "Browsing Tidal", usingText: "Playing media on TIDAL", includeTimestamps: true, detailsPrefix: "Listening to ", - buttonText: "Play on Tidal", }, ListenBrainz: { enabled: false, @@ -89,16 +86,8 @@ export const settingsStore = new Store({ migrationStore.get(settings.ListenBrainz.delay) ?? 5000 ); }, - "5.8.0": (migrationStore) => { - console.log("running migrations for 5.8.0"); - migrationStore.set( - settings.discord.includeTimestamps, - migrationStore.get(settings.discord.includeTimestamps) ?? true - ); - }, "5.9.0": (migrationStore) => { buildMigration("5.9.0", migrationStore, [ - { key: settings.discord.showSong, value: "true" }, { key: settings.discord.idleText, value: "Browsing Tidal" }, { key: settings.discord.usingText, @@ -115,10 +104,7 @@ export const settingsStore = new Store({ buildMigration("5.15.0", migrationStore, [ { key: settings.advanced.tidalUrl, value: "https://listen.tidal.com" }, ]); - }, - "5.16.0": (migrationStore) => { - buildMigration("5.16.0", migrationStore, [{ key: settings.discord.showIdle, value: "true" }]); - }, + } }, }); From 6be577400143f4557d23daaeac0d214ad412ae79 Mon Sep 17 00:00:00 2001 From: 3top1a <3top1a.official@gmail.com> Date: Tue, 22 Oct 2024 22:29:56 +0200 Subject: [PATCH 08/13] Added RPC connection retrying --- src/scripts/discord.ts | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/scripts/discord.ts b/src/scripts/discord.ts index 10c25d3fb..3f8dff52f 100644 --- a/src/scripts/discord.ts +++ b/src/scripts/discord.ts @@ -13,6 +13,8 @@ const clientId = "833617820704440341"; export let rpc: Client; const ACTIVITY_LISTENING = 2; +const MAX_RETRIES = 5; +const RETRY_DELAY = 10000; const observer = () => { if (rpc) { @@ -77,26 +79,32 @@ const getActivity = (): SetActivity => { } }; +/** + * Try to login to RPC and retry if it errors + * @param retryCount Max retry count + */ +const connectWithRetry = async (retryCount = 0) => { + try { + await rpc.login(); + Logger.log('Connected to Discord'); + rpc.on("ready", updateActivity); + Object.values(globalEvents).forEach(event => ipcMain.on(event, observer)); + } catch (error) { + if (retryCount < MAX_RETRIES) { + Logger.log(`Failed to connect to Discord, retrying in ${RETRY_DELAY/1000} seconds... (Attempt ${retryCount + 1}/${MAX_RETRIES})`); + setTimeout(() => connectWithRetry(retryCount + 1), RETRY_DELAY); + } else { + Logger.log('Failed to connect to Discord after maximum retry attempts'); + } + } +}; + /** * Set up the discord rpc and listen on globalEvents.updateInfo */ export const initRPC = () => { rpc = new Client({ transport: {type: "ipc"}, clientId }); - rpc.login().then( - () => { - rpc.on("ready", () => { - updateActivity(); - }); - - const { updateInfo, play, pause, playPause } = globalEvents; - [updateInfo, play, pause, playPause].forEach((status) => { - ipcMain.on(status, observer); - }); - }, - () => { - Logger.log("Can't connect to Discord, is it running?"); - } - ); + connectWithRetry(); }; /** From 974877ea4f4bd1195e2639c6f026ccf1738ba0bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dar=C3=ADo=20Marmie?= Date: Wed, 23 Oct 2024 09:39:13 -0300 Subject: [PATCH 09/13] staticWindowTitle(fix): Order alphabetically on all appearances, change if to a ternary --- src/constants/settings.ts | 2 +- src/pages/settings/preload.ts | 10 +++++----- src/preload.ts | 3 +-- src/scripts/settings.ts | 10 +++++----- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/constants/settings.ts b/src/constants/settings.ts index 31591179f..242dd4cb9 100644 --- a/src/constants/settings.ts +++ b/src/constants/settings.ts @@ -55,9 +55,9 @@ export const settings = { singleInstance: "singleInstance", skipArtists: "skipArtists", skippedArtists: "skippedArtists", + staticWindowTitle: "staticWindowTitle", theme: "theme", trayIcon: "trayIcon", - staticWindowTitle: "staticWindowTitle", updateFrequency: "updateFrequency", windowBounds: { root: "windowBounds", diff --git a/src/pages/settings/preload.ts b/src/pages/settings/preload.ts index 53286e1b5..34eff23b5 100644 --- a/src/pages/settings/preload.ts +++ b/src/pages/settings/preload.ts @@ -46,9 +46,9 @@ let adBlock: HTMLInputElement, singleInstance: HTMLInputElement, skipArtists: HTMLInputElement, skippedArtists: HTMLInputElement, + staticWindowTitle: HTMLInputElement, theme: HTMLSelectElement, trayIcon: HTMLInputElement, - staticWindowTitle: HTMLInputElement, updateFrequency: HTMLInputElement, enableListenBrainz: HTMLInputElement, ListenBrainzAPI: HTMLInputElement, @@ -141,10 +141,10 @@ function refreshSettings() { port.value = settingsStore.get(settings.apiSettings.port); singleInstance.checked = settingsStore.get(settings.singleInstance); skipArtists.checked = settingsStore.get(settings.skipArtists); - theme.value = settingsStore.get(settings.theme); skippedArtists.value = settingsStore.get(settings.skippedArtists).join("\n"); - trayIcon.checked = settingsStore.get(settings.trayIcon); staticWindowTitle.checked = settingsStore.get(settings.staticWindowTitle); + theme.value = settingsStore.get(settings.theme); + trayIcon.checked = settingsStore.get(settings.trayIcon); updateFrequency.value = settingsStore.get(settings.updateFrequency); enableListenBrainz.checked = settingsStore.get(settings.ListenBrainz.enabled); ListenBrainzAPI.value = settingsStore.get(settings.ListenBrainz.api); @@ -261,9 +261,9 @@ window.addEventListener("DOMContentLoaded", () => { port = get("port"); theme = get("themesList"); trayIcon = get("trayIcon"); - staticWindowTitle = get("staticWindowTitle"); skipArtists = get("skipArtists"); skippedArtists = get("skippedArtists"); + staticWindowTitle = get("staticWindowTitle"); singleInstance = get("singleInstance"); updateFrequency = get("updateFrequency"); enableListenBrainz = get("enableListenBrainz"); @@ -298,10 +298,10 @@ window.addEventListener("DOMContentLoaded", () => { addInputListener(port, settings.apiSettings.port); addInputListener(skipArtists, settings.skipArtists); addTextAreaListener(skippedArtists, settings.skippedArtists); + addInputListener(staticWindowTitle, settings.staticWindowTitle); addInputListener(singleInstance, settings.singleInstance); addSelectListener(theme, settings.theme); addInputListener(trayIcon, settings.trayIcon); - addInputListener(staticWindowTitle, settings.staticWindowTitle); addInputListener(updateFrequency, settings.updateFrequency); addInputListener( enableListenBrainz, diff --git a/src/preload.ts b/src/preload.ts index bfd472d09..a2b01a843 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -595,8 +595,7 @@ setInterval(function () { }; // update title, url and play info with new info - if(settingsStore.get(settings.staticWindowTitle)) setTitle(staticTitle) - else setTitle(songDashArtistTitle); + settingsStore.get(settings.staticWindowTitle) ? setTitle(staticTitle) : setTitle(songDashArtistTitle); getTrackURL(); currentSong = songDashArtistTitle; currentPlayStatus = currentStatus; diff --git a/src/scripts/settings.ts b/src/scripts/settings.ts index 7416b1f70..30ea16d1e 100644 --- a/src/scripts/settings.ts +++ b/src/scripts/settings.ts @@ -69,9 +69,9 @@ export const settingsStore = new Store({ singleInstance: true, skipArtists: false, skippedArtists: [""], + staticWindowTitle: false, theme: "none", trayIcon: true, - staticWindowTitle: false, updateFrequency: 500, windowBounds: { width: 800, height: 600 }, }, @@ -128,7 +128,7 @@ const settingsModule = { settingsWindow, }; -export const createSettingsWindow = function() { +export const createSettingsWindow = function () { settingsWindow = new BrowserWindow({ width: 650, height: 700, @@ -160,7 +160,7 @@ export const createSettingsWindow = function() { settingsModule.settingsWindow = settingsWindow; }; -export const showSettingsWindow = function(tab = "general") { +export const showSettingsWindow = function (tab = "general") { if (!settingsWindow) { console.log("Settings window is not initialized. Attempting to create it."); createSettingsWindow(); @@ -171,11 +171,11 @@ export const showSettingsWindow = function(tab = "general") { settingsWindow.webContents.send("refreshData"); settingsWindow.show(); }; -export const hideSettingsWindow = function() { +export const hideSettingsWindow = function () { settingsWindow.hide(); }; -export const closeSettingsWindow = function() { +export const closeSettingsWindow = function () { settingsWindow = null; }; From 0f5e00c4df139a6a429da3b31002cbed172cabbe Mon Sep 17 00:00:00 2001 From: 3top1a <3top1a.official@gmail.com> Date: Wed, 23 Oct 2024 19:14:36 +0200 Subject: [PATCH 10/13] Revert "Removed redundant RPC settings" --- src/constants/settings.ts | 3 ++ src/pages/settings/preload.ts | 35 +++++++++++++++- src/pages/settings/settings.html | 68 ++++++++++++++++++++++++++++++-- src/scripts/discord.ts | 54 +++++++++++++++++++------ src/scripts/settings.ts | 16 +++++++- 5 files changed, 160 insertions(+), 16 deletions(-) diff --git a/src/constants/settings.ts b/src/constants/settings.ts index 716441daf..78fce85b2 100644 --- a/src/constants/settings.ts +++ b/src/constants/settings.ts @@ -27,7 +27,10 @@ export const settings = { enableDiscord: "enableDiscord", discord: { detailsPrefix: "discord.detailsPrefix", + buttonText: "discord.buttonText", includeTimestamps: "discord.includeTimestamps", + showSong: "discord.showSong", + showIdle: "discord.showIdle", idleText: "discord.idleText", usingText: "discord.usingText", }, diff --git a/src/pages/settings/preload.ts b/src/pages/settings/preload.ts index 0a82cf060..498988ba1 100644 --- a/src/pages/settings/preload.ts +++ b/src/pages/settings/preload.ts @@ -20,6 +20,11 @@ const switchesWithSettings = { classToHide: "discord_options", settingsKey: settings.enableDiscord, }, + discord_show_song: { + switch: "discord_show_song", + classToHide: "discord_show_song_options", + settingsKey: settings.discord.showSong, + }, }; let adBlock: HTMLInputElement, @@ -49,7 +54,13 @@ let adBlock: HTMLInputElement, ListenBrainzToken: HTMLInputElement, listenbrainz_delay: HTMLInputElement, enableWaylandSupport: HTMLInputElement, - discord_details_prefix: HTMLInputElement + discord_details_prefix: HTMLInputElement, + discord_include_timestamps: HTMLInputElement, + discord_button_text: HTMLInputElement, + discord_show_song: HTMLInputElement, + discord_show_idle: HTMLInputElement, + discord_idle_text: HTMLInputElement, + discord_using_text: HTMLInputElement; addCustomCss(app); @@ -138,6 +149,12 @@ function refreshSettings() { ListenBrainzToken.value = settingsStore.get(settings.ListenBrainz.token); listenbrainz_delay.value = settingsStore.get(settings.ListenBrainz.delay); discord_details_prefix.value = settingsStore.get(settings.discord.detailsPrefix); + discord_include_timestamps.checked = settingsStore.get(settings.discord.includeTimestamps); + discord_button_text.value = settingsStore.get(settings.discord.buttonText); + discord_show_song.checked = settingsStore.get(settings.discord.showSong); + discord_show_idle.checked = settingsStore.get(settings.discord.showIdle); + discord_idle_text.value = settingsStore.get(settings.discord.idleText); + discord_using_text.value = settingsStore.get(settings.discord.usingText); // set state of all switches with additional settings Object.values(switchesWithSettings).forEach((settingSwitch) => { @@ -250,7 +267,13 @@ window.addEventListener("DOMContentLoaded", () => { ListenBrainzAPI = get("ListenBrainzAPI"); ListenBrainzToken = get("ListenBrainzToken"); discord_details_prefix = get("discord_details_prefix"); + discord_include_timestamps = get("discord_include_timestamps"); listenbrainz_delay = get("listenbrainz_delay"); + discord_button_text = get("discord_button_text"); + discord_show_song = get("discord_show_song"); + discord_show_idle = get("discord_show_idle"); + discord_using_text = get("discord_using_text"); + discord_idle_text = get("discord_idle_text"); refreshSettings(); addInputListener(adBlock, settings.adBlock); @@ -285,4 +308,14 @@ window.addEventListener("DOMContentLoaded", () => { addInputListener(ListenBrainzToken, settings.ListenBrainz.token); addInputListener(listenbrainz_delay, settings.ListenBrainz.delay); addInputListener(discord_details_prefix, settings.discord.detailsPrefix); + addInputListener(discord_include_timestamps, settings.discord.includeTimestamps); + addInputListener(discord_button_text, settings.discord.buttonText); + addInputListener( + discord_show_song, + settings.discord.showSong, + switchesWithSettings.discord_show_song + ); + addInputListener(discord_show_idle, settings.discord.showIdle); + addInputListener(discord_idle_text, settings.discord.idleText); + addInputListener(discord_using_text, settings.discord.usingText); }); diff --git a/src/pages/settings/settings.html b/src/pages/settings/settings.html index bae3aa231..30e839bdc 100644 --- a/src/pages/settings/settings.html +++ b/src/pages/settings/settings.html @@ -226,13 +226,75 @@

Discord RPC

+ +
+
+

Show Idle Text

+

Should the idle text be shown when idle?

+
+ +
+ +
+
+

Idle Text

+

The text displayed on Discord's rich presence while idling in the app.

+ +
+
+ +
+
+

Using Tidal Text

+

The text displayed on Discord's rich presence while "showSong" is turned off

+ +
+
+
-

Details prefix

-

Prefix for the "details" field of Discord's rich presence.

- +

Show media

+

Show the current media in the Discord client

+
+ +
+ + +
diff --git a/src/scripts/discord.ts b/src/scripts/discord.ts index 3f8dff52f..9da1387d2 100644 --- a/src/scripts/discord.ts +++ b/src/scripts/discord.ts @@ -23,14 +23,15 @@ const observer = () => { }; const defaultPresence = { - smallImageKey: "tidal-hifi-icon", - smallImageText: `TIDAL Hi-Fi ${app.getVersion()}`, + largeImageKey: "tidal-hifi-icon", + largeImageText: `TIDAL Hi-Fi ${app.getVersion()}`, instance: false, type: ACTIVITY_LISTENING }; const updateActivity = () => { - if (mediaInfo.status === MediaStatus.paused) { + const showIdle = settingsStore.get(settings.discord.showIdle) ?? true; + if (mediaInfo.status === MediaStatus.paused && !showIdle) { rpc.user?.clearActivity(); } else { rpc.user?.setActivity(getActivity()); @@ -40,11 +41,34 @@ const updateActivity = () => { const getActivity = (): SetActivity => { const presence: SetActivity = { ...defaultPresence }; - includeTimeStamps(); - setPresenceFromMediaInfo(); + if (mediaInfo.status === MediaStatus.paused) { + presence.details = + settingsStore.get(settings.discord.idleText) ?? "Browsing Tidal"; + } else { + const showSong = settingsStore.get(settings.discord.showSong) ?? false; + if (showSong) { + const { includeTimestamps, detailsPrefix, buttonText } = getFromStore(); + includeTimeStamps(includeTimestamps); + setPresenceFromMediaInfo(detailsPrefix, buttonText); + } else { + presence.details = + settingsStore.get(settings.discord.usingText) ?? "Playing media on TIDAL"; + } + } return presence; + function getFromStore() { + const includeTimestamps = + settingsStore.get(settings.discord.includeTimestamps) ?? true; + const detailsPrefix = + settingsStore.get(settings.discord.detailsPrefix) ?? "Listening to "; + const buttonText = + settingsStore.get(settings.discord.buttonText) ?? "Play on TIDAL"; + + return { includeTimestamps, detailsPrefix, buttonText }; + } + /** * Pad a string using spaces to at least 2 characters * @param input string to pad with 2 characters @@ -54,28 +78,36 @@ const getActivity = (): SetActivity => { return input.padEnd(2, " "); } - function setPresenceFromMediaInfo() { + function setPresenceFromMediaInfo(detailsPrefix: string, buttonText: string) { // discord requires a minimum of 2 characters const title = pad(mediaInfo.title); const album = pad(mediaInfo.album); const artists = pad(mediaInfo.artists); - const detailsPrefix = settingsStore.get(settings.discord.detailsPrefix) ?? "Listening to "; - presence.details = `${detailsPrefix}${title}`; - presence.state = artists ? artists : "unknown artist(s)"; if (mediaInfo.url) { + presence.details = `${detailsPrefix}${title}`; + presence.state = artists ? artists : "unknown artist(s)"; presence.largeImageKey = mediaInfo.image; - if (album) presence.largeImageText = album; + if (album) { + presence.largeImageText = album; + } + + presence.buttons = [{ label: buttonText, url: mediaInfo.url }]; + } else { + presence.details = `Watching ${title}`; + presence.state = artists; } } - function includeTimeStamps() { + function includeTimeStamps(includeTimestamps: boolean) { + if (includeTimestamps) { const currentSeconds = convertDurationToSeconds(mediaInfo.current); const durationSeconds = convertDurationToSeconds(mediaInfo.duration); const date = new Date(); const now = Math.floor(date.getTime() / 1000); presence.startTimestamp = now - currentSeconds; presence.endTimestamp = presence.startTimestamp + durationSeconds; + } } }; diff --git a/src/scripts/settings.ts b/src/scripts/settings.ts index a4742b8f1..4e5323abc 100644 --- a/src/scripts/settings.ts +++ b/src/scripts/settings.ts @@ -42,10 +42,13 @@ export const settingsStore = new Store({ enableCustomHotkeys: false, enableDiscord: false, discord: { + showSong: true, + showIdle: true, idleText: "Browsing Tidal", usingText: "Playing media on TIDAL", includeTimestamps: true, detailsPrefix: "Listening to ", + buttonText: "Play on Tidal", }, ListenBrainz: { enabled: false, @@ -86,8 +89,16 @@ export const settingsStore = new Store({ migrationStore.get(settings.ListenBrainz.delay) ?? 5000 ); }, + "5.8.0": (migrationStore) => { + console.log("running migrations for 5.8.0"); + migrationStore.set( + settings.discord.includeTimestamps, + migrationStore.get(settings.discord.includeTimestamps) ?? true + ); + }, "5.9.0": (migrationStore) => { buildMigration("5.9.0", migrationStore, [ + { key: settings.discord.showSong, value: "true" }, { key: settings.discord.idleText, value: "Browsing Tidal" }, { key: settings.discord.usingText, @@ -104,7 +115,10 @@ export const settingsStore = new Store({ buildMigration("5.15.0", migrationStore, [ { key: settings.advanced.tidalUrl, value: "https://listen.tidal.com" }, ]); - } + }, + "5.16.0": (migrationStore) => { + buildMigration("5.16.0", migrationStore, [{ key: settings.discord.showIdle, value: "true" }]); + }, }, }); From 15c8f6a418d4b9dbab4769230ad641db4ca50573 Mon Sep 17 00:00:00 2001 From: Rick van Lieshout Date: Sun, 27 Oct 2024 20:24:32 +0100 Subject: [PATCH 11/13] prepping 5.17 --- CHANGELOG.md | 5 +++++ package-lock.json | 6 +++--- package.json | 4 ++-- scripts/verifyElements.js | 4 ++-- src/pages/settings/settings.html | 4 ++-- src/preload.ts | 4 ++-- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a63b2a706..708d06bcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [5.17.0] + +- Added an option to disable the dynamic title and set it to a static one, [#491](https://github.com/Mastermindzh/tidal-hifi/pull/491) +- Fixed several element names in the dom scraper + ## [5.16.0] - Fix issue #449 Discord RPC stuck on "Browsing Tidal". diff --git a/package-lock.json b/package-lock.json index 3ce905cd4..6c02e2261 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "tidal-hifi", - "version": "5.16.0", + "version": "5.17.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "tidal-hifi", - "version": "5.16.0", + "version": "5.17.0", "license": "MIT", "dependencies": { "@electron/remote": "^2.1.2", @@ -9115,4 +9115,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index d2e72ff79..768201aa5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tidal-hifi", - "version": "5.16.0", + "version": "5.17.0", "description": "Tidal on Electron with widevine(hifi) support", "main": "ts-dist/main.js", "scripts": { @@ -81,4 +81,4 @@ "typescript": "^5.5.3" }, "prettier": "@mastermindzh/prettier-config" -} +} \ No newline at end of file diff --git a/scripts/verifyElements.js b/scripts/verifyElements.js index be19e5ae8..4450ee1fe 100644 --- a/scripts/verifyElements.js +++ b/scripts/verifyElements.js @@ -16,8 +16,8 @@ search: '[class^="searchField"]', shuffle: '*[data-test="shuffle"]', repeat: '*[data-test="repeat"]', - account: '*[class^="profileOptions"]', - settings: '*[data-test^="open-settings"]', + account: '*[data-test^="profile-image-button"]', + settings: '*[data-test^="sidebar-menu-button"]', media: '*[data-test="current-media-imagery"]', image: "img", current: '*[data-test="current-time"]', diff --git a/src/pages/settings/settings.html b/src/pages/settings/settings.html index 30e839bdc..e381feeef 100644 --- a/src/pages/settings/settings.html +++ b/src/pages/settings/settings.html @@ -468,7 +468,7 @@

Upload new themes

TIDAL Hi-Fi

5.16.0 + href="https://github.com/Mastermindzh/tidal-hifi/releases/tag/5.17.0">5.17.0
- + \ No newline at end of file diff --git a/src/preload.ts b/src/preload.ts index 814044ba9..69ede6172 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -48,8 +48,8 @@ const elements = { search: '[class^="searchField"]', shuffle: '*[data-test="shuffle"]', repeat: '*[data-test="repeat"]', - account: '*[class^="profileOptions"]', - settings: '*[data-test^="open-settings"]', + account: '*[data-test^="profile-image-button"]', + settings: '*[data-test^="sidebar-menu-button"]', media: '*[data-test="current-media-imagery"]', image: "img", current: '*[data-test="current-time"]', From 2ab5a556abb9b2e3afc5c8556d0a585dd9df2dba Mon Sep 17 00:00:00 2001 From: Rick van Lieshout Date: Sun, 27 Oct 2024 21:01:37 +0100 Subject: [PATCH 12/13] Removed Songwhip (they shut down) and replaced it with TIDAL's universal link system --- .vscode/settings.json | 1 - CHANGELOG.md | 1 + README.md | 1 - package-lock.json | 2 +- scripts/verifyElements.js | 1 + src/constants/globalEvents.ts | 2 +- src/features/api/swagger.json | 2 +- src/features/sharingService/sharingService.ts | 10 ++++++ src/features/songwhip/models/Artist.ts | 21 ------------ src/features/songwhip/models/ServiceLinks.ts | 4 --- src/features/songwhip/models/whip.ts | 27 ---------------- src/features/songwhip/songwhip.ts | 32 ------------------- src/main.ts | 6 ++-- src/preload.ts | 18 ++++++----- 14 files changed, 28 insertions(+), 100 deletions(-) create mode 100644 src/features/sharingService/sharingService.ts delete mode 100644 src/features/songwhip/models/Artist.ts delete mode 100644 src/features/songwhip/models/ServiceLinks.ts delete mode 100644 src/features/songwhip/models/whip.ts delete mode 100644 src/features/songwhip/songwhip.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index c37b15f51..b9aadb701 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,7 +14,6 @@ "rescrobbler", "scrobble", "scrobbling", - "Songwhip", "trackid", "tracklist", "widevine", diff --git a/CHANGELOG.md b/CHANGELOG.md index 708d06bcf..d271636a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added an option to disable the dynamic title and set it to a static one, [#491](https://github.com/Mastermindzh/tidal-hifi/pull/491) - Fixed several element names in the dom scraper +- Removed Songwhip (they shut down) and replaced it with TIDAL's universal link system ## [5.16.0] diff --git a/README.md b/README.md index 089ae3964..3e848af8b 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,6 @@ The web version of [listen.tidal.com](https://listen.tidal.com) running in elect - AlbumArt in integrations ([best-effort](https://github.com/Mastermindzh/tidal-hifi/pull/88#pullrequestreview-840814847)) - Custom [integrations](#integrations) - [ListenBrainz](https://listenbrainz.org/?redirect=false) integration - - Songwhip.com integration (hotkey `ctrl + w`) - Discord RPC integration (showing "now listening", "Browsing", etc) - Flatpak version only works if both Discord and Tidal-HiFi are flatpaks - MPRIS integration diff --git a/package-lock.json b/package-lock.json index 6c02e2261..63985a89c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9115,4 +9115,4 @@ } } } -} \ No newline at end of file +} diff --git a/scripts/verifyElements.js b/scripts/verifyElements.js index 4450ee1fe..76ad2626c 100644 --- a/scripts/verifyElements.js +++ b/scripts/verifyElements.js @@ -18,6 +18,7 @@ repeat: '*[data-test="repeat"]', account: '*[data-test^="profile-image-button"]', settings: '*[data-test^="sidebar-menu-button"]', + openSettings: '*[data-test^="open-settings"]', media: '*[data-test="current-media-imagery"]', image: "img", current: '*[data-test="current-time"]', diff --git a/src/constants/globalEvents.ts b/src/constants/globalEvents.ts index c08e12ecf..42d89ec0b 100644 --- a/src/constants/globalEvents.ts +++ b/src/constants/globalEvents.ts @@ -10,7 +10,7 @@ export const globalEvents = { showSettings: "showSettings", storeChanged: "storeChanged", error: "error", - whip: "whip", + getUniversalLink: "getUniversalLink", log: "log", toggleFavorite: "toggleFavorite", toggleShuffle: "toggleShuffle", diff --git a/src/features/api/swagger.json b/src/features/api/swagger.json index 740d6968e..bac2fc997 100644 --- a/src/features/api/swagger.json +++ b/src/features/api/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.1.0", "info": { "title": "TIDAL Hi-Fi API", - "version": "5.16.0", + "version": "5.17.0", "description": "", "license": { "name": "MIT", diff --git a/src/features/sharingService/sharingService.ts b/src/features/sharingService/sharingService.ts new file mode 100644 index 000000000..a381cd6a1 --- /dev/null +++ b/src/features/sharingService/sharingService.ts @@ -0,0 +1,10 @@ +export class SharingService { + /** + * Retrieve the universal link given a regular track link + * @param currentUrl + * @returns + */ + public static getUniversalLink(currentUrl: string): string { + return `${currentUrl}?u`; + } +} diff --git a/src/features/songwhip/models/Artist.ts b/src/features/songwhip/models/Artist.ts deleted file mode 100644 index e605f8a54..000000000 --- a/src/features/songwhip/models/Artist.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ServiceLinks } from "./ServiceLinks"; - -export interface Artist { - type: string; - id: number; - path: string; - name: string; - sourceUrl: string; - sourceCountry: string; - url: string; - image: string; - createdAt: string; - updatedAt: string; - refreshedAt: string; - serviceIds: { [key: string]: string }; - orchardId: string; - spotifyId: string; - links: { [key: string]: ServiceLinks[] }; - linksCountries: string[]; - description: string; -} diff --git a/src/features/songwhip/models/ServiceLinks.ts b/src/features/songwhip/models/ServiceLinks.ts deleted file mode 100644 index bb09716f3..000000000 --- a/src/features/songwhip/models/ServiceLinks.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface ServiceLinks { - link: string; - countries: string[]; -} diff --git a/src/features/songwhip/models/whip.ts b/src/features/songwhip/models/whip.ts deleted file mode 100644 index 2433a12c5..000000000 --- a/src/features/songwhip/models/whip.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Artist } from "./Artist"; -import { ServiceLinks } from "./ServiceLinks"; - -export interface WhippedResult { - status: string; - data: { - item: { - type: string; - id: number; - path: string; - name: string; - url: string; - sourceUrl: string; - sourceCountry: string; - releaseDate: string; - createdAt: string; - updatedAt: string; - refreshedAt: string; - image: string; - isrc: string; - isExplicit: boolean; - links: { [key: string]: ServiceLinks[] }; - linksCountries: string[]; - artists: Artist[]; - }; - }; -} diff --git a/src/features/songwhip/songwhip.ts b/src/features/songwhip/songwhip.ts deleted file mode 100644 index 6ac2aa855..000000000 --- a/src/features/songwhip/songwhip.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { WhippedResult } from "./models/whip"; -import axios from "axios"; - -export class Songwhip { - /** - * Call the songwhip API and create a shareable songwhip page - * @param currentUrl - * @returns - */ - public static async whip(currentUrl: string): Promise { - try { - const response = await axios.post("https://songwhip.com/api/songwhip/create", { - url: currentUrl, - // doesn't actually matter.. returns everything the same way anyway - country: "NL", - }); - - return response.data; - } catch (error) { - console.log(JSON.stringify(error)); - } - } - - /** - * Transform a songwhip response into a shareable url - * @param response - * @returns - */ - public static getWhipUrl(response: WhippedResult) { - return `https://songwhip.com${response.data.item.url}`; - } -} diff --git a/src/main.ts b/src/main.ts index 01a888fdf..9fd0f21bf 100644 --- a/src/main.ts +++ b/src/main.ts @@ -10,7 +10,7 @@ import { releaseInhibitorIfActive, } from "./features/idleInhibitor/idleInhibitor"; import { Logger } from "./features/logger"; -import { Songwhip } from "./features/songwhip/songwhip"; +import { SharingService } from "./features/sharingService/sharingService"; import { MediaInfo } from "./models/mediaInfo"; import { MediaStatus } from "./models/mediaStatus"; import { initRPC, rpc, unRPC } from "./scripts/discord"; @@ -250,8 +250,8 @@ ipcMain.on(globalEvents.error, (event) => { console.log(event); }); -ipcMain.handle(globalEvents.whip, async (event, url) => { - return Songwhip.whip(url); +ipcMain.handle(globalEvents.getUniversalLink, async (event, url) => { + return SharingService.getUniversalLink(url); }); Logger.watch(ipcMain); diff --git a/src/preload.ts b/src/preload.ts index 7fb280a0f..d00d9007a 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -10,7 +10,7 @@ import { } from "./features/listenbrainz/listenbrainz"; import { StoreData } from "./features/listenbrainz/models/storeData"; import { Logger } from "./features/logger"; -import { Songwhip } from "./features/songwhip/songwhip"; +import { SharingService } from "./features/sharingService/sharingService"; import { addCustomCss } from "./features/theming/theming"; import { convertDurationToSeconds } from "./features/time/parse"; import { MediaInfo } from "./models/mediaInfo"; @@ -50,6 +50,7 @@ const elements = { repeat: '*[data-test="repeat"]', account: '*[data-test^="profile-image-button"]', settings: '*[data-test^="sidebar-menu-button"]', + openSettings: '*[data-test^="open-settings"]', media: '*[data-test="current-media-imagery"]', image: "img", current: '*[data-test="current-time"]', @@ -220,9 +221,9 @@ ListenBrainzStore.clear(); function addHotKeys() { if (settingsStore.get(settings.enableCustomHotkeys)) { addHotkey("Control+p", function () { - elements.click("account"); + elements.click("settings"); setTimeout(() => { - elements.click("settings"); + elements.click("openSettings"); }, 100); }); addHotkey("Control+l", function () { @@ -254,11 +255,10 @@ function addHotKeys() { elements.click("repeat"); }); addHotkey("control+w", async function () { - const result = await ipcRenderer.invoke(globalEvents.whip, getTrackURL()); - const url = Songwhip.getWhipUrl(result); + const url = SharingService.getUniversalLink(getTrackURL()); clipboard.writeText(url); new Notification({ - title: `Successfully whipped: `, + title: `Universal link generated: `, body: `URL copied to clipboard: ${url}`, }).show(); }); @@ -550,7 +550,7 @@ setInterval(function () { const artistsArray = elements.getArtistsArray(); const artistsString = elements.getArtistsString(artistsArray); const songDashArtistTitle = `${title} - ${artistsString}`; - const staticTitle = "TIDAL Hi-Fi" + const staticTitle = "TIDAL Hi-Fi"; const titleOrArtistsChanged = currentSong !== songDashArtistTitle; const current = elements.getText("current"); const currentStatus = getCurrentlyPlayingStatus(); @@ -595,7 +595,9 @@ setInterval(function () { }; // update title, url and play info with new info - settingsStore.get(settings.staticWindowTitle) ? setTitle(staticTitle) : setTitle(songDashArtistTitle); + settingsStore.get(settings.staticWindowTitle) + ? setTitle(staticTitle) + : setTitle(songDashArtistTitle); getTrackURL(); currentSong = songDashArtistTitle; currentPlayStatus = currentStatus; From 66d0d004bf020d1d82c3361253283d7a83fb824a Mon Sep 17 00:00:00 2001 From: Rick van Lieshout Date: Sun, 27 Oct 2024 21:27:23 +0100 Subject: [PATCH 13/13] discord listening to --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d271636a6..cfb0e0222 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.17.0] - Added an option to disable the dynamic title and set it to a static one, [#491](https://github.com/Mastermindzh/tidal-hifi/pull/491) +- Discord integration now says "Listening to" instead of "playing" [#488](https://github.com/Mastermindzh/tidal-hifi/pull/488) && [#454](https://github.com/Mastermindzh/tidal-hifi/pull/454) - Fixed several element names in the dom scraper -- Removed Songwhip (they shut down) and replaced it with TIDAL's universal link system +- Removed the Songwhip (they shut down) integration and replaced it with TIDAL's universal link system ## [5.16.0]