mirror of
https://github.com/Mastermindzh/tidal-hifi.git
synced 2024-11-22 21:42:46 +01:00
added media keys + notifications
This commit is contained in:
parent
9c3ac88d12
commit
a56d18e414
@ -1,4 +1,6 @@
|
|||||||
appId: com.rickvanlieshout.tidal-hifi
|
appId: com.rickvanlieshout.tidal-hifi
|
||||||
|
electronDownload:
|
||||||
|
mirror: https://github.com/castlabs/electron-releases/releases/download/v
|
||||||
snap:
|
snap:
|
||||||
plugs:
|
plugs:
|
||||||
- default
|
- default
|
||||||
|
566
package-lock.json
generated
566
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -5,7 +5,9 @@
|
|||||||
"main": "src/main.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "electron .",
|
"start": "electron .",
|
||||||
"build": "electron-builder -c ./build/electron-builder.yml"
|
"build": "electron-builder -c ./build/electron-builder.yml",
|
||||||
|
"build-wl": "electron-builder -c ./build/electron-builder.yml -wl",
|
||||||
|
"build-mac": "electron-builder -c ./build/electron-builder.yml -m"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"electron",
|
"electron",
|
||||||
@ -16,11 +18,13 @@
|
|||||||
"author": "Rick van Lieshout <info@rickvanlieshout.com> (http://rickvanlieshout.com)",
|
"author": "Rick van Lieshout <info@rickvanlieshout.com> (http://rickvanlieshout.com)",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hotkeys-js": "^3.7.1"
|
"hotkeys-js": "^3.7.1",
|
||||||
|
"node-notifier": "^6.0.0",
|
||||||
|
"request": "^2.88.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@mastermindzh/prettier-config": "^1.0.0",
|
"@mastermindzh/prettier-config": "^1.0.0",
|
||||||
"electron": "https://github.com/castlabs/electron-releases#v6.0.12-wvvmp",
|
"electron": "https://github.com/castlabs/electron-releases#v6.1.0-wvvmp",
|
||||||
"electron-builder": "^21.2.0",
|
"electron-builder": "^21.2.0",
|
||||||
"electron-reload": "^1.5.0",
|
"electron-reload": "^1.5.0",
|
||||||
"prettier": "^1.18.2"
|
"prettier": "^1.18.2"
|
||||||
|
14
src/main.js
14
src/main.js
@ -1,6 +1,7 @@
|
|||||||
const { app, BrowserWindow } = require("electron");
|
const { app, BrowserWindow, globalShortcut } = require("electron");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tidalUrl = "https://listen.tidal.com";
|
const tidalUrl = "https://listen.tidal.com";
|
||||||
|
const mediaKeys = require("./scripts/media-keys");
|
||||||
let mainWindow;
|
let mainWindow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,6 +20,8 @@ function createWindow(options = {}) {
|
|||||||
y: options.y,
|
y: options.y,
|
||||||
width: 1024,
|
width: 1024,
|
||||||
height: 800,
|
height: 800,
|
||||||
|
icon: "./../build/icon.png",
|
||||||
|
tray: true,
|
||||||
backgroundColor: options.backgroundColor,
|
backgroundColor: options.backgroundColor,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
affinity: "window",
|
affinity: "window",
|
||||||
@ -42,10 +45,11 @@ function createWindow(options = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addGlobalShortcuts() {
|
function addGlobalShortcuts() {
|
||||||
// globalShortcut.register("Control+A", () => {
|
Object.values(mediaKeys).forEach((key) => {
|
||||||
// dialog.showErrorBox("test", "test");
|
globalShortcut.register(key, () => {
|
||||||
// // mainWindow.webContents.send("getPlayInfo");
|
mainWindow.webContents.send("globalKey", key);
|
||||||
// });
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method will be called when Electron has finished
|
// This method will be called when Electron has finished
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
const { setTitle, getTitle } = require("./scripts/window-functions");
|
const { setTitle, getTitle } = require("./scripts/window-functions");
|
||||||
const { dialog } = require("electron").remote;
|
const { dialog } = require("electron").remote;
|
||||||
const hotkeys = require("./scripts/hotkeys");
|
const hotkeys = require("./scripts/hotkeys");
|
||||||
|
const mediaKeys = require("./scripts/media-keys");
|
||||||
|
const notifier = require("node-notifier");
|
||||||
|
const { ipcRenderer } = require("electron");
|
||||||
|
const { app } = require("electron").remote;
|
||||||
|
const { downloadFile } = require("./scripts/download");
|
||||||
|
const notificationPath = `${app.getPath("userData")}/notification.jpg`;
|
||||||
|
|
||||||
const elements = {
|
const elements = {
|
||||||
play: '*[data-test="play"]',
|
play: '*[data-test="play"]',
|
||||||
@ -18,19 +24,55 @@ const elements = {
|
|||||||
block: '[class="blockButton"]',
|
block: '[class="blockButton"]',
|
||||||
account: '*[data-test^="profile-image-button"]',
|
account: '*[data-test^="profile-image-button"]',
|
||||||
settings: '*[data-test^="open-settings"]',
|
settings: '*[data-test^="open-settings"]',
|
||||||
|
media: '*[data-test="current-media-imagery"]',
|
||||||
|
image: '*[class^="image--"]',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an element from the dom
|
||||||
|
* @param {*} key key in elements object to fetch
|
||||||
|
*/
|
||||||
get: function(key) {
|
get: function(key) {
|
||||||
return window.document.querySelector(this[key.toLowerCase()]);
|
return window.document.querySelector(this[key.toLowerCase()]);
|
||||||
},
|
},
|
||||||
|
|
||||||
getText: function(key) {
|
/**
|
||||||
return this.get(key).textContent;
|
* Get the icon of the current song
|
||||||
|
*/
|
||||||
|
getSongIcon: function() {
|
||||||
|
const figure = this.get("media");
|
||||||
|
|
||||||
|
if (figure) {
|
||||||
|
const mediaElement = figure.querySelector(this["image"]);
|
||||||
|
if (mediaElement) {
|
||||||
|
return mediaElement.src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorthand function to get the text of a dom element
|
||||||
|
* @param {*} key key in elements object to fetch
|
||||||
|
*/
|
||||||
|
getText: function(key) {
|
||||||
|
const element = this.get(key);
|
||||||
|
return element ? element.textContent : "";
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorthand function to click a dom element
|
||||||
|
* @param {*} key key in elements object to fetch
|
||||||
|
*/
|
||||||
click: function(key) {
|
click: function(key) {
|
||||||
this.get(key).click();
|
this.get(key).click();
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorthand function to focus a dom element
|
||||||
|
* @param {*} key key in elements object to fetch
|
||||||
|
*/
|
||||||
focus: function(key) {
|
focus: function(key) {
|
||||||
return this.get(key).focus();
|
return this.get(key).focus();
|
||||||
},
|
},
|
||||||
@ -141,25 +183,65 @@ function handleLogout() {
|
|||||||
*/
|
*/
|
||||||
function addIPCEventListeners() {
|
function addIPCEventListeners() {
|
||||||
window.addEventListener("DOMContentLoaded", () => {
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
const { ipcRenderer } = require("electron");
|
ipcRenderer.on("getPlayInfo", () => {
|
||||||
|
|
||||||
ipcRenderer.on("getPlayInfo", (event, col) => {
|
|
||||||
alert(`${elements.getText("title")} - ${elements.getText("artists")}`);
|
alert(`${elements.getText("title")} - ${elements.getText("artists")}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on("globalEvent", (event, args) => {
|
||||||
|
switch (args) {
|
||||||
|
case mediaKeys.playPause:
|
||||||
|
playPause();
|
||||||
|
break;
|
||||||
|
case mediaKeys.next:
|
||||||
|
elements.click("next");
|
||||||
|
break;
|
||||||
|
case mediaKeys.previous:
|
||||||
|
elements.click("previous");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update window title
|
* 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.getText("artists");
|
const artists = elements.getText("artists");
|
||||||
const songDashArtistTitle = `${title} - ${artists}`;
|
const songDashArtistTitle = `${title} - ${artists}`;
|
||||||
|
|
||||||
if (getTitle() !== songDashArtistTitle) {
|
if (getTitle() !== songDashArtistTitle) {
|
||||||
setTitle(songDashArtistTitle);
|
setTitle(songDashArtistTitle);
|
||||||
|
|
||||||
|
const image = elements.getSongIcon();
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
title,
|
||||||
|
message: artists,
|
||||||
|
};
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
if (image.startsWith("http")) {
|
||||||
|
downloadFile(image, notificationPath).then(
|
||||||
|
() => {
|
||||||
|
options.icon = notificationPath;
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
reject();
|
||||||
}
|
}
|
||||||
}, 1000);
|
);
|
||||||
|
} else {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
}).then(
|
||||||
|
() => {
|
||||||
|
notifier.notify(options);
|
||||||
|
},
|
||||||
|
() => {}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
|
||||||
addHotKeys();
|
addHotKeys();
|
||||||
addIPCEventListeners();
|
addIPCEventListeners();
|
||||||
|
26
src/scripts/download.js
Normal file
26
src/scripts/download.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const download = {};
|
||||||
|
const request = require("request");
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* download and save a file
|
||||||
|
* @param {*} fileUrl url to download
|
||||||
|
* @param {*} targetPath path to save it at
|
||||||
|
*/
|
||||||
|
download.downloadFile = function(fileUrl, targetPath) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
var req = request({
|
||||||
|
method: "GET",
|
||||||
|
uri: fileUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
var out = fs.createWriteStream(targetPath);
|
||||||
|
req.pipe(out);
|
||||||
|
|
||||||
|
req.on("end", resolve);
|
||||||
|
|
||||||
|
req.on("error", reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = download;
|
7
src/scripts/media-keys.js
Normal file
7
src/scripts/media-keys.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
const mediaKeys = {
|
||||||
|
play: "MediaPlayPause",
|
||||||
|
next: "MediaNextTrack",
|
||||||
|
previous: "MediaPreviousTrack",
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = mediaKeys;
|
Loading…
Reference in New Issue
Block a user