Merge pull request #246 from pR0Ps/bugfix/update-and-ui-fixes
Mouse and media key fixes
This commit is contained in:
commit
2afc90ef06
17 changed files with 2683 additions and 1978 deletions
|
@ -25,6 +25,9 @@ module.exports = function (grunt) {
|
|||
dist: 'dist'
|
||||
};
|
||||
|
||||
// Serve static files
|
||||
var serveStatic = require('serve-static');
|
||||
|
||||
// Paths to ssh config & private key
|
||||
var sshConfigFile = '.ssh/testServer.json';
|
||||
var sshKeyFile = '.ssh/test-server-key/';
|
||||
|
@ -87,9 +90,9 @@ module.exports = function (grunt) {
|
|||
return [
|
||||
connect().use(
|
||||
'/bower_components',
|
||||
connect.static('./bower_components')
|
||||
serveStatic('./bower_components')
|
||||
),
|
||||
connect.static(appConfig.app)
|
||||
serveStatic(appConfig.app)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ angular.module('JamStash', [
|
|||
'ngRoute',
|
||||
'ngSanitize',
|
||||
'ngLodash',
|
||||
'ui.keypress',
|
||||
'jamstash.subsonic.controller',
|
||||
'jamstash.archive.controller',
|
||||
'jamstash.player.controller',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('JamStash').directive('sortable', function () {
|
||||
angular.module('JamStash')
|
||||
.directive('sortable', function () {
|
||||
return {
|
||||
link: function (scope, elm, attrs) {
|
||||
elm.sortable({
|
||||
|
@ -46,30 +47,6 @@ angular.module('JamStash').directive('sortable', function () {
|
|||
}
|
||||
};
|
||||
}])
|
||||
.directive('stopEvent', function () {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attr) {
|
||||
element.bind(attr.stopEvent, function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('ngEnter', function () {
|
||||
return {
|
||||
scope: { onEnter: '&' },
|
||||
link: function (scope, element) {
|
||||
console.log(scope);
|
||||
element.bind("keydown keypress", function (event) {
|
||||
if (event.which === 13) {
|
||||
scope.onEnter();
|
||||
scope.$apply();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('ngDownload', ['$compile', function ($compile) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
|
@ -92,16 +69,20 @@ angular.module('JamStash').directive('sortable', function () {
|
|||
}
|
||||
};
|
||||
}])
|
||||
.directive('stopEvent', function () {
|
||||
.directive('stopEvent', ['lodash', function (_) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attr) {
|
||||
element.bind(attr.stopEvent, function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
if (attr && attr.stopEvent) {
|
||||
_.forEach(attr.stopEvent.split(','), function (eventName) {
|
||||
element.bind(eventName, function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
}])
|
||||
.directive('ngEnter', function () {
|
||||
return function (scope, element, attrs) {
|
||||
element.bind("keydown keypress", function (event) {
|
||||
|
@ -114,22 +95,4 @@ angular.module('JamStash').directive('sortable', function () {
|
|||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
.directive("ngMsgs", function() {
|
||||
/* Not Using */
|
||||
return {
|
||||
restrict: 'E',
|
||||
transclude : false,
|
||||
scope: {
|
||||
msgs: "="
|
||||
},
|
||||
template: '<span id="msg_{{$index}}" class="message">{{ item }}</span>',
|
||||
link: function (scope, elm, attrs) {
|
||||
scope.$watch(scope.Messages, function () {
|
||||
var content = $compile((template)(scope));
|
||||
elm.append(content);
|
||||
$(elm).parent().fadeIn();
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
|
|
@ -154,9 +154,9 @@ angular.module('JamStash')
|
|||
});
|
||||
};
|
||||
|
||||
$(document).on("click", ".message", function(){
|
||||
$(this).remove();
|
||||
});
|
||||
$(document).on("click", ".message", function(){
|
||||
$(this).remove();
|
||||
});
|
||||
|
||||
// Global Functions
|
||||
window.onbeforeunload = function () {
|
||||
|
@ -171,39 +171,51 @@ angular.module('JamStash')
|
|||
$(this).fadeOut(function () { $(this).remove(); });
|
||||
return false;
|
||||
})
|
||||
$document.keydown(function (e) {
|
||||
$scope.scrollToIndex(e);
|
||||
|
||||
// Shortcut processing
|
||||
$(document).keydown(function (e) {
|
||||
$scope.processKeyEvent(e);
|
||||
});
|
||||
$scope.scrollToIndex = function (e) {
|
||||
var source = e.target.id;
|
||||
if (e.target.tagName.toUpperCase() != 'INPUT') {
|
||||
var unicode = e.charCode ? e.charCode : e.keyCode;
|
||||
if (globals.settings.Debug) { console.log('Keycode Triggered: ' + unicode); }
|
||||
if (unicode == 49) { // 1
|
||||
$('#action_Queue').click();
|
||||
} else if (unicode == 50) {
|
||||
$('#action_Library').click();
|
||||
} else if (unicode == 51) {
|
||||
$('#action_Archive').click();
|
||||
} else if (unicode == 52) {
|
||||
$('#action_Settings').click();
|
||||
} else if (unicode == 53) {
|
||||
} else if (unicode == 54) { // 6
|
||||
$scope.processKeyEvent(e);
|
||||
return true;
|
||||
};
|
||||
$scope.processKeyEvent = function (e) {
|
||||
if (e.isDefaultPrevented() ||
|
||||
e.repeat ||
|
||||
e.altKey || e.metaKey || e.ctrlKey ||
|
||||
(e.target && _.contains(['input', 'textarea', 'select'], e.target.tagName.toLowerCase()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
var key = e.key;
|
||||
if (globals.settings.Debug) { console.log('Key pressed: ' + key); }
|
||||
if (key == "Esc" || key == "Escape") {
|
||||
$rootScope.hideQueue();
|
||||
} else if (key == " " || key == "Space") {
|
||||
player.togglePause();
|
||||
} else if (key == "ArrowLeft" || key == "Left") {
|
||||
player.previousTrack();
|
||||
} else if (key == "ArrowRight" || key == "Right") {
|
||||
player.nextTrack();
|
||||
} else if (key == "-" || key == "_") {
|
||||
persistence.saveVolume(player.turnVolumeDown());
|
||||
} else if (key == "=" || key == "+") {
|
||||
persistence.saveVolume(player.turnVolumeUp());
|
||||
} else if (/^[a-z]$/i.test(key) && $('#tabLibrary').is(':visible')) {
|
||||
if (/^[x-z]$/i.test(key)) {
|
||||
key = 'x-z';
|
||||
}
|
||||
if (unicode >= 65 && unicode <= 90 && $('#tabLibrary').is(':visible')) { // a-z
|
||||
var key = utils.findKeyForCode(unicode);
|
||||
if (key == 'x' || key == 'y' || key == 'z') {
|
||||
key = 'x-z';
|
||||
}
|
||||
var el = '#' + key.toUpperCase();
|
||||
if ($(el).length > 0) {
|
||||
$('#left-component').stop().scrollTo(el, 400);
|
||||
}
|
||||
} else if (unicode == 36 && $('#tabLibrary').is(':visible')) { // home
|
||||
$('#left-component').stop().scrollTo('#MusicFolders', 400);
|
||||
var el = '#' + key.toUpperCase();
|
||||
if ($(el).length > 0) {
|
||||
$('#left-component').stop().scrollTo(el, 400);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
else{
|
||||
return;
|
||||
}
|
||||
$scope.$apply();
|
||||
e.preventDefault();
|
||||
};
|
||||
$scope.scrollToIndexName = function (index) {
|
||||
var el = '#' + index;
|
||||
|
@ -246,82 +258,6 @@ angular.module('JamStash')
|
|||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the target of this event is an input
|
||||
* @param {jQuery event} event
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function isTargetInput (event) {
|
||||
return (event && event.target.tagName === "INPUT");
|
||||
}
|
||||
|
||||
/* We define player-related methods here instead of in player controller
|
||||
in order to bind keypresses to <body> and have global shortcuts.
|
||||
We also check the event so we don't do anything if it's on an input */
|
||||
$scope.togglePause = function (event) {
|
||||
if(!isTargetInput(event)) {
|
||||
if(globals.settings.Jukebox) {
|
||||
$scope.sendToJukebox('stop');
|
||||
} else {
|
||||
player.togglePause();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.turnVolumeUp = function (event) {
|
||||
if(!isTargetInput(event)) {
|
||||
var volume = player.turnVolumeUp();
|
||||
persistence.saveVolume(volume);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.turnVolumeDown = function (event) {
|
||||
if(!isTargetInput(event)) {
|
||||
var volume = player.turnVolumeDown();
|
||||
persistence.saveVolume(volume);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.nextTrack = function (event) {
|
||||
if(!isTargetInput(event)) {
|
||||
player.nextTrack();
|
||||
}
|
||||
};
|
||||
$scope.previousTrack = function (event) {
|
||||
if(!isTargetInput(event)) {
|
||||
player.previousTrack();
|
||||
}
|
||||
};
|
||||
|
||||
$rootScope.addToJukebox = function (id) {
|
||||
if (globals.settings.Debug) { console.log("LOAD JUKEBOX"); }
|
||||
$.ajax({
|
||||
url: globals.BaseURL() + '/jukeboxControl.view?' + globals.BaseParams() + '&action=set&id=' + id,
|
||||
method: 'GET',
|
||||
dataType: globals.settings.Protocol,
|
||||
timeout: globals.settings.Timeout,
|
||||
success: function (data) {
|
||||
/*
|
||||
if (data["subsonic-response"].podcasts.channel !== undefined) {
|
||||
}
|
||||
deferred.resolve(podcasts);
|
||||
*/
|
||||
$.get(globals.BaseURL() + '/jukeboxControl.view?' + globals.BaseParams() + '&action=start');
|
||||
}
|
||||
});
|
||||
};
|
||||
$rootScope.sendToJukebox = function (action) {
|
||||
if (globals.settings.Debug) { console.log("SEND JUKEBOX " + action); }
|
||||
$.ajax({
|
||||
url: globals.BaseURL() + '/jukeboxControl.view?' + globals.BaseParams() + '&action=' + action,
|
||||
method: 'GET',
|
||||
dataType: globals.settings.Protocol,
|
||||
timeout: globals.settings.Timeout,
|
||||
success: function (data) {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.toggleStar = function (item) {
|
||||
subsonic.toggleStar(item).then(function (newStarred) {
|
||||
item.starred = newStarred;
|
||||
|
|
|
@ -3,7 +3,7 @@ describe("Main controller", function () {
|
|||
'use strict';
|
||||
|
||||
var controllerParams, $controller, $q, scope, mockGlobals, player, utils, persistence, subsonic, notifications,
|
||||
deferred;
|
||||
deferred, mockKeypress;
|
||||
beforeEach(function () {
|
||||
mockGlobals = {
|
||||
settings: {
|
||||
|
@ -18,6 +18,16 @@ describe("Main controller", function () {
|
|||
$provide.value('globals', mockGlobals);
|
||||
});
|
||||
|
||||
// Mock a keypress to the application
|
||||
mockKeypress = function(scope, key, target){
|
||||
scope.processKeyEvent({
|
||||
key: key,
|
||||
target: target,
|
||||
isDefaultPrevented: function(){},
|
||||
preventDefault: function(){}
|
||||
});
|
||||
}
|
||||
|
||||
// Mock the player service
|
||||
player = jasmine.createSpyObj("player", [
|
||||
"togglePause",
|
||||
|
@ -78,10 +88,6 @@ describe("Main controller", function () {
|
|||
});
|
||||
});
|
||||
|
||||
xdescribe("toggleSetting -", function () {
|
||||
|
||||
});
|
||||
|
||||
describe("", function () {
|
||||
beforeEach(function () {
|
||||
$controller('AppController', controllerParams);
|
||||
|
@ -99,24 +105,16 @@ describe("Main controller", function () {
|
|||
expect(scope.showQueue).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("When I toggle pause,", function () {
|
||||
it("given that we're using the Jukebox mode, it sends a 'stop' command to the jukebox", function () {
|
||||
mockGlobals.settings.Jukebox = true;
|
||||
spyOn(scope, "sendToJukebox");
|
||||
|
||||
scope.togglePause();
|
||||
expect(scope.sendToJukebox).toHaveBeenCalledWith('stop');
|
||||
});
|
||||
|
||||
it("it toggles pause using the player service", function () {
|
||||
scope.togglePause();
|
||||
describe("When I toggle pause using the keyboard shortcut,", function () {
|
||||
it("it toggles pause on the player service", function () {
|
||||
mockKeypress(scope, ' ');
|
||||
expect(player.togglePause).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it("When I turn the volume up, it sets the player's volume up and saves it using the persistence service", function () {
|
||||
player.turnVolumeUp.and.returnValue(0.6);
|
||||
scope.turnVolumeUp();
|
||||
mockKeypress(scope, '+');
|
||||
|
||||
expect(player.turnVolumeUp).toHaveBeenCalled();
|
||||
expect(persistence.saveVolume).toHaveBeenCalledWith(0.6);
|
||||
|
@ -124,52 +122,49 @@ describe("Main controller", function () {
|
|||
|
||||
it("When I turn the volume down, it sets the player's volume down and saves it using the persistence service", function () {
|
||||
player.turnVolumeDown.and.returnValue(0.4);
|
||||
scope.turnVolumeDown();
|
||||
mockKeypress(scope, '-');
|
||||
|
||||
expect(player.turnVolumeDown).toHaveBeenCalled();
|
||||
expect(persistence.saveVolume).toHaveBeenCalledWith(0.4);
|
||||
});
|
||||
|
||||
it("When I go to the next track, it calls next track on the player", function () {
|
||||
scope.nextTrack();
|
||||
mockKeypress(scope, 'ArrowRight');
|
||||
expect(player.nextTrack).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("When I go to the previous track, it calls previous track on the player", function () {
|
||||
scope.previousTrack();
|
||||
mockKeypress(scope, 'ArrowLeft');
|
||||
expect(player.previousTrack).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("Given that I am targeting an input,", function () {
|
||||
var event;
|
||||
beforeEach(function () {
|
||||
event = { target: { tagName: "INPUT" } };
|
||||
});
|
||||
var target = { 'tagName': "iNPUt" } ;
|
||||
|
||||
it("when I use a shortcut to toggle pause, it doesn't do anything", function () {
|
||||
scope.togglePause(event);
|
||||
mockKeypress(scope, ' ', target);
|
||||
expect(player.togglePause).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("when I use a shortcut to turn the volume up, it doesn't do anything", function () {
|
||||
scope.turnVolumeUp(event);
|
||||
mockKeypress(scope, '+', target);
|
||||
expect(player.turnVolumeUp).not.toHaveBeenCalled();
|
||||
expect(persistence.saveVolume).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("when I use a shortcut to turn the volume down, it doesn't do anything", function () {
|
||||
scope.turnVolumeDown(event);
|
||||
mockKeypress(scope, '-', target);
|
||||
expect(player.turnVolumeDown).not.toHaveBeenCalled();
|
||||
expect(persistence.saveVolume).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("when I use a shortcut to go to the next track, it doesn't do anything", function () {
|
||||
scope.nextTrack(event);
|
||||
mockKeypress(scope, 'RightArrow', target);
|
||||
expect(player.nextTrack).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("when I use a shortcut to go to the previous track, it doesn't do anything", function () {
|
||||
scope.previousTrack(event);
|
||||
mockKeypress(scope, 'LeftArrow', target);
|
||||
expect(player.previousTrack).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<li class="row song" ng-repeat="o in song" ng-click="toggleSelection(o)" ng-dblclick="playFrom($index)" ng-class="{'selected': o.selected, 'playing': o.playing}">
|
||||
<div class="itemactions">
|
||||
<a class="add" href="" title="Add To Queue" ng-click="addSongToQueue(o)" stop-event="click"></a>
|
||||
<!--<a class="remove" href="" title="Remove Song" ng-click="removeSongFromQueue(o)" stop-event="click"></a>-->
|
||||
<a class="play" href="" title="Play this song" ng-click="playSong(o)" stop-event="click"></a>
|
||||
<!--<a class="download" href="" title="Download Song" ng-click="download(o.id)"></a>-->
|
||||
<a href="" title="Star" ng-class="{'favorite': o.starred, 'rate': !o.starred}" ng-click="toggleStar(o)" stop-event="click"></a>
|
||||
<a class="add" href="" title="Add To Queue" ng-click="addSongToQueue(o)" stop-event="click,dblclick"></a>
|
||||
<!--<a class="remove" href="" title="Remove Song" ng-click="removeSongFromQueue(o)" stop-event="click,dblclick"></a>-->
|
||||
<a class="play" href="" title="Play this song" ng-click="playSong(o)" stop-event="click,dblclick"></a>
|
||||
<!--<a class="download" href="" title="Download Song" ng-click="download(o.id)" stop-event="click,dblclick"></a>-->
|
||||
<a href="" title="Star" ng-class="{'favorite': o.starred, 'rate': !o.starred}" ng-click="toggleStar(o)" stop-event="click,dblclick"></a>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="track floatleft" ng-bind-html="o.track"></div>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<link rel="stylesheet" href="subsonic/breadcrumbs-directive/breadcrumbs-directive.css" />
|
||||
<!-- endbuild -->
|
||||
</head>
|
||||
<body ui-keypress="{'32 179': 'togglePause($event)', '43 61 187': 'turnVolumeUp($event)', '45 95 189': 'turnVolumeDown($event)'}" ui-keydown="{'right 176': 'nextTrack($event)', 'left 177': 'previousTrack($event)'}">
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="header">
|
||||
<div id="messages">
|
||||
|
@ -84,20 +84,19 @@
|
|||
<!-- build:js({.,app}) scripts/vendor.min.js -->
|
||||
<!-- bower:js -->
|
||||
<script src="bower_components/jquery/dist/jquery.js"></script>
|
||||
<script src="bower_components/jquery-ui/jquery-ui.js"></script>
|
||||
<script src="bower_components/jplayer/dist/jplayer/jquery.jplayer.js"></script>
|
||||
<script src="bower_components/angular/angular.js"></script>
|
||||
<script src="bower_components/angular-route/angular-route.js"></script>
|
||||
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
|
||||
<script src="bower_components/angular-cookies/angular-cookies.js"></script>
|
||||
<script src="bower_components/angular-resource/angular-resource.js"></script>
|
||||
<script src="bower_components/jquery-ui/jquery-ui.js"></script>
|
||||
<script src="bower_components/jplayer/dist/jplayer/jquery.jplayer.js"></script>
|
||||
<script src="bower_components/jquery-mousewheel/jquery.mousewheel.js"></script>
|
||||
<script src="bower_components/fancybox/source/jquery.fancybox.js"></script>
|
||||
<script src="bower_components/notify.js/notify.js"></script>
|
||||
<script src="bower_components/jquery.scrollTo/jquery.scrollTo.js"></script>
|
||||
<script src="bower_components/jquery-dateFormat/dist/jquery-dateFormat.js"></script>
|
||||
<script src="bower_components/angular-locker/dist/angular-locker.min.js"></script>
|
||||
<script src="bower_components/angular-ui-utils/keypress.js"></script>
|
||||
<script src="bower_components/ng-lodash/build/ng-lodash.js"></script>
|
||||
<script src="bower_components/angular-ui-sortable/sortable.js"></script>
|
||||
<!-- endbower -->
|
||||
|
|
|
@ -85,7 +85,7 @@ angular.module('jamstash.player.directive', ['jamstash.player.service', 'jamstas
|
|||
var p = event.jPlayer.status.currentPercentAbsolute;
|
||||
var isPlaying = !event.jPlayer.status.paused;
|
||||
if (!scope.scrobbled && p > 30 && isPlaying) {
|
||||
if (globals.settings.Debug) { console.log('LAST.FM SCROBBLE - Percent Played: ' + p); }
|
||||
if (globals.settings.Debug) { console.log('Scrobbling - Percent Played: ' + p); }
|
||||
subsonic.scrobble(scope.currentSong);
|
||||
scope.scrobbled = true;
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ angular.module('jamstash.player.directive', ['jamstash.player.service', 'jamstas
|
|||
$player.jPlayer('setMedia', media);
|
||||
if (globals.settings.Jukebox) {
|
||||
$player.jPlayer('mute', true);
|
||||
scope.addToJukebox(newSong.id);
|
||||
subsonic.addToJukebox(newSong);
|
||||
}
|
||||
if (playerService.loadSong === true || globals.settings.Jukebox) {
|
||||
// Do not play, only load
|
||||
|
@ -152,10 +152,9 @@ angular.module('jamstash.player.directive', ['jamstash.player.service', 'jamstas
|
|||
scope.$watch(function () {
|
||||
return playerService.pauseSong;
|
||||
}, function (newVal) {
|
||||
if(newVal === true) {
|
||||
$player.jPlayer('pause');
|
||||
} else {
|
||||
$player.jPlayer('play');
|
||||
$player.jPlayer(newVal ? 'pause' : 'play');
|
||||
if(globals.settings.Jukebox){
|
||||
subsonic.sendToJukebox(newVal ? 'stop' : 'start');
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -76,11 +76,12 @@ describe("jplayer directive", function () {
|
|||
|
||||
it("if the global setting Jukebox is true, it mutes jPlayer and adds the song to subsonic's Jukebox", function () {
|
||||
mockGlobals.settings.Jukebox = true;
|
||||
scope.addToJukebox = jasmine.createSpy("addToJukebox");
|
||||
spyOn(subsonic, "addToJukebox")
|
||||
|
||||
scope.$apply();
|
||||
expect($player.jPlayer).toHaveBeenCalledWith('mute', true);
|
||||
expect(scope.addToJukebox).toHaveBeenCalledWith(playingSong.id);
|
||||
expect(subsonic.addToJukebox).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({ id: playingSong.id}))
|
||||
});
|
||||
|
||||
it("if the player service's loadSong flag is true, it does not play the song, it displays the player controls and sets the player to the song's supplied position", function () {
|
||||
|
@ -142,6 +143,7 @@ describe("jplayer directive", function () {
|
|||
describe("", function () {
|
||||
beforeEach(function () {
|
||||
$.fn.jPlayer.and.stub();
|
||||
spyOn(subsonic, "sendToJukebox")
|
||||
});
|
||||
|
||||
it("When the player service's restartSong flag is true, it restarts the current song, resets the restart flag to false and resets the scrobbled flag to false", function () {
|
||||
|
@ -170,6 +172,25 @@ describe("jplayer directive", function () {
|
|||
expect($player.jPlayer).toHaveBeenCalledWith('play');
|
||||
});
|
||||
|
||||
it("When the player service's pauseSong is true and jukebox is enabled, 'stop' is sent to the jukebox", function () {
|
||||
mockGlobals.settings.Jukebox = true;
|
||||
playerService.pauseSong = true;
|
||||
scope.$apply();
|
||||
|
||||
expect(subsonic.sendToJukebox).toHaveBeenCalledWith('stop');
|
||||
});
|
||||
|
||||
it("Given that the current song is paused and jukebox is enabled, 'start' is sent to the jukebox when it's unpaused", function () {
|
||||
mockGlobals.settings.Jukebox = true;
|
||||
|
||||
playerService.pauseSong = true;
|
||||
scope.$apply();
|
||||
playerService.pauseSong = false;
|
||||
scope.$apply();
|
||||
|
||||
expect(subsonic.sendToJukebox).toHaveBeenCalledWith('start');
|
||||
});
|
||||
|
||||
it("When the player service's volume changes, it sets jPlayer's volume", function () {
|
||||
playerService.getVolume.and.returnValue(0.2034);
|
||||
scope.$apply();
|
||||
|
|
|
@ -15,22 +15,8 @@ angular.module('jamstash.player.controller', ['jamstash.player.service', 'jamsta
|
|||
$scope.settings = globals.settings;
|
||||
$scope.playerSettings = player.settings;
|
||||
|
||||
$scope.play = function () {
|
||||
if (globals.settings.Jukebox) {
|
||||
$scope.sendToJukebox('start');
|
||||
} else {
|
||||
player.togglePause();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.pause = function () {
|
||||
if (globals.settings.Jukebox) {
|
||||
$scope.sendToJukebox('stop');
|
||||
} else {
|
||||
player.togglePause();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.play = player.togglePause;
|
||||
$scope.pause = player.togglePause;
|
||||
$scope.previousTrack = player.previousTrack;
|
||||
$scope.nextTrack = player.nextTrack;
|
||||
}]);
|
||||
|
|
|
@ -46,14 +46,14 @@
|
|||
href=""
|
||||
title="Remove Song"
|
||||
ng-click="vm.removeSongFromQueue(song)"
|
||||
stop-event="click"
|
||||
stop-event="click,dblclick"
|
||||
></a>
|
||||
<a
|
||||
href=""
|
||||
title="Star"
|
||||
ng-class="{'favorite': song.starred, 'rate': ! song.starred}"
|
||||
ng-click="vm.toggleStar(song)"
|
||||
stop-event="click"
|
||||
stop-event="click,dblclick"
|
||||
></a>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
|
|
@ -114,9 +114,7 @@
|
|||
<h3 class="title">Keyboard Shortcuts</h3>
|
||||
<ul class="preferences">
|
||||
<li><em>Esc</em> Hide Queue</li>
|
||||
<li><em>[1-6]</em> Switch to corresponding tab</li>
|
||||
<li><em>[a-z]</em> Use to Quickly Browse to an Artist</li>
|
||||
<li><em>Home</em> Scroll to Top of Artist List</li>
|
||||
<li><em>Spacebar</em> Play/Pause</li>
|
||||
<li><em>→</em> Next Track</li>
|
||||
<li><em>←</em> Previous Track</li>
|
||||
|
|
|
@ -53,7 +53,9 @@ function subsonicService(
|
|||
scrobble : scrobble,
|
||||
search : search,
|
||||
subsonicRequest : subsonicRequest,
|
||||
toggleStar : toggleStar
|
||||
toggleStar : toggleStar,
|
||||
addToJukebox : addToJukebox,
|
||||
sendToJukebox : sendToJukebox
|
||||
});
|
||||
|
||||
// TODO: Hyz: Remove when refactored
|
||||
|
@ -570,4 +572,27 @@ function subsonicService(
|
|||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
function addToJukebox(song) {
|
||||
if (globals.settings.Debug) { console.log("Load Jukebox"); }
|
||||
var promise = self.subsonicRequest('jukeboxControl.view', {
|
||||
params: {
|
||||
action: 'set',
|
||||
id: song.id
|
||||
}
|
||||
}).then(function () {
|
||||
self.sendToJukebox('start');
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
function sendToJukebox(action) {
|
||||
if (globals.settings.Debug) { console.log("Send Jukebox " + action); }
|
||||
var promise = self.subsonicRequest('jukeboxControl.view', {
|
||||
params: {
|
||||
action: action
|
||||
}
|
||||
})
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,20 +26,19 @@
|
|||
},
|
||||
"main": "app/index.html",
|
||||
"dependencies": {
|
||||
"jquery": "~2.1.4",
|
||||
"jquery-ui": "~1.11.4",
|
||||
"jplayer": "~2.9.2",
|
||||
"angular": "~1.4.1",
|
||||
"angular-route": "~1.4.1",
|
||||
"angular-sanitize": "~1.4.1",
|
||||
"angular-cookies": "~1.4.1",
|
||||
"angular-resource": "~1.4.1",
|
||||
"jquery": "~2.1.4",
|
||||
"jquery-ui": "~1.11.4",
|
||||
"jplayer": "~2.9.2",
|
||||
"fancybox": "~2.1.4",
|
||||
"notify.js": "<=1.2.2",
|
||||
"jquery.scrollTo": "~1.4.5",
|
||||
"jquery-dateFormat": "~1.0.2",
|
||||
"angular-locker": "~2.0.1",
|
||||
"angular-ui-utils": "bower-keypress",
|
||||
"open-iconic": "~1.1.1",
|
||||
"ng-lodash": "~0.2.3",
|
||||
"angular-ui-sortable": "~0.13.4"
|
||||
|
|
|
@ -20,20 +20,19 @@ module.exports = function (config) {
|
|||
files: [
|
||||
// bower:
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'bower_components/jquery-ui/jquery-ui.js',
|
||||
'bower_components/jplayer/dist/jplayer/jquery.jplayer.js',
|
||||
'bower_components/angular/angular.js',
|
||||
'bower_components/angular-route/angular-route.js',
|
||||
'bower_components/angular-sanitize/angular-sanitize.js',
|
||||
'bower_components/angular-cookies/angular-cookies.js',
|
||||
'bower_components/angular-resource/angular-resource.js',
|
||||
'bower_components/jquery-ui/jquery-ui.js',
|
||||
'bower_components/jplayer/dist/jplayer/jquery.jplayer.js',
|
||||
'bower_components/jquery-mousewheel/jquery.mousewheel.js',
|
||||
'bower_components/fancybox/source/jquery.fancybox.js',
|
||||
'bower_components/notify.js/notify.js',
|
||||
'bower_components/jquery.scrollTo/jquery.scrollTo.js',
|
||||
'bower_components/jquery-dateFormat/dist/jquery-dateFormat.js',
|
||||
'bower_components/angular-locker/dist/angular-locker.min.js',
|
||||
'bower_components/angular-ui-utils/keypress.js',
|
||||
'bower_components/ng-lodash/build/ng-lodash.js',
|
||||
'bower_components/angular-ui-sortable/sortable.js',
|
||||
'bower_components/angular-mocks/angular-mocks.js',
|
||||
|
|
4232
package-lock.json
generated
4232
package-lock.json
generated
File diff suppressed because it is too large
Load diff
41
package.json
41
package.json
|
@ -28,32 +28,33 @@
|
|||
"main": "app/index.html",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-bump": "^0.3.1",
|
||||
"grunt-contrib-clean": "^0.6.0",
|
||||
"grunt-contrib-concat": "^0.5.1",
|
||||
"grunt-contrib-connect": "^0.10.1",
|
||||
"grunt-contrib-copy": "^0.8.0",
|
||||
"grunt-contrib-cssmin": "^0.12.3",
|
||||
"grunt-contrib-htmlmin": "^0.4.0",
|
||||
"grunt": "^1.0.1",
|
||||
"grunt-bump": "^0.8.0",
|
||||
"grunt-contrib-clean": "^1.0.0",
|
||||
"grunt-contrib-concat": "^1.0.1",
|
||||
"grunt-contrib-connect": "^1.0.2",
|
||||
"grunt-contrib-copy": "^1.0.0",
|
||||
"grunt-contrib-cssmin": "^1.0.2",
|
||||
"grunt-contrib-htmlmin": "^2.0.0",
|
||||
"grunt-contrib-imagemin": "^1.0.1",
|
||||
"grunt-contrib-uglify": "^0.9.1",
|
||||
"grunt-contrib-watch": "^0.6.1",
|
||||
"grunt-contrib-uglify": "^2.0.0",
|
||||
"grunt-contrib-watch": "^1.0.0",
|
||||
"grunt-filerev": "^2.3.1",
|
||||
"grunt-karma": "^0.10.1",
|
||||
"grunt-karma": "^2.0.0",
|
||||
"grunt-notify": "^0.4.1",
|
||||
"grunt-ssh": "^0.12.3",
|
||||
"grunt-svg-sprite": "^1.1.2",
|
||||
"grunt-usemin": "^3.0.0",
|
||||
"grunt-wiredep": "^2.0.0",
|
||||
"jasmine-core": "^2.6.1",
|
||||
"jit-grunt": "^0.9.1",
|
||||
"karma": "^0.12.32",
|
||||
"karma-chrome-launcher": "^0.1.12",
|
||||
"karma-coverage": "^0.3.1",
|
||||
"karma-jasmine": "^0.3.5",
|
||||
"karma-ng-html2js-preprocessor": "^0.1.2",
|
||||
"karma-notify-reporter": "^0.1.1",
|
||||
"grunt-wiredep": "^3.0.1",
|
||||
"jasmine-core": "^2.5.2",
|
||||
"jit-grunt": "^0.10.0",
|
||||
"karma": "^1.3.0",
|
||||
"karma-chrome-launcher": "^2.0.0",
|
||||
"karma-coverage": "^1.1.1",
|
||||
"karma-jasmine": "^1.0.2",
|
||||
"karma-ng-html2js-preprocessor": "^1.0.0",
|
||||
"karma-notify-reporter": "^1.0.1",
|
||||
"serve-static": "^1.13.1",
|
||||
"time-grunt": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue