Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Globalized the song info and song controls, and updated Touch Bar for it. #102

Merged
merged 7 commits into from
Jan 10, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions plugins/notifications/actions.js

This file was deleted.

40 changes: 19 additions & 21 deletions plugins/notifications/back.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
const { nativeImage, Notification } = require("electron");
const {Notification} = require('electron');

const { listenAction } = require("../utils");
const { ACTIONS, CHANNEL } = require("./actions.js");
const notify = info => {
let notificationImage = 'assets/youtube-music.png';

function notify(info) {
let notificationImage = "assets/youtube-music.png";
if (info.image) {
notificationImage = nativeImage.createFromDataURL(info.image);
notificationImage = info.image.resize({height: 256, width: 256});
}

// Fill the notification with content
const notification = {
title: info.title || "Playing",
title: info.title || 'Playing',
body: info.artist,
icon: notificationImage,
silent: true,
silent: true
};
// Send the notification
new Notification(notification).show();
}
};

function listenAndNotify() {
listenAction(CHANNEL, (event, action, imageSrc) => {
switch (action) {
case ACTIONS.NOTIFICATION:
notify(imageSrc);
break;
default:
console.log("Unknown action: " + action);
}
module.exports = win => {
win.on('ready-to-show', () => {
// Register the callback for new song information
global.songInfo.onNewData(songInfo => {
// If song is playing send notification
if (!songInfo.isPaused) {
notify(songInfo);
}
});
});
}

module.exports = listenAndNotify;
};
86 changes: 0 additions & 86 deletions plugins/notifications/front.js

This file was deleted.

120 changes: 120 additions & 0 deletions plugins/songInfo/back.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
const {nativeImage} = require('electron');
th-ch marked this conversation as resolved.
Show resolved Hide resolved
const fetch = require('node-fetch');

// This selects the song title
const titleSelector = '.title.style-scope.ytmusic-player-bar';

// This selects the song image
const imageSelector = '#layout > ytmusic-player-bar > div.middle-controls.style-scope.ytmusic-player-bar > img';

// This selects the song subinfo, this includes artist, views, likes
const subInfoSelector = '#layout > ytmusic-player-bar > div.middle-controls.style-scope.ytmusic-player-bar > div.content-info-wrapper.style-scope.ytmusic-player-bar > span';

// This is used for to control the songs
const presskey = (window, key) => {
window.webContents.sendInputEvent({
type: 'keydown',
keyCode: key
});
};

// Grab the title using the selector
const getTitle = win => {
return win.webContents.executeJavaScript(
'document.querySelector(\'' + titleSelector + '\').innerText'
).catch(error => {
console.log(error);
});
};

// Grab the image src using the selector
const getImageSrc = win => {
return win.webContents.executeJavaScript(
'document.querySelector(\'' + imageSelector + '\').src'
).catch(error => {
console.log(error);
});
};

// Grab the subinfo using the selector
const getSubInfo = async win => {
// Get innerText of subinfo element
const subInfoString = await win.webContents.executeJavaScript(
'document.querySelector("' + subInfoSelector + '").innerText');

// Split and clean the string
const splittedSubInfo = subInfoString.replaceAll('\n', '').split(' • ');

// Make sure we always return 3 elements in the aray
const subInfo = [];
for (let i = 0; i < 3; i++) {
// Fill array with empty string if not defined
subInfo.push(splittedSubInfo[i] || '');
}

return subInfo;
};

// Grab the native image using the src
const getImage = async src => {
const result = await fetch(src);
const buffer = await result.buffer();
return nativeImage.createFromBuffer(buffer);
};

const getPausedStatus = async win => {
const title = await win.webContents.executeJavaScript('document.title');
return !title.includes('-');
};

// This variable will be filled with the callbacks once they register
const callbacks = [];

module.exports = win => {
// Fill songInfo with empty values
global.songInfo = {
title: '',
artist: '',
views: '',
likes: '',
imageSrc: '',
image: null,
isPaused: true
};
// The song control funcions
semvis123 marked this conversation as resolved.
Show resolved Hide resolved
global.songControls = {
previous: () => presskey(win, 'k'),
next: () => presskey(win, 'j'),
pause: () => presskey(win, 'space'),
like: () => presskey(win, '_'),
dislike: () => presskey(win, '+')
};

// This function will allow plugins to register callback that will be triggered when data changes
global.songInfo.onNewData = callback => {
callbacks.push(callback);
};

win.on('page-title-updated', async () => {
// Save the old title temporarily
const oldTitle = global.songInfo.title;
// Get and set the new data
global.songInfo.title = await getTitle(win);
global.songInfo.isPaused = await getPausedStatus(win);

// If title changed then we do need to update other info
if (oldTitle !== global.songInfo.title) {
const subInfo = await getSubInfo(win);
global.songInfo.artist = subInfo[0];
global.songInfo.views = subInfo[1];
global.songInfo.likes = subInfo[2];
global.songInfo.imageSrc = await getImageSrc(win);
global.songInfo.image = await getImage(global.songInfo.imageSrc);
}

// Trigger the callbacks
callbacks.forEach(c => {
c(global.songInfo);
});
});
};
Loading