15
CHANGELOG.md
@ -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/),
|
||||
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
|
||||
|
||||
- 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))
|
||||
|
||||
- @thanasistrisp updated Electron to 24.1.2 and fixed the tray bug :)
|
||||
|
BIN
assets/icons/128x128.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
assets/icons/16x16.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
assets/icons/22x22.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
assets/icons/24x24.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
BIN
assets/icons/256x256.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/icons/32x32.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
assets/icons/384x384.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
assets/icons/48x48.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/icons/64x64.png
Normal file
After Width: | Height: | Size: 11 KiB |
@ -9,7 +9,7 @@ snap:
|
||||
- screen-inhibit-control
|
||||
linux:
|
||||
category: AudioVideo
|
||||
icon: icon.png
|
||||
icon: assets/icons
|
||||
target:
|
||||
- dir
|
||||
executableName: tidal-hifi
|
||||
@ -18,7 +18,7 @@ linux:
|
||||
Name: TIDAL Hi-Fi
|
||||
GenericName: TIDAL Hi-Fi
|
||||
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
|
||||
Terminal: false
|
||||
Type: Application
|
||||
|
@ -1,5 +1,4 @@
|
||||
extends: ./build/electron-builder.base.yml
|
||||
linux:
|
||||
icon: icon.png
|
||||
target:
|
||||
- pacman
|
||||
|
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "tidal-hifi",
|
||||
"version": "5.0.0",
|
||||
"version": "5.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "tidal-hifi",
|
||||
"version": "5.0.0",
|
||||
"version": "5.1.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/remote": "^2.0.9",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "tidal-hifi",
|
||||
"version": "5.0.0",
|
||||
"version": "5.1.0",
|
||||
"description": "Tidal on Electron with widevine(hifi) support",
|
||||
"main": "src/main.js",
|
||||
"scripts": {
|
||||
@ -51,4 +51,4 @@
|
||||
"sass-lint-auto-fix": "^0.21.2"
|
||||
},
|
||||
"prettier": "@mastermindzh/prettier-config"
|
||||
}
|
||||
}
|
@ -9,34 +9,36 @@
|
||||
* windowBounds: { width: 800, height: 600 },
|
||||
*/
|
||||
const settings = {
|
||||
notifications: "notifications",
|
||||
api: "api",
|
||||
menuBar: "menuBar",
|
||||
playBackControl: "playBackControl",
|
||||
skipArtists: "skipArtists",
|
||||
skippedArtists: "skippedArtists",
|
||||
adBlock: "adBlock",
|
||||
disableBackgroundThrottle: "disableBackgroundThrottle",
|
||||
api: "api",
|
||||
apiSettings: {
|
||||
root: "apiSettings",
|
||||
port: "apiSettings.port",
|
||||
},
|
||||
singleInstance: "singleInstance",
|
||||
customCSS: "customCSS",
|
||||
disableBackgroundThrottle: "disableBackgroundThrottle",
|
||||
disableHardwareMediaKeys: "disableHardwareMediaKeys",
|
||||
enableCustomHotkeys: "enableCustomHotkeys",
|
||||
enableDiscord: "enableDiscord",
|
||||
flags: {
|
||||
disableHardwareMediaKeys: "flags.disableHardwareMediaKeys",
|
||||
gpuRasterization: "flags.gpuRasterization",
|
||||
},
|
||||
menuBar: "menuBar",
|
||||
minimizeOnClose: "minimizeOnClose",
|
||||
mpris: "mpris",
|
||||
enableCustomHotkeys: "enableCustomHotkeys",
|
||||
notifications: "notifications",
|
||||
playBackControl: "playBackControl",
|
||||
singleInstance: "singleInstance",
|
||||
skipArtists: "skipArtists",
|
||||
skippedArtists: "skippedArtists",
|
||||
trayIcon: "trayIcon",
|
||||
enableDiscord: "enableDiscord",
|
||||
updateFrequency: "updateFrequency",
|
||||
windowBounds: {
|
||||
root: "windowBounds",
|
||||
width: "windowBounds.width",
|
||||
height: "windowBounds.height",
|
||||
},
|
||||
minimizeOnClose: "minimizeOnClose",
|
||||
};
|
||||
|
||||
module.exports = settings;
|
||||
|
@ -172,7 +172,6 @@ app.on("ready", async () => {
|
||||
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();
|
||||
}
|
||||
|
@ -1,20 +1,22 @@
|
||||
let trayIcon,
|
||||
minimizeOnClose,
|
||||
mpris,
|
||||
let adBlock,
|
||||
api,
|
||||
customCSS,
|
||||
disableBackgroundThrottle,
|
||||
disableHardwareMediaKeys,
|
||||
enableCustomHotkeys,
|
||||
enableDiscord,
|
||||
skipArtists,
|
||||
gpuRasterization,
|
||||
menuBar,
|
||||
minimizeOnClose,
|
||||
mpris,
|
||||
notifications,
|
||||
playBackControl,
|
||||
api,
|
||||
port,
|
||||
menuBar,
|
||||
skippedArtists,
|
||||
adBlock,
|
||||
disableBackgroundThrottle,
|
||||
singleInstance,
|
||||
disableHardwareMediaKeys,
|
||||
gpuRasterization;
|
||||
skipArtists,
|
||||
skippedArtists,
|
||||
trayIcon,
|
||||
updateFrequency;
|
||||
|
||||
const { store, settings } = require("./../../scripts/settings");
|
||||
const { ipcRenderer } = require("electron");
|
||||
@ -25,23 +27,25 @@ const { app } = remote;
|
||||
* Sync the UI forms with the current settings
|
||||
*/
|
||||
function refreshSettings() {
|
||||
notifications.checked = store.get(settings.notifications);
|
||||
playBackControl.checked = store.get(settings.playBackControl);
|
||||
adBlock.checked = store.get(settings.adBlock);
|
||||
api.checked = store.get(settings.api);
|
||||
port.value = store.get(settings.apiSettings.port);
|
||||
menuBar.checked = store.get(settings.menuBar);
|
||||
trayIcon.checked = store.get(settings.trayIcon);
|
||||
mpris.checked = store.get(settings.mpris);
|
||||
customCSS.value = store.get(settings.customCSS);
|
||||
disableBackgroundThrottle.checked = store.get("disableBackgroundThrottle");
|
||||
disableHardwareMediaKeys.checked = store.get(settings.flags.disableHardwareMediaKeys);
|
||||
enableCustomHotkeys.checked = store.get(settings.enableCustomHotkeys);
|
||||
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);
|
||||
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);
|
||||
skippedArtists.value = store.get(settings.skippedArtists).join("\n");
|
||||
adBlock.checked = store.get(settings.adBlock);
|
||||
singleInstance.checked = store.get(settings.singleInstance);
|
||||
disableHardwareMediaKeys.checked = store.get(settings.flags.disableHardwareMediaKeys);
|
||||
gpuRasterization.checked = store.get(settings.flags.gpuRasterization);
|
||||
disableBackgroundThrottle.checked = store.get("disableBackgroundThrottle");
|
||||
trayIcon.checked = store.get(settings.trayIcon);
|
||||
updateFrequency.value = store.get(settings.updateFrequency);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,41 +113,45 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
document.getElementById(tab).click();
|
||||
});
|
||||
|
||||
notifications = get("notifications");
|
||||
playBackControl = get("playBackControl");
|
||||
adBlock = get("adBlock");
|
||||
api = get("apiCheckbox");
|
||||
port = get("port");
|
||||
menuBar = get("menuBar");
|
||||
trayIcon = get("trayIcon");
|
||||
minimizeOnClose = get("minimizeOnClose");
|
||||
mpris = get("mprisCheckbox");
|
||||
customCSS = get("customCSS");
|
||||
disableBackgroundThrottle = get("disableBackgroundThrottle");
|
||||
disableHardwareMediaKeys = get("disableHardwareMediaKeys");
|
||||
enableCustomHotkeys = get("enableCustomHotkeys");
|
||||
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");
|
||||
skippedArtists = get("skippedArtists");
|
||||
adBlock = get("adBlock");
|
||||
disableBackgroundThrottle = get("disableBackgroundThrottle");
|
||||
singleInstance = get("singleInstance");
|
||||
disableHardwareMediaKeys = get("disableHardwareMediaKeys");
|
||||
gpuRasterization = get("gpuRasterization");
|
||||
updateFrequency = get("updateFrequency");
|
||||
|
||||
refreshSettings();
|
||||
|
||||
addInputListener(notifications, settings.notifications);
|
||||
addInputListener(playBackControl, settings.playBackControl);
|
||||
addInputListener(adBlock, settings.adBlock);
|
||||
addInputListener(api, settings.api);
|
||||
addInputListener(port, settings.apiSettings.port);
|
||||
addInputListener(menuBar, settings.menuBar);
|
||||
addInputListener(trayIcon, settings.trayIcon);
|
||||
addInputListener(mpris, settings.mpris);
|
||||
addTextAreaListener(customCSS, settings.customCSS);
|
||||
addInputListener(disableBackgroundThrottle, settings.disableBackgroundThrottle);
|
||||
addInputListener(disableHardwareMediaKeys, settings.flags.disableHardwareMediaKeys);
|
||||
addInputListener(enableCustomHotkeys, settings.enableCustomHotkeys);
|
||||
addInputListener(enableDiscord, settings.enableDiscord);
|
||||
addInputListener(gpuRasterization, settings.flags.gpuRasterization);
|
||||
addInputListener(menuBar, settings.menuBar);
|
||||
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);
|
||||
addTextAreaListener(skippedArtists, settings.skippedArtists);
|
||||
addInputListener(adBlock, settings.adBlock);
|
||||
addInputListener(disableBackgroundThrottle, settings.disableBackgroundThrottle);
|
||||
addInputListener(singleInstance, settings.singleInstance);
|
||||
addInputListener(disableHardwareMediaKeys, settings.flags.disableHardwareMediaKeys);
|
||||
addInputListener(gpuRasterization, settings.flags.gpuRasterization);
|
||||
addInputListener(trayIcon, settings.trayIcon);
|
||||
addInputListener(updateFrequency, settings.updateFrequency);
|
||||
});
|
||||
|
@ -160,7 +160,7 @@
|
||||
<div class="group__option">
|
||||
<div class="group__description">
|
||||
<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 class="group__option">
|
||||
@ -212,6 +212,31 @@
|
||||
</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">
|
||||
<p class="group__title">Flags</p>
|
||||
<div class="group__option">
|
||||
|
@ -7,7 +7,7 @@ const { downloadFile } = require("./scripts/download");
|
||||
const statuses = require("./constants/statuses");
|
||||
const hotkeys = require("./scripts/hotkeys");
|
||||
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 appName = "Tidal Hifi";
|
||||
let currentSong = "";
|
||||
@ -65,16 +65,27 @@ const elements = {
|
||||
return "";
|
||||
},
|
||||
|
||||
getArtists: function () {
|
||||
/**
|
||||
* returns an array of all artists in the current song
|
||||
* @returns {Array} artists
|
||||
*/
|
||||
getArtistsArray: function () {
|
||||
const footer = this.get("footer");
|
||||
|
||||
if (footer) {
|
||||
const artists = footer.querySelector(this["artists"]);
|
||||
if (artists) {
|
||||
return artists.innerText;
|
||||
}
|
||||
const artists = footer.querySelectorAll(this.artists);
|
||||
if (artists) return Array.from(artists).map((artist) => artist.textContent);
|
||||
}
|
||||
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)";
|
||||
},
|
||||
|
||||
@ -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
|
||||
*/
|
||||
@ -289,14 +323,14 @@ 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();
|
||||
new Notification({ title: options.title, body: options.artists, icon: options.icon }).show();
|
||||
}
|
||||
if (player) {
|
||||
player.metadata = {
|
||||
...player.metadata,
|
||||
...{
|
||||
"xesam:title": options.title,
|
||||
"xesam:artist": [options.message],
|
||||
"xesam:artist": [options.artists],
|
||||
"xesam:album": options.album,
|
||||
"mpris:artUrl": options.image,
|
||||
"mpris:length": convertDuration(options.duration) * 1000 * 1000,
|
||||
@ -327,22 +361,40 @@ function getTrackID() {
|
||||
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
|
||||
*/
|
||||
setInterval(function () {
|
||||
const title = elements.getText("title");
|
||||
const artists = elements.getArtists();
|
||||
skipArtistsIfFoundInSkippedArtistsList(artists);
|
||||
const artistsArray = elements.getArtistsArray();
|
||||
const artistsString = elements.getArtistsString(artistsArray);
|
||||
skipArtistsIfFoundInSkippedArtistsList(artistsArray);
|
||||
|
||||
const album = elements.getAlbumName();
|
||||
const current = elements.getText("current");
|
||||
const duration = elements.getText("duration");
|
||||
const songDashArtistTitle = `${title} - ${artists}`;
|
||||
const songDashArtistTitle = `${title} - ${artistsString}`;
|
||||
const currentStatus = getCurrentlyPlayingStatus();
|
||||
const options = {
|
||||
title,
|
||||
message: artists,
|
||||
artists: artistsString,
|
||||
album: album,
|
||||
status: currentStatus,
|
||||
url: getTrackURL(),
|
||||
@ -351,7 +403,7 @@ setInterval(function () {
|
||||
"app-name": appName,
|
||||
};
|
||||
|
||||
const titleOrArtistChanged = currentSong !== songDashArtistTitle;
|
||||
const titleOrArtistsChanged = currentSong !== songDashArtistTitle;
|
||||
|
||||
// update title, url and play info with new info
|
||||
setTitle(songDashArtistTitle);
|
||||
@ -380,24 +432,32 @@ setInterval(function () {
|
||||
}
|
||||
}).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
|
||||
* @param {*} artists list of artists to skip
|
||||
* @param {*} artists array of artists
|
||||
*/
|
||||
function skipArtistsIfFoundInSkippedArtistsList(artists) {
|
||||
if (store.get(skipArtists)) {
|
||||
const skippedArtists = store.get(settings.skippedArtists);
|
||||
if (skippedArtists.find((artist) => artist === artists) !== undefined) {
|
||||
elements.click("next");
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
}, getUpdateFrequency());
|
||||
|
||||
if (process.platform === "linux" && store.get(settings.mpris)) {
|
||||
try {
|
||||
@ -454,7 +514,7 @@ if (process.platform === "linux" && store.get(settings.mpris)) {
|
||||
console.log("player api not working");
|
||||
}
|
||||
}
|
||||
|
||||
addCustomCss();
|
||||
addHotKeys();
|
||||
addIPCEventListeners();
|
||||
addFullScreenListeners();
|
||||
|
@ -26,8 +26,8 @@ const observer = (event, arg) => {
|
||||
...idleStatus,
|
||||
...{
|
||||
details: `Listening to ${mediaInfoModule.mediaInfo.title}`,
|
||||
state: mediaInfoModule.mediaInfo.artist
|
||||
? mediaInfoModule.mediaInfo.artist
|
||||
state: mediaInfoModule.mediaInfo.artists
|
||||
? mediaInfoModule.mediaInfo.artists
|
||||
: "unknown artist(s)",
|
||||
startTimestamp: parseInt(now),
|
||||
endTimestamp: parseInt(remaining),
|
||||
@ -43,7 +43,7 @@ const observer = (event, arg) => {
|
||||
...idleStatus,
|
||||
...{
|
||||
details: `Watching ${mediaInfoModule.mediaInfo.title}`,
|
||||
state: mediaInfoModule.mediaInfo.artist,
|
||||
state: mediaInfoModule.mediaInfo.artists,
|
||||
startTimestamp: parseInt(now),
|
||||
endTimestamp: parseInt(remaining),
|
||||
},
|
||||
|
@ -11,7 +11,7 @@ let expressInstance;
|
||||
/**
|
||||
* 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
|
||||
* @param {*} res
|
||||
@ -24,14 +24,14 @@ expressModule.run = function(mainWindow) {
|
||||
|
||||
const expressApp = express();
|
||||
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) => {
|
||||
var stream = fs.createReadStream(mediaInfo.icon);
|
||||
stream.on("open", function() {
|
||||
stream.on("open", function () {
|
||||
res.set("Content-Type", "image/png");
|
||||
stream.pipe(res);
|
||||
});
|
||||
stream.on("error", function() {
|
||||
stream.on("error", function () {
|
||||
res.set("Content-Type", "text/plain");
|
||||
res.status(404).end("Not found");
|
||||
});
|
||||
@ -54,7 +54,7 @@ expressModule.run = function(mainWindow) {
|
||||
let port = store.get(settings.apiSettings.port);
|
||||
|
||||
expressInstance = expressApp.listen(port, "127.0.0.1", () => {});
|
||||
expressInstance.on("error", function(e) {
|
||||
expressInstance.on("error", function (e) {
|
||||
let message = e.code;
|
||||
if (e.code === "EADDRINUSE") {
|
||||
message = `Port ${port} in use.`;
|
||||
|
@ -2,14 +2,14 @@ const statuses = require("./../constants/statuses");
|
||||
|
||||
const mediaInfo = {
|
||||
title: "",
|
||||
artist: "",
|
||||
artists: "",
|
||||
album: "",
|
||||
icon: "",
|
||||
status: statuses.paused,
|
||||
url: "",
|
||||
current: "",
|
||||
duration: "",
|
||||
image: "tidal-hifi-icon"
|
||||
image: "tidal-hifi-icon",
|
||||
};
|
||||
const mediaInfoModule = {
|
||||
mediaInfo,
|
||||
@ -20,7 +20,7 @@ const mediaInfoModule = {
|
||||
*/
|
||||
mediaInfoModule.update = function (arg) {
|
||||
mediaInfo.title = propOrDefault(arg.title);
|
||||
mediaInfo.artist = propOrDefault(arg.message);
|
||||
mediaInfo.artists = propOrDefault(arg.artists);
|
||||
mediaInfo.album = propOrDefault(arg.album);
|
||||
mediaInfo.icon = propOrDefault(arg.icon);
|
||||
mediaInfo.url = propOrDefault(arg.url);
|
||||
|
@ -7,29 +7,31 @@ let settingsWindow;
|
||||
|
||||
const store = new Store({
|
||||
defaults: {
|
||||
notifications: true,
|
||||
api: true,
|
||||
playBackControl: true,
|
||||
skipArtists: false,
|
||||
skippedArtists: [""],
|
||||
adBlock: false,
|
||||
disableBackgroundThrottle: true,
|
||||
menuBar: true,
|
||||
api: true,
|
||||
apiSettings: {
|
||||
port: 47836,
|
||||
},
|
||||
singleInstance: true,
|
||||
customCSS: "",
|
||||
disableBackgroundThrottle: true,
|
||||
disableHardwareMediaKeys: false,
|
||||
trayIcon: true,
|
||||
minimizeOnClose: false,
|
||||
mpris: false,
|
||||
enableCustomHotkeys: false,
|
||||
enableDiscord: false,
|
||||
windowBounds: { width: 800, height: 600 },
|
||||
flags: {
|
||||
gpuRasterization: true,
|
||||
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: {
|
||||
"3.1.0": (migrationStore) => {
|
||||
|