Skip to content
This repository has been archived by the owner on Oct 27, 2021. It is now read-only.

Commit

Permalink
Start on Login implemented
Browse files Browse the repository at this point in the history
Added hidden application menu
Added close to (mpris) controller
Added Start hidden
LastURL functionality now working
Notification not really fixed but is going to be re-implemented differently - soon
Added 5 more seconds to notifications for now
Notifications isWorthy function removed
Instead, notification decides 'isWorthy' based on preferences in receiving playback/track change messages handler (still somewhat dodgy sometimes - working on it...)
Fixed slow updated notifications/not showing/wrong info bug w/ 70% accuracy now from around 20% accuracy (constantly messing up names etc) - now sometimes just shows the previous information - working on it like I said...
Notification album art missing shows up less
Fixed Sing! sometimes not detecting TrackChange
Prevent about and preferences window being resized
Made sure Sing! node-unofficialmxm links to default browser
Fixed light theme playlist black menu arrow head
Add main media keys w/ D-Bus (no more custom dbus commands)
Moved dbus_service to MRISAndNotifications_service.js allowing for MediaKeys_service.js
Fixed empty lyrics - yet these are from restricted lyrics (appropriate error messages in place)
Fixed Sing! multiple artist separation problem
Added temporary login workaround

These are temporary fixes - I am working on better implementations
  • Loading branch information
Quacky2200 committed Sep 13, 2016
1 parent 6871f0b commit 17e85d0
Show file tree
Hide file tree
Showing 18 changed files with 319 additions and 246 deletions.
26 changes: 0 additions & 26 deletions js/backend/Error/error.html

This file was deleted.

