Merge pull request #223 from Mastermindzh/release/5.1.0

Release/5.1.0
This commit is contained in:
Rick van Lieshout 2023-04-27 15:30:09 +02:00 committed by GitHub
commit 8d44ff8afb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 215 additions and 105 deletions

View File

@ -4,9 +4,24 @@ 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).
## 5.1.0
### New features
- Added proper updates through the MediaSession API
- You can now add custom CSS in the "advanced" settings tab
- You can now configure the updateFrequency in the settings window
- Default value is set to 500 and will overwrite the hardcoded value of 100
### Fixes
- Any songs **including** an artist listed in the `skipped artists` setting will now be skipped even if the song is a collaboration.
- Linux desktop icons have been fixed. See [#222](https://github.com/Mastermindzh/tidal-hifi/pull/222) for details.
## 5.0.0 ## 5.0.0
- Replaced "muting artists" with a full implementation of an Adblock mechanism - Replaced "muting artists" with a full implementation of an Adblock mechanism
> Disabled audio & visual ads, unlocked lyrics, suggested track, track info, unlimited skips thanks to uBlockOrigin custom filters ([source](https://github.com/uBlockOrigin/uAssets/issues/17495)) > Disabled audio & visual ads, unlocked lyrics, suggested track, track info, unlimited skips thanks to uBlockOrigin custom filters ([source](https://github.com/uBlockOrigin/uAssets/issues/17495))
- @thanasistrisp updated Electron to 24.1.2 and fixed the tray bug :) - @thanasistrisp updated Electron to 24.1.2 and fixed the tray bug :)

BIN
assets/icons/128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
assets/icons/16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
assets/icons/22x22.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

BIN
assets/icons/24x24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
assets/icons/256x256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
assets/icons/32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
assets/icons/384x384.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
assets/icons/48x48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
assets/icons/64x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -9,7 +9,7 @@ snap:
- screen-inhibit-control - screen-inhibit-control
linux: linux:
category: AudioVideo category: AudioVideo
icon: icon.png icon: assets/icons
target: target:
- dir - dir
executableName: tidal-hifi executableName: tidal-hifi
@ -18,7 +18,7 @@ linux:
Name: TIDAL Hi-Fi Name: TIDAL Hi-Fi
GenericName: TIDAL Hi-Fi GenericName: TIDAL Hi-Fi
Comment: The web version of listen.tidal.com running in electron with hifi support thanks to widevine. Comment: The web version of listen.tidal.com running in electron with hifi support thanks to widevine.
Icon: icon.png Icon: tidal-hifi
StartupNotify: true StartupNotify: true
Terminal: false Terminal: false
Type: Application Type: Application

View File

@ -1,5 +1,4 @@
extends: ./build/electron-builder.base.yml extends: ./build/electron-builder.base.yml
linux: linux:
icon: icon.png
target: target:
- pacman - pacman

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "tidal-hifi", "name": "tidal-hifi",
"version": "5.0.0", "version": "5.1.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "tidal-hifi", "name": "tidal-hifi",
"version": "5.0.0", "version": "5.1.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@electron/remote": "^2.0.9", "@electron/remote": "^2.0.9",

View File

@ -1,6 +1,6 @@
{ {
"name": "tidal-hifi", "name": "tidal-hifi",
"version": "5.0.0", "version": "5.1.0",
"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": {

View File

@ -9,34 +9,36 @@
* windowBounds: { width: 800, height: 600 }, * windowBounds: { width: 800, height: 600 },
*/ */
const settings = { const settings = {
notifications: "notifications",
api: "api",
menuBar: "menuBar",
playBackControl: "playBackControl",
skipArtists: "skipArtists",
skippedArtists: "skippedArtists",
adBlock: "adBlock", adBlock: "adBlock",
disableBackgroundThrottle: "disableBackgroundThrottle", api: "api",
apiSettings: { apiSettings: {
root: "apiSettings", root: "apiSettings",
port: "apiSettings.port", port: "apiSettings.port",
}, },
singleInstance: "singleInstance", customCSS: "customCSS",
disableBackgroundThrottle: "disableBackgroundThrottle",
disableHardwareMediaKeys: "disableHardwareMediaKeys", disableHardwareMediaKeys: "disableHardwareMediaKeys",
enableCustomHotkeys: "enableCustomHotkeys",
enableDiscord: "enableDiscord",
flags: { flags: {
disableHardwareMediaKeys: "flags.disableHardwareMediaKeys", disableHardwareMediaKeys: "flags.disableHardwareMediaKeys",
gpuRasterization: "flags.gpuRasterization", gpuRasterization: "flags.gpuRasterization",
}, },
menuBar: "menuBar",
minimizeOnClose: "minimizeOnClose",
mpris: "mpris", mpris: "mpris",
enableCustomHotkeys: "enableCustomHotkeys", notifications: "notifications",
playBackControl: "playBackControl",
singleInstance: "singleInstance",
skipArtists: "skipArtists",
skippedArtists: "skippedArtists",
trayIcon: "trayIcon", trayIcon: "trayIcon",
enableDiscord: "enableDiscord", updateFrequency: "updateFrequency",
windowBounds: { windowBounds: {
root: "windowBounds", root: "windowBounds",
width: "windowBounds.width", width: "windowBounds.width",
height: "windowBounds.height", height: "windowBounds.height",
}, },
minimizeOnClose: "minimizeOnClose",
}; };
module.exports = settings; module.exports = settings;

View File

@ -172,7 +172,6 @@ app.on("ready", async () => {
store.get(settings.trayIcon) && addTray(mainWindow, { icon }) && refreshTray(); store.get(settings.trayIcon) && addTray(mainWindow, { icon }) && refreshTray();
store.get(settings.api) && expressModule.run(mainWindow); store.get(settings.api) && expressModule.run(mainWindow);
store.get(settings.enableDiscord) && discordModule.initRPC(); store.get(settings.enableDiscord) && discordModule.initRPC();
// mainWindow.webContents.openDevTools();
} else { } else {
app.quit(); app.quit();
} }

View File

@ -1,20 +1,22 @@
let trayIcon, let adBlock,
minimizeOnClose, api,
mpris, customCSS,
disableBackgroundThrottle,
disableHardwareMediaKeys,
enableCustomHotkeys, enableCustomHotkeys,
enableDiscord, enableDiscord,
skipArtists, gpuRasterization,
menuBar,
minimizeOnClose,
mpris,
notifications, notifications,
playBackControl, playBackControl,
api,
port, port,
menuBar,
skippedArtists,
adBlock,
disableBackgroundThrottle,
singleInstance, singleInstance,
disableHardwareMediaKeys, skipArtists,
gpuRasterization; skippedArtists,
trayIcon,
updateFrequency;
const { store, settings } = require("./../../scripts/settings"); const { store, settings } = require("./../../scripts/settings");
const { ipcRenderer } = require("electron"); const { ipcRenderer } = require("electron");
@ -25,23 +27,25 @@ const { app } = remote;
* Sync the UI forms with the current settings * Sync the UI forms with the current settings
*/ */
function refreshSettings() { function refreshSettings() {
notifications.checked = store.get(settings.notifications); adBlock.checked = store.get(settings.adBlock);
playBackControl.checked = store.get(settings.playBackControl);
api.checked = store.get(settings.api); api.checked = store.get(settings.api);
port.value = store.get(settings.apiSettings.port); customCSS.value = store.get(settings.customCSS);
menuBar.checked = store.get(settings.menuBar); disableBackgroundThrottle.checked = store.get("disableBackgroundThrottle");
trayIcon.checked = store.get(settings.trayIcon); disableHardwareMediaKeys.checked = store.get(settings.flags.disableHardwareMediaKeys);
mpris.checked = store.get(settings.mpris);
enableCustomHotkeys.checked = store.get(settings.enableCustomHotkeys); enableCustomHotkeys.checked = store.get(settings.enableCustomHotkeys);
enableDiscord.checked = store.get(settings.enableDiscord); enableDiscord.checked = store.get(settings.enableDiscord);
gpuRasterization.checked = store.get(settings.flags.gpuRasterization);
menuBar.checked = store.get(settings.menuBar);
minimizeOnClose.checked = store.get(settings.minimizeOnClose); minimizeOnClose.checked = store.get(settings.minimizeOnClose);
mpris.checked = store.get(settings.mpris);
notifications.checked = store.get(settings.notifications);
playBackControl.checked = store.get(settings.playBackControl);
port.value = store.get(settings.apiSettings.port);
singleInstance.checked = store.get(settings.singleInstance);
skipArtists.checked = store.get(settings.skipArtists); skipArtists.checked = store.get(settings.skipArtists);
skippedArtists.value = store.get(settings.skippedArtists).join("\n"); skippedArtists.value = store.get(settings.skippedArtists).join("\n");
adBlock.checked = store.get(settings.adBlock); trayIcon.checked = store.get(settings.trayIcon);
singleInstance.checked = store.get(settings.singleInstance); updateFrequency.value = store.get(settings.updateFrequency);
disableHardwareMediaKeys.checked = store.get(settings.flags.disableHardwareMediaKeys);
gpuRasterization.checked = store.get(settings.flags.gpuRasterization);
disableBackgroundThrottle.checked = store.get("disableBackgroundThrottle");
} }
/** /**
@ -109,41 +113,45 @@ window.addEventListener("DOMContentLoaded", () => {
document.getElementById(tab).click(); document.getElementById(tab).click();
}); });
notifications = get("notifications"); adBlock = get("adBlock");
playBackControl = get("playBackControl");
api = get("apiCheckbox"); api = get("apiCheckbox");
port = get("port"); customCSS = get("customCSS");
menuBar = get("menuBar"); disableBackgroundThrottle = get("disableBackgroundThrottle");
trayIcon = get("trayIcon"); disableHardwareMediaKeys = get("disableHardwareMediaKeys");
minimizeOnClose = get("minimizeOnClose");
mpris = get("mprisCheckbox");
enableCustomHotkeys = get("enableCustomHotkeys"); enableCustomHotkeys = get("enableCustomHotkeys");
enableDiscord = get("enableDiscord"); enableDiscord = get("enableDiscord");
gpuRasterization = get("gpuRasterization");
menuBar = get("menuBar");
minimizeOnClose = get("minimizeOnClose");
mpris = get("mprisCheckbox");
notifications = get("notifications");
playBackControl = get("playBackControl");
port = get("port");
trayIcon = get("trayIcon");
skipArtists = get("skipArtists"); skipArtists = get("skipArtists");
skippedArtists = get("skippedArtists"); skippedArtists = get("skippedArtists");
adBlock = get("adBlock");
disableBackgroundThrottle = get("disableBackgroundThrottle");
singleInstance = get("singleInstance"); singleInstance = get("singleInstance");
disableHardwareMediaKeys = get("disableHardwareMediaKeys"); updateFrequency = get("updateFrequency");
gpuRasterization = get("gpuRasterization");
refreshSettings(); refreshSettings();
addInputListener(notifications, settings.notifications); addInputListener(adBlock, settings.adBlock);
addInputListener(playBackControl, settings.playBackControl);
addInputListener(api, settings.api); addInputListener(api, settings.api);
addInputListener(port, settings.apiSettings.port); addTextAreaListener(customCSS, settings.customCSS);
addInputListener(menuBar, settings.menuBar); addInputListener(disableBackgroundThrottle, settings.disableBackgroundThrottle);
addInputListener(trayIcon, settings.trayIcon); addInputListener(disableHardwareMediaKeys, settings.flags.disableHardwareMediaKeys);
addInputListener(mpris, settings.mpris);
addInputListener(enableCustomHotkeys, settings.enableCustomHotkeys); addInputListener(enableCustomHotkeys, settings.enableCustomHotkeys);
addInputListener(enableDiscord, settings.enableDiscord); addInputListener(enableDiscord, settings.enableDiscord);
addInputListener(gpuRasterization, settings.flags.gpuRasterization);
addInputListener(menuBar, settings.menuBar);
addInputListener(minimizeOnClose, settings.minimizeOnClose); addInputListener(minimizeOnClose, settings.minimizeOnClose);
addInputListener(mpris, settings.mpris);
addInputListener(notifications, settings.notifications);
addInputListener(playBackControl, settings.playBackControl);
addInputListener(port, settings.apiSettings.port);
addInputListener(skipArtists, settings.skipArtists); addInputListener(skipArtists, settings.skipArtists);
addTextAreaListener(skippedArtists, settings.skippedArtists); addTextAreaListener(skippedArtists, settings.skippedArtists);
addInputListener(adBlock, settings.adBlock);
addInputListener(disableBackgroundThrottle, settings.disableBackgroundThrottle);
addInputListener(singleInstance, settings.singleInstance); addInputListener(singleInstance, settings.singleInstance);
addInputListener(disableHardwareMediaKeys, settings.flags.disableHardwareMediaKeys); addInputListener(trayIcon, settings.trayIcon);
addInputListener(gpuRasterization, settings.flags.gpuRasterization); addInputListener(updateFrequency, settings.updateFrequency);
}); });

View File

@ -160,7 +160,7 @@
<div class="group__option"> <div class="group__option">
<div class="group__description"> <div class="group__description">
<label for="port">API port</label> <label for="port">API port</label>
<input id="port" type="text" class="text-input" name="port" /> <input id="port" type="number" class="text-input" name="port" />
</div> </div>
</div> </div>
<div class="group__option"> <div class="group__option">
@ -212,6 +212,31 @@
</section> </section>
<section id="advanced-section" class="tabs__section"> <section id="advanced-section" class="tabs__section">
<div class="group">
<p class="group__title">Settings</p>
<div class="group__option">
<div class="group__description">
<h4>Update frequency</h4>
<p>
The amount of time, in milliseconds, that tidal-hifi will refresh its playback info by scraping the
website.
The default of 500 seems to work in more cases but if you are fine with a bit more resource usage you
can decrease it as well.
</p>
<input id="updateFrequency" type="number" class="text-input" name="updateFrequency" />
</div>
</div>
<div class="group__option">
<div class="group__description">
<h4>Custom CSS</h4>
<p>
The css that you put in here will be injected into a style tag in the head of the document.
</p>
</div>
</div>
</div>
<textarea id="customCSS" class="textarea" cols="40" rows="8" spellcheck="false"></textarea>
<div class="group"> <div class="group">
<p class="group__title">Flags</p> <p class="group__title">Flags</p>
<div class="group__option"> <div class="group__option">

View File

@ -7,7 +7,7 @@ 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 { skipArtists } = require("./constants/settings"); const { skipArtists, updateFrequency, customCSS } = require("./constants/settings");
const notificationPath = `${app.getPath("userData")}/notification.jpg`; const notificationPath = `${app.getPath("userData")}/notification.jpg`;
const appName = "Tidal Hifi"; const appName = "Tidal Hifi";
let currentSong = ""; let currentSong = "";
@ -65,16 +65,27 @@ const elements = {
return ""; return "";
}, },
getArtists: function () { /**
* returns an array of all artists in the current song
* @returns {Array} artists
*/
getArtistsArray: function () {
const footer = this.get("footer"); const footer = this.get("footer");
if (footer) { if (footer) {
const artists = footer.querySelector(this["artists"]); const artists = footer.querySelectorAll(this.artists);
if (artists) { if (artists) return Array.from(artists).map((artist) => artist.textContent);
return artists.innerText;
}
} }
return [];
},
/**
* unify the artists array into a string separated by commas
* @param {Array} artistsArray
* @returns {String} artists
*/
getArtistsString: function (artistsArray) {
if (artistsArray.length > 0) return artistsArray.join(", ");
return "unknown artist(s)"; return "unknown artist(s)";
}, },
@ -132,6 +143,29 @@ const elements = {
}, },
}; };
function addCustomCss() {
window.addEventListener("DOMContentLoaded", () => {
const style = document.createElement("style");
style.innerHTML = store.get(customCSS);
document.head.appendChild(style);
});
}
/**
* Get the update frequency from the store
* make sure it returns a number, if not use the default
*/
function getUpdateFrequency() {
const storeValue = store.get(updateFrequency);
const defaultValue = 500;
if (!isNaN(storeValue)) {
return storeValue;
} else {
return defaultValue;
}
}
/** /**
* Play or pause the current song * Play or pause the current song
*/ */
@ -289,14 +323,14 @@ function updateMediaInfo(options, notify) {
if (options) { if (options) {
ipcRenderer.send(globalEvents.updateInfo, options); ipcRenderer.send(globalEvents.updateInfo, options);
if (store.get(settings.notifications) && notify) { if (store.get(settings.notifications) && notify) {
new Notification({ title: options.title, body: options.message, icon: options.icon }).show(); new Notification({ title: options.title, body: options.artists, 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.artists],
"xesam:album": options.album, "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,
@ -327,22 +361,40 @@ function getTrackID() {
return window.location; return window.location;
} }
function updateMediaSession(options) {
if ("mediaSession" in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: options.title,
artist: options.artists,
album: options.album,
artwork: [
{
src: options.icon,
sizes: "640x640",
type: "image/png",
},
],
});
}
}
/** /**
* Watch for song changes and update title + notify * Watch for song changes and update title + notify
*/ */
setInterval(function () { setInterval(function () {
const title = elements.getText("title"); const title = elements.getText("title");
const artists = elements.getArtists(); const artistsArray = elements.getArtistsArray();
skipArtistsIfFoundInSkippedArtistsList(artists); const artistsString = elements.getArtistsString(artistsArray);
skipArtistsIfFoundInSkippedArtistsList(artistsArray);
const album = elements.getAlbumName(); 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 songDashArtistTitle = `${title} - ${artists}`; const songDashArtistTitle = `${title} - ${artistsString}`;
const currentStatus = getCurrentlyPlayingStatus(); const currentStatus = getCurrentlyPlayingStatus();
const options = { const options = {
title, title,
message: artists, artists: artistsString,
album: album, album: album,
status: currentStatus, status: currentStatus,
url: getTrackURL(), url: getTrackURL(),
@ -351,7 +403,7 @@ setInterval(function () {
"app-name": appName, "app-name": appName,
}; };
const titleOrArtistChanged = currentSong !== songDashArtistTitle; const titleOrArtistsChanged = currentSong !== songDashArtistTitle;
// update title, url and play info with new info // update title, url and play info with new info
setTitle(songDashArtistTitle); setTitle(songDashArtistTitle);
@ -380,24 +432,32 @@ setInterval(function () {
} }
}).then( }).then(
() => { () => {
updateMediaInfo(options, titleOrArtistChanged); updateMediaInfo(options, titleOrArtistsChanged);
if (titleOrArtistsChanged) {
updateMediaSession(options);
}
}, },
() => {} () => {}
); );
/** /**
* automatically skip a song if the artists are found in the list of artists to skip * automatically skip a song if the artists are found in the list of artists to skip
* @param {*} artists list of artists to skip * @param {*} artists array of artists
*/ */
function skipArtistsIfFoundInSkippedArtistsList(artists) { function skipArtistsIfFoundInSkippedArtistsList(artists) {
if (store.get(skipArtists)) { if (store.get(skipArtists)) {
const skippedArtists = store.get(settings.skippedArtists); const skippedArtists = store.get(settings.skippedArtists);
if (skippedArtists.find((artist) => artist === artists) !== undefined) { if (skippedArtists.length > 0) {
const artistsToSkip = skippedArtists.map((artist) => artist);
const artistNames = Object.values(artists).map((artist) => artist);
const foundArtist = artistNames.some((artist) => artistsToSkip.includes(artist));
if (foundArtist) {
elements.click("next"); elements.click("next");
} }
} }
} }
}, 100); }
}, getUpdateFrequency());
if (process.platform === "linux" && store.get(settings.mpris)) { if (process.platform === "linux" && store.get(settings.mpris)) {
try { try {
@ -454,7 +514,7 @@ if (process.platform === "linux" && store.get(settings.mpris)) {
console.log("player api not working"); console.log("player api not working");
} }
} }
addCustomCss();
addHotKeys(); addHotKeys();
addIPCEventListeners(); addIPCEventListeners();
addFullScreenListeners(); addFullScreenListeners();

View File

@ -26,8 +26,8 @@ const observer = (event, arg) => {
...idleStatus, ...idleStatus,
...{ ...{
details: `Listening to ${mediaInfoModule.mediaInfo.title}`, details: `Listening to ${mediaInfoModule.mediaInfo.title}`,
state: mediaInfoModule.mediaInfo.artist state: mediaInfoModule.mediaInfo.artists
? mediaInfoModule.mediaInfo.artist ? mediaInfoModule.mediaInfo.artists
: "unknown artist(s)", : "unknown artist(s)",
startTimestamp: parseInt(now), startTimestamp: parseInt(now),
endTimestamp: parseInt(remaining), endTimestamp: parseInt(remaining),
@ -43,7 +43,7 @@ const observer = (event, arg) => {
...idleStatus, ...idleStatus,
...{ ...{
details: `Watching ${mediaInfoModule.mediaInfo.title}`, details: `Watching ${mediaInfoModule.mediaInfo.title}`,
state: mediaInfoModule.mediaInfo.artist, state: mediaInfoModule.mediaInfo.artists,
startTimestamp: parseInt(now), startTimestamp: parseInt(now),
endTimestamp: parseInt(remaining), endTimestamp: parseInt(remaining),
}, },

View File

@ -11,7 +11,7 @@ let expressInstance;
/** /**
* Function to enable tidal-hifi's express api * Function to enable tidal-hifi's express api
*/ */
expressModule.run = function(mainWindow) { expressModule.run = function (mainWindow) {
/** /**
* Shorthand to handle a fire and forget global event * Shorthand to handle a fire and forget global event
* @param {*} res * @param {*} res
@ -24,14 +24,14 @@ expressModule.run = function(mainWindow) {
const expressApp = express(); const expressApp = express();
expressApp.get("/", (req, res) => res.send("Hello World!")); expressApp.get("/", (req, res) => res.send("Hello World!"));
expressApp.get("/current", (req, res) => res.json(mediaInfo)); expressApp.get("/current", (req, res) => res.json({ ...mediaInfo, artist: mediaInfo.artists }));
expressApp.get("/image", (req, res) => { expressApp.get("/image", (req, res) => {
var stream = fs.createReadStream(mediaInfo.icon); var stream = fs.createReadStream(mediaInfo.icon);
stream.on("open", function() { stream.on("open", function () {
res.set("Content-Type", "image/png"); res.set("Content-Type", "image/png");
stream.pipe(res); stream.pipe(res);
}); });
stream.on("error", function() { stream.on("error", function () {
res.set("Content-Type", "text/plain"); res.set("Content-Type", "text/plain");
res.status(404).end("Not found"); res.status(404).end("Not found");
}); });
@ -54,7 +54,7 @@ expressModule.run = function(mainWindow) {
let port = store.get(settings.apiSettings.port); let port = store.get(settings.apiSettings.port);
expressInstance = expressApp.listen(port, "127.0.0.1", () => {}); expressInstance = expressApp.listen(port, "127.0.0.1", () => {});
expressInstance.on("error", function(e) { expressInstance.on("error", function (e) {
let message = e.code; let message = e.code;
if (e.code === "EADDRINUSE") { if (e.code === "EADDRINUSE") {
message = `Port ${port} in use.`; message = `Port ${port} in use.`;

View File

@ -2,14 +2,14 @@ const statuses = require("./../constants/statuses");
const mediaInfo = { const mediaInfo = {
title: "", title: "",
artist: "", artists: "",
album: "", album: "",
icon: "", icon: "",
status: statuses.paused, status: statuses.paused,
url: "", url: "",
current: "", current: "",
duration: "", duration: "",
image: "tidal-hifi-icon" image: "tidal-hifi-icon",
}; };
const mediaInfoModule = { const mediaInfoModule = {
mediaInfo, mediaInfo,
@ -20,7 +20,7 @@ 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.artists = propOrDefault(arg.artists);
mediaInfo.album = propOrDefault(arg.album); 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);

View File

@ -7,29 +7,31 @@ let settingsWindow;
const store = new Store({ const store = new Store({
defaults: { defaults: {
notifications: true,
api: true,
playBackControl: true,
skipArtists: false,
skippedArtists: [""],
adBlock: false, adBlock: false,
disableBackgroundThrottle: true, api: true,
menuBar: true,
apiSettings: { apiSettings: {
port: 47836, port: 47836,
}, },
singleInstance: true, customCSS: "",
disableBackgroundThrottle: true,
disableHardwareMediaKeys: false, disableHardwareMediaKeys: false,
trayIcon: true,
minimizeOnClose: false,
mpris: false,
enableCustomHotkeys: false, enableCustomHotkeys: false,
enableDiscord: false, enableDiscord: false,
windowBounds: { width: 800, height: 600 },
flags: { flags: {
gpuRasterization: true, gpuRasterization: true,
disableHardwareMediaKeys: false, disableHardwareMediaKeys: false,
}, },
menuBar: true,
minimizeOnClose: false,
mpris: false,
notifications: true,
playBackControl: true,
singleInstance: true,
skipArtists: false,
skippedArtists: [""],
trayIcon: true,
updateFrequency: 500,
windowBounds: { width: 800, height: 600 },
}, },
migrations: { migrations: {
"3.1.0": (migrationStore) => { "3.1.0": (migrationStore) => {