The 'Big Bang'

This commit is contained in:
Rick van Lieshout 2019-09-16 23:13:12 +02:00
commit cbf15965e4
7 changed files with 1454 additions and 0 deletions

53
.editorconfig Normal file
View File

@ -0,0 +1,53 @@
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[**.js]
indent_style = space
indent_size = 2
[**.json]
indent_style = space
indent_size = 2
[**.css]
indent_style = space
indent_size = 2
[**.scss]
indent_style = space
indent_size = 2
[**.html]
indent_style = space
indent_size = 2
[**.jsx]
indent_style = space
indent_size = 2
[src/**.{h,cc}]
indent_style = space
indent_size = 2
[configure]
indent_style = space
indent_size = 2
[Makefile]
indent_style = tab
indent_size = 8
[{deps,tools}/**]
indent_style = ignore
indent_size = ignore
end_of_line = ignore
trim_trailing_whitespace = ignore
charset = ignore
[{test/fixtures,deps,tools/eslint,tools/gyp,tools/icu,tools/msvs}/**]
insert_final_newline = false

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

23
README.md Normal file
View File

@ -0,0 +1,23 @@
# tidal-hifi-electron
The web version of [listen.tidal.com](listen.tidal.com) running in electron with hifi support thanks to widevine.
<!-- toc -->
- [Why](#why)
- [Requirements](#requirements)
- [Integrations](#integrations)
<!-- tocstop -->
## Why
When I started this project there weren't any Linux apps that offered Tidal's "hifi" options nor any scripts to control it.
## Requirements
- Internet connection
## Integrations
- [i3 blocks config]() - My dotfiles where I use this app to fetch currently playing music

61
main.js Normal file
View File

@ -0,0 +1,61 @@
const { app, globalShortcut, BrowserWindow, process } = require("electron");
const path = require("path");
const tidalUrl = "https://listen.tidal.com";
let mainWindow;
/**
* Enable live reload in development builds
*/
require("electron-reload")(__dirname, {
electron: require(`${__dirname}/node_modules/electron`),
});
function createWindow(options = {}) {
// Create the browser window.
mainWindow = new BrowserWindow({
x: options.x,
y: options.y,
width: 1024,
height: 800,
backgroundColor: options.backgroundColor,
webPreferences: {
affinity: "window",
preload: path.join(__dirname, "preload.js"),
plugins: true,
},
});
// load the Tidal website
mainWindow.loadURL(tidalUrl);
// run stuff after first load
mainWindow.webContents.once("did-finish-load", () => {});
// Emitted when the window is closed.
mainWindow.on("closed", function() {
mainWindow = null;
});
}
function addGlobalShortcuts() {
globalShortcut.register("Control+A", () => {
mainWindow.webContents.send("getPlayInfo");
});
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on("ready", () => {
// window with white backround
createWindow();
addGlobalShortcuts();
});
app.on("activate", function() {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow();
}
});

1221
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

27
package.json Normal file
View File

@ -0,0 +1,27 @@
{
"name": "tidal-hifi-electron",
"version": "0.1.0",
"description": "Tidal on Electron with widevine(hifi) support",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"keywords": [
"electron",
"hifi",
"widevine",
"linux"
],
"author": "Rick van Lieshout <info@rickvanlieshout.com> (http://rickvanlieshout.com)",
"license": "ISC",
"dependencies": {
"electron": "https://github.com/castlabs/electron-releases#v6.0.9-wvvmp",
"hotkeys-js": "^3.7.1"
},
"devDependencies": {
"@mastermindzh/prettier-config": "^1.0.0",
"electron-reload": "^1.5.0",
"prettier": "^1.18.2"
},
"prettier": "@mastermindzh/prettier-config"
}

68
preload.js Normal file
View File

@ -0,0 +1,68 @@
const hotkeys = require("hotkeys-js");
function getNode(string) {
return window.document.querySelectorAll(string)[0];
}
/**
* Play or pause the current song
*/
function playPause() {
let controls = getNode('*[class^="playbackControls"]');
let play = controls.querySelectorAll('*[data-test^="play"]')[0];
let pause = controls.querySelectorAll('*[data-test^="pause"]')[0];
if (play) {
play.click();
} else {
pause.click();
}
}
/**
* Click a button
* @param {*} dataTestValue
*/
function clickButton(dataTestValue) {
getNode(`*[data-test^="${dataTestValue}"]`).click();
}
/**
* Return the title of the current song
*/
function getTitle() {
return getNode('*[data-test^="footer-track-title"]').textContent;
}
function getArtists() {
return getNode('*[class^="mediaArtists"]').textContent;
}
/**
* Add hotkeys
*/
function addHotKeys() {
hotkeys("f4", function(event, handler) {
// Prevent the default refresh event under WINDOWS system
event.preventDefault();
playPause();
// clickButton("next");
});
}
/**
* Add ipc event listeners
*/
function addIPCEventListeners() {
window.addEventListener("DOMContentLoaded", () => {
const { ipcRenderer } = require("electron");
ipcRenderer.on("getPlayInfo", (event, col) => {
window.document.querySelectorAll('*[data-test^="next"]')[0].click();
alert(`${getTitle()} - ${getArtists()}`);
});
});
}
addHotKeys();
addIPCEventListeners();