29 changes: 0 additions & 29 deletions js/backend/Error/preload.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,35 @@ var fs = require('fs');
const interpreter = require('./dbus_interpreter');
const notifications = require('freedesktop-notifications');
notifications.setUnflood(true);
let notification = notifications.createNotification({timeout: 1e4});
let notification = notifications.createNotification({timeout: 15e4});
function setupNotification(info){
notification.summary = (info.status == 'Playing' ? 'Now Playing' : info.status);
notification.body = info.activeSong.name.replace(/(\'| - .*| \(.*)/i, '') + '\n' +
info.activeSong.album.replace(/(\'| - .*| \(.*)/i, '') + '\n' +
notification.body = info.activeSong.name.replace(/( - .*| \(.*)/i, '') + '\n' +
info.activeSong.album.replace(/( - .*| \(.*)/i, '') + '\n' +
info.activeSong.artists;
notification.icon = info.activeSong.art;;
notification.icon = info.activeSong.art;
}

//Always make sure we're running as a proper name!
process.title = 'spotifywebplayer';
interpreter.handle(process.stdin, {
updateMpris: (info) => {
player.metadata = {
'mpris:trackid': player.objectPath('track/' + info.activeSong.id),
'mpris:length': info.activeSong.length, // In microseconds
'mpris:artUrl': info.activeSong.art,
'xesam:title': info.activeSong.name.replace(/(\'| - .*| \(.*)/i, ''), //Remove long track titles
'xesam:album': info.activeSong.album.replace(/(\'| - .*| \(.*)/i, ''), //Remove long album names
'xesam:artist': info.activeSong.artists
};
player.playbackStatus = info.status;
player.shuffle = info.shuffle;
player.repeat = info.repeat;
if (info.status == 'Stopped'){
player.playbackStatus = info.status;
} else {
player.metadata = {
'mpris:trackid': player.objectPath('track/' + info.activeSong.id),
'mpris:length': info.activeSong.length, // In microseconds
'mpris:artUrl': info.activeSong.art,
'xesam:title': info.activeSong.name.replace(/(\'| - .*| \(.*)/i, ''), //Remove long track titles
'xesam:album': info.activeSong.album.replace(/(\'| - .*| \(.*)/i, ''), //Remove long album names
'xesam:artist': info.activeSong.artists,
'xesam:url': 'https://play.spotify.com/track/' + info.activeSong.uri
};
player.playbackStatus = info.status;
player.shuffle = info.shuffle;
player.repeat = info.repeat;
}
},
notify: (info) => {
var filepath = info.albumCache;
Expand All @@ -40,13 +46,13 @@ interpreter.handle(process.stdin, {
});
}
});
var file = filepath + '/' + info.activeSong.album + '.jpeg';
var file = (info.activeSong.art ? filepath + '/' + info.activeSong.album + '.jpeg' : process.cwd() + '/icons/spotify-web-player.png');
fs.access(file, fs.F_OK, function(err){
if (err){
request(info.activeSong.art, {encoding: 'binary'}, function(error, response, body) {
if(error) console.log(error);
fs.writeFile(file, body, 'binary', function (err) {
if (err) console.log(err);
lastAlbumArt = file;
if (err) return console.log(err);
info.activeSong.art = file;
setupNotification(info);
notification.push();
Expand All @@ -62,7 +68,6 @@ interpreter.handle(process.stdin, {
});

const Player = require('mpris-service');

const player = Player({
name: 'spotifywebplayer',
identity: 'spotifywebplayer',
Expand Down
28 changes: 28 additions & 0 deletions js/backend/MediaKeys_service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const interpreter = require('./dbus_interpreter');
function send(command, args){
console.log('Sending ' + command + ' event');
interpreter.send(process.stdout, command, args);
}
var DBus = require('dbus');
var dbus = new DBus();
var bus = dbus.getBus('session');
bus.getInterface('org.gnome.SettingsDaemon', '/org/gnome/SettingsDaemon/MediaKeys', 'org.gnome.SettingsDaemon.MediaKeys', function(err, iface) {
if(err) console.log(err);
iface.on('MediaPlayerKeyPressed', function (n, value) {
switch (value) {
case 'Play':
send('PlayPause');
break;
case 'Next':
send('Next');
break;
case 'Previous':
send('Previous');
break;
case 'Stop':
send('Stop');
break;
}
});
iface.GrabMediaPlayerKeys(0, 'org.gnome.SettingsDaemon.MediaKeys');
});
40 changes: 28 additions & 12 deletions js/backend/Preferences/preferences.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ <h1 align='center' style='margin: 20px 0 0'>App Preferences</h1>
<tr>
<td>
<h2>Notifications</h2>
<span>

</span>
<span></span>
</td>
<td></td>
</tr>
Expand Down Expand Up @@ -124,7 +122,7 @@ <h2>On Stop</h2>
<tr class='indent'>
<td>
<h2>Only When Focused</h2>
<span><i>Show any notification </i><b>but only</b> <i>when you're not using the player window</i></span>
<span>Show any enabled notification<i>&nbsp;but only&nbsp;</i>when you're not using the player window</span>
</td>
<td>
<label class='toggle'>
Expand Down Expand Up @@ -160,14 +158,36 @@ <h2>Show Tray Icon</h2>
<tr>
<td>
<h2>Close To Tray</h2>
<span>Allows you to keep the window hidden whilst playing music and use the tray menu or application menu to quit.<br><i>The window will minimise if the tray icon is disabled.</i></span>
<span>Allows you to keep the window hidden whilst playing music and use the tray menu or application menu to quit.<br><i>The window will minimise if the tray icon is disabled</i></span>
</td>
<td>
<label class='toggle'>
<input type='checkbox' name='CloseToTray'>
</label>
</td>
</tr>
<tr>
<td>
<h2>Close To Controller</h2>
<span>Allows you to keep the window hidden without an indicator or application icon taking up space<br/><i>Hint: MPRIS controllers have to raise Spotify Web Player for it to become unhidden</i></span>
</td>
<td>
<label class='toggle'>
<input type='checkbox' name='CloseToController'>
</label>
</td>
</tr>
<tr>
<td>
<h2>Show Application Menu</h2>
<span>Whether Spotify Web Player should hide the application menu<br/>&nbsp;<i>Warning! Without a tray icon, you may not be able to get into the preferences window</i></span>
</td>
<td>
<label class='toggle'>
<input type='checkbox' name='ShowApplicationMenu'>
</label>
</td>
</tr>
<tr>
<td>
<h2>Start on Login</h2>
Expand All @@ -181,8 +201,8 @@ <h2>Start on Login</h2>
</tr>
<tr>
<td>
<h2>Start hidden</h2>
<span>Sometimes waiting is ok, Spotify Web Player is never gonna give you up</span>
<h2>Start Hidden</h2>
<span>Starts Spotify Web Player minimized<br/></span>
</td>
<td>
<label class='toggle'>
Expand All @@ -195,11 +215,7 @@ <h2>Start hidden</h2>
<h2>Navbar</h2>
<span></span>
</td>
<td>
<!-- <label class='toggle'>
<input type="checkbox" name="NavBar.Itself">
</label> -->
</td>
<td></td>
</tr>
<tr class='indent'>
<td>
Expand Down
20 changes: 15 additions & 5 deletions js/backend/Preferences/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ global.remote = require('electron').remote;
let props = remote.getGlobal('props');
var AutoLaunch = require('auto-launch');
let autolaunch = new AutoLaunch({
name: 'Spotify Web Player for Linux'
name: 'Spotify Web Player for Linux',
//A 10 second sleep allows the desktop to load, otherwise no dice... :(
path: '/bin/bash -c "sleep 10 && . ' + props.process.cwd() + '/spotifywebplayer"'
});
global.props = props;
global.windowHook = true;
Expand Down Expand Up @@ -38,11 +40,14 @@ document.onreadystatechange = function(){
recursivelySetupSettings(props.appSettings, ['Theme']);

$('input[name=\'StartOnLogin\']').change(function(){
console.log(props.process.cwd());
if($(this).prop('checked')){
autolaunch.enable();
if (props.process.platform == 'linux'){
if($(this).prop('checked')){
autolaunch.enable();
} else {
autolaunch.disable();
}
} else {
autolaunch.disable();
app.setLoginItemSettings({openAtLogin: $(this).prop('checked')});
}
});

Expand All @@ -51,6 +56,11 @@ document.onreadystatechange = function(){
props.appSettings.save();
props.mainWindow.webContents.executeJavaScript('tray.toggleTray(' + props.appSettings.ShowTray + ')');
});
$('input[name*="ShowApplicationMenu"]').change(function(){
props.appSettings.ShowApplicationMenu = $(this).prop('checked');
props.appSettings.save();
props.mainWindow.webContents.executeJavaScript('appMenu.toggleMenu(' + props.appSettings.ShowApplicationMenu + ')');
});

$('input[name*=\'NavBar\'], select').change(() => {
props.mainWindow.webContents.executeJavaScript('interface.load();interface.clean()');
Expand Down
46 changes: 32 additions & 14 deletions js/backend/dbus_implementation.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,57 @@
/*
* @author Matthew James <[email protected]>
* D-Bus MPRIS Messaging implementer
* D-Bus MPRIS, Notifications and Media Keys Messaging Implementer
*/
var child_process = require('child_process');
var spawn = child_process.spawn;
var lib_node = process.cwd() + '/libs/node/bin/node';
const interpreter = require('./dbus_interpreter');
let dbus = spawnDBus();
let MPRISAndNotifications = spawnMPRISAndNotificationService();
let MediaKeys = spawnMediaKeyService();

function spawnDBus(){
var spawned = spawn(lib_node, [__dirname + '/dbus_service.js']);
function spawnMPRISAndNotificationService(){
var spawned = spawn(lib_node, [__dirname + '/MPRISAndNotifications_service.js']);
spawned.stderr.on('data', (data) => {
console.log('D-Bus Error: ' + data.toString())
console.log('MPRIS & Notification Error: ' + data.toString())
});
spawned.stdout.on('data', (data) => {
console.log('D-Bus/MPRIS says: \n' + data.toString());
console.log('MPRIS & Notification service: \n' + data.toString());
});
spawned.on('exit', () => {
console.log('D-Bus has unexpectedly disconnected.');
console.log('MPRIS & Notification service quit!');
});
return spawned;
}
function spawnMediaKeyService(){
var spawned = spawn(lib_node, [__dirname + '/MediaKeys_service.js']);
spawned.stderr.on('data', (data)=>{
console.log('Media Key Error: ' + data.toString());
});
spawned.stdout.on('data', (data) => {
console.log('Media Keys service: ' + data.toString());
});
spawned.on('exit', () => {
console.log('Media Keys quit!');
});
return spawned;
}

module.exports = {
instance: dbus,
instances: {
MPRISAndNotifications: MPRISAndNotifications,
MediaKeys: MediaKeys
},
interpreter: interpreter,
reload: () => {
dbus = spawnDBus();
MPRISAndNotifications = spawnMPRISAndNotificationService();
MediaKeys = spawnMediaKeyService();
},
quit: () => {
try {
process.kill(dbus.pid);
dbus = null;
} catch (e){
//D-Bus quitted early
}
process.kill(MPRISAndNotifications.pid);
process.kill(MediaKeys.pid);
MPRISAndNotifications = null;
MediaKeys = null;
} catch (e){}
}
};
13 changes: 12 additions & 1 deletion js/backend/dbus_interpreter.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* The JSON string has a standard format of
* {"command": "doSomething", args: {"key":"test"}}
*/
let events = {};
const interpreter = {
/*
* Encapsulate an event object into a sendable string for decapsulation
Expand All @@ -41,10 +42,20 @@ const interpreter = {
handle: (std, handlers) => {
std.on('data', function(data){
var message = interpreter.decapsulate(data.toString());
events = handlers;
//Try processing the command/event
if(message && message.command && handlers.hasOwnProperty(message.command)) handlers[message.command](message.args);
if(message && message.command && events.hasOwnProperty(message.command)) {
try{
events[message.command](message.args);
} catch (e) {
console.log('Handles have not been released! - ' + e);
}
}
});
},
clearHandles: function(){
events = {};
},
/*
* Send a message to a process
* MUST PASS A STDIN/STDOUT object!
Expand Down
Loading

0 comments on commit 17e85d0

Please sign in to comment.