Compare commits

...

30 Commits

Author SHA1 Message Date
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
27 changed files with 2128 additions and 2054 deletions

View File

@@ -9,6 +9,10 @@ jobs:
build_on_linux: build_on_linux:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: 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/checkout@master
- uses: actions/setup-node@master - uses: actions/setup-node@master
with: with:

View File

@@ -9,6 +9,10 @@ jobs:
build_on_linux: build_on_linux:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: 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/checkout@master
- uses: actions/setup-node@master - uses: actions/setup-node@master
with: with:

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

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

View File

@@ -4,10 +4,70 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 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 ## 2.5.0
- Notify-send now correctly shows "Tidal Hifi" as the program name - Notify-send now correctly shows "Tidal HiFi" as the program name
- Updated dependencies (including electron itself) - Updated dependencies (including electron itself)
### known issues ### known issues
@@ -20,13 +80,13 @@ updated to nodejs 16 in actions
## 2.4.0 ## 2.4.0
- Added more mpris settings - Added more MPRIS settings
- Added instruction for rescrobbler to get last.fm working without sandbox mode - Added instruction for rescrobbler to get last.fm working without sandbox mode
## 2.3.0 ## 2.3.0
- Added a setting to minimize to tray on app close (off by default) - Added a setting to minimize to tray on app close (off by default)
- Added the main menu to the trayicon - Added the main menu to the tray icon
## 2.2.1 ## 2.2.1
@@ -43,7 +103,7 @@ moved to: [https://github.com/Mastermindzh/tidal-hifi-aur](https://github.com/Ma
- All fields (current, remaining, and url are also available in the API\*) - All fields (current, remaining, and url are also available in the API\*)
- the artist field is now correctly identified - the artist field is now correctly identified
* current time only updates on play/pause. \* current time only updates on play/pause.
## 2.1.1 ## 2.1.1
@@ -68,7 +128,7 @@ moved to: [https://github.com/Mastermindzh/tidal-hifi-aur](https://github.com/Ma
## 1.3.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 ## 1.2.0
@@ -83,7 +143,7 @@ Bugfixes:
## 1.1.0 ## 1.1.0
- updated to electron 8.0.0 - updated to electron 8.0.0
- Added a beta-version of the mpris service - Added a beta-version of the MPRIS service
- Bugfixes: - Bugfixes:
- icon on gnome not showing in launcher - icon on gnome not showing in launcher

View File

@@ -15,6 +15,7 @@ The web version of [listen.tidal.com](https://listen.tidal.com) running in elect
- [Using releases](#using-releases) - [Using releases](#using-releases)
- [Snap install](#snap-install) - [Snap install](#snap-install)
- [Arch Linux](#arch-linux) - [Arch Linux](#arch-linux)
- [Flatpak](#flatpak)
- [Using source](#using-source) - [Using source](#using-source)
- [features](#features) - [features](#features)
- [Integrations](#integrations) - [Integrations](#integrations)
@@ -58,7 +59,15 @@ snap install --dangerous <path> #for instance: tidal-hifi_1.0.0_amd64.snap
Arch Linux users can use the AUR to install tidal-hifi: Arch Linux users can use the AUR to install tidal-hifi:
```sh ```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
``` ```
### Using source ### Using source
@@ -76,8 +85,10 @@ To install and work with the code on this project follow these steps:
- Notifications - Notifications
- Custom hotkeys ([source](https://defkey.com/tidal-desktop-shortcuts)) - Custom hotkeys ([source](https://defkey.com/tidal-desktop-shortcuts))
- API for status and playback - API for status and playback
- [Mute artists automatically (defaults to "Tidal")]("./docs/muting-artists.md")
- Custom [integrations](#integrations) - Custom [integrations](#integrations)
- [Settings feature](./docs/settings.png) to disable certain functionality. (`ctrl+=`) - [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 ## Integrations
@@ -88,7 +99,7 @@ You can find these in the settings menu (`ctrl + =` by default) under the "integ
It currently includes: It currently includes:
- mpris - mpris media player controls/status - MPRIS - MPRIS media player controls/status
- Discord - Shows what you're listening to on Discord. - Discord - Shows what you're listening to on Discord.
### not included ### not included
@@ -127,7 +138,7 @@ Sometimes it's just easier to start over, cover my own needs and then making it
## Buy me a coffee? Please don't ## Buy me a coffee? Please don't
Instead spend some money on a charity I care for: [kwf.nl](https://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) Inspired by [haydenjames' issue](https://github.com/Mastermindzh/tidal-hifi/issues/27#issuecomment-704198429)
## Images ## Images

View File

@@ -0,0 +1,33 @@
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: assets/icon.png
StartupNotify: true
Terminal: false
Type: Application
Categories: Network;Application;AudioVideo;Audio;Video
StartupWMClass: tidal-hifi
X-PulseAudio-Properties: media.role=music
mac:
category: public.app-category.entertainment
win:
icon: build/icon.png
artifactName: "tidalhifi"
appId: com.rickvanlieshout.tidalhifi
executableName: tidalhifi

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,37 +1,17 @@
appId: com.rickvanlieshout.tidal-hifi electronVersion: 19.0.5
electronVersion: 8.5.2
electronDownload: electronDownload:
version: 8.5.2-wvvmp version: 19.0.5+wvcus
mirror: https://github.com/castlabs/electron-releases/releases/download/v mirror: https://github.com/castlabs/electron-releases/releases/download/v
snap:
plugs:
- default
- screen-inhibit-control
linux: linux:
category: Audio category: Audio
target: target:
# - pacman - pacman
- tar.gz - tar.gz
- deb - deb
- rpm - rpm
- AppImage - AppImage
- snap - snap
- freebsd - 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: win:
target: msi target: msi
icon: build/icon.png icon: build/icon.png

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

3524
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,19 @@
{ {
"name": "tidal-hifi", "name": "tidal-hifi",
"version": "2.5.0", "version": "4.0.1",
"description": "Tidal on Electron with widevine(hifi) support", "description": "Tidal on Electron with widevine(hifi) support",
"main": "src/main.js", "main": "src/main.js",
"scripts": { "scripts": {
"start": "electron .", "start": "electron .",
"build": "electron-builder --publish=never -c ./build/electron-builder.yml", "build": "electron-builder --publish=never -c ./build/electron-builder.yml",
"build-deb": "electron-builder --publish=never -c ./build/electron-builder.deb.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-rpm": "electron-builder --publish=never -c ./build/electron-builder.rpm.yml",
"build-snap": "electron-builder --publish=never -c ./build/electron-builder.snap.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-arch": "electron-builder --publish=never -c ./build/electron-builder.pacman.yml",
"build-wl": "electron-builder --publish=never -c ./build/electron-builder.yml -wl", "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": [ "keywords": [
"electron", "electron",
@@ -23,19 +25,18 @@
"homepage": "https://github.com/Mastermindzh/tidal-hifi", "homepage": "https://github.com/Mastermindzh/tidal-hifi",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@electron/remote": "^2.0.8",
"discord-rpc": "^4.0.1", "discord-rpc": "^4.0.1",
"electron-store": "^8.0.1", "electron-store": "^8.0.1",
"express": "^4.17.1", "express": "^4.17.1",
"hotkeys-js": "^3.8.7", "hotkeys-js": "^3.8.7",
"mpris-service": "^2.1.2", "mpris-service": "^2.1.2",
"node-notifier": "^10.0.0",
"request": "^2.88.2" "request": "^2.88.2"
}, },
"devDependencies": { "devDependencies": {
"@mastermindzh/prettier-config": "^1.0.0", "@mastermindzh/prettier-config": "^1.0.0",
"electron": "git+https://github.com/castlabs/electron-releases.git#v16.0.4+wvcus", "electron": "git+https://github.com/castlabs/electron-releases.git#v19.0.5+wvcus",
"electron-builder": "^22.14.5", "electron-builder": "^23.2.0",
"electron-reload": "^1.5.0",
"prettier": "^2.5.0" "prettier": "^2.5.0"
}, },
"prettier": "@mastermindzh/prettier-config" "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,6 +6,7 @@ const globalEvents = {
previous: "previous", previous: "previous",
updateInfo: "update-info", updateInfo: "update-info",
hideSettings: "hideSettings", hideSettings: "hideSettings",
refreshMenuBar: "refreshMenubar",
showSettings: "showSettings", showSettings: "showSettings",
storeChanged: "storeChanged", storeChanged: "storeChanged",
error: "error", error: "error",

View File

@@ -13,10 +13,18 @@ const settings = {
api: "api", api: "api",
menuBar: "menuBar", menuBar: "menuBar",
playBackControl: "playBackControl", playBackControl: "playBackControl",
muteArtists: "muteArtists",
mutedArtists: "mutedArtists",
apiSettings: { apiSettings: {
root: "apiSettings", root: "apiSettings",
port: "apiSettings.port", port: "apiSettings.port",
}, },
singleInstance: "singleInstance",
disableHardwareMediaKeys: "disableHardwareMediaKeys",
flags: {
disableHardwareMediaKeys: "flags.disableHardwareMediaKeys",
gpuRasterization: "flags.gpuRasterization",
},
mpris: "mpris", mpris: "mpris",
enableCustomHotkeys: "enableCustomHotkeys", enableCustomHotkeys: "enableCustomHotkeys",
trayIcon: "trayIcon", trayIcon: "trayIcon",

View File

@@ -1,4 +1,5 @@
const { app, BrowserWindow, globalShortcut, ipcMain } = require("electron"); require("@electron/remote/main").initialize();
const { app, BrowserWindow, components, globalShortcut, ipcMain } = require("electron");
const { const {
settings, settings,
store, store,
@@ -16,17 +17,55 @@ const mediaKeys = require("./constants/mediaKeys");
const mediaInfoModule = require("./scripts/mediaInfo"); const mediaInfoModule = require("./scripts/mediaInfo");
const discordModule = require("./scripts/discord"); const discordModule = require("./scripts/discord");
const globalEvents = require("./constants/globalEvents"); const globalEvents = require("./constants/globalEvents");
const flagValues = require("./constants/flags");
let mainWindow; let mainWindow;
let icon = path.join(__dirname, "../assets/icon.png"); let icon = path.join(__dirname, "../assets/icon.png");
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) { function syncMenuBarWithStore() {
require("electron-reload")(`${__dirname}`, { mainWindow.setMenuBarVisibility(store.get(settings.menuBar));
electron: require(`${__dirname}/../node_modules/electron`), }
});
/**
* 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 = {}) { function createWindow(options = {}) {
@@ -37,18 +76,16 @@ function createWindow(options = {}) {
width: store && store.get(settings.windowBounds.width), width: store && store.get(settings.windowBounds.width),
height: store && store.get(settings.windowBounds.height), height: store && store.get(settings.windowBounds.height),
icon, icon,
tray: true,
backgroundColor: options.backgroundColor, backgroundColor: options.backgroundColor,
webPreferences: { webPreferences: {
affinity: "window",
preload: path.join(__dirname, "preload.js"), preload: path.join(__dirname, "preload.js"),
plugins: true, plugins: true,
devTools: true, // I like tinkering, others might too devTools: true, // I like tinkering, others might too
enableRemoteModule: true,
}, },
}); });
require("@electron/remote/main").enable(mainWindow.webContents);
mainWindow.setMenuBarVisibility(store.get(settings.menuBar)); syncMenuBarWithStore();
// load the Tidal website // load the Tidal website
mainWindow.loadURL(tidalUrl); mainWindow.loadURL(tidalUrl);
@@ -87,14 +124,20 @@ function addGlobalShortcuts() {
// This method will be called when Electron has finished // This method will be called when Electron has finished
// initialization and is ready to create browser windows. // initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs. // Some APIs can only be used after this event occurs.
app.on("ready", () => { app.on("ready", async () => {
createWindow(); if (isMainInstanceOrMultipleInstancesAllowed()) {
addMenu(); await components.whenReady();
createSettingsWindow(); createWindow();
addGlobalShortcuts(); addMenu();
store.get(settings.trayIcon) && addTray({ icon }) && refreshTray(); createSettingsWindow();
store.get(settings.api) && expressModule.run(mainWindow); addGlobalShortcuts();
store.get(settings.enableDiscord) && discordModule.initRPC(); store.get(settings.trayIcon) && addTray({ 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 () { app.on("activate", function () {
@@ -105,20 +148,28 @@ app.on("activate", function () {
} }
}); });
app.on("browser-window-created", (_, window) => {
require("@electron/remote/main").enable(window.webContents);
});
// IPC // IPC
ipcMain.on(globalEvents.updateInfo, (event, arg) => { ipcMain.on(globalEvents.updateInfo, (_event, arg) => {
mediaInfoModule.update(arg); mediaInfoModule.update(arg);
}); });
ipcMain.on(globalEvents.hideSettings, (event, arg) => { ipcMain.on(globalEvents.hideSettings, (_event, _arg) => {
hideSettingsWindow(); hideSettingsWindow();
}); });
ipcMain.on(globalEvents.showSettings, (event, arg) => { ipcMain.on(globalEvents.showSettings, (_event, _arg) => {
showSettingsWindow(); showSettingsWindow();
}); });
ipcMain.on(globalEvents.storeChanged, (event, arg) => { ipcMain.on(globalEvents.refreshMenuBar, (_event, _arg) => {
mainWindow.setMenuBarVisibility(store.get(settings.menuBar)); syncMenuBarWithStore();
});
ipcMain.on(globalEvents.storeChanged, (_event, _arg) => {
syncMenuBarWithStore();
if (store.get(settings.enableDiscord) && !discordModule.rpc) { if (store.get(settings.enableDiscord) && !discordModule.rpc) {
discordModule.initRPC(); discordModule.initRPC();
@@ -127,6 +178,6 @@ ipcMain.on(globalEvents.storeChanged, (event, arg) => {
} }
}); });
ipcMain.on(globalEvents.error, (event, arg) => { ipcMain.on(globalEvents.error, (event, _arg) => {
console.log(event); console.log(event);
}); });

View File

@@ -1,13 +1,24 @@
let notifications; let trayIcon,
let playBackControl; minimizeOnClose,
let api; mpris,
let port; enableCustomHotkeys,
let menuBar; enableDiscord,
muteArtists,
notifications,
playBackControl,
api,
port,
menuBar,
mutedArtists,
singleInstance,
disableHardwareMediaKeys,
gpuRasterization;
const { store, settings } = require("./../../scripts/settings"); const { store, settings } = require("./../../scripts/settings");
const { ipcRenderer } = require("electron"); const { ipcRenderer } = require("electron");
const globalEvents = require("./../../constants/globalEvents"); const globalEvents = require("./../../constants/globalEvents");
const remote = require("@electron/remote");
const { app } = remote;
/** /**
* Sync the UI forms with the current settings * Sync the UI forms with the current settings
*/ */
@@ -22,31 +33,35 @@ function refreshSettings() {
enableCustomHotkeys.checked = store.get(settings.enableCustomHotkeys); enableCustomHotkeys.checked = store.get(settings.enableCustomHotkeys);
enableDiscord.checked = store.get(settings.enableDiscord); enableDiscord.checked = store.get(settings.enableDiscord);
minimizeOnClose.checked = store.get(settings.minimizeOnClose); 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 * Open an url in the default browsers
*/ */
window.openExternal = function (url) { function openExternal(url) {
const { shell } = require("electron"); const { shell } = require("electron");
shell.openExternal(url); shell.openExternal(url);
}; }
/** /**
* hide the settings window * hide the settings window
*/ */
window.hide = function () { function hide() {
ipcRenderer.send(globalEvents.hideSettings); ipcRenderer.send(globalEvents.hideSettings);
}; }
/** /**
* Restart tidal-hifi after changes * Restart tidal-hifi after changes
*/ */
window.restart = function () { function restart() {
const remote = require("electron").remote; app.relaunch();
remote.app.relaunch(); app.quit();
remote.app.exit(0); }
};
/** /**
* Bind UI components to functions after DOMContentLoaded * Bind UI components to functions after DOMContentLoaded
@@ -56,8 +71,16 @@ window.addEventListener("DOMContentLoaded", () => {
return document.getElementById(id); 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) { function addInputListener(source, key) {
source.addEventListener("input", function (event, data) { source.addEventListener("input", function (_event, _data) {
if (this.value === "on") { if (this.value === "on") {
store.set(key, source.checked); store.set(key, source.checked);
} else { } else {
@@ -67,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", () => { ipcRenderer.on("refreshData", () => {
refreshSettings(); refreshSettings();
}); });
@@ -85,6 +115,11 @@ window.addEventListener("DOMContentLoaded", () => {
mpris = get("mprisCheckbox"); mpris = get("mprisCheckbox");
enableCustomHotkeys = get("enableCustomHotkeys"); enableCustomHotkeys = get("enableCustomHotkeys");
enableDiscord = get("enableDiscord"); enableDiscord = get("enableDiscord");
muteArtists = get("muteArtists");
mutedArtists = get("mutedArtists");
singleInstance = get("singleInstance");
disableHardwareMediaKeys = get("disableHardwareMediaKeys");
gpuRasterization = get("gpuRasterization");
refreshSettings(); refreshSettings();
@@ -98,4 +133,9 @@ window.addEventListener("DOMContentLoaded", () => {
addInputListener(enableCustomHotkeys, settings.enableCustomHotkeys); addInputListener(enableCustomHotkeys, settings.enableCustomHotkeys);
addInputListener(enableDiscord, settings.enableDiscord); addInputListener(enableDiscord, settings.enableDiscord);
addInputListener(minimizeOnClose, settings.minimizeOnClose); 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"> <html lang="en">
<head> <head>
<title>Tidal-hifi settings</title>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" />
@@ -10,7 +11,7 @@
<body> <body>
<div class="header"> <div class="header">
<h1 class="title">Settings</h1> <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"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="18px" height="18px" viewBox="0 0 348.333 348.334">
<g> <g>
@@ -36,6 +37,9 @@
<input type="radio" name="tabset" id="integrations" /> <input type="radio" name="tabset" id="integrations" />
<label for="integrations">Integrations</label> <label for="integrations">Integrations</label>
<!-- advanced tab -->
<input type="radio" name="tabset" id="advanced" />
<label for="advanced">Advanced</label>
<!-- about tab --> <!-- about tab -->
<input type="radio" name="tabset" id="about" /> <input type="radio" name="tabset" id="about" />
<label for="about">About</label> <label for="about">About</label>
@@ -54,6 +58,17 @@
<span class="slider round"></span> <span class="slider round"></span>
</label> </label>
</div> </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>
<div class="section"> <div class="section">
<h3>UI</h3> <h3>UI</h3>
@@ -93,13 +108,23 @@
<div class="option"> <div class="option">
<h4>Hotkeys</h4> <h4>Hotkeys</h4>
<p> <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> </p>
<label class="switch"> <label class="switch">
<input id="enableCustomHotkeys" type="checkbox"> <input id="enableCustomHotkeys" type="checkbox">
<span class="slider round"></span> <span class="slider round"></span>
</label> </label>
</div> </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> </div>
</section> </section>
<section id="api" class="tab-panel"> <section id="api" class="tab-panel">
@@ -139,12 +164,12 @@
<div class="section"> <div class="section">
<h3>integrations</h3> <h3>integrations</h3>
<p style="margin-bottom: 15px;"> <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> </p>
<div class="option"> <div class="option">
<h4>mpris-player</h4> <h4>MPRIS-player</h4>
<p> <p>
Whether to enable the mpris media player controls for Linux systems Whether to enable the MPRIS media player controls for Linux systems
</p> </p>
<label class="switch"> <label class="switch">
<input id="mprisCheckbox" type="checkbox"> <input id="mprisCheckbox" type="checkbox">
@@ -163,19 +188,47 @@
</div> </div>
</div> </div>
</section> </section>
<section id="about" class="tab-panel">
<div class="section"> <section id="advanced" class="tab-panel">
<img style="width: 100px; height: auto; display: block; margin: 0 auto; margin-bottom: 20px; margin-top: 20px;" src = "./icon.png"> <div class="section">
<p style="max-width: 350px; display:block; margin: 0 auto; text-align: center;"> <h3>Flags</h3>
<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 /> <div class="option">
It uses <a href="javascript:openExternal('https://castlabs.com/');">castlabs</a> versions of Electron for widevine support. <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> </p>
<label class="switch">
<input id="disableHardwareMediaKeys" type="checkbox">
<span class="slider round"></span>
</label>
</div> </div>
</section> <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>
<small>Some settings require a restart of Tidal-hifi. To do so click the button below:</small> <!-- about -->
<button onClick="restart()" style ="width: 100%">Restart Tidal-hifi</button> <section id="about" class="tab-panel">
<div class="section">
<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 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 id="restart" style ="width: 100%">Restart Tidal-hifi</button>
</div> </div>
</div> </div>
</div> </div>
@@ -469,5 +522,19 @@
button:hover{ button:hover{
background-color: rgba(229,238,255,.3); 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> </style>
</html> </html>

View File

@@ -1,14 +1,14 @@
const { setTitle } = require("./scripts/window-functions"); const { setTitle } = require("./scripts/window-functions");
const { dialog, process } = require("electron").remote; const { dialog, process, Notification } = require('@electron/remote');
const { store, settings } = require("./scripts/settings"); const { store, settings } = require("./scripts/settings");
const { ipcRenderer } = require("electron"); const { ipcRenderer } = require("electron");
const { app } = require("electron").remote; const { app } = require('@electron/remote');
const { downloadFile } = require("./scripts/download"); const { downloadFile } = require("./scripts/download");
const statuses = require("./constants/statuses"); const statuses = require("./constants/statuses");
const hotkeys = require("./scripts/hotkeys"); const hotkeys = require("./scripts/hotkeys");
const globalEvents = require("./constants/globalEvents"); const globalEvents = require("./constants/globalEvents");
const notifier = require("node-notifier");
const notificationPath = `${app.getPath("userData")}/notification.jpg`; const notificationPath = `${app.getPath("userData")}/notification.jpg`;
const appName = "Tidal Hifi";
let currentSong = ""; let currentSong = "";
let player; let player;
let currentPlayStatus = statuses.paused; let currentPlayStatus = statuses.paused;
@@ -16,6 +16,7 @@ let progressBarTime;
let currentTimeChanged = false; let currentTimeChanged = false;
let currentTime; let currentTime;
let currentURL = undefined; let currentURL = undefined;
let isMutedArtist = false;
const elements = { const elements = {
play: '*[data-test="play"]', play: '*[data-test="play"]',
@@ -36,10 +37,14 @@ const elements = {
media: '*[data-test="current-media-imagery"]', media: '*[data-test="current-media-imagery"]',
image: "img", image: "img",
current: '*[data-test="current-time"]', current: '*[data-test="current-time"]',
duration: '*[data-test="duration-time"]', duration: '*[data-test="duration"]',
bar: '*[data-test="progress-bar"]', bar: '*[data-test="progress-bar"]',
footer: "#footerPlayer", 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 * Get an element from the dom
* @param {*} key key in elements object to fetch * @param {*} key key in elements object to fetch
@@ -57,7 +62,7 @@ const elements = {
if (figure) { if (figure) {
const mediaElement = figure.querySelector(this["image"]); const mediaElement = figure.querySelector(this["image"]);
if (mediaElement) { if (mediaElement) {
return mediaElement.src; return mediaElement.src.replace("80x80", "640x640");
} }
} }
@@ -77,6 +82,33 @@ const elements = {
return "unknown artist(s)"; 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 * Shorthand function to get the text of a dom element
* @param {*} key key in elements object to fetch * @param {*} key key in elements object to fetch
@@ -157,6 +189,9 @@ function addHotKeys() {
hotkeys.add("control+=", function () { hotkeys.add("control+=", function () {
ipcRenderer.send(globalEvents.showSettings); ipcRenderer.send(globalEvents.showSettings);
}); });
hotkeys.add("control+0", function () {
ipcRenderer.send(globalEvents.showSettings);
});
} }
/** /**
@@ -190,13 +225,19 @@ function handleLogout() {
); );
} }
function addFullScreenListeners() {
window.document.addEventListener("fullscreenchange", () => {
ipcRenderer.send(globalEvents.refreshMenuBar);
});
}
/** /**
* Add ipc event listeners. * Add ipc event listeners.
* Some actions triggered outside of the site need info from the site. * Some actions triggered outside of the site need info from the site.
*/ */
function addIPCEventListeners() { function addIPCEventListeners() {
window.addEventListener("DOMContentLoaded", () => { window.addEventListener("DOMContentLoaded", () => {
ipcRenderer.on("globalEvent", (event, args) => { ipcRenderer.on("globalEvent", (_event, args) => {
switch (args) { switch (args) {
case globalEvents.playPause: case globalEvents.playPause:
playPause(); playPause();
@@ -251,13 +292,16 @@ function convertDuration(duration) {
function updateMediaInfo(options, notify) { function updateMediaInfo(options, notify) {
if (options) { if (options) {
ipcRenderer.send(globalEvents.updateInfo, options); ipcRenderer.send(globalEvents.updateInfo, options);
store.get(settings.notifications) && notify && notifier.notify(options); if (store.get(settings.notifications) && notify) {
new Notification({ title: options.title, body: options.message, icon: options.icon }).show();
}
if (player) { if (player) {
player.metadata = { player.metadata = {
...player.metadata, ...player.metadata,
...{ ...{
"xesam:title": options.title, "xesam:title": options.title,
"xesam:artist": [options.message], "xesam:artist": [options.message],
"xesam:album": options.album,
"mpris:artUrl": options.image, "mpris:artUrl": options.image,
"mpris:length": convertDuration(options.duration) * 1000 * 1000, "mpris:length": convertDuration(options.duration) * 1000 * 1000,
}, },
@@ -290,26 +334,29 @@ function updateURL() {
setInterval(function () { setInterval(function () {
const title = elements.getText("title"); const title = elements.getText("title");
const artists = elements.getArtists(); const artists = elements.getArtists();
const album = elements.getAlbumName();
const current = elements.getText("current"); const current = elements.getText("current");
const duration = elements.getText("duration"); const duration = elements.getText("duration");
const appName = "Tidal Hifi";
const progressBarcurrentTime = elements.get("bar").getAttribute("aria-valuenow"); const progressBarcurrentTime = elements.get("bar").getAttribute("aria-valuenow");
const songDashArtistTitle = `${title} - ${artists}`; const songDashArtistTitle = `${title} - ${artists}`;
const currentStatus = getCurrentlyPlayingStatus(); const currentStatus = getCurrentlyPlayingStatus();
const options = { const options = {
title, title,
message: artists, message: artists,
album: album,
status: currentStatus, status: currentStatus,
url: currentURL, url: currentURL,
current: current, current: current,
duration: duration, duration: duration,
'app-name': appName, "app-name": appName,
}; };
const playStatusChanged = currentStatus !== currentPlayStatus; const playStatusChanged = currentStatus !== currentPlayStatus;
const progressBarTimeChanged = progressBarcurrentTime !== progressBarTime; const progressBarTimeChanged = progressBarcurrentTime !== progressBarTime;
const titleOrArtistChanged = currentSong !== songDashArtistTitle; const titleOrArtistChanged = currentSong !== songDashArtistTitle;
muteArtistIfFoundInMutedArtistsList();
if (titleOrArtistChanged || playStatusChanged || progressBarTimeChanged || currentTimeChanged) { if (titleOrArtistChanged || playStatusChanged || progressBarTimeChanged || currentTimeChanged) {
// update title, url and play info with new info // update title, url and play info with new info
setTitle(songDashArtistTitle); setTitle(songDashArtistTitle);
@@ -364,7 +411,25 @@ setInterval(function () {
() => {} () => {}
); );
} }
}, 200);
/**
* 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 (currentStatus === statuses.playing && isMutedArtist && elements.isMuted()) {
elements.click("volume");
isMutedArtist = false;
}
}
}
}, 500);
if (process.platform === "linux" && store.get(settings.mpris)) { if (process.platform === "linux" && store.get(settings.mpris)) {
try { try {
@@ -424,3 +489,4 @@ if (process.platform === "linux" && store.get(settings.mpris)) {
addHotKeys(); addHotKeys();
addIPCEventListeners(); addIPCEventListeners();
addFullScreenListeners();

View File

@@ -31,6 +31,10 @@ const observer = (event, arg) => {
: "unknown artist(s)", : "unknown artist(s)",
startTimestamp: parseInt(now), startTimestamp: parseInt(now),
endTimestamp: parseInt(remaining), 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 }], buttons: [{ label: "Play on Tidal", url: mediaInfoModule.mediaInfo.url }],
}, },
}); });
@@ -60,24 +64,32 @@ const idleStatus = {
*/ */
discordModule.initRPC = function () { discordModule.initRPC = function () {
rpc = new discordrpc.Client({ transport: "ipc" }); rpc = new discordrpc.Client({ transport: "ipc" });
rpc.login({ clientId }).catch(console.error); rpc.login({ clientId }).then(
discordModule.rpc = rpc; () => {
discordModule.rpc = rpc;
rpc.on("ready", () => { rpc.on("ready", () => {
rpc.setActivity(idleStatus); rpc.setActivity(idleStatus);
}); });
ipcMain.on(globalEvents.updateInfo, observer); ipcMain.on(globalEvents.updateInfo, observer);
},
() => {
console.error("Can't connect to Discord, is it running?");
}
);
}; };
/** /**
* Remove any RPC connection with discord and remove the event listener on globalEvents.updateInfo * Remove any RPC connection with discord and remove the event listener on globalEvents.updateInfo
*/ */
discordModule.unRPC = function () { discordModule.unRPC = function () {
rpc.clearActivity(); if (rpc) {
rpc.destroy(); rpc.clearActivity();
rpc = false; rpc.destroy();
discordModule.rpc = rpc; rpc = false;
ipcMain.removeListener(globalEvents.updateInfo, observer); discordModule.rpc = undefined;
ipcMain.removeListener(globalEvents.updateInfo, observer);
}
}; };
module.exports = discordModule; module.exports = discordModule;

View File

@@ -3,11 +3,13 @@ const statuses = require("./../constants/statuses");
const mediaInfo = { const mediaInfo = {
title: "", title: "",
artist: "", artist: "",
album: "",
icon: "", icon: "",
status: statuses.paused, status: statuses.paused,
url: "", url: "",
current: "", current: "",
duration: "" duration: "",
image: "tidal-hifi-icon"
}; };
const mediaInfoModule = { const mediaInfoModule = {
mediaInfo, mediaInfo,
@@ -19,11 +21,13 @@ const mediaInfoModule = {
mediaInfoModule.update = function (arg) { mediaInfoModule.update = function (arg) {
mediaInfo.title = propOrDefault(arg.title); mediaInfo.title = propOrDefault(arg.title);
mediaInfo.artist = propOrDefault(arg.message); mediaInfo.artist = propOrDefault(arg.message);
mediaInfo.album = propOrDefault(arg.album);
mediaInfo.icon = propOrDefault(arg.icon); mediaInfo.icon = propOrDefault(arg.icon);
mediaInfo.url = propOrDefault(arg.url); mediaInfo.url = propOrDefault(arg.url);
mediaInfo.status = propOrDefault(arg.status); mediaInfo.status = propOrDefault(arg.status);
mediaInfo.current = propOrDefault(arg.current); mediaInfo.current = propOrDefault(arg.current);
mediaInfo.duration = propOrDefault(arg.duration); mediaInfo.duration = propOrDefault(arg.duration);
mediaInfo.image = propOrDefault(arg.image);
}; };
/** /**

View File

@@ -1,4 +1,4 @@
const { Menu } = require("electron"); const { Menu, app } = require("electron");
const { showSettingsWindow } = require("./settings"); const { showSettingsWindow } = require("./settings");
const isMac = process.platform === "darwin"; const isMac = process.platform === "darwin";
@@ -10,6 +10,14 @@ const settingsMenuEntry = {
accelerator: "Control+/", accelerator: "Control+/",
}; };
const quitMenuEntry = {
label: "Quit",
click() {
app.exit(0);
},
accelerator: "Control+Q"
};
const mainMenu = [ const mainMenu = [
...(isMac ...(isMac
? [ ? [
@@ -25,17 +33,15 @@ const mainMenu = [
{ role: "hideothers" }, { role: "hideothers" },
{ role: "unhide" }, { role: "unhide" },
{ type: "separator" }, { type: "separator" },
{ role: "quit" }, quitMenuEntry,
], ],
}, },
] ]
: []), : []),
// { role: 'fileMenu' }
{ {
label: "File", label: "File",
submenu: [settingsMenuEntry, isMac ? { role: "close" } : { role: "quit" }], submenu: [settingsMenuEntry, isMac ? { role: "close" } : quitMenuEntry],
}, },
// { role: 'editMenu' }
{ {
label: "Edit", label: "Edit",
submenu: [ submenu: [
@@ -61,7 +67,6 @@ const mainMenu = [
settingsMenuEntry, settingsMenuEntry,
], ],
}, },
// { role: 'viewMenu' }
{ {
label: "View", label: "View",
submenu: [ submenu: [
@@ -75,7 +80,6 @@ const mainMenu = [
{ role: "togglefullscreen" }, { role: "togglefullscreen" },
], ],
}, },
// { role: 'windowMenu' }
{ {
label: "Window", label: "Window",
submenu: [ submenu: [

View File

@@ -10,16 +10,33 @@ const store = new Store({
notifications: true, notifications: true,
api: true, api: true,
playBackControl: true, playBackControl: true,
muteArtists: false,
mutedArtists: ["TIDAL"],
menuBar: true, menuBar: true,
apiSettings: { apiSettings: {
port: 47836, port: 47836,
}, },
singleInstance: true,
disableHardwareMediaKeys: false,
trayIcon: true, trayIcon: true,
minimizeOnClose : false, minimizeOnClose: false,
mpris: false, mpris: false,
enableCustomHotkeys: false, enableCustomHotkeys: false,
enableDiscord: false, enableDiscord: false,
windowBounds: { width: 800, height: 600 }, 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
);
},
}, },
}); });
@@ -37,7 +54,6 @@ settingsModule.createSettingsWindow = function () {
frame: false, frame: false,
title: "Tidal-hifi - settings", title: "Tidal-hifi - settings",
webPreferences: { webPreferences: {
affinity: "window",
preload: path.join(__dirname, "../pages/settings/preload.js"), preload: path.join(__dirname, "../pages/settings/preload.js"),
plugins: true, plugins: true,
nodeIntegration: true, nodeIntegration: true,