mirror of
https://github.com/Mastermindzh/tidal-hifi.git
synced 2024-11-25 23:03:52 +01:00
added media keys + notifications
This commit is contained in:
parent
9c3ac88d12
commit
a56d18e414
@ -1,4 +1,6 @@
|
||||
appId: com.rickvanlieshout.tidal-hifi
|
||||
electronDownload:
|
||||
mirror: https://github.com/castlabs/electron-releases/releases/download/v
|
||||
snap:
|
||||
plugs:
|
||||
- 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",
|
||||
"scripts": {
|
||||
"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": [
|
||||
"electron",
|
||||
@ -16,11 +18,13 @@
|
||||
"author": "Rick van Lieshout <info@rickvanlieshout.com> (http://rickvanlieshout.com)",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hotkeys-js": "^3.7.1"
|
||||
"hotkeys-js": "^3.7.1",
|
||||
"node-notifier": "^6.0.0",
|
||||
"request": "^2.88.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@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-reload": "^1.5.0",
|
||||
"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 tidalUrl = "https://listen.tidal.com";
|
||||
const mediaKeys = require("./scripts/media-keys");
|
||||
let mainWindow;
|
||||
|
||||
/**
|
||||
@ -19,6 +20,8 @@ function createWindow(options = {}) {
|
||||
y: options.y,
|
||||
width: 1024,
|
||||
height: 800,
|
||||
icon: "./../build/icon.png",
|
||||
tray: true,
|
||||
backgroundColor: options.backgroundColor,
|
||||
webPreferences: {
|
||||
affinity: "window",
|
||||
@ -42,10 +45,11 @@ function createWindow(options = {}) {
|
||||
}
|
||||
|
||||
function addGlobalShortcuts() {
|
||||
// globalShortcut.register("Control+A", () => {
|
||||
// dialog.showErrorBox("test", "test");
|
||||
// // mainWindow.webContents.send("getPlayInfo");
|
||||
// });
|
||||
Object.values(mediaKeys).forEach((key) => {
|
||||
globalShortcut.register(key, () => {
|
||||
mainWindow.webContents.send("globalKey", key);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
|
@ -1,6 +1,12 @@
|
||||
const { setTitle, getTitle } = require("./scripts/window-functions");
|
||||
const { dialog } = require("electron").remote;
|
||||
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 = {
|
||||
play: '*[data-test="play"]',
|
||||
@ -18,19 +24,55 @@ const elements = {
|
||||
block: '[class="blockButton"]',
|
||||
account: '*[data-test^="profile-image-button"]',
|
||||
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) {
|
||||
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) {
|
||||
this.get(key).click();
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Shorthand function to focus a dom element
|
||||
* @param {*} key key in elements object to fetch
|
||||
*/
|
||||
focus: function(key) {
|
||||
return this.get(key).focus();
|
||||
},
|
||||
@ -141,25 +183,65 @@ function handleLogout() {
|
||||
*/
|
||||
function addIPCEventListeners() {
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const { ipcRenderer } = require("electron");
|
||||
|
||||
ipcRenderer.on("getPlayInfo", (event, col) => {
|
||||
ipcRenderer.on("getPlayInfo", () => {
|
||||
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() {
|
||||
const title = elements.getText("title");
|
||||
const artists = elements.getText("artists");
|
||||
const songDashArtistTitle = `${title} - ${artists}`;
|
||||
|
||||
if (getTitle() !== 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();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
}).then(
|
||||
() => {
|
||||
notifier.notify(options);
|
||||
},
|
||||
() => {}
|
||||
);
|
||||
}
|
||||
}, 1000);
|
||||
}, 200);
|
||||
|
||||
addHotKeys();
|
||||
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