mirror of
https://github.com/Mastermindzh/tidal-hifi.git
synced 2025-09-13 15:19:17 +02:00
Compare commits
28 Commits
cff5fc37b2
...
5.18.0
Author | SHA1 | Date | |
---|---|---|---|
35ed4807e3 | |||
deff9524a8 | |||
34c7777eeb | |||
048e949f30 | |||
|
4a976bc58c | ||
ff4c51234b | |||
|
c4ee6b51b9 | ||
45fe336598 | |||
|
fe9f50aaf5 | ||
aaf7a1b662 | |||
755be0ee30 | |||
|
9d736b2bd9 | ||
f4d4b1a1df | |||
|
0c27c815f5 | ||
|
a3aa45a96b | ||
ae699887b2 | |||
a8c635932f | |||
66d0d004bf | |||
d1e0321058 | |||
2ab5a556ab | |||
baf719fc60 | |||
15c8f6a418 | |||
f73521e2e5 | |||
|
0f5e00c4df | ||
|
974877ea4f | ||
|
cb8667bd41 | ||
91156e5936 | |||
|
57e9a2dcb8 |
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -14,7 +14,6 @@
|
||||
"rescrobbler",
|
||||
"scrobble",
|
||||
"scrobbling",
|
||||
"Songwhip",
|
||||
"trackid",
|
||||
"tracklist",
|
||||
"widevine",
|
||||
|
13
CHANGELOG.md
13
CHANGELOG.md
@@ -4,6 +4,19 @@ 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.18.0]
|
||||
|
||||
- [Dianoga](https://github.com/Dianoga) fixed the duration selector, restoring mpris & partial API data.
|
||||
- PR: #554
|
||||
- Added `xesam:url` property to mpris metadata fixes [#506](https://github.com/Mastermindzh/tidal-hifi/issues/506)
|
||||
|
||||
## [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 the Songwhip (they shut down) integration and replaced it with TIDAL's universal link system
|
||||
|
||||
## [5.16.0]
|
||||
|
||||
- Fix issue #449 Discord RPC stuck on "Browsing Tidal".
|
||||
|
@@ -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
|
||||
|
95
package-lock.json
generated
95
package-lock.json
generated
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"name": "tidal-hifi",
|
||||
"version": "5.16.0",
|
||||
"version": "5.18.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "tidal-hifi",
|
||||
"version": "5.16.0",
|
||||
"version": "5.18.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/remote": "^2.1.2",
|
||||
"@types/swagger-jsdoc": "^6.0.4",
|
||||
"@xhayper/discord-rpc": "^1.2.0",
|
||||
"axios": "^1.7.7",
|
||||
"axios": "^1.7.9",
|
||||
"cors": "^2.8.5",
|
||||
"electron-store": "^8.2.0",
|
||||
"express": "^4.21.1",
|
||||
"hotkeys-js": "^3.13.7",
|
||||
"express": "^4.21.2",
|
||||
"hotkeys-js": "^3.13.9",
|
||||
"mpris-service": "^2.1.2",
|
||||
"request": "^2.88.2",
|
||||
"sass": "^1.78.0",
|
||||
"sass": "^1.79.4",
|
||||
"swagger-ui-express": "^5.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -2127,6 +2127,7 @@
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
@@ -2363,9 +2364,9 @@
|
||||
"integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.7",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
|
||||
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
|
||||
"version": "1.7.9",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
|
||||
"integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
@@ -2425,6 +2426,7 @@
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -2522,6 +2524,7 @@
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
@@ -2533,6 +2536,7 @@
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@@ -2760,6 +2764,7 @@
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -2786,6 +2791,7 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
@@ -4161,9 +4167,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.21.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
|
||||
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
@@ -4185,7 +4191,7 @@
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.10",
|
||||
"path-to-regexp": "0.1.12",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "6.13.0",
|
||||
"range-parser": "~1.2.1",
|
||||
@@ -4200,6 +4206,10 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/express/node_modules/debug": {
|
||||
@@ -4612,6 +4622,7 @@
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -5084,9 +5095,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/hotkeys-js": {
|
||||
"version": "3.13.7",
|
||||
"resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.13.7.tgz",
|
||||
"integrity": "sha512-ygFIdTqqwG4fFP7kkiYlvayZppeIQX2aPpirsngkv1xM1lP0piDY5QEh68nQnIKvz64hfocxhBaD/uK3sSK1yQ==",
|
||||
"version": "3.13.9",
|
||||
"resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.13.9.tgz",
|
||||
"integrity": "sha512-3TRCj9u9KUH6cKo25w4KIdBfdBfNRjfUwrljCLDC2XhmPDG0SjAZFcFZekpUZFmXzfYoGhFDcdx2gX/vUVtztQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://jaywcjlove.github.io/#/sponsor"
|
||||
}
|
||||
@@ -5331,6 +5343,7 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
},
|
||||
@@ -5384,6 +5397,7 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -5401,6 +5415,7 @@
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
},
|
||||
@@ -6377,6 +6392,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -6674,9 +6690,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
|
||||
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w=="
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
||||
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/path-type": {
|
||||
"version": "4.0.0",
|
||||
@@ -6716,6 +6733,7 @@
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
@@ -7196,6 +7214,7 @@
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"picomatch": "^2.2.1"
|
||||
},
|
||||
@@ -7472,12 +7491,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.78.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.78.0.tgz",
|
||||
"integrity": "sha512-AaIqGSrjo5lA2Yg7RvFZrlXDBCp3nV4XP73GrLGvdRWWwk+8H3l0SDvq/5bA4eF+0RFPLuWUk3E+P1U/YqnpsQ==",
|
||||
"version": "1.79.4",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.79.4.tgz",
|
||||
"integrity": "sha512-K0QDSNPXgyqO4GZq2HO5Q70TLxTH6cIT59RdoCHMivrC8rqzaTw5ab9prjz9KUN1El4FLXrBXJhik61JR4HcGg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"chokidar": "^4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
},
|
||||
@@ -7488,6 +7507,34 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sass/node_modules/chokidar": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz",
|
||||
"integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readdirp": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.16.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/sass/node_modules/readdirp": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz",
|
||||
"integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 14.16.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz",
|
||||
@@ -8550,6 +8597,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
@@ -8561,6 +8609,7 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
|
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "tidal-hifi",
|
||||
"version": "5.16.0",
|
||||
"version": "5.18.0",
|
||||
"description": "Tidal on Electron with widevine(hifi) support",
|
||||
"main": "ts-dist/main.js",
|
||||
"scripts": {
|
||||
@@ -43,14 +43,14 @@
|
||||
"@electron/remote": "^2.1.2",
|
||||
"@types/swagger-jsdoc": "^6.0.4",
|
||||
"@xhayper/discord-rpc": "^1.2.0",
|
||||
"axios": "^1.7.7",
|
||||
"axios": "^1.7.9",
|
||||
"cors": "^2.8.5",
|
||||
"electron-store": "^8.2.0",
|
||||
"express": "^4.21.1",
|
||||
"hotkeys-js": "^3.13.7",
|
||||
"express": "^4.21.2",
|
||||
"hotkeys-js": "^3.13.9",
|
||||
"mpris-service": "^2.1.2",
|
||||
"request": "^2.88.2",
|
||||
"sass": "^1.78.0",
|
||||
"sass": "^1.79.4",
|
||||
"swagger-ui-express": "^5.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@@ -16,17 +16,19 @@
|
||||
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"]',
|
||||
openSettings: '*[data-test^="open-settings"]',
|
||||
media: '*[data-test="current-media-imagery"]',
|
||||
image: "img",
|
||||
current: '*[data-test="current-time"]',
|
||||
duration: '*[class^=playbackControlsContainer] *[data-test="duration"]',
|
||||
duration: '*[class^=_playbackControlsContainer] *[data-test="duration"]',
|
||||
bar: '*[data-test="progress-bar"]',
|
||||
footer: "#footerPlayer",
|
||||
mediaItem: "[data-type='mediaItem']",
|
||||
album_header_title: '*[class^="playingFrom"] span:nth-child(2)',
|
||||
playingFrom: '*[class^="playingFrom"] span:nth-child(2)',
|
||||
album_header_title: '*[class^="_playingFrom"] span:nth-child(2)',
|
||||
playing_from: '*[class^="_playingFrom"] span:nth-child(2)',
|
||||
queue_album: "*[class^=playQueueItemsContainer] *[class^=groupTitle] span:nth-child(2)",
|
||||
currentlyPlaying: "[class^='isPlayingIcon'], [data-test-is-playing='true']",
|
||||
album_name_cell: '[class^="album"]',
|
||||
tracklist_row: '[data-test="tracklist-row"]',
|
||||
|
@@ -10,7 +10,7 @@ export const globalEvents = {
|
||||
showSettings: "showSettings",
|
||||
storeChanged: "storeChanged",
|
||||
error: "error",
|
||||
whip: "whip",
|
||||
getUniversalLink: "getUniversalLink",
|
||||
log: "log",
|
||||
toggleFavorite: "toggleFavorite",
|
||||
toggleShuffle: "toggleShuffle",
|
||||
|
@@ -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",
|
||||
},
|
||||
@@ -52,6 +55,7 @@ export const settings = {
|
||||
singleInstance: "singleInstance",
|
||||
skipArtists: "skipArtists",
|
||||
skippedArtists: "skippedArtists",
|
||||
staticWindowTitle: "staticWindowTitle",
|
||||
theme: "theme",
|
||||
trayIcon: "trayIcon",
|
||||
updateFrequency: "updateFrequency",
|
||||
|
@@ -2,7 +2,7 @@
|
||||
"openapi": "3.1.0",
|
||||
"info": {
|
||||
"title": "TIDAL Hi-Fi API",
|
||||
"version": "5.16.0",
|
||||
"version": "5.18.0",
|
||||
"description": "",
|
||||
"license": {
|
||||
"name": "MIT",
|
||||
|
10
src/features/sharingService/sharingService.ts
Normal file
10
src/features/sharingService/sharingService.ts
Normal file
@@ -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`;
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -1,4 +0,0 @@
|
||||
export interface ServiceLinks {
|
||||
link: string;
|
||||
countries: string[];
|
||||
}
|
@@ -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[];
|
||||
};
|
||||
};
|
||||
}
|
@@ -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<WhippedResult> {
|
||||
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}`;
|
||||
}
|
||||
}
|
@@ -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);
|
||||
|
@@ -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,
|
||||
@@ -41,6 +46,7 @@ let adBlock: HTMLInputElement,
|
||||
singleInstance: HTMLInputElement,
|
||||
skipArtists: HTMLInputElement,
|
||||
skippedArtists: HTMLInputElement,
|
||||
staticWindowTitle: HTMLInputElement,
|
||||
theme: HTMLSelectElement,
|
||||
trayIcon: HTMLInputElement,
|
||||
updateFrequency: HTMLInputElement,
|
||||
@@ -49,7 +55,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);
|
||||
|
||||
@@ -129,8 +141,9 @@ 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<string, string[]>(settings.skippedArtists).join("\n");
|
||||
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);
|
||||
@@ -138,6 +151,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) => {
|
||||
@@ -244,13 +263,20 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
trayIcon = get("trayIcon");
|
||||
skipArtists = get("skipArtists");
|
||||
skippedArtists = get("skippedArtists");
|
||||
staticWindowTitle = get("staticWindowTitle");
|
||||
singleInstance = get("singleInstance");
|
||||
updateFrequency = get("updateFrequency");
|
||||
enableListenBrainz = get("enableListenBrainz");
|
||||
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);
|
||||
@@ -272,6 +298,7 @@ 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);
|
||||
@@ -285,4 +312,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);
|
||||
});
|
||||
|
@@ -106,6 +106,16 @@
|
||||
<span class="switch__slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="group__option">
|
||||
<div class="group__description">
|
||||
<h4>Static Window Title</h4>
|
||||
<p>Makes the window title "TIDAL Hi-Fi" instead of changing to the currently playing song.</p>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input id="staticWindowTitle" type="checkbox" />
|
||||
<span class="switch__slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="group__option">
|
||||
<div class="group__description">
|
||||
<h4>Minimize on Close</h4>
|
||||
@@ -226,13 +236,75 @@
|
||||
</label>
|
||||
</div>
|
||||
<div id="discord_options">
|
||||
|
||||
<div class="group__option" class="hidden">
|
||||
<div class="group__description">
|
||||
<h4>Details prefix</h4>
|
||||
<p>Prefix for the "details" field of Discord's rich presence.</p>
|
||||
<input id="discord_details_prefix" type="text" class="text-input" name="discord_details_prefix" />
|
||||
<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__description">
|
||||
<h4>Idle Text</h4>
|
||||
<p>The text displayed on Discord's rich presence while idling in the app.</p>
|
||||
<input id="discord_idle_text" type="text" class="text-input" name="discord_idle_text" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group__option" class="hidden">
|
||||
<div class="group__description">
|
||||
<h4>Using Tidal Text</h4>
|
||||
<p>The text displayed on Discord's rich presence while "showSong" is turned off</p>
|
||||
<input id="discord_using_text" type="text" class="text-input" name="discord_using_text" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group__option" class="hidden">
|
||||
<div class="group__description">
|
||||
<h4>Show media</h4>
|
||||
<p>Show the current media in the Discord client</p>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input id="discord_show_song" type="checkbox" />
|
||||
<span class="switch__slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div id="discord_show_song_options" class="hidden">
|
||||
|
||||
<div class="group__option" class="hidden">
|
||||
<div class="group__description">
|
||||
<h4>Include timestamps</h4>
|
||||
<p>Show current/end playtime in the Discord client</p>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input id="discord_include_timestamps" type="checkbox" />
|
||||
<span class="switch__slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="group__option" class="hidden">
|
||||
<div class="group__description">
|
||||
<h4>Details prefix</h4>
|
||||
<p>Prefix for the "details" field of Discord's rich presence.</p>
|
||||
<input id="discord_details_prefix" type="text" class="text-input" name="discord_details_prefix" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group__option">
|
||||
<div class="group__description">
|
||||
<h4>Button text</h4>
|
||||
<p>Text to display on the button below the media information.</p>
|
||||
<input id="discord_button_text" type="text" class="text-input" name="discord_button_text" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
@@ -406,7 +478,7 @@
|
||||
<h4>TIDAL Hi-Fi</h4>
|
||||
<div class="about-section__version">
|
||||
<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.18.0">5.18.0</a>
|
||||
</div>
|
||||
<div class="about-section__links">
|
||||
<a target="_blank" rel="noopener" href="https://github.com/mastermindzh/tidal-hifi/"
|
||||
@@ -429,4 +501,4 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
@@ -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";
|
||||
@@ -48,17 +48,18 @@ 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"]',
|
||||
openSettings: '*[data-test^="open-settings"]',
|
||||
media: '*[data-test="current-media-imagery"]',
|
||||
image: "img",
|
||||
current: '*[data-test="current-time"]',
|
||||
duration: '*[class^=playbackControlsContainer] *[data-test="duration"]',
|
||||
duration: '*[class^=_playbackControlsContainer] *[data-test="duration"]',
|
||||
bar: '*[data-test="progress-bar"]',
|
||||
footer: "#footerPlayer",
|
||||
mediaItem: "[data-type='mediaItem']",
|
||||
album_header_title: '*[class^="playingFrom"] span:nth-child(2)',
|
||||
playing_from: '*[class^="playingFrom"] span:nth-child(2)',
|
||||
album_header_title: '*[class^="_playingFrom"] span:nth-child(2)',
|
||||
playing_from: '*[class^="_playingFrom"] span:nth-child(2)',
|
||||
queue_album: "*[class^=playQueueItemsContainer] *[class^=groupTitle] span:nth-child(2)",
|
||||
currentlyPlaying: "[class^='isPlayingIcon'], [data-test-is-playing='true']",
|
||||
album_name_cell: '[class^="album"]',
|
||||
@@ -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();
|
||||
});
|
||||
@@ -483,6 +483,7 @@ function updateMpris(mediaInfo: MediaInfo) {
|
||||
"xesam:title": mediaInfo.title,
|
||||
"xesam:artist": [mediaInfo.artists],
|
||||
"xesam:album": mediaInfo.album,
|
||||
"xesam:url": mediaInfo.url,
|
||||
"mpris:artUrl": mediaInfo.image,
|
||||
"mpris:length": convertDuration(mediaInfo.duration) * 1000 * 1000,
|
||||
"mpris:trackid": "/org/mpris/MediaPlayer2/track/" + getTrackID(),
|
||||
@@ -550,6 +551,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 +596,9 @@ setInterval(function () {
|
||||
};
|
||||
|
||||
// update title, url and play info with new info
|
||||
setTitle(songDashArtistTitle);
|
||||
settingsStore.get(settings.staticWindowTitle)
|
||||
? setTitle(staticTitle)
|
||||
: setTitle(songDashArtistTitle);
|
||||
getTrackURL();
|
||||
currentSong = songDashArtistTitle;
|
||||
currentPlayStatus = currentStatus;
|
||||
|
@@ -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<string, boolean>(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<string, string>(settings.discord.idleText) ?? "Browsing Tidal";
|
||||
} else {
|
||||
const showSong = settingsStore.get<string, boolean>(settings.discord.showSong) ?? false;
|
||||
if (showSong) {
|
||||
const { includeTimestamps, detailsPrefix, buttonText } = getFromStore();
|
||||
includeTimeStamps(includeTimestamps);
|
||||
setPresenceFromMediaInfo(detailsPrefix, buttonText);
|
||||
} else {
|
||||
presence.details =
|
||||
settingsStore.get<string, string>(settings.discord.usingText) ?? "Playing media on TIDAL";
|
||||
}
|
||||
}
|
||||
|
||||
return presence;
|
||||
|
||||
function getFromStore() {
|
||||
const includeTimestamps =
|
||||
settingsStore.get<string, boolean>(settings.discord.includeTimestamps) ?? true;
|
||||
const detailsPrefix =
|
||||
settingsStore.get<string, string>(settings.discord.detailsPrefix) ?? "Listening to ";
|
||||
const buttonText =
|
||||
settingsStore.get<string, string>(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,35 @@ 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<string, string>(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);
|
||||
const now = Math.trunc((Date.now() + 500) / 1000);
|
||||
presence.startTimestamp = now - currentSeconds;
|
||||
presence.endTimestamp = presence.startTimestamp + durationSeconds;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -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,
|
||||
@@ -66,6 +69,7 @@ export const settingsStore = new Store({
|
||||
singleInstance: true,
|
||||
skipArtists: false,
|
||||
skippedArtists: [""],
|
||||
staticWindowTitle: false,
|
||||
theme: "none",
|
||||
trayIcon: true,
|
||||
updateFrequency: 500,
|
||||
@@ -86,8 +90,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 +116,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" }]);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user