Compare commits

..

2 Commits

Author SHA1 Message Date
Times-Z
fde7ffc35f Merge 403354186e into 15cc6bb6d4 2024-06-24 14:36:32 +02:00
TimesZ
403354186e doc: update swagger with all routes & deprecated old image api route 2024-06-21 19:08:27 +02:00
17 changed files with 840 additions and 1289 deletions

View File

@@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@master - uses: actions/checkout@master
- uses: actions/setup-node@master - uses: actions/setup-node@master
with: with:
node-version: 22.4 node-version: 19
- run: npm install - run: npm install
- run: npm run build - run: npm run build
@@ -31,7 +31,7 @@ jobs:
- uses: actions/checkout@master - uses: actions/checkout@master
- uses: actions/setup-node@master - uses: actions/setup-node@master
with: with:
node-version: 22.4 node-version: 19
- run: npm install - run: npm install
- run: npm run build - run: npm run build
@@ -41,6 +41,6 @@ jobs:
- uses: actions/checkout@master - uses: actions/checkout@master
- uses: actions/setup-node@master - uses: actions/setup-node@master
with: with:
node-version: 22.4 node-version: 19
- run: npm install - run: npm install
- run: npm run build - run: npm run build

View File

@@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@master - uses: actions/checkout@master
- uses: actions/setup-node@master - uses: actions/setup-node@master
with: with:
node-version: 22.4 node-version: 19
- run: npm install - run: npm install
- run: npm run build - run: npm run build
- uses: actions/upload-artifact@master - uses: actions/upload-artifact@master
@@ -35,7 +35,7 @@ jobs:
- uses: actions/checkout@master - uses: actions/checkout@master
- uses: actions/setup-node@master - uses: actions/setup-node@master
with: with:
node-version: 22.4 node-version: 19
- run: npm install - run: npm install
- run: npm run build - run: npm run build
- uses: actions/upload-artifact@master - uses: actions/upload-artifact@master
@@ -49,7 +49,7 @@ jobs:
- uses: actions/checkout@master - uses: actions/checkout@master
- uses: actions/setup-node@master - uses: actions/setup-node@master
with: with:
node-version: 22.4 node-version: 19
- run: npm install - run: npm install
- run: npm run build - run: npm run build
- uses: actions/upload-artifact@master - uses: actions/upload-artifact@master

View File

