mirror of
https://github.com/Mastermindzh/tidal-hifi.git
synced 2024-11-22 13:32:42 +01:00
commit
3641f07558
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -2,6 +2,7 @@
|
||||
"cSpell.words": [
|
||||
"Brainz",
|
||||
"Castlabs",
|
||||
"Fi's",
|
||||
"flac",
|
||||
"Flatpak",
|
||||
"geqnfr",
|
||||
|
10
CHANGELOG.md
10
CHANGELOG.md
@ -4,6 +4,16 @@ 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.14]
|
||||
|
||||
- Simplified `MediaInfo` & `Options` types
|
||||
- Added `playingFrom` information to the info API
|
||||
- also changed the way we update Album info since Playing From now shows the correct Album.
|
||||
- API now allows you to set the `hostname` so you can control who can interact with the API.
|
||||
- Reworked swagger generation hotfix to properly generate `swagger.json` during the compile step
|
||||
- Might switch to tsoa in the future, idk yet.
|
||||
- Added [Tidal Magazine](https://tidal.com/magazine/) integration (in the menubar or use `Ctrl + M`)
|
||||
|
||||
## [5.13.1]
|
||||
|
||||
- removed Swagger generation step in favor of pre-generated file.
|
||||
|
@ -50,6 +50,7 @@ The web version of [listen.tidal.com](https://listen.tidal.com) running in elect
|
||||
- [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
|
||||
- UI + Json config (`~/.config/tidal-hifi/`, or `~/.var/app/com.mastermindzh.tidal-hifi/` for Flatpak)
|
||||
|
||||
|
233
package-lock.json
generated
233
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "tidal-hifi",
|
||||
"version": "5.13.1",
|
||||
"version": "5.14.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "tidal-hifi",
|
||||
"version": "5.13.1",
|
||||
"version": "5.14.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/remote": "^2.1.2",
|
||||
@ -20,7 +20,6 @@
|
||||
"mpris-service": "^2.1.2",
|
||||
"request": "^2.88.2",
|
||||
"sass": "^1.75.0",
|
||||
"swagger-jsdoc": "^6.2.8",
|
||||
"swagger-ui-express": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -45,6 +44,8 @@
|
||||
"stylelint-config-standard": "^36.0.0",
|
||||
"stylelint-config-standard-scss": "^13.0.0",
|
||||
"stylelint-prettier": "^5.0.0",
|
||||
"swagger-jsdoc": "^6.2.8",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsc-watch": "^6.0.4",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
@ -62,6 +63,7 @@
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz",
|
||||
"integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jsdevtools/ono": "^7.1.3",
|
||||
"@types/json-schema": "^7.0.6",
|
||||
@ -73,6 +75,7 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz",
|
||||
"integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
@ -80,12 +83,14 @@
|
||||
"node_modules/@apidevtools/swagger-methods": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz",
|
||||
"integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg=="
|
||||
"integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@apidevtools/swagger-parser": {
|
||||
"version": "10.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz",
|
||||
"integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@apidevtools/json-schema-ref-parser": "^9.0.6",
|
||||
"@apidevtools/openapi-schemas": "^2.0.4",
|
||||
@ -276,6 +281,19 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/css-parser-algorithms": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.5.0.tgz",
|
||||
@ -877,10 +895,39 @@
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.15",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
|
||||
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@jsdevtools/ono": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
|
||||
"integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="
|
||||
"integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@malept/cross-spawn-promise": {
|
||||
"version": "1.1.1",
|
||||
@ -1045,6 +1092,34 @@
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsconfig/node10": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
||||
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node12": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node14": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node16": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/body-parser": {
|
||||
"version": "1.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
||||
@ -1161,7 +1236,8 @@
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="
|
||||
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/keyv": {
|
||||
"version": "3.1.4",
|
||||
@ -1565,6 +1641,16 @@
|
||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-walk": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
|
||||
"integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
@ -1859,10 +1945,18 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/array-flatten": {
|
||||
"version": "1.1.1",
|
||||
@ -1988,7 +2082,8 @@
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
@ -2336,7 +2431,8 @@
|
||||
"node_modules/call-me-maybe": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
|
||||
"integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ=="
|
||||
"integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/callsites": {
|
||||
"version": "3.1.0",
|
||||
@ -2575,7 +2671,8 @@
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "1.6.2",
|
||||
@ -2845,6 +2942,13 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
@ -3081,6 +3185,16 @@
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/dir-compare": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz",
|
||||
@ -3219,6 +3333,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
||||
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esutils": "^2.0.2"
|
||||
},
|
||||
@ -3803,6 +3918,7 @@
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -4270,7 +4386,8 @@
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
@ -4937,6 +5054,7 @@
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
@ -5229,6 +5347,7 @@
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
@ -5477,12 +5596,14 @@
|
||||
"node_modules/lodash.get": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
|
||||
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
|
||||
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
@ -5500,7 +5621,8 @@
|
||||
"node_modules/lodash.mergewith": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
|
||||
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="
|
||||
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.template": {
|
||||
"version": "4.5.0",
|
||||
@ -5558,6 +5680,13 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/map-stream": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
|
||||
@ -6186,6 +6315,7 @@
|
||||
"version": "12.1.3",
|
||||
"resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
|
||||
"integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/optionator": {
|
||||
@ -6302,6 +6432,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -7947,6 +8078,8 @@
|
||||
"version": "6.2.8",
|
||||
"resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz",
|
||||
"integrity": "sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"commander": "6.2.0",
|
||||
"doctrine": "3.0.0",
|
||||
@ -7966,6 +8099,7 @@
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@ -7975,6 +8109,7 @@
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz",
|
||||
"integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
@ -7983,6 +8118,7 @@
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
@ -8002,6 +8138,7 @@
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
@ -8013,6 +8150,7 @@
|
||||
"version": "10.0.3",
|
||||
"resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.3.tgz",
|
||||
"integrity": "sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@apidevtools/swagger-parser": "10.0.3"
|
||||
},
|
||||
@ -8322,6 +8460,50 @@
|
||||
"typescript": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
"version": "10.9.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
"@tsconfig/node12": "^1.0.7",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@tsconfig/node16": "^1.0.2",
|
||||
"acorn": "^8.4.1",
|
||||
"acorn-walk": "^8.1.1",
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"v8-compile-cache-lib": "^3.0.1",
|
||||
"yn": "3.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"ts-node": "dist/bin.js",
|
||||
"ts-node-cwd": "dist/bin-cwd.js",
|
||||
"ts-node-esm": "dist/bin-esm.js",
|
||||
"ts-node-script": "dist/bin-script.js",
|
||||
"ts-node-transpile-only": "dist/bin-transpile.js",
|
||||
"ts-script": "dist/bin-script-deprecated.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/core": ">=1.2.50",
|
||||
"@swc/wasm": ">=1.2.50",
|
||||
"@types/node": "*",
|
||||
"typescript": ">=2.7"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@swc/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@swc/wasm": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/tsc-watch": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-6.0.4.tgz",
|
||||
@ -8486,10 +8668,18 @@
|
||||
"uuid": "bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/validator": {
|
||||
"version": "13.12.0",
|
||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz",
|
||||
"integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
@ -8682,6 +8872,7 @@
|
||||
"version": "2.0.0-1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz",
|
||||
"integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
@ -8722,6 +8913,16 @@
|
||||
"fd-slicer": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
@ -8738,6 +8939,7 @@
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz",
|
||||
"integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
@ -8757,6 +8959,7 @@
|
||||
"version": "9.5.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
|
||||
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": "^12.20.0 || >=14"
|
||||
@ -8815,4 +9018,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "tidal-hifi",
|
||||
"version": "5.13.1",
|
||||
"version": "5.14.0",
|
||||
"description": "Tidal on Electron with widevine(hifi) support",
|
||||
"main": "ts-dist/main.js",
|
||||
"scripts": {
|
||||
@ -8,9 +8,10 @@
|
||||
"watchStart": "nodemon dist -x \"npm run start\"",
|
||||
"compile": "tsc && npm run sass-and-copy",
|
||||
"deps": "npm run watch",
|
||||
"watch": "tsc-watch --onSuccess \"npm run sass-and-copy\"",
|
||||
"watch": "tsc-watch --onSuccess \"npm run compile-all\"",
|
||||
"copy-files": "copyfiles -u 1 --exclude './src/**/*.ts' --exclude './src/**/*.scss' \"./src/**/*\" ts-dist",
|
||||
"copy-themes-dev": "copyfiles -u 1 \"./themes/*\" node_modules/electron/dist/resources",
|
||||
"compile-all": "npm run sass-and-copy && ts-node scripts/generate-swagger.ts",
|
||||
"sass-and-copy": "npm run sass && npm run copy-files && npm run copy-themes-dev",
|
||||
"build": "npm run builder -- -c ./build/electron-builder.yml",
|
||||
"build-deb": "npm run builder -- -c ./build/electron-builder.deb.yml",
|
||||
@ -50,7 +51,6 @@
|
||||
"mpris-service": "^2.1.2",
|
||||
"request": "^2.88.2",
|
||||
"sass": "^1.75.0",
|
||||
"swagger-jsdoc": "^6.2.8",
|
||||
"swagger-ui-express": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -75,6 +75,8 @@
|
||||
"stylelint-config-standard": "^36.0.0",
|
||||
"stylelint-config-standard-scss": "^13.0.0",
|
||||
"stylelint-prettier": "^5.0.0",
|
||||
"swagger-jsdoc": "^6.2.8",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsc-watch": "^6.0.4",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
|
30
scripts/generate-swagger.ts
Normal file
30
scripts/generate-swagger.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import fs from "fs";
|
||||
import swaggerjsdoc from "swagger-jsdoc";
|
||||
import packagejson from "./../package.json";
|
||||
|
||||
const specs = swaggerjsdoc({
|
||||
definition: {
|
||||
openapi: "3.1.0",
|
||||
info: {
|
||||
title: "TIDAL Hi-Fi API",
|
||||
version: packagejson.version,
|
||||
description: "",
|
||||
license: {
|
||||
name: packagejson.license,
|
||||
url: "https://github.com/Mastermindzh/tidal-hifi/blob/master/LICENSE",
|
||||
},
|
||||
contact: {
|
||||
name: "Rick <mastermindzh> van Lieshout",
|
||||
url: "https://www.rickvanlieshout.com",
|
||||
},
|
||||
},
|
||||
externalDocs: {
|
||||
description: "swagger.json",
|
||||
url: "swagger.json",
|
||||
},
|
||||
},
|
||||
apis: ["**/*.ts"],
|
||||
});
|
||||
|
||||
fs.writeFileSync("src/features/api/swagger.json", JSON.stringify(specs, null, 2), "utf8");
|
||||
console.log("Written swagger.json");
|
@ -25,7 +25,8 @@
|
||||
bar: '*[data-test="progress-bar"]',
|
||||
footer: "#footerPlayer",
|
||||
mediaItem: "[data-type='mediaItem']",
|
||||
album_header_title: '.header-details [data-test="title"]',
|
||||
album_header_title: '*[class^="playingFrom"] span:nth-child(2)',
|
||||
playingFrom: '*[class^="playingFrom"] span:nth-child(2)',
|
||||
currentlyPlaying: "[class^='isPlayingIcon'], [data-test-is-playing='true']",
|
||||
album_name_cell: '[class^="album"]',
|
||||
tracklist_row: '[data-test="tracklist-row"]',
|
||||
|
@ -14,6 +14,7 @@ export const settings = {
|
||||
apiSettings: {
|
||||
root: "apiSettings",
|
||||
port: "apiSettings.port",
|
||||
hostname: "apiSettings.hostname",
|
||||
},
|
||||
customCSS: "customCSS",
|
||||
disableBackgroundThrottle: "disableBackgroundThrottle",
|
||||
|
@ -1,7 +1,6 @@
|
||||
import cors from "cors";
|
||||
import { BrowserWindow, dialog } from "electron";
|
||||
import express from "express";
|
||||
import swaggerSpec from "./swagger.json";
|
||||
import cors from "cors";
|
||||
import swaggerUi from "swagger-ui-express";
|
||||
import { settingsStore } from "../../scripts/settings";
|
||||
import { settings } from "./../../constants/settings";
|
||||
@ -9,12 +8,14 @@ import { addCurrentInfo } from "./features/current";
|
||||
import { addPlaybackControl } from "./features/player";
|
||||
import { addSettingsAPI } from "./features/settings/settings";
|
||||
import { addLegacyApi } from "./legacy";
|
||||
import swaggerSpec from "./swagger.json";
|
||||
|
||||
/**
|
||||
* Function to enable TIDAL Hi-Fi's express api
|
||||
*/
|
||||
export const startApi = (mainWindow: BrowserWindow) => {
|
||||
const port = settingsStore.get<string, number>(settings.apiSettings.port);
|
||||
const hostname = settingsStore.get<string, string>(settings.apiSettings.hostname) ?? "127.0.0.1";
|
||||
|
||||
const expressApp = express();
|
||||
expressApp.use(cors());
|
||||
@ -29,7 +30,7 @@ export const startApi = (mainWindow: BrowserWindow) => {
|
||||
addCurrentInfo(expressApp);
|
||||
addSettingsAPI(expressApp, mainWindow);
|
||||
|
||||
const expressInstance = expressApp.listen(port, "127.0.0.1");
|
||||
const expressInstance = expressApp.listen(port, hostname);
|
||||
expressInstance.on("error", function (e: { code: string }) {
|
||||
let message = e.code;
|
||||
if (e.code === "EADDRINUSE") {
|
||||
|
@ -2,7 +2,7 @@
|
||||
"openapi": "3.1.0",
|
||||
"info": {
|
||||
"title": "TIDAL Hi-Fi API",
|
||||
"version": "5.13.1",
|
||||
"version": "5.14.0",
|
||||
"description": "",
|
||||
"license": {
|
||||
"name": "MIT",
|
||||
@ -13,11 +13,6 @@
|
||||
"url": "https://www.rickvanlieshout.com"
|
||||
}
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "http://localhost:47836"
|
||||
}
|
||||
],
|
||||
"externalDocs": {
|
||||
"description": "swagger.json",
|
||||
"url": "swagger.json"
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { MediaStatus } from "./mediaStatus";
|
||||
import { MediaPlayerInfo } from "./mediaPlayerInfo";
|
||||
import { MediaStatus } from "./mediaStatus";
|
||||
|
||||
export interface MediaInfo {
|
||||
title: string;
|
||||
@ -8,6 +8,7 @@ export interface MediaInfo {
|
||||
icon: string;
|
||||
status: MediaStatus;
|
||||
url: string;
|
||||
playingFrom: string;
|
||||
current: string;
|
||||
currentInSeconds?: number;
|
||||
duration: string;
|
||||
|
@ -1,15 +0,0 @@
|
||||
export interface Options {
|
||||
title: string;
|
||||
artists: string;
|
||||
album: string;
|
||||
status: string;
|
||||
url: string;
|
||||
current: string;
|
||||
currentInSeconds: number;
|
||||
duration: string;
|
||||
durationInSeconds: number;
|
||||
"app-name": string;
|
||||
image: string;
|
||||
icon: string;
|
||||
favorite: boolean;
|
||||
}
|
@ -24,7 +24,7 @@ const switchesWithSettings = {
|
||||
switch: "discord_show_song",
|
||||
classToHide: "discord_show_song_options",
|
||||
settingsKey: settings.discord.showSong,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let adBlock: HTMLInputElement,
|
||||
@ -35,6 +35,7 @@ let adBlock: HTMLInputElement,
|
||||
enableCustomHotkeys: HTMLInputElement,
|
||||
enableDiscord: HTMLInputElement,
|
||||
gpuRasterization: HTMLInputElement,
|
||||
hostname: HTMLInputElement,
|
||||
menuBar: HTMLInputElement,
|
||||
minimizeOnClose: HTMLInputElement,
|
||||
mpris: HTMLInputElement,
|
||||
@ -127,6 +128,7 @@ function refreshSettings() {
|
||||
enableDiscord.checked = settingsStore.get(settings.enableDiscord);
|
||||
enableWaylandSupport.checked = settingsStore.get(settings.flags.enableWaylandSupport);
|
||||
gpuRasterization.checked = settingsStore.get(settings.flags.gpuRasterization);
|
||||
hostname.value = settingsStore.get(settings.apiSettings.hostname);
|
||||
menuBar.checked = settingsStore.get(settings.menuBar);
|
||||
minimizeOnClose.checked = settingsStore.get(settings.minimizeOnClose);
|
||||
mpris.checked = settingsStore.get(settings.mpris);
|
||||
@ -243,6 +245,7 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
enableDiscord = get("enableDiscord");
|
||||
enableWaylandSupport = get("enableWaylandSupport");
|
||||
gpuRasterization = get("gpuRasterization");
|
||||
hostname = get("hostname");
|
||||
menuBar = get("menuBar");
|
||||
minimizeOnClose = get("minimizeOnClose");
|
||||
mpris = get("mprisCheckbox");
|
||||
@ -264,7 +267,7 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
discord_button_text = get("discord_button_text");
|
||||
discord_show_song = get("discord_show_song");
|
||||
discord_using_text = get("discord_using_text");
|
||||
discord_idle_text = get("discord_idle_text")
|
||||
discord_idle_text = get("discord_idle_text");
|
||||
|
||||
refreshSettings();
|
||||
addInputListener(adBlock, settings.adBlock);
|
||||
@ -276,6 +279,7 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
addInputListener(enableDiscord, settings.enableDiscord, switchesWithSettings.discord);
|
||||
addInputListener(enableWaylandSupport, settings.flags.enableWaylandSupport);
|
||||
addInputListener(gpuRasterization, settings.flags.gpuRasterization);
|
||||
addInputListener(hostname, settings.apiSettings.hostname);
|
||||
addInputListener(menuBar, settings.menuBar);
|
||||
addInputListener(minimizeOnClose, settings.minimizeOnClose);
|
||||
addInputListener(mpris, settings.mpris);
|
||||
@ -299,7 +303,11 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
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_song,
|
||||
settings.discord.showSong,
|
||||
switchesWithSettings.discord_show_song
|
||||
);
|
||||
addInputListener(discord_idle_text, settings.discord.idleText);
|
||||
addInputListener(discord_using_text, settings.discord.usingText);
|
||||
});
|
||||
|
@ -167,6 +167,16 @@
|
||||
<input id="port" type="number" class="text-input" name="port" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="group__option">
|
||||
<div class="group__description">
|
||||
<h4>API hostname</h4>
|
||||
<p>By default (127.0.0.1) only local apps can interface with the API. <br />
|
||||
Change to 0.0.0.0 to allow <strong>anyone</strong> to interact with it. <br />
|
||||
Other options are available
|
||||
</p>
|
||||
<input id="hostname" type="text" class="text-input" name="hostname" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="group__option">
|
||||
<div class="group__description">
|
||||
<h4>Playback control</h4>
|
||||
@ -433,7 +443,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.13.1">5.13.1</a>
|
||||
href="https://github.com/Mastermindzh/tidal-hifi/releases/tag/5.14.0">5.14.0</a>
|
||||
</div>
|
||||
<div class="about-section__links">
|
||||
<a target="_blank" rel="noopener" href="https://github.com/mastermindzh/tidal-hifi/"
|
||||
|
@ -13,16 +13,15 @@ import { Logger } from "./features/logger";
|
||||
import { Songwhip } from "./features/songwhip/songwhip";
|
||||
import { addCustomCss } from "./features/theming/theming";
|
||||
import { convertDurationToSeconds } from "./features/time/parse";
|
||||
import { MediaInfo } from "./models/mediaInfo";
|
||||
import { MediaStatus } from "./models/mediaStatus";
|
||||
import { Options } from "./models/options";
|
||||
import { RepeatState } from "./models/repeatState";
|
||||
import { downloadFile } from "./scripts/download";
|
||||
import { addHotkey } from "./scripts/hotkeys";
|
||||
import { settingsStore } from "./scripts/settings";
|
||||
import { setTitle } from "./scripts/window-functions";
|
||||
import { RepeatState } from "./models/repeatState";
|
||||
|
||||
const notificationPath = `${app.getPath("userData")}/notification.jpg`;
|
||||
const appName = "TIDAL Hi-Fi";
|
||||
let currentSong = "";
|
||||
let player: Player;
|
||||
let currentPlayStatus = MediaStatus.paused;
|
||||
@ -32,7 +31,7 @@ let scrobbleWaitingForDelay = false;
|
||||
let currentlyPlaying = MediaStatus.paused;
|
||||
let currentRepeatState: RepeatState = RepeatState.off;
|
||||
let currentShuffleState = false;
|
||||
let currentMediaInfo: Options;
|
||||
let currentMediaInfo: MediaInfo;
|
||||
let currentNotification: Electron.Notification;
|
||||
|
||||
const elements = {
|
||||
@ -57,7 +56,8 @@ const elements = {
|
||||
bar: '*[data-test="progress-bar"]',
|
||||
footer: "#footerPlayer",
|
||||
mediaItem: "[data-type='mediaItem']",
|
||||
album_header_title: '.header-details [data-test="title"]',
|
||||
album_header_title: '*[class^="playingFrom"] span:nth-child(2)',
|
||||
playing_from: '*[class^="playingFrom"] span:nth-child(2)',
|
||||
currentlyPlaying: "[class^='isPlayingIcon'], [data-test-is-playing='true']",
|
||||
album_name_cell: '[class^="album"]',
|
||||
tracklist_row: '[data-test="tracklist-row"]',
|
||||
@ -380,23 +380,24 @@ function convertDuration(duration: string) {
|
||||
/**
|
||||
* Update Tidal-hifi's media info
|
||||
*
|
||||
* @param {*} options
|
||||
* @param {*} mediaInfo
|
||||
*/
|
||||
function updateMediaInfo(options: Options, notify: boolean) {
|
||||
if (options) {
|
||||
currentMediaInfo = options;
|
||||
ipcRenderer.send(globalEvents.updateInfo, options);
|
||||
function updateMediaInfo(mediaInfo: MediaInfo, notify: boolean) {
|
||||
if (mediaInfo) {
|
||||
currentMediaInfo = mediaInfo;
|
||||
ipcRenderer.send(globalEvents.updateInfo, mediaInfo);
|
||||
if (settingsStore.get(settings.notifications) && notify) {
|
||||
if (currentNotification) currentNotification.close();
|
||||
currentNotification = new Notification({
|
||||
title: options.title,
|
||||
body: options.artists,
|
||||
icon: options.icon,
|
||||
title: mediaInfo.title,
|
||||
body: mediaInfo.artists,
|
||||
icon: mediaInfo.icon,
|
||||
});
|
||||
currentNotification.show();
|
||||
}
|
||||
updateMpris(options);
|
||||
updateListenBrainz(options);
|
||||
|
||||
updateMpris(mediaInfo);
|
||||
updateListenBrainz(mediaInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -454,32 +455,32 @@ function addMPRIS() {
|
||||
}
|
||||
}
|
||||
|
||||
function updateMpris(options: Options) {
|
||||
function updateMpris(mediaInfo: MediaInfo) {
|
||||
if (player) {
|
||||
player.metadata = {
|
||||
...player.metadata,
|
||||
...{
|
||||
"xesam:title": options.title,
|
||||
"xesam:artist": [options.artists],
|
||||
"xesam:album": options.album,
|
||||
"mpris:artUrl": options.image,
|
||||
"mpris:length": convertDuration(options.duration) * 1000 * 1000,
|
||||
"xesam:title": mediaInfo.title,
|
||||
"xesam:artist": [mediaInfo.artists],
|
||||
"xesam:album": mediaInfo.album,
|
||||
"mpris:artUrl": mediaInfo.image,
|
||||
"mpris:length": convertDuration(mediaInfo.duration) * 1000 * 1000,
|
||||
"mpris:trackid": "/org/mpris/MediaPlayer2/track/" + getTrackID(),
|
||||
},
|
||||
};
|
||||
player.playbackStatus = options.status === MediaStatus.paused ? "Paused" : "Playing";
|
||||
player.playbackStatus = mediaInfo.status === MediaStatus.paused ? "Paused" : "Playing";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the listenbrainz service with new data based on a few conditions
|
||||
*/
|
||||
function updateListenBrainz(options: Options) {
|
||||
function updateListenBrainz(mediaInfo: MediaInfo) {
|
||||
if (settingsStore.get(settings.ListenBrainz.enabled)) {
|
||||
const oldData = ListenBrainzStore.get(ListenBrainzConstants.oldData) as StoreData;
|
||||
if (
|
||||
(!oldData && options.status === MediaStatus.playing) ||
|
||||
(oldData && oldData.title !== options.title)
|
||||
(!oldData && mediaInfo.status === MediaStatus.playing) ||
|
||||
(oldData && oldData.title !== mediaInfo.title)
|
||||
) {
|
||||
if (!scrobbleWaitingForDelay) {
|
||||
scrobbleWaitingForDelay = true;
|
||||
@ -487,10 +488,10 @@ function updateListenBrainz(options: Options) {
|
||||
currentListenBrainzDelayId = setTimeout(
|
||||
() => {
|
||||
ListenBrainz.scrobble(
|
||||
options.title,
|
||||
options.artists,
|
||||
options.status,
|
||||
convertDuration(options.duration)
|
||||
mediaInfo.title,
|
||||
mediaInfo.artists,
|
||||
mediaInfo.status,
|
||||
convertDuration(mediaInfo.duration)
|
||||
);
|
||||
scrobbleWaitingForDelay = false;
|
||||
},
|
||||
@ -547,20 +548,19 @@ setInterval(function () {
|
||||
if (repeatStateChanged) currentRepeatState = repeatState;
|
||||
|
||||
skipArtistsIfFoundInSkippedArtistsList(artistsArray);
|
||||
|
||||
const album = elements.getAlbumName();
|
||||
const duration = elements.getText("duration");
|
||||
const options = {
|
||||
const options: MediaInfo = {
|
||||
title,
|
||||
artists: artistsString,
|
||||
album: album,
|
||||
playingFrom: elements.getText("playing_from"),
|
||||
status: currentStatus,
|
||||
url: getTrackURL(),
|
||||
current,
|
||||
currentInSeconds: convertDurationToSeconds(current),
|
||||
duration,
|
||||
durationInSeconds: convertDurationToSeconds(duration),
|
||||
"app-name": appName,
|
||||
image: "",
|
||||
icon: "",
|
||||
favorite: elements.isFavorite(),
|
||||
|
@ -2,12 +2,13 @@ import { MediaInfo } from "../models/mediaInfo";
|
||||
import { MediaStatus } from "../models/mediaStatus";
|
||||
import { RepeatState } from "../models/repeatState";
|
||||
|
||||
export const mediaInfo = {
|
||||
const defaultInfo: MediaInfo = {
|
||||
title: "",
|
||||
artists: "",
|
||||
album: "",
|
||||
icon: "",
|
||||
status: MediaStatus.paused as string,
|
||||
playingFrom: "",
|
||||
status: MediaStatus.paused,
|
||||
url: "",
|
||||
current: "",
|
||||
currentInSeconds: 0,
|
||||
@ -17,42 +18,19 @@ export const mediaInfo = {
|
||||
favorite: false,
|
||||
|
||||
player: {
|
||||
status: MediaStatus.paused as string,
|
||||
status: MediaStatus.paused,
|
||||
shuffle: false,
|
||||
repeat: RepeatState.off as string,
|
||||
repeat: RepeatState.off,
|
||||
},
|
||||
};
|
||||
|
||||
export let mediaInfo: MediaInfo = { ...defaultInfo };
|
||||
|
||||
export const updateMediaInfo = (arg: MediaInfo) => {
|
||||
mediaInfo.title = propOrDefault(arg.title);
|
||||
mediaInfo.artists = propOrDefault(arg.artists);
|
||||
mediaInfo.album = propOrDefault(arg.album);
|
||||
mediaInfo.icon = propOrDefault(arg.icon);
|
||||
mediaInfo.url = toUniversalUrl(propOrDefault(arg.url));
|
||||
mediaInfo.status = propOrDefault(arg.status);
|
||||
mediaInfo.current = propOrDefault(arg.current);
|
||||
mediaInfo.currentInSeconds = arg.currentInSeconds ?? 0;
|
||||
mediaInfo.duration = propOrDefault(arg.duration);
|
||||
mediaInfo.durationInSeconds = arg.durationInSeconds ?? 0;
|
||||
mediaInfo.image = propOrDefault(arg.image);
|
||||
mediaInfo.favorite = arg.favorite;
|
||||
|
||||
mediaInfo.player = {
|
||||
status: propOrDefault(arg.player?.status),
|
||||
shuffle: arg.player?.shuffle ?? false,
|
||||
repeat: propOrDefault(arg.player?.repeat),
|
||||
};
|
||||
mediaInfo = { ...defaultInfo, ...arg };
|
||||
mediaInfo.url = toUniversalUrl(mediaInfo.url);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the property or a default value
|
||||
* @param {*} prop property to check
|
||||
* @param {*} defaultValue defaults to ""
|
||||
*/
|
||||
function propOrDefault(prop: string, defaultValue = "") {
|
||||
return prop || defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the universal link syntax (?u) to any url
|
||||
* @param url url to append the universal link syntax to
|
||||
|
@ -11,6 +11,23 @@ const settingsMenuEntry = {
|
||||
accelerator: "Control+=",
|
||||
};
|
||||
|
||||
const tidalMagazineEntry = {
|
||||
label: "Magazine",
|
||||
click() {
|
||||
const magazineWindow = new BrowserWindow({
|
||||
autoHideMenuBar: true,
|
||||
webPreferences: {
|
||||
sandbox: false,
|
||||
plugins: true,
|
||||
devTools: true, // I like tinkering, others might too
|
||||
},
|
||||
});
|
||||
magazineWindow.loadURL("https://tidal.com/magazine/");
|
||||
magazineWindow.show();
|
||||
},
|
||||
accelerator: "Control+M",
|
||||
};
|
||||
|
||||
const quitMenuEntry = {
|
||||
label: "Quit",
|
||||
click() {
|
||||
@ -41,6 +58,7 @@ export const getMenu = function (mainWindow: BrowserWindow) {
|
||||
{ role: "hideothers" },
|
||||
{ role: "unhide" },
|
||||
{ type: "separator" },
|
||||
tidalMagazineEntry,
|
||||
quitMenuEntry,
|
||||
],
|
||||
},
|
||||
@ -48,7 +66,7 @@ export const getMenu = function (mainWindow: BrowserWindow) {
|
||||
: []),
|
||||
{
|
||||
label: "File",
|
||||
submenu: [settingsMenuEntry, isMac ? { role: "close" } : quitMenuEntry],
|
||||
submenu: [settingsMenuEntry, tidalMagazineEntry, isMac ? { role: "close" } : quitMenuEntry],
|
||||
},
|
||||
{
|
||||
label: "Edit",
|
||||
@ -101,6 +119,7 @@ export const getMenu = function (mainWindow: BrowserWindow) {
|
||||
},
|
||||
settingsMenuEntry,
|
||||
toggleWindow,
|
||||
tidalMagazineEntry,
|
||||
quitMenuEntry,
|
||||
];
|
||||
|
||||
|
@ -31,6 +31,7 @@ export const settingsStore = new Store({
|
||||
api: true,
|
||||
apiSettings: {
|
||||
port: 47836,
|
||||
hostname: "127.0.0.1",
|
||||
},
|
||||
customCSS: [],
|
||||
disableBackgroundThrottle: true,
|
||||
@ -101,6 +102,11 @@ export const settingsStore = new Store({
|
||||
},
|
||||
]);
|
||||
},
|
||||
"5.14.0": (migrationStore) => {
|
||||
buildMigration("5.14.0", migrationStore, [
|
||||
{ key: settings.apiSettings.hostname, value: "127.0.0.1" },
|
||||
]);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user