Compare commits

...

14 Commits
1 ... 2.1.1

Author SHA1 Message Date
148d1746ad Merge pull request #42 from Mastermindzh/feature/improving-discord-integration-with-maroxy
Discord improvements with Mar0xy
2021-04-19 23:18:41 +02:00
ae51f9610c - The discord integration now doesn't send an update every 15 seconds it sends an update whenever the media info changes
- consolidated updating the media info changes with the status changes into a single global event
2021-04-19 23:08:19 +02:00
5eb3b8d95f released version 2.1.0 on the AUR version as well. 2021-04-19 21:31:12 +02:00
ebdae6bc88 bumped a few packages and added a changelog 2021-04-19 20:59:37 +02:00
Marie
ab25bf16b2 Add Discord RPC & fix artist in mediainfo (#40) 2021-04-19 20:43:25 +02:00
31670d0c2b updated aur info 2021-01-10 14:11:45 +01:00
9ca3d3b37d added some extra images, updated the TOC and bumped the ini dependency 2021-01-10 13:53:34 +01:00
fb9082e995 Changes some hotkeys around and fixed some bugs with the hotkeys. Fixes #34 and #35 2021-01-10 13:52:22 +01:00
87a4ff3fc5 Merge pull request #32 from Mastermindzh/feature/mpris-403-fix 2020-11-29 12:32:47 +01:00
1e5b7d61f5 added changelog etc 2020-11-29 12:31:58 +01:00
8177e6e3ca re-enabled mpris after the 403 has been fixed 2020-11-29 10:55:01 +01:00
9f26db22fc updated arch install files. fixes #27 2020-10-07 20:33:39 +02:00
e2ea4d13c4 added the option to disable the system tray icon and fixed the settings menu 2020-10-07 20:10:31 +02:00
c222113cf1 updated arch builds 2020-10-05 10:50:15 +02:00
18 changed files with 735 additions and 219 deletions

View File

@@ -4,6 +4,41 @@ 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).
## 2.1.1
- The discord integration now doesn't send an update every 15 seconds it sends an update whenever the media info changes
- consolidated updating the media info changes with the status changes into a single global event
## 2.1.0
- [Mar0xy](https://github.com/Mar0xy) added Discord integration.
- Several versions have been bumped to fix vulnerabilities
## 2.0.0
### Breaking changes
- Changed settings hotkey from "ctrl+/" to "ctrl+=" to avoid a conflict with the default Tidal hotkeys
## Other changes
- Added a setting to disable custom hotkeys
- Fixed the bug that the previous song hotkey would register 3 times. (Twice due to a duplicate block of code + once from the default tidal hotkey)
## 1.3.0
-- re-enabled mpris-service wit the electron downloader fixes
## 1.2.0
- Added the ability to disable the tray icon
## 1.1.1
Bugfixes:
- Arch AUR install failed before, it is fixed now by using the included build scripts
## 1.1.0
- updated to electron 8.0.0

View File

@@ -14,12 +14,18 @@ The web version of [listen.tidal.com](listen.tidal.com) running in electron with
- [Installation](#installation)
- [Using releases](#using-releases)
- [Snap install](#snap-install)
- [Arch Linux](#arch-linux)
- [Using source](#using-source)
- [features](#features)
- [Integrations](#integrations)
- [Known bugs](#known-bugs)
- [Why](#why)
- [Why not extend existing projects?](#why-not-extend-existing-projects)
- [Special thanks to..](#special-thanks-to)
- [Special thanks to...](#special-thanks-to)
- [Buy me a coffee? Please don't](#buy-me-a-coffee-please-dont)
- [Images](#images)
- [settings window](#settings-window)
- [user setups](#user-setups)
<!-- tocstop -->
@@ -66,9 +72,9 @@ To install and work with the code on this project follow these steps:
- HiFi playback
- Notifications
- Shortcuts ([source](https://defkey.com/tidal-desktop-shortcuts))
- Custom hotkeys ([source](https://defkey.com/tidal-desktop-shortcuts))
- API for status and playback
- [Settings feature](./docs/settings.png) to disable certain functionality. (`ctrl+/`)
- [Settings feature](./docs/settings.png) to disable certain functionality. (`ctrl+=`)
## Integrations
@@ -95,7 +101,23 @@ Whilst there are a handful of projects attempting to run Tidal on Electron they
Sometimes it's just easier to start over, cover my own needs and then making it available to the public :)
## Special thanks to..
## Special thanks to...
- [Castlabs](https://castlabs.com/)
For maintaining Electron with Widevine CDM installation, Verified Media Path (VMP), and persistent licenses (StorageID)
## Buy me a coffee? Please don't
Instead spend some money on a charity I care for: [kwf.nl](secure.kwf.nl/donation).
Inspired by [haydenjames' issue](https://github.com/Mastermindzh/tidal-hifi/issues/27#issuecomment-704198429)
## Images
### settings window
![settings window](./docs/settings-preview.png)
### user setups
Some of our users are kind enough to share their usage pictures.
If you want to see them or possibly even add one please do so in the following issue: [#3 - image thread](https://github.com/Mastermindzh/tidal-hifi/issues/3).

View File

@@ -1,5 +1,7 @@
appId: com.rickvanlieshout.tidal-hifi
electronVersion: 8.5.2
electronDownload:
version: 8.5.2-wvvmp
mirror: https://github.com/castlabs/electron-releases/releases/download/v
snap:
plugs:

View File

@@ -1,6 +1,6 @@
pkgbase = tidal-hifi-git
pkgdesc = The web version of listen.tidal.com running in electron with hifi support thanks to widevine.
pkgver = 1.1.1
pkgver = 2.1.0
pkgrel = 1
url = https://github.com/Mastermindzh/tidal-hifi
arch = x86_64
@@ -11,9 +11,9 @@ pkgbase = tidal-hifi-git
depends = nss
depends = gtk3
provides = tidal-hifi
source = https://github.com/Mastermindzh/tidal-hifi/archive/1.1.1.zip
source = https://github.com/Mastermindzh/tidal-hifi/archive/2.1.0.zip
source = tidal-hifi.desktop
sha512sums = a538b8b18c31c21017b2591e7fc2afa40ac4d33ffdbd59d7a14fd3c53aa6be11ee749d679ee4626a543c2b7f9dd154cef97e8ed3257cf8d46f389a0db765330d
sha512sums = 30b50243e7033219351f7d7f318757e4590e5c78a7031762cf846ae3652b424ab3f54388cba44209e49434d8534edb198e1c65d0b53450b4367636ef0f4653e0
sha512sums = 35f38ac308b871c1822d7f6f760f2fb54c3748cf769822cb0f0dfb90f0f5754ba9316da5e903a0d2e9839de3a43ec76f238f3f2e44021956fa1da19142081349
pkgname = tidal-hifi-git

View File

@@ -2,7 +2,7 @@
_pkgname=tidal-hifi
pkgname="$_pkgname-git"
pkgver=1.1.1
pkgver=2.1.0
pkgrel=1
pkgdesc="The web version of listen.tidal.com running in electron with hifi support thanks to widevine."
arch=("x86_64")
@@ -15,7 +15,7 @@ provides=("$_pkgname")
source=("https://github.com/Mastermindzh/tidal-hifi/archive/$pkgver.zip"
"${_pkgname}.desktop")
sha512sums=('a538b8b18c31c21017b2591e7fc2afa40ac4d33ffdbd59d7a14fd3c53aa6be11ee749d679ee4626a543c2b7f9dd154cef97e8ed3257cf8d46f389a0db765330d'
sha512sums=('30b50243e7033219351f7d7f318757e4590e5c78a7031762cf846ae3652b424ab3f54388cba44209e49434d8534edb198e1c65d0b53450b4367636ef0f4653e0'
'35f38ac308b871c1822d7f6f760f2fb54c3748cf769822cb0f0dfb90f0f5754ba9316da5e903a0d2e9839de3a43ec76f238f3f2e44021956fa1da19142081349')
cdToPkg(){

BIN
docs/settings-preview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 KiB

421
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "tidal-hifi",
"version": "1.1.1",
"version": "2.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -70,6 +70,16 @@
"integrity": "sha512-qAfo81CsD7yQIM9mVyh6B/U47li5g7cfpVQEDMfQeF8pSZVwzbhwU3crc0qG4DmpsebpJPR49AKOExQyJ05Cpg==",
"dev": true
},
"abstract-socket": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/abstract-socket/-/abstract-socket-2.1.1.tgz",
"integrity": "sha512-YZJizsvS1aBua5Gd01woe4zuyYBGgSMeqDOB6/ChwdTI904KP6QGtJswXl4hcqWxbz86hQBe++HWV0hF1aGUtA==",
"optional": true,
"requires": {
"bindings": "^1.2.1",
"nan": "^2.12.1"
}
},
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@@ -290,6 +300,15 @@
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
"dev": true
},
"bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"optional": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
},
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -441,8 +460,7 @@
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
},
"builder-util": {
"version": "21.2.0",
@@ -545,6 +563,15 @@
}
}
},
"call-bind": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz",
"integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==",
"requires": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.0"
}
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -843,6 +870,21 @@
"assert-plus": "^1.0.0"
}
},
"dbus-next": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/dbus-next/-/dbus-next-0.5.1.tgz",
"integrity": "sha512-PzsudTX5HMLocSuwHefIohto8L4Gnh5ST2+VNAoax9Xurh+lTosmXIfgi/Mrc93vqUU3D1v7jE9/vjiWd3KIbA==",
"requires": {
"abstract-socket": "^2.0.0",
"event-stream": "3.3.4",
"hexy": "^0.2.10",
"jsbi": "^2.0.5",
"long": "^4.0.0",
"put": "0.0.6",
"safe-buffer": "^5.1.1",
"xml2js": "^0.4.17"
}
},
"debounce-fn": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-3.0.1.tgz",
@@ -875,6 +917,19 @@
"mimic-response": "^1.0.0"
}
},
"deep-equal": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
"integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
"requires": {
"is-arguments": "^1.0.4",
"is-date-object": "^1.0.1",
"is-regex": "^1.0.4",
"object-is": "^1.0.1",
"object-keys": "^1.1.1",
"regexp.prototype.flags": "^1.2.0"
}
},
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -891,8 +946,6 @@
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
"dev": true,
"optional": true,
"requires": {
"object-keys": "^1.0.12"
}
@@ -919,6 +972,15 @@
"dev": true,
"optional": true
},
"discord-rpc": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/discord-rpc/-/discord-rpc-3.2.0.tgz",
"integrity": "sha512-KJv0EVbGMlr04HoG6f5b3wD7X9kSHzQ2Ed2qfHSDvYJ1MkE8RbCQmMcQQrSvAxpfsqZgUjB/bsfi/mjyicCH+A==",
"requires": {
"node-fetch": "^2.6.1",
"ws": "^7.3.1"
}
},
"dmg-builder": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-21.2.0.tgz",
@@ -968,6 +1030,11 @@
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
"dev": true
},
"duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="
},
"duplexer3": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
@@ -1117,6 +1184,34 @@
"integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==",
"dev": true
},
"es-abstract": {
"version": "1.17.7",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz",
"integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==",
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1",
"is-callable": "^1.2.2",
"is-regex": "^1.1.1",
"object-inspect": "^1.8.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.1",
"string.prototype.trimend": "^1.0.1",
"string.prototype.trimstart": "^1.0.1"
}
},
"es-to-primitive": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
"requires": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.2"
}
},
"es6-error": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
@@ -1146,6 +1241,20 @@
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"event-stream": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
"integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=",
"requires": {
"duplexer": "~0.1.1",
"from": "~0",
"map-stream": "~0.1.0",
"pause-stream": "0.0.11",
"split": "0.3",
"stream-combiner": "~0.0.4",
"through": "~2.3.1"
}
},
"execa": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
@@ -1281,6 +1390,12 @@
"pend": "~1.2.0"
}
},
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"optional": true
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -1344,6 +1459,11 @@
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"from": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
"integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4="
},
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
@@ -1362,12 +1482,27 @@
"dev": true,
"optional": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
"get-intrinsic": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz",
"integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1"
}
},
"get-stream": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
@@ -1503,18 +1638,36 @@
"har-schema": "^2.0.0"
}
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"requires": {
"function-bind": "^1.1.1"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"has-symbols": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
},
"has-yarn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
"integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==",
"dev": true
},
"hexy": {
"version": "0.2.11",
"resolved": "https://registry.npmjs.org/hexy/-/hexy-0.2.11.tgz",
"integrity": "sha512-ciq6hFsSG/Bpt2DmrZJtv+56zpPdnq+NQ4ijEFrveKN0ZG1mhl/LdT1NQZ9se6ty1fACcI4d4vYqC9v8EYpH2A=="
},
"hosted-git-info": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
@@ -1588,9 +1741,9 @@
"dev": true
},
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true
},
"ipaddr.js": {
@@ -1598,6 +1751,11 @@
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
"integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
},
"is-arguments": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
"integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA=="
},
"is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -1607,6 +1765,11 @@
"binary-extensions": "^2.0.0"
}
},
"is-callable": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA=="
},
"is-ci": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
@@ -1616,6 +1779,16 @@
"ci-info": "^2.0.0"
}
},
"is-date-object": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
"integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
},
"is-docker": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -1668,21 +1841,40 @@
"path-is-inside": "^1.0.1"
}
},
"is-regex": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
"requires": {
"has-symbols": "^1.0.1"
}
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
},
"is-symbol": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
"integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
"requires": {
"has-symbols": "^1.0.1"
}
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"is-wsl": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz",
"integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog=="
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"requires": {
"is-docker": "^2.0.0"
}
},
"is-yarn-global": {
"version": "0.3.0",
@@ -1722,6 +1914,11 @@
"esprima": "^4.0.0"
}
},
"jsbi": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/jsbi/-/jsbi-2.0.5.tgz",
"integrity": "sha512-TzO/62Hxeb26QMb4IGlI/5X+QLr9Uqp1FPkwp2+KOICW+Q+vSuFj61c8pkT6wAns4WcK56X7CmSHhJeDGWOqxQ=="
},
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
@@ -1822,6 +2019,11 @@
"dev": true,
"optional": true
},
"long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
},
"lowercase-keys": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
@@ -1855,6 +2057,11 @@
}
}
},
"map-stream": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
"integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ="
},
"matcher": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
@@ -1943,33 +2150,84 @@
"minimist": "^1.2.5"
}
},
"mpris-service": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mpris-service/-/mpris-service-2.1.0.tgz",
"integrity": "sha512-HWFimtWYrfm7iMz8VjTrY68c2vwBMb5kDXqAQ9GmgIMv5exfgz+w277F1XFBc72Nu6FM3QH6jqMGT89m2MMDBg==",
"requires": {
"dbus-next": "^0.5.1",
"deep-equal": "^1.0.1",
"source-map-support": "^0.5.11"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"nan": {
"version": "2.14.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
"optional": true
},
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
},
"node-notifier": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz",
"integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==",
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-9.0.1.tgz",
"integrity": "sha512-fPNFIp2hF/Dq7qLDzSg4vZ0J4e9v60gJR+Qx7RbjbWqzPDdEqeVpEx5CFeDAELIl+A/woaaNn1fQ5nEVerMxJg==",
"requires": {
"growly": "^1.3.0",
"is-wsl": "^2.1.1",
"semver": "^6.3.0",
"is-wsl": "^2.2.0",
"semver": "^7.3.2",
"shellwords": "^0.1.1",
"which": "^1.3.1"
"uuid": "^8.3.0",
"which": "^2.0.2"
},
"dependencies": {
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"requires": {
"yallist": "^4.0.0"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"requires": {
"lru-cache": "^6.0.0"
}
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"requires": {
"isexe": "^2.0.0"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
},
@@ -2022,12 +2280,35 @@
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
},
"object-inspect": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
"integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA=="
},
"object-is": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.4.tgz",
"integrity": "sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg==",
"requires": {
"call-bind": "^1.0.0",
"define-properties": "^1.1.3"
}
},
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true,
"optional": true
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
},
"object.assign": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
"requires": {
"call-bind": "^1.0.0",
"define-properties": "^1.1.3",
"has-symbols": "^1.0.1",
"object-keys": "^1.1.1"
}
},
"on-finished": {
"version": "2.3.0",
@@ -2140,6 +2421,14 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"pause-stream": {
"version": "0.0.11",
"resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
"integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
"requires": {
"through": "~2.3"
}
},
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@@ -2248,6 +2537,11 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"put": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/put/-/put-0.0.6.tgz",
"integrity": "sha1-MPX2C9bkOJvTKeFqJThsuy5KAKM="
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
@@ -2350,6 +2644,15 @@
"picomatch": "^2.2.1"
}
},
"regexp.prototype.flags": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
"integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.1"
}
},
"registry-auth-token": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz",
@@ -2471,8 +2774,7 @@
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"semver": {
"version": "5.7.1",
@@ -2612,14 +2914,12 @@
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"source-map-support": {
"version": "0.5.13",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
"integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@@ -2657,6 +2957,14 @@
"integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==",
"dev": true
},
"split": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
"integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=",
"requires": {
"through": "2"
}
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -2690,6 +2998,32 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"stream-combiner": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
"integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=",
"requires": {
"duplexer": "~0.1.1"
}
},
"string.prototype.trimend": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz",
"integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==",
"requires": {
"call-bind": "^1.0.0",
"define-properties": "^1.1.3"
}
},
"string.prototype.trimstart": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz",
"integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==",
"requires": {
"call-bind": "^1.0.0",
"define-properties": "^1.1.3"
}
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -2769,6 +3103,11 @@
"execa": "^0.7.0"
}
},
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
},
"to-readable-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
@@ -2964,6 +3303,7 @@
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
@@ -3078,16 +3418,35 @@
"signal-exit": "^3.0.2"
}
},
"ws": {
"version": "7.4.5",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz",
"integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g=="
},
"xdg-basedir": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
"integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
"dev": true
},
"xml2js": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
}
},
"xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
},
"y18n": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"dev": true
},
"yallist": {

View File

@@ -1,6 +1,6 @@
{
"name": "tidal-hifi",
"version": "1.1.1",
"version": "2.1.1",
"description": "Tidal on Electron with widevine(hifi) support",
"main": "src/main.js",
"scripts": {
@@ -23,10 +23,12 @@
"homepage": "https://github.com/Mastermindzh/tidal-hifi",
"license": "MIT",
"dependencies": {
"discord-rpc": "^3.2.0",
"electron-store": "^5.1.1",
"express": "^4.17.1",
"hotkeys-js": "^3.7.6",
"node-notifier": "^6.0.0",
"mpris-service": "^2.1.0",
"node-notifier": "^9.0.1",
"request": "^2.88.2"
},
"devDependencies": {

View File

@@ -7,7 +7,6 @@ const globalEvents = {
updateInfo: "update-info",
hideSettings: "hideSettings",
showSettings: "showSettings",
updateStatus: "update-status",
storeChanged: "storeChanged",
error: "error",
};

View File

@@ -18,6 +18,9 @@ const settings = {
port: "apiSettings.port",
},
mpris: "mpris",
enableCustomHotkeys: "enableCustomHotkeys",
trayIcon: "trayIcon",
enableDiscord: "enableDiscord",
windowBounds: {
root: "windowBounds",
width: "windowBounds.width",

View File

@@ -9,12 +9,12 @@ const {
} = require("./scripts/settings");
const { addTray, refreshTray } = require("./scripts/tray");
const { addMenu } = require("./scripts/menu");
const path = require("path");
const tidalUrl = "https://listen.tidal.com";
const expressModule = require("./scripts/express");
const mediaKeys = require("./constants/mediaKeys");
const mediaInfoModule = require("./scripts/mediaInfo");
const discordModule = require("./scripts/discord");
const globalEvents = require("./constants/globalEvents");
let mainWindow;
@@ -83,9 +83,9 @@ app.on("ready", () => {
addMenu();
createSettingsWindow();
addGlobalShortcuts();
addTray({ icon });
refreshTray();
store.get(settings.trayIcon) && addTray({ icon }) && refreshTray();
store.get(settings.api) && expressModule.run(mainWindow);
store.get(settings.enableDiscord) && discordModule.initRPC();
});
app.on("activate", function () {
@@ -97,7 +97,6 @@ app.on("activate", function () {
});
// IPC
ipcMain.on(globalEvents.updateInfo, (event, arg) => {
mediaInfoModule.update(arg);
});
@@ -109,11 +108,14 @@ ipcMain.on(globalEvents.showSettings, (event, arg) => {
showSettingsWindow();
});
ipcMain.on(globalEvents.updateStatus, (event, arg) => {
mediaInfoModule.updateStatus(arg);
});
ipcMain.on(globalEvents.storeChanged, (event, arg) => {
mainWindow.setMenuBarVisibility(store.get(settings.menuBar));
if (store.get(settings.enableDiscord) && !discordModule.rpc) {
discordModule.initRPC();
} else if (!store.get(settings.enableDiscord) && discordModule.rpc) {
discordModule.unRPC();
}
});
ipcMain.on(globalEvents.error, (event, arg) => {

View File

@@ -17,7 +17,10 @@ function refreshSettings() {
api.checked = store.get(settings.api);
port.value = store.get(settings.apiSettings.port);
menuBar.checked = store.get(settings.menuBar);
trayIcon.checked = store.get(settings.trayIcon);
mpris.checked = store.get(settings.mpris);
enableCustomHotkeys.checked = store.get(settings.enableCustomHotkeys);
enableDiscord.checked = store.get(settings.enableDiscord);
}
/**
@@ -76,7 +79,10 @@ window.addEventListener("DOMContentLoaded", () => {
api = get("apiCheckbox");
port = get("port");
menuBar = get("menuBar");
trayIcon = get("trayIcon");
mpris = get("mprisCheckbox");
enableCustomHotkeys = get("enableCustomHotkeys");
enableDiscord = get("enableDiscord");
refreshSettings();
@@ -85,5 +91,8 @@ window.addEventListener("DOMContentLoaded", () => {
addInputListener(api, settings.api);
addInputListener(port, settings.apiSettings.port);
addInputListener(menuBar, settings.menuBar);
addInputListener(trayIcon, settings.trayIcon);
addInputListener(mpris, settings.mpris);
addInputListener(enableCustomHotkeys, settings.enableCustomHotkeys);
addInputListener(enableDiscord, settings.enableDiscord);
});

View File

@@ -68,15 +68,35 @@
</label>
</div>
</div>
<div class="section">
<h3>System</h3>
<div class="option">
<h4>Tray icon</h4>
<p>
Show Tidal-hifi's tray icon<br />
</p>
<label class="switch">
<input id="trayIcon" type="checkbox">
<span class="slider round"></span>
</label>
</div>
<div class="option">
<h4>Hotkeys</h4>
<p>
Enables extra hotkeys to achieve feature parity with the <a href = "javascript:openExternal('https://defkey.com/tidal-desktop-shortcuts')">desktop apps</a><br />
</p>
<label class="switch">
<input id="enableCustomHotkeys" type="checkbox">
<span class="slider round"></span>
</label>
</div>
</div>
</section>
<section id="api" class="tab-panel">
<div class="section">
<h3>Api</h3>
<p style="margin-bottom: 15px;">
Tidal-hifi has a web api built in to allow users to get current song information. You can optionally enable playback control as well.
<br />
<br />
<small>* api changes require a restart to update</small>
</p>
<div class="option">
@@ -104,18 +124,14 @@
</label>
</div>
</div>
<button onClick="restart()">Restart Tidal-hifi</button>
</section>
<section id="integrations" class="tab-panel">
<div class="section">
<h3>integrations</h3>
<p style="margin-bottom: 15px;">
Tidal-hifi is extensible trough the use of integrations. You can enable or disable integrations here
<br />
* not all integrations require restarting but some do, your best bet is to restart :)
</p>
<!-- disabled until the 403 with mpris-service/dbus is fixed -->
<!-- <div class="option">
<div class="option">
<h4>mpris-player</h4>
<p>
Whether to enable the mpris media player controls for Linux systems
@@ -124,8 +140,17 @@
<input id="mprisCheckbox" type="checkbox">
<span class="slider round"></span>
</label>
</div> -->
<button onClick="restart()">Restart Tidal-hifi</button>
</div>
<div class="option">
<h4>Discord RPC</h4>
<p>
Show what you're listening to on Discord
</p>
<label class="switch">
<input id="enableDiscord" type="checkbox">
<span class="slider round"></span>
</label>
</div>
</div>
</section>
<section id="about" class="tab-panel">
@@ -138,6 +163,9 @@
</div>
</section>
<small>Some settings require a restart of Tidal-hifi. To do so click the button below:</small>
<button onClick="restart()" style ="width: 100%">Restart Tidal-hifi</button>
</div>
</div>
</div>

View File

@@ -1,4 +1,4 @@
const { setTitle, getTitle } = require("./scripts/window-functions");
const { setTitle } = require("./scripts/window-functions");
const { dialog, process } = require("electron").remote;
const { store, settings } = require("./scripts/settings");
const { ipcRenderer } = require("electron");
@@ -10,7 +10,8 @@ const globalEvents = require("./constants/globalEvents");
const notifier = require("node-notifier");
const notificationPath = `${app.getPath("userData")}/notification.jpg`;
let currentSong = "";
// let player;
let player;
let currentPlayStatus = statuses.paused;
const elements = {
play: '*[data-test="play"]',
@@ -18,7 +19,7 @@ const elements = {
next: '*[data-test="next"]',
previous: 'button[data-test="previous"]',
title: '*[data-test^="footer-track-title"]',
artists: '*[class^="mediaArtists"]',
artists: '*[data-test^="grid-item-detail-text-title-artist"]',
home: '*[data-test="menu--home"]',
back: '[class^="backwardButton"]',
forward: '[class^="forwardButton"]',
@@ -29,7 +30,8 @@ const elements = {
account: '*[data-test^="profile-image-button"]',
settings: '*[data-test^="open-settings"]',
media: '*[data-test="current-media-imagery"]',
image: '*[class^="image--"]',
image: "img",
url: 'a[href*="/track/"]',
/**
* Get an element from the dom
@@ -101,6 +103,7 @@ function playPause() {
* https://defkey.com/tidal-desktop-shortcuts
*/
function addHotKeys() {
if (store.get(settings.enableCustomHotkeys)) {
hotkeys.add("Control+p", function () {
elements.click("account").click("settings");
});
@@ -120,36 +123,18 @@ function addHotKeys() {
elements.click("forward");
});
hotkeys.add("control+f", function () {
elements.focus("search");
});
hotkeys.add("control+u", function () {
// reloading window without cache should show the update bar if applicable
window.location.reload(true);
});
hotkeys.add("control+left", function () {
elements.click("previous");
});
hotkeys.add("control+right", function () {
elements.click("next");
});
hotkeys.add("control+right", function () {
elements.click("next");
});
hotkeys.add("control+s", function () {
elements.click("shuffle");
});
hotkeys.add("control+r", function () {
elements.click("repeat");
});
}
hotkeys.add("control+/", function () {
// always add the hotkey for the settings window
hotkeys.add("control+=", function () {
ipcRenderer.send(globalEvents.showSettings);
});
}
@@ -172,8 +157,8 @@ function handleLogout() {
},
function (response) {
if (logoutOptions.indexOf("Yes, please") == response) {
for (i = 0; i < window.localStorage.length; i++) {
key = window.localStorage.key(i);
for (let i = 0; i < window.localStorage.length; i++) {
const key = window.localStorage.key(i);
if (key.startsWith("_TIDAL_activeSession")) {
window.localStorage.removeItem(key);
i = window.localStorage.length + 1;
@@ -216,9 +201,9 @@ function addIPCEventListeners() {
/**
* Update the current status of tidal (e.g playing or paused)
*/
function updateStatus() {
function getCurrentlyPlayingStatus() {
let pause = elements.get("pause");
let status;
let status = undefined;
// if pause button is visible tidal is playing
if (pause) {
@@ -226,12 +211,30 @@ function updateStatus() {
} else {
status = statuses.paused;
}
return status;
}
if (status) {
ipcRenderer.send(globalEvents.updateStatus, status);
// if (player) {
// player.playbackStatus = status == statuses.paused ? "Paused" : "Playing";
// }
/**
* Update Tidal-hifi's media info
*
* @param {*} options
*/
function updateMediaInfo(options, notify) {
if (options) {
ipcRenderer.send(globalEvents.updateInfo, options);
store.get(settings.notifications) && notify && notifier.notify(options);
if (player) {
player.metadata = {
...player.metadata,
...{
"xesam:title": options.title,
"xesam:artist": [options.artists],
"mpris:artUrl": options.image,
},
};
player.playbackStatus = options.status == statuses.paused ? "Paused" : "Playing";
}
}
}
@@ -240,23 +243,29 @@ function updateStatus() {
*/
setInterval(function () {
const title = elements.getText("title");
const url = elements.get("url").href.replace(/[^0-9]/g, "");
const artists = elements.getText("artists");
const songDashArtistTitle = `${title} - ${artists}`;
updateStatus();
if (getTitle() !== songDashArtistTitle) {
setTitle(songDashArtistTitle);
if (currentSong !== songDashArtistTitle) {
currentSong = songDashArtistTitle;
const image = elements.getSongIcon();
const currentStatus = getCurrentlyPlayingStatus();
const options = {
title,
message: artists,
status: currentStatus,
url: `https://tidal.com/browse/track/${url}`,
};
new Promise((resolve, reject) => {
const playStatusChanged = currentStatus !== currentPlayStatus;
const titleOrArtistChanged = currentSong !== songDashArtistTitle;
if (titleOrArtistChanged || playStatusChanged) {
// update title and play info with new info
setTitle(songDashArtistTitle);
currentSong = songDashArtistTitle;
currentPlayStatus = currentStatus;
const image = elements.getSongIcon();
new Promise((resolve) => {
if (image.startsWith("http")) {
downloadFile(image, notificationPath).then(
() => {
@@ -264,85 +273,74 @@ setInterval(function () {
resolve();
},
() => {
reject();
// if the image can't be downloaded then continue without it
resolve();
}
);
} else {
reject();
// if the image can't be found on the page continue without it
resolve();
}
}).then(
() => {
ipcRenderer.send(globalEvents.updateInfo, options);
store.get(settings.notifications) && notifier.notify(options);
// if (player) {
// player.metadata = {
// ...player.metadata,
// ...{
// "xesam:title": title,
// "xesam:artist": [artists],
// "mpris:artUrl": image,
// },
// };
// }
updateMediaInfo(options, titleOrArtistChanged);
},
() => {}
);
}
}
}, 200);
// if (process.platform === "linux" && store.get(settings.mpris)) {
// try {
// const Player = require("mpris-service");
// player = Player({
// name: "tidal-hifi",
// identity: "tidal-hifi",
// supportedUriSchemes: ["file"],
// supportedMimeTypes: [
// "audio/mpeg",
// "audio/flac",
// "audio/x-flac",
// "application/ogg",
// "audio/wav",
// ],
// supportedInterfaces: ["player"],
// desktopEntry: "tidal-hifi",
// });
if (process.platform === "linux" && store.get(settings.mpris)) {
try {
const Player = require("mpris-service");
player = Player({
name: "tidal-hifi",
identity: "tidal-hifi",
supportedUriSchemes: ["file"],
supportedMimeTypes: [
"audio/mpeg",
"audio/flac",
"audio/x-flac",
"application/ogg",
"audio/wav",
],
supportedInterfaces: ["player"],
desktopEntry: "tidal-hifi",
});
// // Events
// var events = {
// next: "next",
// previous: "previous",
// pause: "pause",
// playpause: "playpause",
// stop: "stop",
// play: "play",
// loopStatus: "repeat",
// shuffle: "shuffle",
// seek: "seek",
// };
// Object.keys(events).forEach(function (eventName) {
// player.on(eventName, function () {
// const eventValue = events[eventName];
// switch (events[eventValue]) {
// case events.playpause:
// playPause();
// break;
// Events
var events = {
next: "next",
previous: "previous",
pause: "pause",
playpause: "playpause",
stop: "stop",
play: "play",
loopStatus: "repeat",
shuffle: "shuffle",
seek: "seek",
};
Object.keys(events).forEach(function (eventName) {
player.on(eventName, function () {
const eventValue = events[eventName];
switch (events[eventValue]) {
case events.playpause:
playPause();
break;
// default:
// elements.click(eventValue);
// }
// });
// });
default:
elements.click(eventValue);
}
});
});
// player.on("quit", function () {
// app.quit();
// });
// } catch (exception) {
// console.log("player api not working");
// }
// }
player.on("quit", function () {
app.quit();
});
} catch (exception) {
console.log("player api not working");
}
}
addHotKeys();
addIPCEventListeners();

57
src/scripts/discord.js Normal file
View File

@@ -0,0 +1,57 @@
const discordrpc = require("discord-rpc");
const { ipcMain } = require("electron");
const electron = require("electron");
const globalEvents = require("../constants/globalEvents");
const clientId = "833617820704440341";
const mediaInfoModule = require("./mediaInfo");
const discordModule = [];
let rpc;
const observer = (event, arg) => {
if (mediaInfoModule.mediaInfo.status == "paused" && rpc) {
rpc.setActivity(idleStatus);
} else if (rpc) {
rpc.setActivity({
...idleStatus,
...{
details: `Listening to ${mediaInfoModule.mediaInfo.title}`,
state: mediaInfoModule.mediaInfo.artist,
buttons: [{ label: "Play on Tidal", url: mediaInfoModule.mediaInfo.url }],
},
});
}
};
const idleStatus = {
details: `Browsing Tidal`,
largeImageKey: "tidal-hifi-icon",
largeImageText: `Tidal HiFi ${electron.app.getVersion()}`,
instance: false,
};
/**
* Set up the discord rpc and listen on globalEvents.updateInfo
*/
discordModule.initRPC = function () {
rpc = new discordrpc.Client({ transport: "ipc" });
rpc.login({ clientId }).catch(console.error);
discordModule.rpc = rpc;
rpc.on("ready", () => {
rpc.setActivity(idleStatus);
});
ipcMain.on(globalEvents.updateInfo, observer);
};
/**
* Remove any RPC connection with discord and remove the event listener on globalEvents.updateInfo
*/
discordModule.unRPC = function () {
rpc.clearActivity();
rpc.destroy();
rpc = false;
discordModule.rpc = rpc;
ipcMain.removeListener(globalEvents.updateInfo, observer);
};
module.exports = discordModule;

View File

@@ -5,6 +5,7 @@ const mediaInfo = {
artist: "",
icon: "",
status: statuses.paused,
url: "",
};
const mediaInfoModule = {
mediaInfo,
@@ -17,15 +18,8 @@ mediaInfoModule.update = function(arg) {
mediaInfo.title = propOrDefault(arg.title);
mediaInfo.artist = propOrDefault(arg.message);
mediaInfo.icon = propOrDefault(arg.icon);
};
/**
* Update tidal's status in the mediaInfo constant
*/
mediaInfoModule.updateStatus = function(status) {
if (Object.values(statuses).includes(status)) {
mediaInfo.status = status;
}
mediaInfo.url = propOrDefault(arg.url);
mediaInfo.status = propOrDefault(arg.status);
};
/**

View File

@@ -14,7 +14,10 @@ const store = new Store({
apiSettings: {
port: 47836,
},
trayIcon: true,
mpris: false,
enableCustomHotkeys: false,
enableDiscord: false,
windowBounds: { width: 800, height: 600 },
},
});

View File

@@ -8,6 +8,9 @@ trayModule.addTray = function(options = { icon: "" }) {
};
trayModule.refreshTray = function () {
if (!tray) {
trayModule.addTray();
}
tray.on("click", function (e) {
// do nothing on click
});