Compare commits

..

69 Commits
2.1.0 ... 4.1.1

Author SHA1 Message Date
4941aae950 Bugfix/4.1.1 (#161)
* - Fixed `cannot read property of undefined` error because of not passing mainWindow around.
- vincens2005, fixed inconsistent auto muting

* Fix inconsistent auto-muting (#159)

* fix muting sometimes not working

* fix inconsistent unmuting

* fix bad code in inconsistent muting fig

Co-authored-by: Cukmekerb <cukmekerb@gmail.com>
2022-08-23 21:20:46 +02:00
1439a11969 Feature/4.1.0 (#156)
* added protocol handler

* Switched icon strategies to fix bugs with icons

* fixed tray icon issues

* fixed about :)

* Fixed playback, mpris and API issues
2022-08-07 16:05:48 +02:00
Tomasz Hołubowicz
3a3e0e1a2d Add instruction for installation via Nix (#153) 2022-07-05 16:41:12 +02:00
fa9ab22867 - Updated build config to make use of a base file that doesn't build anything.
- This fixes the issue of unwanted extra build targets that were introduced with the electron-builder update
2022-06-25 21:45:30 +02:00
207a61d199 4.0.0 with electron 19.0.5 release 2022-06-23 17:06:17 +02:00
Tomasz Hołubowicz
7b18322e17 Bump electron version (#152) 2022-06-23 17:00:35 +02:00
8f47756244 fixed hardware media flag upadting gpu rasterization options 2022-06-18 10:40:31 +02:00
Marie
cdcf9431bf Fix bugs related to media info (#150)
* Fix duration time element

* change interval time from 200 to 500
2022-06-18 10:26:21 +02:00
374f3da740 Added a separate advanced options settings panel with flags
- Added gpu-rasterization flag

config setting `disableHardwareMediaKeys` moved to `flags.disableHardwareMediaKeys`, it will be migrated automatically
2022-05-07 18:13:36 +02:00
3965ada0a2 Add link to flathub 2022-04-23 23:18:08 +02:00
79ff02d06c Electron 15, single-instance-lock and setting to disable hardwareMediaKeyHandling (#134)
* Update to Electron 15 and add Flatpak to README (#131)

* Update functional

* Change to 15

* Replace window.hide, window.restart with counterparts

* Fix openexternal by doing default JS

* Change mouse to pointer for <a> elements

* turn mouse to pointer for exit button

* Fix deprecation of Audio for AudioVideo

* Made a small mistake

* Add Flatpak to readme

* 3.0.0 prep

* Added setting to disable multiple tidal-hifi windows (defaults to true)

fixes #121

* Added setting to disable HardwareMediaKeyHandling (defaults to false)

fixes #133

Co-authored-by: Marie <marie@kaifa.ch>
2022-04-23 22:59:32 +02:00
7b2afd2290 added separate build-unpacked config 2022-04-22 00:21:05 +02:00
5fde20ace1 hotfix, downgrade packaged version to 8.5.2 2022-04-21 23:58:48 +02:00
7f5f5e7f62 Merge branch 'master' of github.com:Mastermindzh/tidal-hifi 2022-04-21 17:52:50 +02:00
6a1a1efe74 add apt-get update 2022-04-21 17:52:31 +02:00
94e1bb1780 add apt-get update 2022-04-21 17:51:21 +02:00
d66dd8cc9e 2.8.1 release 2022-04-21 17:49:11 +02:00
Cukmekerb
de97ac8a00 make quit button actually quit app (#123) 2022-04-21 17:46:49 +02:00
Marie
82ac5edf22 Update build version to fit with package.json electron version (#128)
* Update build version to fit with package.json electron version

* Update electron-builder.yml

* Use wvcus.2 for additional fixes

* Also use wvcus.2 for package.json
2022-04-21 17:46:05 +02:00
Bruno Unna
909c8ee8ba Fix the link to donations for kwf (#120)
Co-authored-by: Bruno Unna <bunna@getvisibility.com>
2022-04-11 12:07:55 +02:00
Marie
15b6b13e14 Change tidal-hifi to tidal-hifi-bin for AUR (#118) 2022-04-01 15:41:30 +02:00
89589b75e1 changed muted artists to TIDAL 2022-03-31 17:42:34 +02:00
6a7b3eefd4 Muting artists automatically (#116)
Co-authored-by: Cukmekerb <cukmekerb@gmail.com>
2022-03-31 17:37:12 +02:00
dependabot[bot]
0583c4a188 Bump plist from 3.0.4 to 3.0.5 (#115)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-28 08:53:36 +02:00
dependabot[bot]
8855e7f89f Bump minimist from 1.2.5 to 1.2.6 (#114)
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-26 18:59:52 +01:00
dependabot[bot]
4fbb598c50 Bump node-fetch from 2.6.1 to 2.6.7 (#105)
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-17 16:47:48 +01:00
101fe967d3 version bump and changelog 2022-02-17 12:58:35 +01:00
Marie
53468e0dc3 Fix issue causing the app to crash (#104) 2022-02-17 12:57:26 +01:00
53cecbcd18 added a hotkey on ctrl+0 for settings. fixes #91 2022-01-23 11:02:28 +01:00
5a65f60cc5 Fixed bug: Triggering fullscreen from the Tidal web app would cause the menubar to be visible even if it was disabled in the settings (#96)
Co-authored-by: Diogo Oliveira <dromarques@outlook.com>
2022-01-23 10:55:50 +01:00
d51d5cdc24 Use native electron notifications and album text (#90)
Co-authored-by: Diogo Oliveira <dromarques@outlook.com>
2021-12-28 17:31:10 +01:00
0dec967e71 Add album image to media module and discord (#86)
Co-authored-by: Diogo Oliveira <diogoomarques98@gmail.com>
Co-authored-by: Marie <marie@kaifa.ch>
2021-12-19 13:18:39 +01:00
Kevin Yuan
c940d0991d Generate pacman builds using Github workflows (#81)
* Show "Tidal Hifi" as application name for notify-send

Set the 'app-name' variable for notify-send under Linux

* Generate pacman builds using Github workflows
Previous builds failed due to missing build dependencies when building the package using the Github workflow Linux environment
2021-12-08 18:35:39 +01:00
662ef6ad7b new deps (#77) 2021-12-04 12:51:19 +01:00
5313ab13d3 Merge pull request #76 from Mastermindzh/develop 2021-12-04 11:23:32 +01:00
f43f227191 added changelog and bumped version 2021-12-04 11:23:03 +01:00
Kevin Yuan
ae25d88e94 Show "Tidal Hifi" as application name for notify-send notifications (#75) 2021-12-04 11:21:14 +01:00
5ef6074015 Release 2.4.0 (#74)
Update MPRIS functionality to provide length, artist, and current position.
Also added rescrobbler explanation to the README.

Co-authored-by: Vinay V <cool00geek@yahoo.com>
2021-11-29 22:43:51 +01:00
8fea5265e7 Merge branch 'master' of github.com:Mastermindzh/tidal-hifi 2021-06-17 20:51:15 +02:00
8d2e03ca6b Merge branch 'master' of github.com:Mastermindzh/tidal-hifi 2021-06-17 20:45:33 +02:00
1074de228b Merge branch 'master' of github.com:Mastermindzh/tidal-hifi 2021-06-17 20:44:30 +02:00
Ignacio Brasca
64d1aa4041 Implement minimized action to hide the application on close (#60)
* Implement minimzed action to hide the application on close instead of
closing it.

* Add close event on the tray icon

* Add all items in the menu (not only Show/Close app)

* Changes on mainWindow. Toggle instead of Open/Close pair button
2021-06-17 20:44:23 +02:00
Ignacio Brasca
6608330ed3 Implement minimized action to hide the application on close (#60)
* Implement minimzed action to hide the application on close instead of
closing it.

* Add close event on the tray icon

* Add all items in the menu (not only Show/Close app)

* Changes on mainWindow. Toggle instead of Open/Close pair button
2021-06-17 20:37:14 +02:00
aa562c4a30 Merge branch 'master' of github.com:Mastermindzh/tidal-hifi 2021-05-30 15:40:32 +02:00
d6f63ac560 fixed artists retrieval, removed arch build steps 2021-05-30 15:40:27 +02:00
cdc0f49789 corrected KWF link 2021-04-30 08:55:48 +02:00
2f290f83fd Dev -> master (#49)
Co-authored-by: Cristian <54779545+callapa1@users.noreply.github.com>
2021-04-30 08:55:04 +02:00
d34ddfeb75 new version + readme updates 2021-04-25 18:32:52 +02:00
b7f163c1a1 Merge pull request #43 from MXY-Group/time 2021-04-25 18:23:11 +02:00
Marie
791a92a446 change let to const and use full length as names. 2021-04-22 11:34:26 +02:00
Marie
10c1e57680 extract Switch to function and change variable names. 2021-04-22 11:33:57 +02:00
Marie
c65d1a56c8 add the enableRemoteModule preference as the new castlabs release uses v10 2021-04-22 11:14:49 +02:00
Marie
d8f2dbd0c2 Update castlabs electron to the newest release from 6 days ago. 2021-04-21 17:24:18 +02:00
Marie
43ce85bb28 Change "listening to" to "watching" for videos 2021-04-21 04:56:59 +02:00
Marie
8201e23e4b Forgot to remove the now unused url element. 2021-04-21 04:48:23 +02:00
Marie
3cc288e014 Fix URL fetching 2021-04-21 04:44:44 +02:00
Marie
08ec7fadac Add Video support 2021-04-21 03:31:44 +02:00
Marie
7a30b125ec Add switch case for Video/Song 2021-04-21 03:31:28 +02:00
Marie
cac5db123f fix 1-2 second deflay between switching songs at song end 2021-04-20 23:09:53 +02:00
Marie
59f8b2d0b5 remove durationchanged as it was no longer needed 2021-04-20 22:22:04 +02:00
Marie
81a536bbdb revert last change 2021-04-20 22:15:34 +02:00
Marie
5e952e3899 Fix delay of one second when switching at song end 2021-04-20 22:12:11 +02:00
Marie
df887b8628 add time left to discord rpc & duration, current to mediainfo 2021-04-20 21:56:45 +02:00
Marie
31d90a342c add time left for discord rpc 2021-04-20 21:56:02 +02:00
Marie
8607337580 Merge pull request #2 from Mastermindzh/master
Merge new updates to master
2021-04-20 01:18:16 +02:00
4fe42a3671 update aur version files 2021-04-19 23:39:46 +02:00
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
36 changed files with 7964 additions and 2541 deletions

View File

@@ -9,10 +9,14 @@ jobs:
build_on_linux:
runs-on: ubuntu-latest
steps:
- name: update apt
run: sudo apt-get update
- name: Install libarchive-tools
run: sudo apt-get install -y libarchive-tools
- uses: actions/checkout@master
- uses: actions/setup-node@master
with:
node-version: 12
node-version: 16
- run: npm install
- run: npm run build
@@ -22,7 +26,7 @@ jobs:
- uses: actions/checkout@master
- uses: actions/setup-node@master
with:
node-version: 12
node-version: 16
- run: npm install
- run: npm run build
@@ -32,6 +36,6 @@ jobs:
- uses: actions/checkout@master
- uses: actions/setup-node@master
with:
node-version: 12
node-version: 16
- run: npm install
- run: npm run build

View File

@@ -9,10 +9,14 @@ jobs:
build_on_linux:
runs-on: ubuntu-latest
steps:
- name: update apt
run: sudo apt-get update
- name: Install libarchive-tools
run: sudo apt-get install -y libarchive-tools
- uses: actions/checkout@master
- uses: actions/setup-node@master
with:
node-version: 12
node-version: 16
- run: npm install
- run: npm run build
- uses: actions/upload-artifact@master
@@ -26,7 +30,7 @@ jobs:
- uses: actions/checkout@master
- uses: actions/setup-node@master
with:
node-version: 12
node-version: 16
- run: npm install
- run: npm run build
- uses: actions/upload-artifact@master
@@ -40,7 +44,7 @@ jobs:
- uses: actions/checkout@master
- uses: actions/setup-node@master
with:
node-version: 12
node-version: 16
- run: npm install
- run: npm run build
- uses: actions/upload-artifact@master

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"cSpell.words": ["hifi", "rescrobbler", "widevine"]
}

View File

@@ -4,6 +4,128 @@ 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).
## 4.1.1
- Fixed `cannot read property of undefined` error because of not passing mainWindow around.
- vincens2005, fixed inconsistent auto muting
## 4.1.0
- Added `tidal://` protocol support
- Switched icon strategies to fix bugs with icons
- Fixed tray icon bugs
- Menu now shows in KDE as well
- Toggle window is supported from tray icon
- regular click is still ignored, see [this issue](https://github.com/electron/electron/issues/6773)
- Fixed about tab not showing
- Fixed playback, mpris and API issues
## 4.0.1
- Updated build config to make use of a base file that doesn't build anything.
- This fixes the issue of unwanted extra build targets that were introduced with the electron-builder update
## 4.0.0
- Updated to Electron 19.0.5
## 3.1.1
- Media update timeout set to 500 instead of 200
- Updated property name for duration because of a tidal update
- flag for "disable hardware media keys" now working again
## 3.1.0
- Added a separate advanced options settings panel with flags
- Added gpu-rasterization flag
- config setting `disableHardwareMediaKeys` moved to `flags.disableHardwareMediaKeys`, it will be migrated automatically
## 3.0.0
- Updated to Electron 15
- Fixed the develop "build-unpacked" command
- Added setting to disable multiple tidal-hifi windows (defaults to true)
- Added setting to disable HardwareMediaKeyHandling (defaults to false)
## 2.8.2
- Updated dependencies
- Downgraded packaged version of electron to 8.5.2, doesn't seem to like a newer build
- Fixed the annoying (and useless) terminal warning about `allowRendererProcessReuse`
## 2.8.1
- Mar0xy fixed some build issues (thanks!)
- vincens2005 fixed the quit button in the menubar
## 2.8.0
- Added the ability to mute artists automatically
- Added better error handling for discord rpc
## 2.7.2
- Disabled sandboxing to fix a display compositor issue on Linux.
## 2.7.1
- Fixed bug: Triggering full screen from the Tidal web app would cause the menubar to be visible even if it was disabled in the settings
## 2.7.0
- Switched to the native Notifier (removed node-notifier)
- Album art now also has a name, based on [best effort](https://github.com/Mastermindzh/tidal-hifi/pull/88#pullrequestreview-840814847)
## 2.6.0
- Add album images to media info and discord
## 2.5.0
- Notify-send now correctly shows "Tidal HiFi" as the program name
- Updated dependencies (including electron itself)
### known issues
- Requires older version of nodejs due to electron-builder (use lts/gallium)
### builds
updated to nodejs 16 in actions
## 2.4.0
- Added more MPRIS settings
- Added instruction for rescrobbler to get last.fm working without sandbox mode
## 2.3.0
- Added a setting to minimize to tray on app close (off by default)
- Added the main menu to the tray icon
## 2.2.1
- artists is now gotten specifically from the footer. This fixes the [unknown artists bug](https://github.com/Mastermindzh/tidal-hifi/issues/45).
- the discord module will check whether the artists is empty and if so substitute it with a default message. This is to prevent sending an empty state to Discord (which it doesn't support). fixes [#45](https://github.com/Mastermindzh/tidal-hifi/issues/54)
### removed arch build details from source control
moved to: [https://github.com/Mastermindzh/tidal-hifi-aur](https://github.com/Mastermindzh/tidal-hifi-aur)
## 2.2.0
- The discord integration now adds a time remaining field based on the song duration
- All fields (current, remaining, and url are also available in the API\*)
- the artist field is now correctly identified
\* current time only updates on play/pause.
## 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.
@@ -22,7 +144,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## 1.3.0
-- re-enabled mpris-service wit the electron downloader fixes
-- re-enabled MPRIS-service wit the electron downloader fixes
## 1.2.0
@@ -37,7 +159,7 @@ Bugfixes:
## 1.1.0
- updated to electron 8.0.0
- Added a beta-version of the mpris service
- Added a beta-version of the MPRIS service
- Bugfixes:
- icon on gnome not showing in launcher

View File

@@ -3,7 +3,7 @@ Tidal-hifi
<img src = "./build/icon.png" height="40" align="right" />
</h1>
The web version of [listen.tidal.com](listen.tidal.com) running in electron with hifi support thanks to widevine.
The web version of [listen.tidal.com](https://listen.tidal.com) running in electron with hifi support thanks to widevine.
![tidal-hifi preview](./docs/preview.png)
@@ -12,20 +12,23 @@ The web version of [listen.tidal.com](listen.tidal.com) running in electron with
<!-- toc -->
- [Installation](#installation)
- [Using releases](#using-releases)
- [Snap install](#snap-install)
- [Arch Linux](#arch-linux)
- [Using source](#using-source)
- [features](#features)
* [Using releases](#using-releases)
* [Snap](#snap)
* [Arch Linux](#arch-linux)
* [Flatpak](#flatpak)
* [Nix](#nix)
* [Using source](#using-source)
- [Features](#features)
- [Integrations](#integrations)
- [Known bugs](#known-bugs)
* [Known bugs](#known-bugs)
+ [last.fm doesn't work out of the box. Use rescrobbler as a workaround](#lastfm-doesnt-work-out-of-the-box-use-rescrobbler-as-a-workaround)
- [Why](#why)
- [Why not extend existing projects?](#why-not-extend-existing-projects)
- [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)
* [Settings window](#settings-window)
* [User setups](#user-setups)
<!-- tocstop -->
@@ -35,17 +38,17 @@ The web version of [listen.tidal.com](listen.tidal.com) running in electron with
Various packaged versions of the software are available on the [releases](https://github.com/Mastermindzh/tidal-hifi/releases) tab.
#### Snap install
### Snap
To install with `snap` you need to download the pre-packaged snap-package from this repository, found under releases:
1. Download:
1. Download
```sh
wget <URI> #for instance: https://github.com/Mastermindzh/tidal-hifi/releases/download/1.0/tidal-hifi_1.0.0_amd64.snap
```
2. Install:
2. Install
```sh
snap install --dangerous <path> #for instance: tidal-hifi_1.0.0_amd64.snap
@@ -56,33 +59,68 @@ snap install --dangerous <path> #for instance: tidal-hifi_1.0.0_amd64.snap
Arch Linux users can use the AUR to install tidal-hifi:
```sh
trizen tidal-hifi
trizen tidal-hifi-bin
```
### Flatpak
To install via [Flatpak](https://flathub.org/apps/details/com.mastermindzh.tidal-hifi) run the following command:
```sh
flatpak install flathub com.mastermindzh.tidal-hifi
```
### Nix
To install with Nix run the following command:
```sh
nix-env -iA nixpkgs.tidal-hifi
```
### Using source
To install and work with the code on this project follow these steps:
- git clone https://github.com/Mastermindzh/tidal-hifi.git
- git clone [https://github.com/Mastermindzh/tidal-hifi.git](https://github.com/Mastermindzh/tidal-hifi.git)
- cd tidal-hifi
- npm install
- npm start
## features
## Features
- HiFi playback
- Notifications
- Custom hotkeys ([source](https://defkey.com/tidal-desktop-shortcuts))
- API for status and playback
- [Settings feature](./docs/settings.png) to disable certain functionality. (`ctrl+=`)
- [Mute artists automatically (defaults to "Tidal")]("./docs/muting-artists.md")
- Custom [integrations](#integrations)
- [Settings feature](./docs/settings.png) to disable certain functionality. (`ctrl+=` or `ctrl+0`)
- AlbumArt in integrations ([best-effort](https://github.com/Mastermindzh/tidal-hifi/pull/88#pullrequestreview-840814847))
## Integrations
Tidal-hifi comes with several integrations out of the box.
You can find these in the settings menu (`ctrl + =` by default) under the "integrations" tab.
![integrations menu, showing a list of integrations](./docs/integrations.png)
It currently includes:
- MPRIS - MPRIS media player controls/status
- Discord - Shows what you're listening to on Discord.
Not included:
- [i3 blocks config](https://github.com/Mastermindzh/dotfiles/commit/9714b2fa1d670108ce811d5511fd3b7a43180647) - My dotfiles where I use this app to fetch currently playing music (direct commit)
### Known bugs
- [Last.fm login doesn't work](https://github.com/Mastermindzh/tidal-hifi/issues/4).
#### last.fm doesn't work out of the box. Use rescrobbler as a workaround
The last.fm login doesn't work, as is evident from the following issue: [Last.fm login doesn't work](https://github.com/Mastermindzh/tidal-hifi/issues/4).
However, in that same issue you can read about a workaround using [rescrobbler](https://github.com/InputUsername/rescrobbled).
For now that will be the default workaround.
## Why
@@ -108,16 +146,16 @@ Sometimes it's just easier to start over, cover my own needs and then making it
## Buy me a coffee? Please don't
Instead spend some money on a charity I care for: [kwf.nl](secure.kwf.nl/donation).
Instead spend some money on a charity I care for: [kwf.nl](https://www.kwf.nl/donatie/donation).
Inspired by [haydenjames' issue](https://github.com/Mastermindzh/tidal-hifi/issues/27#issuecomment-704198429)
## Images
### settings window
### Settings window
![settings window](./docs/settings-preview.png)
### user setups
### 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

@@ -0,0 +1,39 @@
appId: com.rickvanlieshout.tidal-hifi
electronVersion: 19.0.5
electronDownload:
version: 19.0.5+wvcus
mirror: https://github.com/castlabs/electron-releases/releases/download/v
snap:
plugs:
- default
- screen-inhibit-control
linux:
category: Audio
target:
- dir
executableName: tidal-hifi
desktop:
Encoding: UTF-8
Name: tidal-hifi
GenericName: tidal-hifi
Comment: The web version of listen.tidal.com running in electron with hifi support thanks to widevine.
Icon: icon.png
StartupNotify: true
Terminal: false
Type: Application
Categories: Network;Application;AudioVideo;Audio;Video
StartupWMClass: tidal-hifi
X-PulseAudio-Properties: media.role=music
MimeType: x-scheme-handler/tidal;
mac:
category: public.app-category.entertainment
win:
icon: icon.png
artifactName: "tidalhifi"
appId: com.rickvanlieshout.tidalhifi
executableName: tidalhifi
protocols:
name: "tidal"
role: "Viewer"
schemes: ["tidal"]

View File

@@ -1,6 +1,6 @@
extends: ./build/electron-builder.yml
extends: ./build/electron-builder.base.yml
linux:
category: Audio
icon: ./assets/icon.png
icon: icon.png
target:
- deb

View File

@@ -1,6 +1,6 @@
extends: ./build/electron-builder.yml
extends: ./build/electron-builder.base.yml
linux:
category: Audio
icon: ./assets/icon.png
icon: icon.png
target:
- pacman

View File

@@ -1,6 +1,6 @@
extends: ./build/electron-builder.yml
extends: ./build/electron-builder.base.yml
linux:
category: Audio
icon: ./assets/TIDAL.icns
icon: icon.png
target:
- rpm

View File

@@ -1,6 +1,6 @@
extends: ./build/electron-builder.yml
extends: ./build/electron-builder.base.yml
linux:
category: Audio
icon: ./assets/icon.png
icon: icon.png
target:
- snap

View File

@@ -0,0 +1,4 @@
extends: ./build/electron-builder.base.yml
linux:
target:
- dir

View File

@@ -1,36 +1,20 @@
appId: com.rickvanlieshout.tidal-hifi
electronVersion: 8.5.2
electronVersion: 19.0.5
electronDownload:
version: 8.5.2-wvvmp
version: 19.0.5+wvcus
mirror: https://github.com/castlabs/electron-releases/releases/download/v
snap:
plugs:
- default
- screen-inhibit-control
linux:
category: Audio
target:
# - pacman
- pacman
- tar.gz
- deb
- rpm
- AppImage
- snap
- freebsd
executableName: tidal-hifi
desktop:
Encoding: UTF-8
Name: tidal-hifi
GenericName: tidal-hifi
Comment: The web version of listen.tidal.com running in electron with hifi support thanks to widevine.
Icon: assets/icon.png
StartupNotify: true
Terminal: false
Type: Application
Categories: Network;Application;Audio;Video
StartupWMClass: tidal-hifi
X-PulseAudio-Properties: media.role=music
mac:
category: public.app-category.entertainment
win:
target: msi
icon: icon.png
artifactName: "tidalhifi"
appId: com.rickvanlieshout.tidalhifi
executableName: tidalhifi

BIN
build/icon-inverted.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
build/icon.icns Executable file

Binary file not shown.

View File

@@ -1,20 +0,0 @@
pkgbase = tidal-hifi-git
pkgdesc = The web version of listen.tidal.com running in electron with hifi support thanks to widevine.
pkgver = 2.0.0
pkgrel = 1
url = https://github.com/Mastermindzh/tidal-hifi
arch = x86_64
license = custom:MIT
makedepends = npm
makedepends = git
depends = libxss
depends = nss
depends = gtk3
provides = tidal-hifi
source = https://github.com/Mastermindzh/tidal-hifi/archive/2.0.0.zip
source = tidal-hifi.desktop
sha512sums = 68fce020128b637fd37383a5afae71d2e4f3eec2d6b4bfcd7f410dcec18c91327d163deb21750e2251967a31f83b2b16092d11d3ff500a1fecd8c595448f380e
sha512sums = 35f38ac308b871c1822d7f6f760f2fb54c3748cf769822cb0f0dfb90f0f5754ba9316da5e903a0d2e9839de3a43ec76f238f3f2e44021956fa1da19142081349
pkgname = tidal-hifi-git

View File

@@ -1,58 +0,0 @@
# Maintainer: Rick van Lieshout <info@rickvanlieshout.com>
_pkgname=tidal-hifi
pkgname="$_pkgname-git"
pkgver=2.0.0
pkgrel=1
pkgdesc="The web version of listen.tidal.com running in electron with hifi support thanks to widevine."
arch=("x86_64")
url="https://github.com/Mastermindzh/tidal-hifi"
license=("custom:MIT")
depends=("libxss" "nss" "gtk3")
makedepends=("npm" "git")
provides=("$_pkgname")
source=("https://github.com/Mastermindzh/tidal-hifi/archive/$pkgver.zip"
"${_pkgname}.desktop")
sha512sums=('68fce020128b637fd37383a5afae71d2e4f3eec2d6b4bfcd7f410dcec18c91327d163deb21750e2251967a31f83b2b16092d11d3ff500a1fecd8c595448f380e'
'35f38ac308b871c1822d7f6f760f2fb54c3748cf769822cb0f0dfb90f0f5754ba9316da5e903a0d2e9839de3a43ec76f238f3f2e44021956fa1da19142081349')
cdToPkg(){
cd "tidal-hifi-$pkgver"
}
prepare() {
cdToPkg
# install build dependencies
npm install
}
build() {
cdToPkg
# We are not using the systems Electron as we need castlab's Electron.
npm run build-arch
}
package() {
cdToPkg
install -d "${pkgdir}/opt/${_pkgname}/" "${pkgdir}/usr/bin" "${pkgdir}/usr/share/doc" "${pkgdir}/usr/share/licenses"
cp -r dist/linux-unpacked/* "${pkgdir}/opt/${_pkgname}/"
chmod +x "${pkgdir}/opt/${_pkgname}/${_pkgname}"
ln -s "/opt/${_pkgname}/${_pkgname}" "${pkgdir}/usr/bin/${_pkgname}"
install -Dm 644 "build/icon.png" "${pkgdir}/usr/share/pixmaps/${_pkgname}.png"
install -Dm 644 "${srcdir}/${_pkgname}.desktop" "${pkgdir}/usr/share/applications/${_pkgname}.desktop"
install -Dm 644 "README.md" "${pkgdir}/usr/share/doc/${pkgname}/README.md"
install -Dm 644 "LICENSE" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
ln -s "/opt/${_pkgname}/LICENSE.electron.txt" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE.electron.txt"
ln -s "/opt/${_pkgname}/LICENSES.chromium.html" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSES.chromium.html"
}

View File

@@ -1,18 +0,0 @@
#!/bin/bash
# Will generate a correctly formatted SRCINFO file
SCRIPT_DIST=".SRCINFO"
# generate SRCINFO
makepkg --printsrcinfo > $SCRIPT_DIST
# replace pkgbase with tidal-hifi-git
pkgName="tidal-hifi-git"
sed -i "1s/.*/pkgbase = $pkgName/" $SCRIPT_DIST
# replace pkgbase with tidal-hifi-git
sed -i '/^pkgname/ d' $SCRIPT_DIST
echo "pkgname = $pkgName" >> $SCRIPT_DIST
# remove double line breaks and replace with single line breaks
sed -i '/^$/N;/^\n$/D' $SCRIPT_DIST

View File

@@ -1,13 +0,0 @@
[Desktop Entry]
Encoding=UTF-8
Name=tidal-hifi
GenericName=tidal-hifi
Comment=The web version of listen.tidal.com running in electron with hifi support thanks to widevine.
Exec=tidal-hifi %u
Icon=tidal-hifi.png
StartupNotify=true
Terminal=false
Type=Application
Categories=Network;Application;Audio;Video
StartupWMClass=tidal-hifi
X-PulseAudio-Properties=media.role=music

BIN
docs/integrations.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

11
docs/muting-artists.md Normal file
View File

@@ -0,0 +1,11 @@
# Muting artists
If you feel that some of your music is embarrassing for others you can mute specific artists in the settings window.
This functionality is inspired by the [adblock ticket](https://github.com/Mastermindzh/tidal-hifi/issues/112), and whilst I personally feel you should simply buy Tidal, I also believe in muting sound that you don't want to hear.
Anyway, to block an artist, open the settings window (see image below) and enter a list of artists in the textarea as seen below.
Don't forget to turn the feature on and Tidal-hifi will automatically mute the player whenever that artist is playing.
This will allow you to skip the song without anyone noticing. (you can always say "no idea, it seems to have no audio").
![muted artists settings window](./settings-muted-artists.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

8281
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,19 @@
{
"name": "tidal-hifi",
"version": "2.1.0",
"version": "4.1.1",
"description": "Tidal on Electron with widevine(hifi) support",
"main": "src/main.js",
"scripts": {
"start": "electron .",
"build": "electron-builder --publish=never -c ./build/electron-builder.yml",
"build-deb": "electron-builder --publish=never -c ./build/electron-builder.deb.yml",
"build-unpacked": "electron-builder --publish=never -c ./build/electron-builder.unpacked.yml",
"build-rpm": "electron-builder --publish=never -c ./build/electron-builder.rpm.yml",
"build-snap": "electron-builder --publish=never -c ./build/electron-builder.snap.yml",
"build-arch": "electron-builder --publish=never -c ./build/electron-builder.pacman.yml",
"build-wl": "electron-builder --publish=never -c ./build/electron-builder.yml -wl",
"build-mac": "electron-builder --publish=never -c ./build/electron-builder.yml -m"
"build-mac": "electron-builder --publish=never -c ./build/electron-builder.yml -m",
"build-base": "electron-builder --publish=never -c ./build/electron-builder.base.yml"
},
"keywords": [
"electron",
@@ -23,21 +25,19 @@
"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",
"mpris-service": "^2.1.0",
"node-notifier": "^9.0.1",
"@electron/remote": "^2.0.8",
"discord-rpc": "^4.0.1",
"electron-store": "^8.1.0",
"express": "^4.18.1",
"hotkeys-js": "^3.9.4",
"mpris-service": "^2.1.2",
"request": "^2.88.2"
},
"devDependencies": {
"@mastermindzh/prettier-config": "^1.0.0",
"electron": "git+https://github.com/castlabs/electron-releases.git#v8.5.2-wvvmp",
"electron-builder": "^21.2.0",
"electron-reload": "^1.5.0",
"prettier": "^2.0.4",
"dot-prop": ">=4.2.1"
"electron": "git+https://github.com/castlabs/electron-releases.git#v19.0.5+wvcus",
"electron-builder": "^23.3.3",
"prettier": "^2.7.1"
},
"prettier": "@mastermindzh/prettier-config"
}

6
src/constants/flags.js Normal file
View File

@@ -0,0 +1,6 @@
const flags = {
gpuRasterization: [{ flag: "enable-gpu-rasterization", value: undefined }],
disableHardwareMediaKeys: [{ flag: "disable-features", value: "HardwareMediaKeyHandling" }],
};
module.exports = flags;

View File

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

View File

@@ -13,10 +13,18 @@ const settings = {
api: "api",
menuBar: "menuBar",
playBackControl: "playBackControl",
muteArtists: "muteArtists",
mutedArtists: "mutedArtists",
apiSettings: {
root: "apiSettings",
port: "apiSettings.port",
},
singleInstance: "singleInstance",
disableHardwareMediaKeys: "disableHardwareMediaKeys",
flags: {
disableHardwareMediaKeys: "flags.disableHardwareMediaKeys",
gpuRasterization: "flags.gpuRasterization",
},
mpris: "mpris",
enableCustomHotkeys: "enableCustomHotkeys",
trayIcon: "trayIcon",
@@ -26,6 +34,7 @@ const settings = {
width: "windowBounds.width",
height: "windowBounds.height",
},
minimizeOnClose: "minimizeOnClose",
};
module.exports = settings;

3
src/constants/values.js Normal file
View File

@@ -0,0 +1,3 @@
module.exports = {
name: "tidal-hifi",
};

View File

@@ -1,4 +1,5 @@
const { app, BrowserWindow, globalShortcut, ipcMain } = require("electron");
require("@electron/remote/main").initialize();
const { app, BrowserWindow, components, globalShortcut, ipcMain, protocol } = require("electron");
const {
settings,
store,
@@ -16,18 +17,56 @@ const mediaKeys = require("./constants/mediaKeys");
const mediaInfoModule = require("./scripts/mediaInfo");
const discordModule = require("./scripts/discord");
const globalEvents = require("./constants/globalEvents");
const flagValues = require("./constants/flags");
let mainWindow;
let icon = path.join(__dirname, "../assets/icon.png");
const PROTOCOL_PREFIX = "tidal";
setFlags();
function setFlags() {
const flags = store.get().flags;
if (flags) {
for (const [key, value] of Object.entries(flags)) {
if (value) {
flagValues[key].forEach((flag) => {
console.log(`enabling command line switch ${flag.flag} with value ${flag.value}`);
app.commandLine.appendSwitch(flag.flag, flag.value);
});
}
}
}
/**
* Fix Display Compositor issue.
*/
app.commandLine.appendSwitch("disable-seccomp-filter-sandbox");
}
/**
* Enable live reload in development builds
* Update the menuBarVisbility according to the store value
*
*/
if (!app.isPackaged) {
require("electron-reload")(`${__dirname}`, {
electron: require(`${__dirname}/../node_modules/electron`),
});
function syncMenuBarWithStore() {
mainWindow.setMenuBarVisibility(store.get(settings.menuBar));
}
/**
* Determine whether the current window is the main window
* if singleInstance is requested.
* If singleInstance isn't requested simply return true
* @returns true if singInstance is not requested, otherwise true/false based on whether the current window is the main window
*/
function isMainInstanceOrMultipleInstancesAllowed() {
if (store.get(settings.singleInstance)) {
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
return false;
}
}
return true;
}
function createWindow(options = {}) {
@@ -38,17 +77,16 @@ function createWindow(options = {}) {
width: store && store.get(settings.windowBounds.width),
height: store && store.get(settings.windowBounds.height),
icon,
tray: true,
backgroundColor: options.backgroundColor,
webPreferences: {
affinity: "window",
preload: path.join(__dirname, "preload.js"),
plugins: true,
devTools: true, // I like tinkering, others might too
},
});
mainWindow.setMenuBarVisibility(store.get(settings.menuBar));
require("@electron/remote/main").enable(mainWindow.webContents);
registerHttpProtocols();
syncMenuBarWithStore();
// load the Tidal website
mainWindow.loadURL(tidalUrl);
@@ -56,6 +94,14 @@ function createWindow(options = {}) {
// run stuff after first load
mainWindow.webContents.once("did-finish-load", () => {});
mainWindow.on("close", function (event) {
if (!app.isQuiting && store.get(settings.minimizeOnClose)) {
event.preventDefault();
mainWindow.hide();
refreshTray(mainWindow);
}
return false;
});
// Emitted when the window is closed.
mainWindow.on("closed", function () {
closeSettingsWindow();
@@ -68,6 +114,13 @@ function createWindow(options = {}) {
});
}
function registerHttpProtocols() {
protocol.registerHttpProtocol(PROTOCOL_PREFIX, (request, _callback) => {
mainWindow.loadURL(`${tidalUrl}/${request.url.substring(PROTOCOL_PREFIX.length + 3)}`);
});
app.setAsDefaultProtocolClient(PROTOCOL_PREFIX);
}
function addGlobalShortcuts() {
Object.keys(mediaKeys).forEach((key) => {
globalShortcut.register(`${key}`, () => {
@@ -79,14 +132,20 @@ function addGlobalShortcuts() {
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on("ready", () => {
app.on("ready", async () => {
if (isMainInstanceOrMultipleInstancesAllowed()) {
await components.whenReady();
createWindow();
addMenu();
addMenu(mainWindow);
createSettingsWindow();
addGlobalShortcuts();
store.get(settings.trayIcon) && addTray({ icon }) && refreshTray();
store.get(settings.trayIcon) && addTray(mainWindow, { icon }) && refreshTray();
store.get(settings.api) && expressModule.run(mainWindow);
store.get(settings.enableDiscord) && discordModule.initRPC();
// mainWindow.webContents.openDevTools();
} else {
app.quit();
}
});
app.on("activate", function () {
@@ -97,32 +156,36 @@ app.on("activate", function () {
}
});
// IPC
app.on("browser-window-created", (_, window) => {
require("@electron/remote/main").enable(window.webContents);
});
ipcMain.on(globalEvents.updateInfo, (event, arg) => {
// IPC
ipcMain.on(globalEvents.updateInfo, (_event, arg) => {
mediaInfoModule.update(arg);
});
ipcMain.on(globalEvents.hideSettings, (event, arg) => {
ipcMain.on(globalEvents.hideSettings, (_event, _arg) => {
hideSettingsWindow();
});
ipcMain.on(globalEvents.showSettings, (event, arg) => {
ipcMain.on(globalEvents.showSettings, (_event, _arg) => {
showSettingsWindow();
});
ipcMain.on(globalEvents.updateStatus, (event, arg) => {
mediaInfoModule.updateStatus(arg);
ipcMain.on(globalEvents.refreshMenuBar, (_event, _arg) => {
syncMenuBarWithStore();
});
ipcMain.on(globalEvents.storeChanged, (event, arg) => {
mainWindow.setMenuBarVisibility(store.get(settings.menuBar));
if(store.get(settings.enableDiscord) && !discordModule.rpc) {
ipcMain.on(globalEvents.storeChanged, (_event, _arg) => {
syncMenuBarWithStore();
if (store.get(settings.enableDiscord) && !discordModule.rpc) {
discordModule.initRPC();
} else if(!store.get(settings.enableDiscord) && discordModule.rpc) {
} else if (!store.get(settings.enableDiscord) && discordModule.rpc) {
discordModule.unRPC();
}
});
ipcMain.on(globalEvents.error, (event, arg) => {
ipcMain.on(globalEvents.error, (event, _arg) => {
console.log(event);
});

View File

@@ -1,13 +1,24 @@
let notifications;
let playBackControl;
let api;
let port;
let menuBar;
let trayIcon,
minimizeOnClose,
mpris,
enableCustomHotkeys,
enableDiscord,
muteArtists,
notifications,
playBackControl,
api,
port,
menuBar,
mutedArtists,
singleInstance,
disableHardwareMediaKeys,
gpuRasterization;
const { store, settings } = require("./../../scripts/settings");
const { ipcRenderer } = require("electron");
const globalEvents = require("./../../constants/globalEvents");
const remote = require("@electron/remote");
const { app } = remote;
/**
* Sync the UI forms with the current settings
*/
@@ -21,31 +32,36 @@ function refreshSettings() {
mpris.checked = store.get(settings.mpris);
enableCustomHotkeys.checked = store.get(settings.enableCustomHotkeys);
enableDiscord.checked = store.get(settings.enableDiscord);
minimizeOnClose.checked = store.get(settings.minimizeOnClose);
muteArtists.checked = store.get(settings.muteArtists);
mutedArtists.value = store.get(settings.mutedArtists).join("\n");
singleInstance.checked = store.get(settings.singleInstance);
disableHardwareMediaKeys.checked = store.get(settings.flags.disableHardwareMediaKeys);
gpuRasterization.checked = store.get(settings.flags.gpuRasterization);
}
/**
* Open an url in the default browsers
*/
window.openExternal = function (url) {
function openExternal(url) {
const { shell } = require("electron");
shell.openExternal(url);
};
}
/**
* hide the settings window
*/
window.hide = function () {
function hide() {
ipcRenderer.send(globalEvents.hideSettings);
};
}
/**
* Restart tidal-hifi after changes
*/
window.restart = function () {
const remote = require("electron").remote;
remote.app.relaunch();
remote.app.exit(0);
};
function restart() {
app.relaunch();
app.quit();
}
/**
* Bind UI components to functions after DOMContentLoaded
@@ -55,8 +71,16 @@ window.addEventListener("DOMContentLoaded", () => {
return document.getElementById(id);
}
document.getElementById("close").addEventListener("click", hide);
document.getElementById("restart").addEventListener("click", restart);
document.querySelectorAll("#openExternal").forEach((elem) =>
elem.addEventListener("click", function (event) {
openExternal(event.target.getAttribute("data-url"));
})
);
function addInputListener(source, key) {
source.addEventListener("input", function (event, data) {
source.addEventListener("input", function (_event, _data) {
if (this.value === "on") {
store.set(key, source.checked);
} else {
@@ -66,6 +90,13 @@ window.addEventListener("DOMContentLoaded", () => {
});
}
function addTextAreaListener(source, key) {
source.addEventListener("input", function (_event, _data) {
store.set(key, source.value.split("\n"));
ipcRenderer.send(globalEvents.storeChanged);
});
}
ipcRenderer.on("refreshData", () => {
refreshSettings();
});
@@ -80,9 +111,15 @@ window.addEventListener("DOMContentLoaded", () => {
port = get("port");
menuBar = get("menuBar");
trayIcon = get("trayIcon");
minimizeOnClose = get("minimizeOnClose");
mpris = get("mprisCheckbox");
enableCustomHotkeys = get("enableCustomHotkeys");
enableDiscord = get("enableDiscord");
muteArtists = get("muteArtists");
mutedArtists = get("mutedArtists");
singleInstance = get("singleInstance");
disableHardwareMediaKeys = get("disableHardwareMediaKeys");
gpuRasterization = get("gpuRasterization");
refreshSettings();
@@ -95,4 +132,10 @@ window.addEventListener("DOMContentLoaded", () => {
addInputListener(mpris, settings.mpris);
addInputListener(enableCustomHotkeys, settings.enableCustomHotkeys);
addInputListener(enableDiscord, settings.enableDiscord);
addInputListener(minimizeOnClose, settings.minimizeOnClose);
addInputListener(muteArtists, settings.muteArtists);
addTextAreaListener(mutedArtists, settings.mutedArtists);
addInputListener(singleInstance, settings.singleInstance);
addInputListener(disableHardwareMediaKeys, settings.flags.disableHardwareMediaKeys);
addInputListener(gpuRasterization, settings.flags.gpuRasterization);
});

View File

@@ -2,6 +2,7 @@
<html lang="en">
<head>
<title>Tidal-hifi settings</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
@@ -10,7 +11,7 @@
<body>
<div class="header">
<h1 class="title">Settings</h1>
<a href="javascript:hide();" class="exitWindow">
<a id="close" style="cursor: pointer;" class="exitWindow">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="18px" height="18px" viewBox="0 0 348.333 348.334">
<g>
@@ -25,10 +26,10 @@
</div>
<div class="body">
<div class="tabset">
<!-- Tab 1 -->
<input type="radio" name="tabset" id="general" checked />
<label for="general">General</label>
<!-- Tab 2 -->
<input type="radio" name="tabset" id="api" />
<label for="api">Api</label>
@@ -36,6 +37,9 @@
<input type="radio" name="tabset" id="integrations" />
<label for="integrations">Integrations</label>
<!-- advanced tab -->
<input type="radio" name="tabset" id="advanced" />
<label for="advanced">Advanced</label>
<!-- about tab -->
<input type="radio" name="tabset" id="about" />
<label for="about">About</label>
@@ -54,6 +58,17 @@
<span class="slider round"></span>
</label>
</div>
<div class="option">
<h4>Mute Artists automatically</h4>
<p>
The following list of artists (1 per line) will be muted automatically.
</p>
<label class="switch" style="margin-bottom:10px">
<input id="muteArtists" type="checkbox">
<span class="slider round"></span>
</label>
<textarea id="mutedArtists" cols="40" rows="5"></textarea>
</div>
</div>
<div class="section">
<h3>UI</h3>
@@ -80,23 +95,46 @@
<span class="slider round"></span>
</label>
</div>
<div class="option">
<h4>Minimize on Close</h4>
<p>
Minimize window on close instead <br />
</p>
<label class="switch">
<input id="minimizeOnClose" 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 />
Enables extra hotkeys to achieve feature parity with the <a id="openExternal"
style="text-decoration: underline; cursor: pointer;"
data-url="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 class="option">
<h4>Single instance</h4>
<p>
Prevent opening multiple tidal-hifi instances
</p>
<label class="switch">
<input id="singleInstance" 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.
Tidal-hifi has a web api built in to allow users to get current song information. You can optionally
enable playback control as well.
</p>
<div class="option">
@@ -129,12 +167,12 @@
<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
Tidal-hifi is extensible through the use of integrations. You can enable or disable integrations here
</p>
<div class="option">
<h4>mpris-player</h4>
<h4>MPRIS-player</h4>
<p>
Whether to enable the mpris media player controls for Linux systems
Whether to enable the MPRIS media player controls for Linux systems
</p>
<label class="switch">
<input id="mprisCheckbox" type="checkbox">
@@ -153,19 +191,51 @@
</div>
</div>
</section>
<section id="advanced" class="tab-panel">
<div class="section">
<h3>Flags</h3>
<div class="option">
<h4>Disable hardware media keys</h4>
<p>
Disable built-in media keys. <br />
Also prevents certain desktop environments from recognizing the chrome MPRIS client separetely from the
custom MPRIS client.
</p>
<label class="switch">
<input id="disableHardwareMediaKeys" type="checkbox">
<span class="slider round"></span>
</label>
</div>
<div class="option">
<h4>Enable GPU rasterization</h4>
<p>
Move a part of the rendering to the GPU for increased performance.
</p>
<label class="switch">
<input id="gpuRasterization" type="checkbox">
<span class="slider round"></span>
</label>
</div>
</div>
</section>
<section id="about" class="tab-panel">
<div class="section">
<img style="width: 100px; height: auto; display: block; margin: 0 auto; margin-bottom: 20px; margin-top: 20px;" src = "./icon.png">
<img alt="tidal icon"
style="width: 100px; height: auto; display: block; margin: 0 auto; margin-bottom: 20px; margin-top: 20px;"
src="./icon.png">
<p style="max-width: 350px; display:block; margin: 0 auto; text-align: center;">
<a href ="javascript:openExternal('https://github.com/Mastermindzh/tidal-hifi');">Tidal-hifi</a> is made by <a href ="javascript:openExternal('https://www.rickvanlieshout.com')">Rick van Lieshout</a>.<br />
It uses <a href="javascript:openExternal('https://castlabs.com/');">castlabs</a> versions of Electron for widevine support.
<a id="openExternal" style="text-decoration: underline; cursor: pointer;"
data-url="https://github.com/Mastermindzh/tidal-hifi">Tidal-hifi</a> is made by <a id="openExternal"
data-url="https://www.rickvanlieshout.com" style="text-decoration: underline; cursor: pointer;">Rick van
Lieshout</a>.<br />
It uses <a style="text-decoration: underline; cursor: pointer;" id="openExternal"
data-url="https://castlabs.com/">Castlabs'</a> versions of Electron for widevine support.
</p>
</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>
<small>Some settings require a restart of Tidal-hifi. To do so, click the button below:</small>
<button id="restart" style="width: 100%">Restart Tidal-hifi</button>
</div>
</div>
</div>
@@ -176,6 +246,7 @@
-webkit-user-select: none;
-webkit-app-region: drag;
}
.header a {
-webkit-app-region: no-drag;
}
@@ -311,9 +382,10 @@
box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
background-color: #5a5a5a;
}
/* Tabs */
.tabset > input[type="radio"] {
.tabset>input[type="radio"] {
position: absolute;
left: -200vw;
}
@@ -322,15 +394,15 @@
display: none;
}
.tabset > input:first-child:checked ~ .tab-panels > .tab-panel:first-child,
.tabset > input:nth-child(3):checked ~ .tab-panels > .tab-panel:nth-child(2),
.tabset > input:nth-child(5):checked ~ .tab-panels > .tab-panel:nth-child(3),
.tabset > input:nth-child(7):checked ~ .tab-panels > .tab-panel:nth-child(4)
{
.tabset>input:first-child:checked~.tab-panels>.tab-panel:first-child,
.tabset>input:nth-child(3):checked~.tab-panels>.tab-panel:nth-child(2),
.tabset>input:nth-child(5):checked~.tab-panels>.tab-panel:nth-child(3),
.tabset>input:nth-child(7):checked~.tab-panels>.tab-panel:nth-child(4),
.tabset>input:nth-child(9):checked~.tab-panels>.tab-panel:nth-child(5) {
display: block;
}
.tabset > label {
.tabset>label {
position: relative;
display: inline-block;
padding: 15px 0px 10px;
@@ -338,12 +410,12 @@
cursor: pointer;
}
.tabset > input + label {
.tabset>input+label {
color: #e0e0e0;
margin-right: 30px;
}
.tabset > input:checked + label {
.tabset>input:checked+label {
color: #0ff;
border-bottom: 2px solid #0ff;
}
@@ -351,6 +423,7 @@
.tab-panel {
padding: 10px 0;
}
/* switches */
/* The switch - the box around the slider */
@@ -360,6 +433,7 @@
width: 50px;
height: 28px;
}
/* Hide default HTML checkbox */
.switch input {
@@ -367,6 +441,7 @@
width: 0;
height: 0;
}
/* The slider */
.slider {
@@ -393,19 +468,20 @@
transition: .4s;
}
input:checked + .slider {
input:checked+.slider {
background-color: #0ff;
}
input:focus + .slider {
input:focus+.slider {
box-shadow: 0 0 1px #0ff;
}
input:checked + .slider:before {
input:checked+.slider:before {
-webkit-transform: translateX(22px);
-ms-transform: translateX(22px);
transform: translateX(22px);
}
/* Rounded sliders */
.slider.round {
@@ -415,6 +491,7 @@
.slider.round:before {
border-radius: 50%;
}
/* input field */
input {
@@ -433,11 +510,11 @@
}
/* buttons */
button{
border:none;
background:none;
button {
border: none;
background: none;
align-items: center;
background-color: rgba(229,238,255,.2);
background-color: rgba(229, 238, 255, .2);
display: inline-flex;
justify-content: center;
border-radius: 12px;
@@ -452,12 +529,30 @@
min-height: 0;
min-width: 0;
font-size: 1.14286rem;
font-family: nationale,nationale-regular,Helvetica,sans-serif;
font-family: nationale, nationale-regular, Helvetica, sans-serif;
margin-top: 10px;
cursor: pointer;
}
button:hover{
background-color: rgba(229,238,255,.3);
button:hover {
background-color: rgba(229, 238, 255, .3);
}
textarea {
color: #72777f;
background: #242528;
border: 0;
width: 100%;
color: rgba(229, 238, 255, .6);
padding: 0 0 12px;
display: block;
}
textarea:focus {
outline: none;
border: 0;
border-bottom: 1px solid #0ff;
}
</style>
</html>

View File

@@ -1,16 +1,18 @@
const { setTitle, getTitle } = require("./scripts/window-functions");
const { dialog, process } = require("electron").remote;
const { setTitle } = require("./scripts/window-functions");
const { dialog, process, Notification } = require("@electron/remote");
const { store, settings } = require("./scripts/settings");
const { ipcRenderer } = require("electron");
const { app } = require("electron").remote;
const { app } = require("@electron/remote");
const { downloadFile } = require("./scripts/download");
const statuses = require("./constants/statuses");
const hotkeys = require("./scripts/hotkeys");
const globalEvents = require("./constants/globalEvents");
const notifier = require("node-notifier");
const notificationPath = `${app.getPath("userData")}/notification.jpg`;
const appName = "Tidal Hifi";
let currentSong = "";
let player;
let currentPlayStatus = statuses.paused;
let isMutedArtist = true;
const elements = {
play: '*[data-test="play"]',
@@ -18,7 +20,7 @@ const elements = {
next: '*[data-test="next"]',
previous: 'button[data-test="previous"]',
title: '*[data-test^="footer-track-title"]',
artists: '*[class^="css-14o5h2y"]',
artists: '*[data-test^="grid-item-detail-text-title-artist"]',
home: '*[data-test="menu--home"]',
back: '[class^="backwardButton"]',
forward: '[class^="forwardButton"]',
@@ -30,8 +32,15 @@ const elements = {
settings: '*[data-test^="open-settings"]',
media: '*[data-test="current-media-imagery"]',
image: "img",
url: 'a[href*="/track/"]',
current: '*[data-test="current-time"]',
duration: '*[data-test="duration"]',
bar: '*[data-test="progress-bar"]',
footer: "#footerPlayer",
album_header_title: '.header-details [data-test="title"]',
playing_title: 'span[data-test="table-cell-title"].css-geqnfr',
album_name_cell: '[data-test="table-cell-album"]',
tracklist_row: '[data-test="tracklist-row"]',
volume: '*[data-test="volume"]',
/**
* Get an element from the dom
* @param {*} key key in elements object to fetch
@@ -49,13 +58,53 @@ const elements = {
if (figure) {
const mediaElement = figure.querySelector(this["image"]);
if (mediaElement) {
return mediaElement.src;
return mediaElement.src.replace("80x80", "640x640");
}
}
return "";
},
getArtists: function () {
const footer = this.get("footer");
if (footer) {
const artists = footer.querySelector(this["artists"]);
if (artists) {
return artists.innerText;
}
}
return "unknown artist(s)";
},
getAlbumName: function () {
//If listening to an album, get its name from the header title
if (window.location.href.includes("/album/")) {
const albumName = window.document.querySelector(this.album_header_title);
if (albumName) {
return albumName.textContent;
}
//If listening to a playlist or a mix, get album name from the list
} else if (
window.location.href.includes("/playlist/") ||
window.location.href.includes("/mix/")
) {
if (currentPlayStatus === statuses.playing) {
const row = window.document.querySelector(this.playing_title).closest(this.tracklist_row);
if (row) {
return row.querySelector(this.album_name_cell).textContent;
}
}
}
return "";
},
isMuted: function () {
return this.get("volume").getAttribute("aria-checked") === "false"; // it's muted if aria-checked is false
},
/**
* Shorthand function to get the text of a dom element
* @param {*} key key in elements object to fetch
@@ -136,6 +185,9 @@ function addHotKeys() {
hotkeys.add("control+=", function () {
ipcRenderer.send(globalEvents.showSettings);
});
hotkeys.add("control+0", function () {
ipcRenderer.send(globalEvents.showSettings);
});
}
/**
@@ -169,13 +221,19 @@ function handleLogout() {
);
}
function addFullScreenListeners() {
window.document.addEventListener("fullscreenchange", () => {
ipcRenderer.send(globalEvents.refreshMenuBar);
});
}
/**
* Add ipc event listeners.
* Some actions triggered outside of the site need info from the site.
*/
function addIPCEventListeners() {
window.addEventListener("DOMContentLoaded", () => {
ipcRenderer.on("globalEvent", (event, args) => {
ipcRenderer.on("globalEvent", (_event, args) => {
switch (args) {
case globalEvents.playPause:
playPause();
@@ -200,9 +258,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) {
@@ -210,40 +268,99 @@ function updateStatus() {
} else {
status = statuses.paused;
}
return status;
}
if (status) {
ipcRenderer.send(globalEvents.updateStatus, status);
/**
* Convert the duration from MM:SS to seconds
* @param {*} duration
*/
function convertDuration(duration) {
const parts = duration.split(":");
return parseInt(parts[1]) + 60 * parseInt(parts[0]);
}
/**
* Update Tidal-hifi's media info
*
* @param {*} options
*/
function updateMediaInfo(options, notify) {
if (options) {
ipcRenderer.send(globalEvents.updateInfo, options);
if (store.get(settings.notifications) && notify) {
new Notification({ title: options.title, body: options.message, icon: options.icon }).show();
}
if (player) {
player.playbackStatus = status == statuses.paused ? "Paused" : "Playing";
player.metadata = {
...player.metadata,
...{
"xesam:title": options.title,
"xesam:artist": [options.message],
"xesam:album": options.album,
"mpris:artUrl": options.image,
"mpris:length": convertDuration(options.duration) * 1000 * 1000,
},
};
player.playbackStatus = options.status == statuses.paused ? "Paused" : "Playing";
}
}
}
/**
* Checks if Tidal is playing a video or song by grabbing the "a" element from the title.
* If it's a song it returns the track URL, if not it will return undefined
*/
function getTrackURL() {
const URLelement = elements.get("title").querySelector("a");
if (URLelement !== null) {
const id = URLelement.href.replace(/[^0-9]/g, "");
return `https://tidal.com/browse/track/${id}`;
}
return window.location;
}
/**
* Watch for song changes and update title + notify
*/
setInterval(function () {
const title = elements.getText("title");
const url = elements.get("url").href.replace(/[^0-9]/g, "");
const artists = elements.getText("artists");
const artists = elements.getArtists();
muteArtistIfFoundInMutedArtistsList(); // doing this here so that nothing can possibly fail before we call this function
const album = elements.getAlbumName();
const current = elements.getText("current");
const duration = elements.getText("duration");
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,
url: `https://tidal.com/browse/track/${url}`,
album: album,
status: currentStatus,
url: getTrackURL(),
current,
duration,
"app-name": appName,
};
new Promise((resolve, reject) => {
const titleOrArtistChanged = currentSong !== songDashArtistTitle;
// update title, url and play info with new info
setTitle(songDashArtistTitle);
getTrackURL();
currentSong = songDashArtistTitle;
currentPlayStatus = currentStatus;
const image = elements.getSongIcon();
new Promise((resolve) => {
if (image.startsWith("http")) {
options.image = image;
downloadFile(image, notificationPath).then(
() => {
options.icon = notificationPath;
@@ -260,25 +377,29 @@ setInterval(function () {
}
}).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);
},
() => {}
);
/**
* Checks whether the current artist is included in the "muted artists" list and if so it will automatically mute the player
*/
function muteArtistIfFoundInMutedArtistsList() {
if (store.get(settings.muteArtists)) {
const mutedArtists = store.get(settings.mutedArtists);
if (mutedArtists.find((artist) => artist === artists) !== undefined) {
if (!elements.isMuted()) {
isMutedArtist = true;
elements.click("volume");
}
} else if (isMutedArtist && elements.isMuted()) {
elements.click("volume");
isMutedArtist = false;
}
}
}, 200);
}
}, 1000);
if (process.platform === "linux" && store.get(settings.mpris)) {
try {
@@ -323,6 +444,10 @@ if (process.platform === "linux" && store.get(settings.mpris)) {
}
});
});
// Override get position function
player.getPosition = function () {
return convertDuration(elements.getText("current")) * 1000 * 1000;
};
player.on("quit", function () {
app.quit();
@@ -334,3 +459,4 @@ if (process.platform === "linux" && store.get(settings.mpris)) {
addHotKeys();
addIPCEventListeners();
addFullScreenListeners();

View File

@@ -1,52 +1,95 @@
const discordrpc = require("discord-rpc");
const clientId = '833617820704440341';
const { app, ipcMain } = require("electron");
const globalEvents = require("../constants/globalEvents");
const clientId = "833617820704440341";
const mediaInfoModule = require("./mediaInfo");
const discordModule = [];
let discord;
function timeToSeconds(timeArray) {
let minutes = timeArray[0] * 1;
let seconds = minutes * 60 + timeArray[1] * 1;
return seconds;
}
let rpc;
const observer = (event, arg) => {
if (mediaInfoModule.mediaInfo.status == "paused" && rpc) {
rpc.setActivity(idleStatus);
} else if (rpc) {
const currentSeconds = timeToSeconds(mediaInfoModule.mediaInfo.current.split(":"));
const durationSeconds = timeToSeconds(mediaInfoModule.mediaInfo.duration.split(":"));
const date = new Date();
const now = (date.getTime() / 1000) | 0;
const remaining = date.setSeconds(date.getSeconds() + (durationSeconds - currentSeconds));
if (mediaInfoModule.mediaInfo.url) {
rpc.setActivity({
...idleStatus,
...{
details: `Listening to ${mediaInfoModule.mediaInfo.title}`,
state: mediaInfoModule.mediaInfo.artist
? mediaInfoModule.mediaInfo.artist
: "unknown artist(s)",
startTimestamp: parseInt(now),
endTimestamp: parseInt(remaining),
largeImageKey: mediaInfoModule.mediaInfo.image,
largeImageText: mediaInfoModule.mediaInfo.album
? mediaInfoModule.mediaInfo.album
: `${idleStatus.largeImageText}`,
buttons: [{ label: "Play on Tidal", url: mediaInfoModule.mediaInfo.url }],
},
});
} else {
rpc.setActivity({
...idleStatus,
...{
details: `Watching ${mediaInfoModule.mediaInfo.title}`,
state: mediaInfoModule.mediaInfo.artist,
startTimestamp: parseInt(now),
endTimestamp: parseInt(remaining),
},
});
}
}
};
const idleStatus = {
details: `Browsing Tidal`,
largeImageKey: 'tidal-hifi-icon',
largeImageText: 'Tidal HiFi 2.0.0',
largeImageKey: "tidal-hifi-icon",
largeImageText: `Tidal HiFi ${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);
rpc = new discordrpc.Client({ transport: "ipc" });
rpc.login({ clientId }).then(
() => {
discordModule.rpc = rpc;
rpc.on('ready', () => {
rpc.on("ready", () => {
rpc.setActivity(idleStatus);
})
discord = setInterval(() => {
if (mediaInfoModule.mediaInfo.status == 'paused' && rpc) {
rpc.setActivity(idleStatus);
} else if (rpc) {
rpc.setActivity({
details: `Listening to ${mediaInfoModule.mediaInfo.title}`,
state: mediaInfoModule.mediaInfo.artist,
largeImageKey: 'tidal-hifi-icon',
largeImageText: 'Tidal HiFi 2.0.0',
buttons: [
{ label: "Play on Tidal", url: mediaInfoModule.mediaInfo.url }
],
instance: false,
});
ipcMain.on(globalEvents.updateInfo, observer);
},
() => {
console.error("Can't connect to Discord, is it running?");
}
}, 15e3);
}
);
};
/**
* Remove any RPC connection with discord and remove the event listener on globalEvents.updateInfo
*/
discordModule.unRPC = function () {
clearInterval(discord);
if (rpc) {
rpc.clearActivity();
rpc.destroy();
rpc = false;
discordModule.rpc = rpc;
}
discordModule.rpc = undefined;
ipcMain.removeListener(globalEvents.updateInfo, observer);
}
};
module.exports = discordModule;

View File

@@ -3,9 +3,13 @@ const statuses = require("./../constants/statuses");
const mediaInfo = {
title: "",
artist: "",
album: "",
icon: "",
status: statuses.paused,
url: ""
url: "",
current: "",
duration: "",
image: "tidal-hifi-icon"
};
const mediaInfoModule = {
mediaInfo,
@@ -14,20 +18,16 @@ const mediaInfoModule = {
/**
* Update artist and song info in the mediaInfo constant
*/
mediaInfoModule.update = function(arg) {
mediaInfoModule.update = function (arg) {
mediaInfo.title = propOrDefault(arg.title);
mediaInfo.artist = propOrDefault(arg.message);
mediaInfo.album = propOrDefault(arg.album);
mediaInfo.icon = propOrDefault(arg.icon);
mediaInfo.url = propOrDefault(arg.url);
};
/**
* Update tidal's status in the mediaInfo constant
*/
mediaInfoModule.updateStatus = function(status) {
if (Object.values(statuses).includes(status)) {
mediaInfo.status = status;
}
mediaInfo.status = propOrDefault(arg.status);
mediaInfo.current = propOrDefault(arg.current);
mediaInfo.duration = propOrDefault(arg.duration);
mediaInfo.image = propOrDefault(arg.image);
};
/**

View File

@@ -1,6 +1,7 @@
const { Menu } = require("electron");
const { Menu, app } = require("electron");
const { showSettingsWindow } = require("./settings");
const isMac = process.platform === "darwin";
const { name } = require("./../constants/values");
const settingsMenuEntry = {
label: "Settings",
@@ -10,11 +11,29 @@ const settingsMenuEntry = {
accelerator: "Control+/",
};
const mainMenu = [
const quitMenuEntry = {
label: "Quit",
click() {
app.exit(0);
},
accelerator: "Control+Q",
};
const menuModule = {};
menuModule.getMenu = function (mainWindow) {
const toggleWindow = {
label: "Toggle Window",
click: function () {
mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show();
},
};
const mainMenu = [
...(isMac
? [
{
label: app.name,
label: name,
submenu: [
{ role: "about" },
settingsMenuEntry,
@@ -25,17 +44,15 @@ const mainMenu = [
{ role: "hideothers" },
{ role: "unhide" },
{ type: "separator" },
{ role: "quit" },
quitMenuEntry,
],
},
]
: []),
// { role: 'fileMenu' }
{
label: "File",
submenu: [settingsMenuEntry, isMac ? { role: "close" } : { role: "quit" }],
submenu: [settingsMenuEntry, isMac ? { role: "close" } : quitMenuEntry],
},
// { role: 'editMenu' }
{
label: "Edit",
submenu: [
@@ -61,7 +78,6 @@ const mainMenu = [
settingsMenuEntry,
],
},
// { role: 'viewMenu' }
{
label: "View",
submenu: [
@@ -73,13 +89,14 @@ const mainMenu = [
{ role: "zoomout" },
{ type: "separator" },
{ role: "togglefullscreen" },
{ role: "toggledevtools" },
],
},
// { role: 'windowMenu' }
{
label: "Window",
submenu: [
{ role: "minimize" },
toggleWindow,
...(isMac
? [{ type: "separator" }, { role: "front" }, { type: "separator" }, { role: "window" }]
: [{ role: "close" }]),
@@ -92,16 +109,14 @@ const mainMenu = [
showSettingsWindow("about");
},
},
];
toggleWindow,
];
const menuModule = { mainMenu };
menuModule.getMenu = function () {
return Menu.buildFromTemplate(mainMenu);
};
menuModule.addMenu = function () {
Menu.setApplicationMenu(menuModule.getMenu());
menuModule.addMenu = function (mainWindow) {
Menu.setApplicationMenu(menuModule.getMenu(mainWindow));
};
module.exports = menuModule;

View File

@@ -10,15 +10,33 @@ const store = new Store({
notifications: true,
api: true,
playBackControl: true,
muteArtists: false,
mutedArtists: ["TIDAL"],
menuBar: true,
apiSettings: {
port: 47836,
},
singleInstance: true,
disableHardwareMediaKeys: false,
trayIcon: true,
minimizeOnClose: false,
mpris: false,
enableCustomHotkeys: false,
enableDiscord: false,
windowBounds: { width: 800, height: 600 },
flags: {
gpuRasterization: true,
disableHardwareMediaKeys: false,
},
},
migrations: {
"3.1.0": (migrationStore) => {
console.log("running migrations for 3.1.0");
migrationStore.set(
settings.flags.disableHardwareMediaKeys,
migrationStore.get("disableHardwareMediaKeys") ?? false
);
},
},
});
@@ -36,7 +54,6 @@ settingsModule.createSettingsWindow = function () {
frame: false,
title: "Tidal-hifi - settings",
webPreferences: {
affinity: "window",
preload: path.join(__dirname, "../pages/settings/preload.js"),
plugins: true,
nodeIntegration: true,

View File

@@ -3,20 +3,20 @@ const { getMenu } = require("./menu");
const trayModule = {};
let tray;
trayModule.addTray = function (options = { icon: "" }) {
trayModule.addTray = function (mainWindow, options = { icon: "" }) {
tray = new Tray(options.icon);
tray.setIgnoreDoubleClickEvents(true);
tray.setToolTip("Tidal-hifi");
const menu = getMenu(mainWindow);
tray.setContextMenu(menu);
};
trayModule.refreshTray = function () {
trayModule.refreshTray = function (mainWindow) {
if (!tray) {
trayModule.addTray();
trayModule.addTray(mainWindow);
}
tray.on("click", function (e) {
// do nothing on click
});
tray.setToolTip("Tidal-hifi");
tray.setContextMenu(getMenu());
};
module.exports = trayModule;