Only When Focused
- Show any notification but only when you're not using the player window
+ Show any enabled notification but only when you're not using the player window
@@ -160,7 +158,7 @@ Show Tray Icon
Close To Tray
- Allows you to keep the window hidden whilst playing music and use the tray menu or application menu to quit.The window will minimise if the tray icon is disabled.
+ Allows you to keep the window hidden whilst playing music and use the tray menu or application menu to quit.The window will minimise if the tray icon is disabled
@@ -168,6 +166,28 @@ Close To Tray
+
+
+ Close To Controller
+ Allows you to keep the window hidden without an indicator or application icon taking up spaceHint: MPRIS controllers have to raise Spotify Web Player for it to become unhidden
+
+
+
+
+
+
+
+
+
+ Show Application Menu
+ Whether Spotify Web Player should hide the application menu Warning! Without a tray icon, you may not be able to get into the preferences window
+
+
+
+
+
+
+
Start on Login
@@ -181,8 +201,8 @@ Start on Login
- Start hidden
- Sometimes waiting is ok, Spotify Web Player is never gonna give you up
+ Start Hidden
+ Starts Spotify Web Player minimized
@@ -195,11 +215,7 @@ Start hidden
Navbar
-
-
-
+
diff --git a/js/backend/Preferences/preload.js b/js/backend/Preferences/preload.js
index c145100..e42e0fe 100755
--- a/js/backend/Preferences/preload.js
+++ b/js/backend/Preferences/preload.js
@@ -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;
@@ -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')});
}
});
@@ -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()');
diff --git a/js/backend/dbus_implementation.js b/js/backend/dbus_implementation.js
index 38f450e..749c485 100755
--- a/js/backend/dbus_implementation.js
+++ b/js/backend/dbus_implementation.js
@@ -1,39 +1,57 @@
/*
* @author Matthew James
- * 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){}
}
};
diff --git a/js/backend/dbus_interpreter.js b/js/backend/dbus_interpreter.js
index 1395da9..6fb3f97 100755
--- a/js/backend/dbus_interpreter.js
+++ b/js/backend/dbus_interpreter.js
@@ -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
@@ -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!
diff --git a/js/backend/properties.js b/js/backend/properties.js
index 6e859fe..82806e7 100755
--- a/js/backend/properties.js
+++ b/js/backend/properties.js
@@ -4,8 +4,39 @@ module.exports = function(electron){
const os = require('os');
const fs = require('fs');
var home = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
+ var appSettings = require('./app-settings')(
+ home + '/.spotifywebplayer/preferences.json',
+ {
+ CloseToTray: true,
+ CloseToController: false,
+ ShowApplicationMenu: true,
+ ShowTray: true,
+ Notifications: {
+ ShowTrackChange: true,
+ ShowPlaybackPlaying: true,
+ ShowPlaybackPaused: true,
+ ShowPlaybackStopped: true,
+ OnlyWhenFocused: true,
+ },
+ NavBar: {
+ Follow: true,
+ User: true,
+ Radio: true,
+ YourMusic: true,
+ Browse: true,
+ Settings: true,
+ Search: true,
+ Sing: true
+ },
+ Theme: 'dark',
+ StartOnLogin: false,
+ StartHidden: false,
+ ShowDevTools: false,
+ lastURL: null
+ }
+ );
//Global properties that may be required by the web application
- return {
+ const props = {
PROC_NAME: 'spotifywebplayer',
NAME: 'Spotify Web Player',
fs: fs,
@@ -19,35 +50,7 @@ module.exports = function(electron){
APP_ICON: __dirname + '/../../icons/spotify-web-player.png',
APP_ICON_SMALL: __dirname + '/../../icons/spotify-ico-small.png',
userhome: home,
- appSettings: require('./app-settings')(
- home + '/.spotifywebplayer/preferences.json',
- {
- CloseToTray: true,
- ShowTray: true,
- Notifications: {
- ShowTrackChange: true,
- ShowPlaybackPlaying: true,
- ShowPlaybackPaused: true,
- ShowPlaybackStopped: true,
- OnlyWhenFocused: true
- },
- NavBar: {
- Follow: true,
- User: true,
- Radio: true,
- YourMusic: true,
- Browse: true,
- Settings: true,
- Search: true,
- Sing: true
- },
- Theme: 'dark',
- StartOnLogin: false,
- StartHidden: false,
- ShowDevTools: false,
- lastURL: null
- }
- ),
+ appSettings: appSettings,
globalShortcut: electron.globalShortcut,
APP_DIR: home + '/.spotifywebplayer',
HOST: 'https://play.spotify.com',
@@ -96,6 +99,7 @@ module.exports = function(electron){
minHeight: height,
maxWidth: width,
maxHeight: height,
+ resizable: false,
show: false,
webPreferences: {preload: __dirname + '/About/preload.js'}
});
@@ -115,6 +119,7 @@ module.exports = function(electron){
minHeight: height,
maxWidth: width,
maxHeight: height,
+ resizable: false,
show: false,
webPreferences: {preload: __dirname + '/Preferences/preload.js'}
});
@@ -127,7 +132,7 @@ module.exports = function(electron){
icon: global.props.APP_ICON,
width: 1200,
height: 700,
- show: !props.appSettings.StartHidden,
+ show: false,
backgroundColor: "#121314",
minWidth: 800,
minHeight: 600,
@@ -135,26 +140,19 @@ module.exports = function(electron){
nodeIntegration: false,
preload: __dirname + "/../preloaded/main.js",
plugins: true,
+ webSecurity: false,
allowDisplayingInsecureContent: true,
- allowRunningInsecureContent: true
+ allowRunningInsecureContent: true,
}
});
- if(props.appSettings.StartHidden){
- mainWindow.webContents.once('did-finish-load', function(){
- //mainWindow.show();
- mainWindow.minimize();
+ appSettings.open((err, data) => {
+ mainWindow.webContents.once('dom-ready', () => {
+ mainWindow.show();
+ if(appSettings.StartHidden) mainWindow.minimize();
});
- }
- mainWindow.webContents.on('plugin-crashed', () => {
- console.log('Plugin crashed and cannot continue.');
- electron.app.quit();
+ mainWindow.loadURL((appSettings.lastURL && appSettings.lastURL.indexOf('play.spotify.com') > -1 ? appSettings.lastURL : props.HOST));
+ if (appSettings.ShowDevTools) mainWindow.openDevTools();
});
- //Setup a new window
- mainWindow.loadURL((
- props.appSettings.lastURL && props.appSettings.lastURL.indexOf('play.spotify.com') > -1 ?
- props.appSettings.lastURL :
- global.props.HOST
- ));
mainWindow.on('page-title-updated', function(event){
event.preventDefault();
});
@@ -167,4 +165,5 @@ module.exports = function(electron){
return mainWindow;
}
};
+ return props;
};
diff --git a/js/preloaded/Sing!/sing.js b/js/preloaded/Sing!/sing.js
index cf37267..8715bda 100755
--- a/js/preloaded/Sing!/sing.js
+++ b/js/preloaded/Sing!/sing.js
@@ -1,13 +1,5 @@
//Elements
let ui, navButton, timeButton, timer;
-//Make lyrics cache if it doesn't exist
-props.fs.access(props.lyricCache, props.fs.F_OK, (err) => {
- if (err){
- props.fs.mkdir(props.lyricCache, (err) => {
- if (err) console.log(err);
- });
- }
-});
//Load UI Element first
props.fs.readFile(__dirname + '/ui.html', function(err, data){
if(err) console.log(err);
@@ -52,6 +44,9 @@ props.fs.readFile(__dirname + '/ui.html', function(err, data){
singFuncs.load(controller.getTrackUri(), controller.getTrackName(), controller.getArtist());
}
});
+ $('a[id*=\'nav-\']').not('#nav-sing').click(function(){
+ if(singFuncs.isOpen()) singFuncs.toggleUI(false);
+ });
});
});
function toggleLyricScroller(toggle){
@@ -67,7 +62,14 @@ function toggleLyricScroller(toggle){
}
const singFuncs = {
load: (trackURI, trackName, trackArtist) => {
- //alert('TrackURI: ' + trackURI + ' \nName: ' + trackName + '\nArtist: ' + trackArtist);
+ //Make lyrics cache if it doesn't exist
+ props.fs.access(props.lyricCache, props.fs.F_OK, (err) => {
+ if (err){
+ props.fs.mkdir(props.lyricCache, (err) => {
+ if (err) console.log(err);
+ });
+ }
+ });
if (singFuncs.isOpen() && props.appSettings.NavBar.Sing && $('#sing-ui').attr('data-ref') != trackURI && trackURI && trackName && trackArtist){
singFuncs.showLoader();
var filepath = props.lyricCache + '/' + trackArtist.split(',')[0] + '-' + trackName.match(/(\w+)/g).join('-') + '.html';
@@ -79,9 +81,9 @@ const singFuncs = {
singFuncs.hideLoader();
if (err){
console.log(err);
- $('#sing-ui #sing-container').html("
Sorry, I couldn't find the lyrics to this song. ");
+ $('#sing-ui #sing-container').html("
Sorry, I couldn't find the lyrics to this song. (" + err + ") ");
} else {
- lyrics = "" + result.title + " " + result.artist + " " + result.lyrics.replace(/\n/g, ' ') + "
Lyrics from MusixMatch, using node-unofficialmxm
";
+ lyrics = "" + result.title + " " + result.artists.join(', ') + " " + result.lyrics.replace(/\n/g, ' ') + "
Lyrics from MusixMatch, using node-unofficialmxm
";
props.fs.writeFile(filepath, lyrics, (err) => {
if (err) console.log(err);
$('#sing-ui #sing-container').html(lyrics);
@@ -92,9 +94,13 @@ const singFuncs = {
props.fs.readFile(filepath, (error, data) => {
singFuncs.hideLoader();
if (err){
- $('#sing-ui #sing-container').html("
Sorry, I couldn't get the lyrics to this song. ");
+ $('#sing-ui #sing-container').html("
Sorry, I couldn't get the lyrics to this song. (" + error + ") ");
} else {
$('#sing-ui #sing-container').html(data.toString());
+ $('#sing-ui #sing-container a').click(function(){
+ props.electron.shell.openExternal($(this).attr('href'));
+ return false;
+ });
}
});
}
diff --git a/js/preloaded/advertisements.css b/js/preloaded/advertisements.css
index dd1ec52..ed50bb7 100755
--- a/js/preloaded/advertisements.css
+++ b/js/preloaded/advertisements.css
@@ -9,8 +9,9 @@ html, body{width: 100%;height:100%;border:0 !important;margin:0;padding:0;}
#window_advert{position: fixed; display:none;height:100%;width:100%;background:rgba(0,0,0,0.75);z-index:10000}
#window_advert_container{display:table;position:relative;width:100%;height:100%}
#advert_container{display:table-cell;vertical-align:middle;text-align:center}
-#advert{position:relative;text-align:right;display:inline-block;border-radius:10px;overflow:hidden;width:1200px;height:270px;min-width: 800px;max-width: 75%;}
+#advert{position:relative;text-align:right;display:inline-block;border-radius:10px;overflow:hidden;min-height:240px;min-width: 800px;max-width: 75%;}
#advert a, #advert a:hover, #advert a:active, #advert a:visited{display:block;position:absolute;width:100%;height:100%;left:0;top:0;border:none;text-decoration: none}
#advert #hpto-container .hpto-button{background:rgba(0,0,0,0.75);padding:5px;display:inline-block;border-radius:5px;margin:10px;}
-#advert #hpto-container{position:relative;height:100%;width:100%}
+#advert #hpto-container{position:relative;display: inline-block; width: 900px;height: 270px;background-size: cover;}
+#window_advert #advert #hpto-container iframe {background-color: none !important}
diff --git a/js/preloaded/controller.js b/js/preloaded/controller.js
index b83a370..baeb062 100755
--- a/js/preloaded/controller.js
+++ b/js/preloaded/controller.js
@@ -17,6 +17,7 @@ shortcuts = {
'MediaPlayPause': () => {controller.playPause()},
'MediaPreviousTrack': () => {controller.previous()},
}
+
const controller = {
information: {
albumCache: props.albumCache,
@@ -25,56 +26,50 @@ const controller = {
shuffle: false,
status: 'Stopped',
activeSong: {id: '', uri: '', name: '', album: '', artists: '', art: '', length: 0},
- update: () => {
+ update: (notify) => {
var isPlaying = controller.isPlaying() == 'Playing';
var uri = controller.getTrackUri();
var activeSong = controller.information.activeSong;
- var notify = controller.information._isNotificationWorthy();
controller.information.status = controller.isPlaying();
controller.information.shuffle = controller.isShuffled();
controller.information.repeat = controller.isRepeat();
controller.toggleGlobalShortcuts(isPlaying);
- if(!uri && isPlaying){
- activeSong.name = controller.getTrackName();
- activeSong.id = 0;
- activeSong.album = '';
- activeSong.artists = controller.getArtist();
- activeSong.art = controller.getAlbumArt();
- activeSong.length = 3e+7; //30 Seconds (approximate advertisement length?)
- controller.information._updateMpris();
- if(notify) controller.information.sendNotification();
- if(uri) sing.load(uri, activeSong.name, activeSong.artists);
- } else if(uri && isPlaying){
- controller.getTrackInfo((data) => {
+
+ if(uri && uri != activeSong.uri){
+ controller.getTrackInfo(uri, (data) => {
activeSong.uri = uri;
- activeSong.id = data['id'];
+ activeSong.id = data['track_number'];
activeSong.name = data['name'];
activeSong.album = data['album']['name'];
activeSong.artists = buildArtistsString(data['artists']);
- activeSong.art = data['album']['images'][0]['url'],
+ activeSong.art = data['album']['images'][1]['url'],
activeSong.length = data['duration_ms'] * 1000; //Length in Microseconds
controller.information._updateMpris();
- if(notify) controller.information.sendNotification();
+ activeSong.artists = controller.getArtist();
+
sing.load(uri, activeSong.name, activeSong.artists);
+ if (notify) controller.information.sendNotification();
+ controller.information._updateMpris();
});
- } else if (uri == controller.information.activeSong.uri){
+ } else if(uri && uri == activeSong.uri) {
if (notify) controller.information.sendNotification();
controller.information._updateMpris();
+ sing.load(uri, controller.getTrackName(), controller.getArtist());
+ // activeSong.name = controller.getTrackName();
+ // //Adverts don't have albums!
+ // activeSong.album = (!uri ? '' : controller.getAlbum());
+ // activeSong.artists = controller.getArtist();
+ // activeSong.id = 0;
+ // activeSong.uri = uri;
+ // activeSong.length = 3e7;//30 seconds for average advert?
+ // activeSong.art = controller.getAlbumArt();
+ // if (notify) controller.information.sendNotification();
+ // controller.information._updateMpris();
}
},
- _isNotificationWorthy: () => {
- var hasPlaybackChanged = controller.information.status != controller.isPlaying();
- var isTrackChange = controller.information.activeSong.uri != controller.getTrackUri();
- var isTrackChangeWorthy = isTrackChange && props.appSettings.Notifications.ShowTrackChange;
- var isPauseWorthy = hasPlaybackChanged && controller.isPlaying() == 'Paused' && props.appSettings.Notifications.ShowPlaybackPaused;
- var isStoppedWorthy = hasPlaybackChanged && controller.isPlaying() == 'Stopped' && props.appSettings.Notifications.ShowPlaybackStopped;
- var isPlayingWorthy = hasPlaybackChanged && controller.isPlaying() == 'Playing' && !isTrackChange && props.appSettings.Notifications.ShowPlaybackPlaying;
- var isFocusWorthy = (props.appSettings.Notifications.OnlyWhenFocused ? !props.mainWindow.isFocused() : true);
- return (isTrackChangeWorthy || isPauseWorthy || isStoppedWorthy || isPlayingWorthy) && isFocusWorthy;
- },
sendNotification: () => {
if(dbus) {
- dbus.interpreter.send(dbus.instance.stdin, "notify", controller.information);
+ dbus.interpreter.send(dbus.instances.MPRISAndNotifications.stdin, "notify", controller.information);
} else {
//Suport OS X & Windows with other notification systems
new Notification(
@@ -89,7 +84,7 @@ const controller = {
}
},
_updateMpris: () => {
- if(dbus) dbus.interpreter.send(dbus.instance.stdin, 'updateMpris', controller.information);
+ if(dbus) dbus.interpreter.send(dbus.instances.MPRISAndNotifications.stdin, 'updateMpris', controller.information);
},
},
getTrackUri: () => {
@@ -111,9 +106,7 @@ const controller = {
getAlbum: () => {
return $('#cover-art a', $('#app-player').contents()).attr('data-tooltip').replace(/( by (.*))/, '');
},
- getTrackInfo: (callback) => {
- var uri = controller.getTrackUri();
- if (!uri) return;
+ getTrackInfo: (uri, callback) => {
$.getJSON("https://api.spotify.com/v1/tracks/" + uri, callback);
},
play: () => {
@@ -190,9 +183,10 @@ const controller = {
return playlists;
},
setupDBusHandlers: () => {
+ dbus.interpreter.clearHandles();
if(props.process.platform == 'linux' && dbus){
- if(!dbus.instance) dbus.reload();
- dbus.interpreter.handle(dbus.instance.stdout, {
+ if(!dbus.instances.MPRISAndNotifications) dbus.reload();
+ dbus.interpreter.handle(dbus.instances.MPRISAndNotifications.stdout, {
Quit: () => {tray.contextMenu.quit.click},
Raise: () => {props.mainWindow.show();props.mainWindow.focus();},
Play: controller.play,
@@ -202,8 +196,13 @@ const controller = {
Stop: controller.stop,
openUri: (uri) => {console.log('openUri (MPRIS specification) not implemented.');}
});
+ dbus.interpreter.handle(dbus.instances.MediaKeys.stdout, {
+ PlayPause: controller.playPause,
+ Next: controller.next,
+ Previous: controller.previous
+ });
} else if (props.process.platform == 'linux'){
- console.err('dbus is undefined');
+ console.err('dbus is undefined')
}
},
/**
@@ -222,5 +221,13 @@ const controller = {
}
}
};
+$('button#next, button#previous, button#play-pause', $('iframe#app-player').contents()).click(() => {
+ var times = 0;
+ var timer = setInterval(() => {
+ if (times > 5) return clearInterval(timer);
+ controller.update(false);
+ }, 1000);
+})
+
controller.setupDBusHandlers();
module.exports = controller;
diff --git a/js/preloaded/interface.js b/js/preloaded/interface.js
index a399924..ece89a4 100755
--- a/js/preloaded/interface.js
+++ b/js/preloaded/interface.js
@@ -115,6 +115,9 @@ setInterval(() => {
interface.load();
//Clean will remove everything that's not :first-child that was inserted before.
interface.clean();
+ if($('#modal-notification-area').is(':visible') && $('#modal-notification-area #dialog #indicator').text() == "Can't connect to Spotify. Trying again now..."){
+ props.mainWindow.loadURL('about:blank');
+ }
}, 5e3);
document.addEventListener("visibilitychange", function(){
window_focus = document.visibilityState == "visible";
diff --git a/js/preloaded/main.js b/js/preloaded/main.js
index f729031..240bf97 100755
--- a/js/preloaded/main.js
+++ b/js/preloaded/main.js
@@ -1,23 +1,16 @@
+require('electron-cookies');
global.remote = require('electron').remote;
let props = remote.getGlobal('props');
global.props = props;
-if (window.location.href == 'about:blank' ||
- window.location.href == "data:text/html,chromewebdata"){
- return require('./../backend/Error/preload.js');
-}
-require('electron-cookies');
let dbus = remote.getGlobal('dbus');
global.dbus = dbus;
-
console.log = props.console.log;
-console.error = props.console.log;
-console.info = () => {};
//If the window is a pop-up window
if (window.opener){
- //Set our default properties for the popup window and escape.
var popupWindow = remote.getCurrentWindow();
+ //Set our default properties for the popup window and escape.
popupWindow.setSize(800, 600);
popupWindow.setMenu(null);
popupWindow.show();
diff --git a/js/preloaded/spotify-player.js b/js/preloaded/spotify-player.js
index a2d7c27..ab0f003 100755
--- a/js/preloaded/spotify-player.js
+++ b/js/preloaded/spotify-player.js
@@ -9,13 +9,15 @@ global.controller = require('./controller');
global.tray = require('./tray');
global.interface = require('./interface');
global.sing = require('./Sing!/sing');
+global.appMenu = require('./window-menu');
/**
* Update controls according to login/control status
*/
function checkControlStatus(){
- var loggedIn = user.isLoggedIn();
- windowHook = loggedIn;
- tray.toggleTray(loggedIn);
+ var loggedIn = user.isLoggedIn();
+ windowHook = loggedIn;
+ tray.toggleTray(loggedIn);
+ appMenu.toggleMenu(loggedIn && props.appSettings.ShowApplicationMenu);
}
/**
* When the window closes, hide only if logged in
@@ -25,50 +27,63 @@ window.onbeforeunload = function(e) {
props.mainWindow.setApplicationMenu(null);
return true;
}
- if(windowHook && props.appSettings.CloseToTray && props.appSettings.ShowTray){
- props.mainWindow.hide();
- return false;
+ if(windowHook && ((props.appSettings.CloseToTray && props.appSettings.ShowTray) || props.appSettings.CloseToController)){
+ props.mainWindow.hide();
+ return false;
} else if (windowHook && props.appSettings.CloseToTray && !props.appSettings.ShowTray){
props.mainWindow.minimize();
return false;
}
};
-/**
- * Allow people to reload the page when necessary
- */
-// global.reload = function(){
-// windowHook = false;
-// dbus.quit();
-// props.electron.app.setApplicationMenu(null);
-// controller.toggleGlobalShortcuts(false);
-// tray.toggleMediaButtons(false);
-// tray.toggleTray(false);
-// window.location = window.location;
-// }
-var windowMenu = require('./window-menu');
-props.electron.app.setApplicationMenu(windowMenu);
+setInterval(() => {
+ if($('#modal-notification-area').is(':visible')) {
+ tray.toggleTray(false);
+ if(dbus) dbus.clearHandles();
+ appMenu.toggleMenu(false);
+ windowHook = false;
+ window.location.reload();
+ }
+}, 1000);
interface.load();
/**
* Check for message events from Spotify
*/
window.addEventListener('message', function(event){
- //Check if we want to change the title (normally due to song change)
+ var isFocusWorthy = (props.appSettings.Notifications.OnlyWhenFocused ? !props.mainWindow.isFocused() : true);
+ //Update our information early when the buttons play_pause, next and previous are pressed
+ if (event.data.indexOf('track_id') > -1) return controller.information.update(false);
if (event.data.indexOf("application_set_title") > 0) {
+ var args = JSON.parse(event.data)['args'][0];
//If there's no song, don't do anything
- if(JSON.parse(event.data)['args'][0].indexOf("Spotify Web Player") >= 0) return;
- //If there's nothing, we have stopped playback
- if(JSON.parse(event.data)['args'][0] == "") controller.information.update();
- //If the title starts with http, it may be an advertisement from Spotify.
- if(JSON.parse(event.data)['args'][0].indexOf("http") > 0) controller.information.update(); //Playing advert?
- //Get our metadata from Spotify as we need a new image and the album name.
- tray.toggleMediaButtons(true);
+ if(args.indexOf("Spotify Web Player") >= 0) return;
+ //If there's nothing, we have stopped playback
+ if(args == "") return controller.information.update(props.appSettings.Notifications.ShowPlaybackStopped && isFocusWorthy);
+ //An advert from Spotify
+ if(args.indexOf("http") > 0) {
+ //An advert from Spotify, let's update manually...
+ console.log('advert');
+ controller.information.status = 'Playing';
+ controller.information.activeSong.name = controller.getTrackName();
+ controller.information.activeSong.album = '';
+ controller.information.activeSong.artists = controller.getArtist();
+ controller.information.activeSong.id = 0;
+ controller.information.activeSong.uri = '';
+ controller.informationactiveSong.length = 3e7;//30 seconds for average advert?
+ controller.informationactiveSong.art = controller.getAlbumArt();
+ return controller.information._updateMpris();
+ }
+ //Get our metadata from Spotify as we need a new image and the album name.
+ tray.toggleMediaButtons(true);
sing.enableButton();
- controller.information.update();
+ setTimeout(() => {
+ //1 second gives us and spotify enough time to 'change' tracks successful so we can show the right information
+ controller.information.update(props.appSettings.Notifications.ShowTrackChange && isFocusWorthy);
+ }, 500);
} else if (event.data.indexOf("player_play") > 0){
- controller.information.update();
+ controller.information.update(props.appSettings.Notifications.ShowPlaybackPlaying && isFocusWorthy);
} else if (event.data.indexOf("player_pause") > 0){
- //We pressed pause - update the information
- controller.information.update();
+ //We pressed pause - update the information
+ controller.information.update(props.appSettings.Notifications.ShowPlaybackPaused && isFocusWorthy);
} else if (event.data.indexOf('USER_ACTIVE') > 0 || event.data.indexOf("spb-connected") > 0){
checkControlStatus();
if (props.appSettings.lastURL !== window.location.href){
diff --git a/js/preloaded/themes/light-theme.css b/js/preloaded/themes/light-theme.css
index 700e9c0..d120bd3 100755
--- a/js/preloaded/themes/light-theme.css
+++ b/js/preloaded/themes/light-theme.css
@@ -331,7 +331,7 @@ hr{border-top: 1px solid #bfbfbf !important;margin: 10px 20px !important;}
}
.popover:not(.no-arrow).arrow-top:before{border-bottom-color:#f3f3f3;}
-.popover:not(.no-arrow).arrow-bottom:before{border-bottom-color: #f3f3f3;}
+.popover:not(.no-arrow).arrow-bottom:before{border-top-color:#f3f3f3;}
.btn:hover:not(.just-changed):not(.stay-added):after,
.tl-row .btn-play::after{
border: 1px solid #e3e3e3;
diff --git a/js/preloaded/user.js b/js/preloaded/user.js
index cc907ed..ef46d14 100755
--- a/js/preloaded/user.js
+++ b/js/preloaded/user.js
@@ -34,6 +34,10 @@ module.exports = {
logout: function(){
tray.toggleMediaButtons(false);
tray.toggleTray(false);
+ appMenu.toggleMenu(false);
+ if (dbus) dbus.interpreter.clearHandles();
+ props.appSettings.lastURL = null;
+ props.appSettings.save();
windowHook = false;
if (!props.mainWindow.isVisible()) props.mainWindow.show();
props.clearCache();
diff --git a/js/preloaded/window-menu.js b/js/preloaded/window-menu.js
index 5c22df2..3c3c74d 100755
--- a/js/preloaded/window-menu.js
+++ b/js/preloaded/window-menu.js
@@ -15,7 +15,7 @@ var template = [
{
label: 'Logout',
click: () => {
- tray.contextMenu.logout.click();
+ user.logout();
}
},
{
@@ -58,4 +58,16 @@ var template = [
submenu: [{label: 'About', click: () => {props.aboutWindow.show();props.aboutWindow.focus();}}]
}
];
-module.exports = Menu.buildFromTemplate(template);
\ No newline at end of file
+let _menu;
+module.exports = {
+ toggleMenu: (toggle) => {
+ if(toggle && !_menu){
+ _menu = Menu.buildFromTemplate(template);
+ props.electron.app.setApplicationMenu(_menu);
+ } else if(!toggle && _menu){
+ props.electron.app.setApplicationMenu(null);
+ _menu = null;
+ }
+ }
+}
+
\ No newline at end of file