@@ -4,21 +4,6 @@ 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/), 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). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [5.16.0]
- Fix issue #449 Discord RPC stuck on "Browsing Tidal".
- Fix issue #448 Add option to disable the discord rpc idle text
- Notifications are now send at the end of the update process, allowing other events to happen sooner.
## [5.15.0]
- Added all missing swagger/openApi info with the help of [Times-Z](https://github.com/Times-Z)
- Updated most dependency versions
- This includes Electron 31!
- Added a channel selector so we can now use Tidal's staging environment directly from the app
- implements [#437](https://github.com/Mastermindzh/tidal-hifi/issues/437)
## [5.14.1] ## [5.14.1]
- Fixed `getAlbumName` not finding album name whilst on queue page - Fixed `getAlbumName` not finding album name whilst on queue page

View File

@@ -26,7 +26,7 @@ The web version of [listen.tidal.com](https://listen.tidal.com) running in elect
- [Using source](#using-source) - [Using source](#using-source)
- [Integrations](#integrations) - [Integrations](#integrations)
- [Known bugs](#known-bugs) - [Known bugs](#known-bugs)
- [DRM not working on Windows (error S6007)](#drm-not-working-on-windows-error-s6007) - [DRM not working on Windows](#drm-not-working-on-windows)
- [Special thanks to](#special-thanks-to) - [Special thanks to](#special-thanks-to)
- [Donations](#donations) - [Donations](#donations)
- [Images](#images) - [Images](#images)
@@ -153,13 +153,11 @@ Integrations with other projects that are not included natively:
## Known bugs ## Known bugs
### DRM not working on Windows (error S6007) ### DRM not working on Windows
Most Windows users run into DRM issues when trying to use TIDAL Hi-Fi. Most Windows users run into DRM issues when trying to use TIDAL Hi-Fi.
Nothing I can do about that I'm afraid... Tidal is working on removing/changing DRM so when they finish with that we can give it another shot. Nothing I can do about that I'm afraid... Tidal is working on removing/changing DRM so when they finish with that we can give it another shot.
Until then you'll have to use the official app unfortunately.
## Special thanks to ## Special thanks to
- [Castlabs](https://castlabs.com/) - [Castlabs](https://castlabs.com/)

1493
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "tidal-hifi", "name": "tidal-hifi",
"version": "5.16.0", "version": "5.14.1",
"description": "Tidal on Electron with widevine(hifi) support", "description": "Tidal on Electron with widevine(hifi) support",
"main": "ts-dist/main.js", "main": "ts-dist/main.js",
"scripts": { "scripts": {
@@ -50,7 +50,7 @@
"hotkeys-js": "^3.13.7", "hotkeys-js": "^3.13.7",
"mpris-service": "^2.1.2", "mpris-service": "^2.1.2",
"request": "^2.88.2", "request": "^2.88.2",
"sass": "^1.77.8", "sass": "^1.77.4",
"swagger-ui-express": "^5.0.1" "swagger-ui-express": "^5.0.1"
}, },
"devDependencies": { "devDependencies": {
@@ -58,27 +58,27 @@
"@types/cors": "^2.8.17", "@types/cors": "^2.8.17",
"@types/discord-rpc": "^4.0.8", "@types/discord-rpc": "^4.0.8",
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/node": "^20.14.10", "@types/node": "^20.12.12",
"@types/request": "^2.48.12", "@types/request": "^2.48.12",
"@types/swagger-ui-express": "^4.1.6", "@types/swagger-ui-express": "^4.1.6",
"@typescript-eslint/eslint-plugin": "^7.16.0", "@typescript-eslint/eslint-plugin": "^6.18.0",
"@typescript-eslint/parser": "^7.15.0", "@typescript-eslint/parser": "^6.18.0",
"copyfiles": "^2.4.1", "copyfiles": "^2.4.1",
"electron": "git+https://github.com/castlabs/electron-releases#v31.1.0+wvcus", "electron": "git+https://github.com/castlabs/electron-releases#v28.1.1+wvcus",
"electron-builder": "~24.9.4", "electron-builder": "^24.9.1",
"eslint": "^8.57.0", "eslint": "^8.56.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"markdown-toc": "^1.2.0", "markdown-toc": "^1.2.0",
"nodemon": "^3.1.4", "nodemon": "^3.0.2",
"prettier": "^3.3.2", "prettier": "^3.1.1",
"stylelint": "^16.6.1", "stylelint": "^16.1.0",
"stylelint-config-standard": "^36.0.1", "stylelint-config-standard": "^36.0.0",
"stylelint-config-standard-scss": "^13.1.0", "stylelint-config-standard-scss": "^13.0.0",
"stylelint-prettier": "^5.0.0", "stylelint-prettier": "^5.0.0",
"swagger-jsdoc": "^6.2.8", "swagger-jsdoc": "^6.2.8",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"tsc-watch": "^6.2.0", "tsc-watch": "^6.0.4",
"typescript": "^5.5.3" "typescript": "^5.3.3"
}, },
"prettier": "@mastermindzh/prettier-config" "prettier": "@mastermindzh/prettier-config"
} }

View File

@@ -10,10 +10,6 @@
*/ */
export const settings = { export const settings = {
adBlock: "adBlock", adBlock: "adBlock",
advanced: {
root: "advanced",
tidalUrl: "advanced.tidalUrl",
},
api: "api", api: "api",
apiSettings: { apiSettings: {
root: "apiSettings", root: "apiSettings",
@@ -30,7 +26,6 @@ export const settings = {
buttonText: "discord.buttonText", buttonText: "discord.buttonText",
includeTimestamps: "discord.includeTimestamps", includeTimestamps: "discord.includeTimestamps",
showSong: "discord.showSong", showSong: "discord.showSong",
showIdle: "discord.showIdle",
idleText: "discord.idleText", idleText: "discord.idleText",
usingText: "discord.usingText", usingText: "discord.usingText",
}, },

View File

@@ -29,13 +29,12 @@ export const addPlaybackControl = (expressApp: Router, mainWindow: BrowserWindow
if (settingsStore.get(settings.playBackControl)) { if (settingsStore.get(settings.playBackControl)) {
/** /**
* @swagger * @swagger
* /player/play: * /play:
* post: * get:
* summary: Play the current media * summary: Play action
* tags: [player]
* responses: * responses:
* 200: * 200:
* description: Ok * description: Action performed
* content: * content:
* text/plain: * text/plain:
* schema: * schema:
@@ -45,13 +44,12 @@ export const addPlaybackControl = (expressApp: Router, mainWindow: BrowserWindow
/** /**
* @swagger * @swagger
* /player/favorite/toggle: * /favorite/toggle:
* post: * post:
* summary: Add the current media to your favorites, or remove it if its already added to your favorites * summary: Toggle favorite
* tags: [player]
* responses: * responses:
* 200: * 200:
* description: Ok * description: Action performed
* content: * content:
* text/plain: * text/plain:
* schema: * schema:
@@ -61,13 +59,12 @@ export const addPlaybackControl = (expressApp: Router, mainWindow: BrowserWindow
/** /**
* @swagger * @swagger
* /player/pause: * /pause:
* post: * get:
* summary: Pause the current media * summary: Pause action
* tags: [player]
* responses: * responses:
* 200: * 200:
* description: Ok * description: Action performed
* content: * content:
* text/plain: * text/plain:
* schema: * schema:
@@ -77,13 +74,12 @@ export const addPlaybackControl = (expressApp: Router, mainWindow: BrowserWindow
/** /**
* @swagger * @swagger
* /player/next: * /next:
* post: * get:
* summary: Play the next song * summary: Next action
* tags: [player]
* responses: * responses:
* 200: * 200:
* description: Ok * description: Action performed
* content: * content:
* text/plain: * text/plain:
* schema: * schema:
@@ -93,13 +89,12 @@ export const addPlaybackControl = (expressApp: Router, mainWindow: BrowserWindow
/** /**
* @swagger * @swagger
* /player/previous: * /previous:
* post: * get:
* summary: Play the previous song * summary: Previous action
* tags: [player]
* responses: * responses:
* 200: * 200:
* description: Ok * description: Action performed
* content: * content:
* text/plain: * text/plain:
* schema: * schema:
@@ -107,47 +102,17 @@ export const addPlaybackControl = (expressApp: Router, mainWindow: BrowserWindow
*/ */
createPlayerAction("/previous", globalEvents.previous); createPlayerAction("/previous", globalEvents.previous);
/**
* @swagger
* /player/shuffle/toggle:
* post:
* summary: Play the previous song
* tags: [player]
* responses:
* 200:
* description: Ok
* content:
* text/plain:
* schema:
* $ref: '#/components/schemas/OkResponse'
*/
createPlayerAction("/shuffle/toggle", globalEvents.toggleShuffle); createPlayerAction("/shuffle/toggle", globalEvents.toggleShuffle);
/**
* @swagger
* /player/repeat/toggle:
* post:
* summary: Toggle the repeat status, toggles between "off" , "single" and "all"
* tags: [player]
* responses:
* 200:
* description: Ok
* content:
* text/plain:
* schema:
* $ref: '#/components/schemas/OkResponse'
*/
createPlayerAction("/repeat/toggle", globalEvents.toggleRepeat); createPlayerAction("/repeat/toggle", globalEvents.toggleRepeat);
/** /**
* @swagger * @swagger
* /player/playpause: * /playpause:
* post: * get:
* summary: Start playing the media if paused, or pause the media if playing * summary: Toggle play/pause
* tags: [player]
* responses: * responses:
* 200: * 200:
* description: Ok * description: Action performed
* content: * content:
* text/plain: * text/plain:
* schema: * schema:

View File

@@ -18,7 +18,6 @@ export const addLegacyApi = (expressApp: Router, mainWindow: BrowserWindow) => {
* /image: * /image:
* get: * get:
* summary: Get current image * summary: Get current image
* tags: [legacy]
* deprecated: true * deprecated: true
* responses: * responses:
* 200: * 200:
@@ -37,108 +36,13 @@ export const addLegacyApi = (expressApp: Router, mainWindow: BrowserWindow) => {
addLegacyControls(); addLegacyControls();
} }
function addLegacyControls() { function addLegacyControls() {
/**
* @swagger
* /play:
* get:
* summary: Play the current media
* tags: [legacy]
* deprecated: true
* responses:
* 200:
* description: Action performed
* content:
* text/plain:
* schema:
* $ref: '#/components/schemas/OkResponse'
*/
expressApp.get("/play", ({ res }) => handleGlobalEvent(res, globalEvents.play)); expressApp.get("/play", ({ res }) => handleGlobalEvent(res, globalEvents.play));
/**
* @swagger
* /favorite/toggle:
* get:
* summary: Add the current media to your favorites, or remove it if its already added to your favorites
* tags: [legacy]
* deprecated: true
* responses:
* 200:
* description: Ok
* content:
* text/plain:
* schema:
* $ref: '#/components/schemas/OkResponse'
*/
expressApp.post("/favorite/toggle", (req, res) => expressApp.post("/favorite/toggle", (req, res) =>
handleGlobalEvent(res, globalEvents.toggleFavorite) handleGlobalEvent(res, globalEvents.toggleFavorite)
); );
/**
* @swagger
* /pause:
* get:
* summary: Pause the current media
* tags: [legacy]
* deprecated: true
* responses:
* 200:
* description: Ok
* content:
* text/plain:
* schema:
* $ref: '#/components/schemas/OkResponse'
*/
expressApp.get("/pause", (req, res) => handleGlobalEvent(res, globalEvents.pause)); expressApp.get("/pause", (req, res) => handleGlobalEvent(res, globalEvents.pause));
/**
* @swagger
* /next:
* get:
* summary: Play the next song
* tags: [legacy]
* deprecated: true
* responses:
* 200:
* description: Ok
* content:
* text/plain:
* schema:
* $ref: '#/components/schemas/OkResponse'
*/
expressApp.get("/next", (req, res) => handleGlobalEvent(res, globalEvents.next)); expressApp.get("/next", (req, res) => handleGlobalEvent(res, globalEvents.next));
/**
* @swagger
* /previous:
* get:
* summary: Play the previous song
* tags: [legacy]
* deprecated: true
* responses:
* 200:
* description: Ok
* content:
* text/plain:
* schema:
* $ref: '#/components/schemas/OkResponse'
*/
expressApp.get("/previous", (req, res) => handleGlobalEvent(res, globalEvents.previous)); expressApp.get("/previous", (req, res) => handleGlobalEvent(res, globalEvents.previous));
/**
* @swagger
* /playpause:
* get:
* summary: Toggle play/pause
* tags: [legacy]
* deprecated: true
* responses:
* 200:
* description: Ok
* content:
* text/plain:
* schema:
* $ref: '#/components/schemas/OkResponse'
*/
expressApp.get("/playpause", (req, res) => { expressApp.get("/playpause", (req, res) => {
if (mediaInfo.status === MediaStatus.playing) { if (mediaInfo.status === MediaStatus.playing) {
handleGlobalEvent(res, globalEvents.pause); handleGlobalEvent(res, globalEvents.pause);

View File

@@ -2,7 +2,7 @@
"openapi": "3.1.0", "openapi": "3.1.0",
"info": { "info": {
"title": "TIDAL Hi-Fi API", "title": "TIDAL Hi-Fi API",
"version": "5.16.0", "version": "5.14.1",
"description": "", "description": "",
"license": { "license": {
"name": "MIT", "name": "MIT",
@@ -62,15 +62,12 @@
} }
} }
}, },
"/player/play": { "/play": {
"post": { "get": {
"summary": "Play the current media", "summary": "Play action",
"tags": [
"player"
],
"responses": { "responses": {
"200": { "200": {
"description": "Ok", "description": "Action performed",
"content": { "content": {
"text/plain": { "text/plain": {
"schema": { "schema": {
@@ -82,15 +79,12 @@
} }
} }
}, },
"/player/favorite/toggle": { "/favorite/toggle": {
"post": { "post": {
"summary": "Add the current media to your favorites, or remove it if its already added to your favorites", "summary": "Toggle favorite",
"tags": [
"player"
],
"responses": { "responses": {
"200": { "200": {
"description": "Ok", "description": "Action performed",
"content": { "content": {
"text/plain": { "text/plain": {
"schema": { "schema": {
@@ -102,15 +96,12 @@
} }
} }
}, },
"/player/pause": { "/pause": {
"post": { "get": {
"summary": "Pause the current media", "summary": "Pause action",
"tags": [
"player"
],
"responses": { "responses": {
"200": { "200": {
"description": "Ok", "description": "Action performed",
"content": { "content": {
"text/plain": { "text/plain": {
"schema": { "schema": {
@@ -122,15 +113,12 @@
} }
} }
}, },
"/player/next": { "/next": {
"post": { "get": {
"summary": "Play the next song", "summary": "Next action",
"tags": [
"player"
],
"responses": { "responses": {
"200": { "200": {
"description": "Ok", "description": "Action performed",
"content": { "content": {
"text/plain": { "text/plain": {
"schema": { "schema": {
@@ -142,15 +130,12 @@
} }
} }
}, },
"/player/previous": { "/previous": {
"post": { "get": {
"summary": "Play the previous song", "summary": "Previous action",
"tags": [
"player"
],
"responses": { "responses": {
"200": { "200": {
"description": "Ok", "description": "Action performed",
"content": { "content": {
"text/plain": { "text/plain": {
"schema": { "schema": {
@@ -162,55 +147,12 @@
} }
} }
}, },
"/player/shuffle/toggle": { "/playpause": {
"post": { "get": {
"summary": "Play the previous song", "summary": "Toggle play/pause",
"tags": [
"player"
],
"responses": { "responses": {
"200": { "200": {
"description": "Ok", "description": "Action performed",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/OkResponse"
}
}
}
}
}
}
},
"/player/repeat/toggle": {
"post": {
"summary": "Toggle the repeat status, toggles between \"off\" , \"single\" and \"all\"",
"tags": [
"player"
],
"responses": {
"200": {
"description": "Ok",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/OkResponse"
}
}
}
}
}
}
},
"/player/playpause": {
"post": {
"summary": "Start playing the media if paused, or pause the media if playing",
"tags": [
"player"
],
"responses": {
"200": {
"description": "Ok",
"content": { "content": {
"text/plain": { "text/plain": {
"schema": { "schema": {
@@ -313,9 +255,6 @@
"/image": { "/image": {
"get": { "get": {
"summary": "Get current image", "summary": "Get current image",
"tags": [
"legacy"
],
"deprecated": true, "deprecated": true,
"responses": { "responses": {
"200": { "200": {
@@ -334,132 +273,6 @@
} }
} }
} }
},
"/play": {
"get": {
"summary": "Play the current media",
"tags": [
"legacy"
],
"deprecated": true,
"responses": {
"200": {
"description": "Action performed",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/OkResponse"
}
}
}
}
}
}
},
"/favorite/toggle": {
"get": {
"summary": "Add the current media to your favorites, or remove it if its already added to your favorites",
"tags": [
"legacy"
],
"deprecated": true,
"responses": {
"200": {
"description": "Ok",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/OkResponse"
}
}
}
}
}
}
},
"/pause": {
"get": {
"summary": "Pause the current media",
"tags": [
"legacy"
],
"deprecated": true,
"responses": {
"200": {
"description": "Ok",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/OkResponse"
}
}
}
}
}
}
},
"/next": {
"get": {
"summary": "Play the next song",
"tags": [
"legacy"
],
"deprecated": true,
"responses": {
"200": {
"description": "Ok",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/OkResponse"
}
}
}
}
}
}
},
"/previous": {
"get": {
"summary": "Play the previous song",
"tags": [
"legacy"
],
"deprecated": true,
"responses": {
"200": {
"description": "Ok",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/OkResponse"
}
}
}
}
}
}
},
"/playpause": {
"get": {
"summary": "Toggle play/pause",
"tags": [
"legacy"
],
"deprecated": true,
"responses": {
"200": {
"description": "Ok",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/OkResponse"
}
}
}
}
}
}
} }
}, },
"components": { "components": {

View File

@@ -48,9 +48,6 @@ export class ListenBrainz {
} else { } else {
// Fetches the oldData required for scrobbling and proceeds to construct a playing_now data payload for the Playing Now area // Fetches the oldData required for scrobbling and proceeds to construct a playing_now data payload for the Playing Now area
const oldData = ListenBrainzStore.get(ListenBrainzConstants.oldData) as StoreData; const oldData = ListenBrainzStore.get(ListenBrainzConstants.oldData) as StoreData;
const tidalUrl =
settingsStore.get<string, string>(settings.advanced.tidalUrl) ||
"https://listen.tidal.com";
const playing_data = { const playing_data = {
listen_type: "playing_now", listen_type: "playing_now",
payload: [ payload: [
@@ -98,7 +95,7 @@ export class ListenBrainz {
additional_info: { additional_info: {
media_player: "Tidal Hi-Fi", media_player: "Tidal Hi-Fi",
submission_client: "Tidal Hi-Fi", submission_client: "Tidal Hi-Fi",
music_service: tidalUrl, music_service: "listen.tidal.com",
duration: oldData.duration, duration: oldData.duration,
}, },
artist_name: oldData.artists, artist_name: oldData.artists,

View File

@@ -24,6 +24,7 @@ import {
showSettingsWindow, showSettingsWindow,
} from "./scripts/settings"; } from "./scripts/settings";
import { addTray, refreshTray } from "./scripts/tray"; import { addTray, refreshTray } from "./scripts/tray";
const tidalUrl = "https://listen.tidal.com";
let mainInhibitorId = -1; let mainInhibitorId = -1;
initialize(); initialize();
@@ -39,9 +40,6 @@ const windowPreferences = {
setDefaultFlags(app); setDefaultFlags(app);
setManagedFlagsFromSettings(app); setManagedFlagsFromSettings(app);
const tidalUrl =
settingsStore.get<string, string>(settings.advanced.tidalUrl) || "https://listen.tidal.com";
/** /**
* Update the menuBarVisibility according to the store value * Update the menuBarVisibility according to the store value
* *

View File

@@ -29,7 +29,6 @@ const switchesWithSettings = {
let adBlock: HTMLInputElement, let adBlock: HTMLInputElement,
api: HTMLInputElement, api: HTMLInputElement,
channel: HTMLSelectElement,
customCSS: HTMLInputElement, customCSS: HTMLInputElement,
disableBackgroundThrottle: HTMLInputElement, disableBackgroundThrottle: HTMLInputElement,
disableHardwareMediaKeys: HTMLInputElement, disableHardwareMediaKeys: HTMLInputElement,
@@ -58,7 +57,6 @@ let adBlock: HTMLInputElement,
discord_include_timestamps: HTMLInputElement, discord_include_timestamps: HTMLInputElement,
discord_button_text: HTMLInputElement, discord_button_text: HTMLInputElement,
discord_show_song: HTMLInputElement, discord_show_song: HTMLInputElement,
discord_show_idle: HTMLInputElement,
discord_idle_text: HTMLInputElement, discord_idle_text: HTMLInputElement,
discord_using_text: HTMLInputElement; discord_using_text: HTMLInputElement;
@@ -123,7 +121,6 @@ function refreshSettings() {
try { try {
adBlock.checked = settingsStore.get(settings.adBlock); adBlock.checked = settingsStore.get(settings.adBlock);
api.checked = settingsStore.get(settings.api); api.checked = settingsStore.get(settings.api);
channel.value = settingsStore.get(settings.advanced.tidalUrl);
customCSS.value = settingsStore.get<string, string[]>(settings.customCSS).join("\n"); customCSS.value = settingsStore.get<string, string[]>(settings.customCSS).join("\n");
disableBackgroundThrottle.checked = settingsStore.get(settings.disableBackgroundThrottle); disableBackgroundThrottle.checked = settingsStore.get(settings.disableBackgroundThrottle);
disableHardwareMediaKeys.checked = settingsStore.get(settings.flags.disableHardwareMediaKeys); disableHardwareMediaKeys.checked = settingsStore.get(settings.flags.disableHardwareMediaKeys);
@@ -152,7 +149,6 @@ function refreshSettings() {
discord_include_timestamps.checked = settingsStore.get(settings.discord.includeTimestamps); discord_include_timestamps.checked = settingsStore.get(settings.discord.includeTimestamps);
discord_button_text.value = settingsStore.get(settings.discord.buttonText); discord_button_text.value = settingsStore.get(settings.discord.buttonText);
discord_show_song.checked = settingsStore.get(settings.discord.showSong); 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_idle_text.value = settingsStore.get(settings.discord.idleText);
discord_using_text.value = settingsStore.get(settings.discord.usingText); discord_using_text.value = settingsStore.get(settings.discord.usingText);
@@ -242,7 +238,6 @@ window.addEventListener("DOMContentLoaded", () => {
adBlock = get("adBlock"); adBlock = get("adBlock");
api = get("apiCheckbox"); api = get("apiCheckbox");
channel = get<HTMLSelectElement>("channel");
customCSS = get("customCSS"); customCSS = get("customCSS");
disableBackgroundThrottle = get("disableBackgroundThrottle"); disableBackgroundThrottle = get("disableBackgroundThrottle");
disableHardwareMediaKeys = get("disableHardwareMediaKeys"); disableHardwareMediaKeys = get("disableHardwareMediaKeys");
@@ -271,14 +266,12 @@ window.addEventListener("DOMContentLoaded", () => {
listenbrainz_delay = get("listenbrainz_delay"); listenbrainz_delay = get("listenbrainz_delay");
discord_button_text = get("discord_button_text"); discord_button_text = get("discord_button_text");
discord_show_song = get("discord_show_song"); discord_show_song = get("discord_show_song");
discord_show_idle = get("discord_show_idle");
discord_using_text = get("discord_using_text"); discord_using_text = get("discord_using_text");
discord_idle_text = get("discord_idle_text"); discord_idle_text = get("discord_idle_text");
refreshSettings(); refreshSettings();
addInputListener(adBlock, settings.adBlock); addInputListener(adBlock, settings.adBlock);
addInputListener(api, settings.api); addInputListener(api, settings.api);
addSelectListener(channel, settings.advanced.tidalUrl);
addTextAreaListener(customCSS, settings.customCSS); addTextAreaListener(customCSS, settings.customCSS);
addInputListener(disableBackgroundThrottle, settings.disableBackgroundThrottle); addInputListener(disableBackgroundThrottle, settings.disableBackgroundThrottle);
addInputListener(disableHardwareMediaKeys, settings.flags.disableHardwareMediaKeys); addInputListener(disableHardwareMediaKeys, settings.flags.disableHardwareMediaKeys);
@@ -315,7 +308,6 @@ window.addEventListener("DOMContentLoaded", () => {
settings.discord.showSong, settings.discord.showSong,
switchesWithSettings.discord_show_song switchesWithSettings.discord_show_song
); );
addInputListener(discord_show_idle, settings.discord.showIdle);
addInputListener(discord_idle_text, settings.discord.idleText); addInputListener(discord_idle_text, settings.discord.idleText);
addInputListener(discord_using_text, settings.discord.usingText); addInputListener(discord_using_text, settings.discord.usingText);
}); });

View File

@@ -49,7 +49,7 @@
<div class="group__option"> <div class="group__option">
<div class="group__description"> <div class="group__description">
<h4>Notifications</h4> <h4>Notifications</h4>
<p>Show a notification when new media starts.</p> <p>Show a notification when a new song starts.</p>
</div> </div>
<label class="switch"> <label class="switch">
<input id="notifications" type="checkbox" /> <input id="notifications" type="checkbox" />
@@ -147,7 +147,7 @@
<p class="group__title">API</p> <p class="group__title">API</p>
<div class="group__description"> <div class="group__description">
<p> <p>
TIDAL Hi-Fi has a built-in web API to allow users to get current media information. TIDAL Hi-Fi has a built-in web API to allow users to get current song information.
You can optionally enable playback control as well. You can optionally enable playback control as well.
</p> </p>
</div> </div>
@@ -227,17 +227,6 @@
</div> </div>
<div id="discord_options"> <div id="discord_options">
<div class="group__option" class="hidden">
<div class="group__description">
<h4>Show Idle Text</h4>
<p>Should the idle text be shown when idle?</p>
</div>
<label class="switch">
<input id="discord_show_idle" type="checkbox" />
<span class="switch__slider"></span>
</label>
</div>
<div class="group__option" class="hidden"> <div class="group__option" class="hidden">
<div class="group__description"> <div class="group__description">
<h4>Idle Text</h4> <h4>Idle Text</h4>
@@ -256,8 +245,8 @@
<div class="group__option" class="hidden"> <div class="group__option" class="hidden">
<div class="group__description"> <div class="group__description">
<h4>Show media</h4> <h4>Show song</h4>
<p>Show the current media in the Discord client</p> <p>Show the current song in the Discord client</p>
</div> </div>
<label class="switch"> <label class="switch">
<input id="discord_show_song" type="checkbox" /> <input id="discord_show_song" type="checkbox" />
@@ -289,7 +278,7 @@
<div class="group__option"> <div class="group__option">
<div class="group__description"> <div class="group__description">
<h4>Button text</h4> <h4>Button text</h4>
<p>Text to display on the button below the media information.</p> <p>Text to display on the button below the song information.</p>
<input id="discord_button_text" type="text" class="text-input" name="discord_button_text" /> <input id="discord_button_text" type="text" class="text-input" name="discord_button_text" />
</div> </div>
</div> </div>
@@ -327,7 +316,7 @@
</div> </div>
<div class="group__description"> <div class="group__description">
<h4>ScrobbleDelay</h4> <h4>ScrobbleDelay</h4>
<p>The delay (in ms) to send a listen to ListenBrainz. Prevents spamming the API when you fast forward <p>The delay (in ms) to send a song to ListenBrainz. Prevents spamming the API when you fast forward
immediately</p> immediately</p>
<input id="listenbrainz_delay" type="number" class="text-input" name="listenbrainz_delay" /> <input id="listenbrainz_delay" type="number" class="text-input" name="listenbrainz_delay" />
</div> </div>
@@ -349,20 +338,6 @@
<input id="updateFrequency" type="number" class="text-input" name="updateFrequency" /> <input id="updateFrequency" type="number" class="text-input" name="updateFrequency" />
</div> </div>
</div> </div>
<div class="group__option">
<div class="group__description">
<h4>Tidal channel / URL</h4>
<p>
Which URL Tidal Hi-Fi should use.
<strong>note! Beta might break at any time</strong>
</p>
<select class="select-input" id="channel" name="channel">
<option value="https://listen.tidal.com">Stable (listen.tidal.com)</option>
<option value="https://listen.stage.tidal.com">Staging (listen.stage.tidal.com)</option>
</select>
</div>
</div>
</div> </div>
<div class="group"> <div class="group">
<p class="group__title">Flags</p> <p class="group__title">Flags</p>
@@ -468,7 +443,7 @@
<h4>TIDAL Hi-Fi</h4> <h4>TIDAL Hi-Fi</h4>
<div class="about-section__version"> <div class="about-section__version">
<a target="_blank" rel="noopener" <a target="_blank" rel="noopener"
href="https://github.com/Mastermindzh/tidal-hifi/releases/tag/5.16.0">5.16.0</a> href="https://github.com/Mastermindzh/tidal-hifi/releases/tag/5.14.1">5.14.1</a>
</div> </div>
<div class="about-section__links"> <div class="about-section__links">
<a target="_blank" rel="noopener" href="https://github.com/mastermindzh/tidal-hifi/" <a target="_blank" rel="noopener" href="https://github.com/mastermindzh/tidal-hifi/"
@@ -491,4 +466,4 @@
</div> </div>
</body> </body>
</html> </html>

View File

@@ -74,7 +74,7 @@ const elements = {
}, },
/** /**
* Get the icon of the current media * Get the icon of the current song
*/ */
getSongIcon: function () { getSongIcon: function () {
const figure = this.get("media"); const figure = this.get("media");
@@ -90,7 +90,7 @@ const elements = {
}, },
/** /**
* returns an array of all artists in the current media * returns an array of all artists in the current song
* @returns {Array} artists * @returns {Array} artists
*/ */
getArtistsArray: function () { getArtistsArray: function () {
@@ -195,7 +195,7 @@ function getUpdateFrequency() {
} }
/** /**
* Play or pause the current media * Play or pause the current song
*/ */
function playPause() { function playPause() {
const play = elements.get("play"); const play = elements.get("play");
@@ -394,30 +394,18 @@ function updateMediaInfo(mediaInfo: MediaInfo, notify: boolean) {
if (mediaInfo) { if (mediaInfo) {
currentMediaInfo = mediaInfo; currentMediaInfo = mediaInfo;
ipcRenderer.send(globalEvents.updateInfo, mediaInfo); ipcRenderer.send(globalEvents.updateInfo, mediaInfo);
if (settingsStore.get(settings.notifications) && notify) {
if (currentNotification) currentNotification.close();
currentNotification = new Notification({
title: mediaInfo.title,
body: mediaInfo.artists,
icon: mediaInfo.icon,
});
currentNotification.show();
}
updateMpris(mediaInfo); updateMpris(mediaInfo);
updateListenBrainz(mediaInfo); updateListenBrainz(mediaInfo);
if (notify) {
sendNotification(mediaInfo);
}
}
}
/**
* send a desktop notification if enabled in settings
* @param mediaInfo
* @param notify Whether to notify
*/
async function sendNotification(mediaInfo: MediaInfo) {
if (settingsStore.get(settings.notifications)) {
if (currentNotification) {
currentNotification.close();
}
currentNotification = new Notification({
title: mediaInfo.title,
body: mediaInfo.artists,
icon: mediaInfo.icon,
});
currentNotification.show();
} }
} }

View File

@@ -14,7 +14,7 @@ export let rpc: Client;
const observer = () => { const observer = () => {
if (rpc) { if (rpc) {
updateActivity(); rpc.setActivity(getActivity());
} }
}; };
@@ -24,15 +24,6 @@ const defaultPresence = {
instance: false, instance: false,
}; };
const updateActivity = () => {
const showIdle = settingsStore.get<string, boolean>(settings.discord.showIdle) ?? true;
if (mediaInfo.status === MediaStatus.paused && !showIdle) {
rpc.clearActivity();
} else {
rpc.setActivity(getActivity());
}
};
const getActivity = (): Presence => { const getActivity = (): Presence => {
const presence: Presence = { ...defaultPresence }; const presence: Presence = { ...defaultPresence };
@@ -63,33 +54,18 @@ const getActivity = (): Presence => {
return { includeTimestamps, detailsPrefix, buttonText }; return { includeTimestamps, detailsPrefix, buttonText };
} }
/**
* Pad a string using spaces to at least 2 characters
* @param input string to pad with 2 characters
* @returns
*/
function pad(input: string): string {
return input.padEnd(2, " ");
}
function setPresenceFromMediaInfo(detailsPrefix: string, buttonText: string) { 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);
if (mediaInfo.url) { if (mediaInfo.url) {
presence.details = `${detailsPrefix}${title}`; presence.details = `${detailsPrefix}${mediaInfo.title}`;
presence.state = artists ? artists : "unknown artist(s)"; presence.state = mediaInfo.artists ? mediaInfo.artists : "unknown artist(s)";
presence.largeImageKey = mediaInfo.image; presence.largeImageKey = mediaInfo.image;
if (album) { if (mediaInfo.album) {
presence.largeImageText = album; presence.largeImageText = mediaInfo.album;
} }
presence.buttons = [{ label: buttonText, url: mediaInfo.url }]; presence.buttons = [{ label: buttonText, url: mediaInfo.url }];
} else { } else {
presence.details = `Watching ${title}`; presence.details = `Watching ${mediaInfo.title}`;
presence.state = artists; presence.state = mediaInfo.artists;
} }
} }
@@ -114,13 +90,9 @@ export const initRPC = () => {
rpc.login({ clientId }).then( rpc.login({ clientId }).then(
() => { () => {
rpc.on("ready", () => { rpc.on("ready", () => {
updateActivity(); rpc.setActivity(getActivity());
});
const { updateInfo, play, pause, playPause } = globalEvents;
[updateInfo, play, pause, playPause].forEach((status) => {
ipcMain.on(status, observer);
}); });
ipcMain.on(globalEvents.updateInfo, observer);
}, },
() => { () => {
Logger.log("Can't connect to Discord, is it running?"); Logger.log("Can't connect to Discord, is it running?");

View File

@@ -28,9 +28,6 @@ const buildMigration = (
export const settingsStore = new Store({ export const settingsStore = new Store({
defaults: { defaults: {
adBlock: false, adBlock: false,
advanced: {
tidalUrl: "https://listen.tidal.com",
},
api: true, api: true,
apiSettings: { apiSettings: {
port: 47836, port: 47836,
@@ -43,7 +40,6 @@ export const settingsStore = new Store({
enableDiscord: false, enableDiscord: false,
discord: { discord: {
showSong: true, showSong: true,
showIdle: true,
idleText: "Browsing Tidal", idleText: "Browsing Tidal",
usingText: "Playing media on TIDAL", usingText: "Playing media on TIDAL",
includeTimestamps: true, includeTimestamps: true,
@@ -111,14 +107,6 @@ export const settingsStore = new Store({
{ key: settings.apiSettings.hostname, value: "127.0.0.1" }, { key: settings.apiSettings.hostname, value: "127.0.0.1" },
]); ]);
}, },
"5.15.0": (migrationStore) => {
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" }]);
},
}, },
}); });