Further refactoring of the queue controller and view
- Removes queue-related functions from the main controller. They are now handled by queue.js, which delegates them to player-service.js - Fixes problem in scrobbling. A song is no longer scrobbled every time it is paused. A song will not be scrobbled upon loading, only while it is playing. - Moves the entire html for the sidebar queue to queue.html. It replaces a template that was no longer used. - Most queue-related functions in player return player itself to make them chainable just like in jQuery, e.g. : player.shuffleQueue().playFirstSong();
This commit is contained in:
parent
83869b7808
commit
c787c468b9
12 changed files with 85 additions and 89 deletions
|
@ -304,18 +304,11 @@ angular.module('JamStash')
|
|||
notifications.updateMessage($scope.selectedSongs.length + ' Song(s) Added to Queue', true);
|
||||
$scope.selectedSongs.length = 0;
|
||||
}
|
||||
};
|
||||
$scope.addSongToQueue = function (data) {
|
||||
$rootScope.queue.push(data);
|
||||
};
|
||||
$rootScope.removeSong = function (item, songs) {
|
||||
var index = songs.indexOf(item);
|
||||
songs.splice(index, 1);
|
||||
};
|
||||
$scope.removeSongFromQueue = function (item) {
|
||||
var index = $rootScope.queue.indexOf(item)
|
||||
$rootScope.queue.splice(index, 1);
|
||||
};
|
||||
$scope.isActive = function (route) {
|
||||
return route === $location.path();
|
||||
};
|
||||
|
@ -344,20 +337,6 @@ angular.module('JamStash')
|
|||
}
|
||||
});
|
||||
};
|
||||
$scope.queueRemoveSelected = function (data, event) {
|
||||
angular.forEach($scope.selectedSongs, function (item, key) {
|
||||
var index = $rootScope.queue.indexOf(item);
|
||||
if (index > -1) {
|
||||
$rootScope.queue.splice(index, 1);
|
||||
}
|
||||
});
|
||||
};
|
||||
$scope.queueEmpty = function () {
|
||||
//TODO: Hyz: Remove
|
||||
//self.selectedSongs([]);
|
||||
$rootScope.queue = [];
|
||||
$.fancybox.close();
|
||||
};
|
||||
$scope.queueTotal = function () {
|
||||
var total = 0;
|
||||
utils.arrayForEach(self.queue(), function (item) {
|
||||
|
@ -369,10 +348,6 @@ angular.module('JamStash')
|
|||
return '0 song(s), 00:00:00 total time';
|
||||
}
|
||||
};
|
||||
$scope.queueShuffle = function () {
|
||||
//TODO: Hyz: Remove
|
||||
$rootScope.queue.sort(function () { return 0.5 - Math.random(); });
|
||||
};
|
||||
$scope.selectedSongs = [];
|
||||
$scope.selectSong = function (data) {
|
||||
var i = $scope.selectedSongs.indexOf(data);
|
||||
|
@ -412,11 +387,6 @@ angular.module('JamStash')
|
|||
}
|
||||
});
|
||||
};
|
||||
// Hyz: I don't know yet how to remove the circular dependency between player-service
|
||||
// and notification-service... So I'll keep this one there until I know.
|
||||
$rootScope.nextTrack = function (loadonly, song) {
|
||||
player.nextTrack(loadonly, song);
|
||||
};
|
||||
|
||||
$scope.updateFavorite = function (item) {
|
||||
var id = item.id;
|
||||
|
|
|
@ -66,7 +66,6 @@ describe("Main controller", function() {
|
|||
spyOn(locker, "get").and.callFake(function(key) {
|
||||
return fakeStorage[key];
|
||||
});
|
||||
spyOn(utils, "browserStorageCheck").and.returnValue(true);
|
||||
});
|
||||
|
||||
describe("loadTrackPosition -", function() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<li class="row song" ng-repeat="o in song" ng-click="selectSong(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="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="Start Playing From This Song" ng-click="playFrom($index)" stop-event="click"></a>-->
|
||||
<!--<a class="download" href="" title="Download Song" ng-click="download(o.id)"></a>-->
|
||||
|
|
|
@ -100,14 +100,6 @@ angular.module('jamstash.utils', ['jamstash.settings'])
|
|||
break;
|
||||
}
|
||||
};
|
||||
// HTML5
|
||||
this.browserStorageCheck = function () {
|
||||
if (typeof (localStorage) === 'undefined') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
this.timeToSeconds = function (time) {
|
||||
var a = time.split(':'); // split it at the colons
|
||||
var seconds;
|
||||
|
|
|
@ -48,19 +48,7 @@
|
|||
|
||||
<div class="clear"></div>
|
||||
</div><!-- end #content -->
|
||||
<div id="SideBar" ng-controller="QueueController">
|
||||
<div class="headeractions">
|
||||
<a class="buttonimg" title="Shuffle Queue" ng-click="queueShuffle()"><img src="images/fork_gd_11x12.png"></a>
|
||||
<a class="buttonimg" id="action_Empty" title="Delete Queue" ng-click="queueEmpty()"><img src="images/trash_fill_gd_12x12.png"></a>
|
||||
<a class="buttonimg" id="action_DeleteSelected" title="Remove Selected From Queue" ng-click="queueRemoveSelected()"><img src="images/x_11x11.png"></a>
|
||||
</div>
|
||||
<div class="header">Queue</div>
|
||||
<div id="SideQueue">
|
||||
<ul class="simplelist songlist noselect">
|
||||
<div ng-repeat="song in [player.queue] track by $index" class="songs" ng-include src="'common/songs_lite.html'" sortable></div>
|
||||
</ul>
|
||||
<div class="colspacer"></div>
|
||||
</div>
|
||||
<div id="SideBar" ng-include src="'queue/queue.html'" ng-controller="QueueController">
|
||||
<!--
|
||||
<div id="NowPlaying">
|
||||
<div class="header"><img src="images/rss_12x12.png" /> Now Playing</div>
|
||||
|
|
|
@ -42,9 +42,11 @@ angular.module('jamstash.player.directive', ['jamstash.player.service', 'jamstas
|
|||
currentTime: '#played',
|
||||
duration: '#duration'
|
||||
},
|
||||
setmedia: function() {
|
||||
scope.scrobbled = false;
|
||||
},
|
||||
play: function() {
|
||||
scope.revealControls();
|
||||
scope.scrobbled = false;
|
||||
},
|
||||
ended: function() {
|
||||
// We do this here and not on the service because we cannot create
|
||||
|
@ -60,7 +62,8 @@ angular.module('jamstash.player.directive', ['jamstash.player.service', 'jamstas
|
|||
timeupdate: function (event) {
|
||||
// Scrobble song once percentage is reached
|
||||
var p = event.jPlayer.status.currentPercentAbsolute;
|
||||
if (!scope.scrobbled && p > 30) {
|
||||
var isPlaying = !event.jPlayer.status.paused;
|
||||
if (!scope.scrobbled && p > 30 && isPlaying) {
|
||||
if (globals.settings.Debug) { console.log('LAST.FM SCROBBLE - Percent Played: ' + p); }
|
||||
subsonic.scrobble(scope.currentSong);
|
||||
scope.scrobbled = true;
|
||||
|
@ -131,6 +134,7 @@ angular.module('jamstash.player.directive', ['jamstash.player.service', 'jamstas
|
|||
.fadeTo("slow", 1).delay(500)
|
||||
.fadeTo("slow", 0).delay(500)
|
||||
.fadeTo("slow", 1);
|
||||
//TODO: Hyz: Pass position and queue as parameter and move this away in another service
|
||||
scope.saveTrackPosition();
|
||||
scope.saveQueue();
|
||||
}
|
||||
|
|
|
@ -134,10 +134,10 @@ describe("jplayer directive", function() {
|
|||
expect(scope.revealControls).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("When jPlayer starts to play the current song, it resets the scrobbled flag to false", function() {
|
||||
it("When jPlayer gets new media, it resets the scrobbled flag to false", function() {
|
||||
scope.scrobbled = true;
|
||||
|
||||
var e = $.jPlayer.event.play;
|
||||
var e = $.jPlayer.event.setmedia;
|
||||
$player.trigger(e);
|
||||
|
||||
expect(scope.scrobbled).toBeFalsy();
|
||||
|
|
|
@ -80,19 +80,33 @@ angular.module('jamstash.player.service', ['jamstash.settings', 'angular-undersc
|
|||
|
||||
emptyQueue: function() {
|
||||
player.queue = [];
|
||||
return player;
|
||||
},
|
||||
|
||||
shuffleQueue: function() {
|
||||
player.queue = _.shuffle(player.queue);
|
||||
player.queue = _(player.queue).shuffle();
|
||||
return player;
|
||||
},
|
||||
|
||||
addSong: function(song) {
|
||||
player.queue.push(song);
|
||||
return player;
|
||||
},
|
||||
|
||||
addSongs: function (songs) {
|
||||
player.queue = player.queue.concat(songs);
|
||||
return player;
|
||||
},
|
||||
|
||||
removeSong: function(song) {
|
||||
var index = player.queue.indexOf(song);
|
||||
player.queue.splice(index, 1);
|
||||
return player;
|
||||
},
|
||||
|
||||
removeSongs: function (songs) {
|
||||
player.queue = _(player.queue).difference(songs);
|
||||
return player;
|
||||
},
|
||||
|
||||
getPlayingSong: function() {
|
||||
|
|
|
@ -139,11 +139,23 @@ describe("Player service -", function() {
|
|||
expect(player.queue).toEqual([firstSong, secondSong, thirdSong, newSong]);
|
||||
});
|
||||
|
||||
it("when I add 3 songs to the queue, they are appended to the end of the playing queue", function() {
|
||||
var secondNewSong = {id: 6338, name: 'Preconquest', artist: 'France Wisley', album: 'Unmix'};
|
||||
var thirdNewSong = {id: 3696, name: 'Cetene', artist: 'Hilario Masley', album: 'Gonapophysal'};
|
||||
player.addSongs([newSong, secondNewSong, thirdNewSong]);
|
||||
expect(player.queue).toEqual([firstSong, secondSong, thirdSong, newSong, secondNewSong, thirdNewSong]);
|
||||
});
|
||||
|
||||
it("when I remove the second song, the playing queue is now only the first and third song", function() {
|
||||
player.removeSong(secondSong);
|
||||
expect(player.queue).toEqual([firstSong, thirdSong]);
|
||||
});
|
||||
|
||||
it("when I remove the first and third songs, the playing queue is now only the second song", function() {
|
||||
player.removeSongs([firstSong, thirdSong]);
|
||||
expect(player.queue).toEqual([secondSong]);
|
||||
});
|
||||
|
||||
it("when the first song is playing, isLastSongPlaying returns false", function() {
|
||||
player.playingIndex = 0;
|
||||
expect(player.isLastSongPlaying()).toBeFalsy();
|
||||
|
|
|
@ -1,5 +1,24 @@
|
|||
<div id="queue" class="tabcontent">
|
||||
<div class="section fullsection floatleft">
|
||||
<ul class="songlist simplelist noselect" ng-if="song.length > 0" ng-include src="'common/songs.html'" sortable></ul>
|
||||
<div class="headeractions">
|
||||
<a class="buttonimg" title="Shuffle Queue" ng-click="shuffleQueue()"><img src="images/fork_gd_11x12.png"></a>
|
||||
<a class="buttonimg" title="Delete Queue" ng-click="emptyQueue()"><img src="images/trash_fill_gd_12x12.png"></a>
|
||||
<a class="buttonimg" title="Remove Selected From Queue" ng-click="removeSelectedSongsFromQueue()"><img src="images/x_11x11.png"></a>
|
||||
</div>
|
||||
<div class="header">Queue</div>
|
||||
<div id="SideQueue">
|
||||
<ul class="simplelist songlist noselect">
|
||||
<div ng-repeat="song in [player.queue] track by $index" class="songs" sortable>
|
||||
<li class="row song" ng-repeat="o in song" ng-click="selectSong(o)" ng-dblclick="playSong(o)" ng-class="{'selected': o.selected, 'playing': o.playing}">
|
||||
<div class="itemactions">
|
||||
<a class="remove" href="" title="Remove Song" ng-click="removeSongFromQueue(o)" stop-event="click"></a>
|
||||
<a href="" title="Favorite" ng-class="{'favorite': o.starred, 'rate': !o.starred}" ng-click="updateFavorite(o)" stop-event="click"></a>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="title floatleft" title="{{o.description}}" ng-bind-html="o.name"></div>
|
||||
<div class="time floatleft">{{o.time}}</div>
|
||||
<div class="clear"></div>
|
||||
</li>
|
||||
|
||||
</div>
|
||||
</ul>
|
||||
<div class="colspacer"></div>
|
||||
</div>
|
|
@ -11,11 +11,13 @@ angular.module('jamstash.queue.controller', ['jamstash.player.service'])
|
|||
player.play(song);
|
||||
};
|
||||
|
||||
$scope.queueEmpty = function() {
|
||||
$scope.emptyQueue = function() {
|
||||
player.emptyQueue();
|
||||
//TODO: Hyz: Shouldn't it be in a directive ?
|
||||
$.fancybox.close();
|
||||
};
|
||||
|
||||
$scope.queueShuffle = function() {
|
||||
$scope.shuffleQueue = function() {
|
||||
player.shuffleQueue();
|
||||
};
|
||||
|
||||
|
@ -26,4 +28,8 @@ angular.module('jamstash.queue.controller', ['jamstash.player.service'])
|
|||
$scope.removeSongFromQueue = function(song) {
|
||||
player.removeSong(song);
|
||||
};
|
||||
|
||||
$scope.removeSelectedSongsFromQueue = function () {
|
||||
player.removeSongs($scope.selectedSongs);
|
||||
};
|
||||
}]);
|
||||
|
|
|
@ -22,49 +22,41 @@ describe("Queue controller", function() {
|
|||
});
|
||||
});
|
||||
|
||||
it("When I call playSong, it calls play in the player service", function() {
|
||||
it("When I play a song, it calls play in the player service", function() {
|
||||
spyOn(player, "play");
|
||||
var songIndexInQueue = 3;
|
||||
|
||||
scope.playSong(songIndexInQueue);
|
||||
|
||||
expect(player.play).toHaveBeenCalledWith(songIndexInQueue);
|
||||
scope.playSong(song);
|
||||
expect(player.play).toHaveBeenCalledWith(song);
|
||||
});
|
||||
|
||||
it("When I call queueEmpty, it calls emptyQueue in the player service", function() {
|
||||
it("When I empty the queue, it calls emptyQueue in the player service", function() {
|
||||
spyOn(player, "emptyQueue");
|
||||
|
||||
scope.queueEmpty();
|
||||
|
||||
scope.emptyQueue();
|
||||
expect(player.emptyQueue).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("When I call queueShuffle, it calls shuffleQueue in the player service", function() {
|
||||
it("When I shuffle the queue, it calls shuffleQueue in the player service", function() {
|
||||
spyOn(player, "shuffleQueue");
|
||||
|
||||
scope.queueShuffle();
|
||||
|
||||
scope.shuffleQueue();
|
||||
expect(player.shuffleQueue).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("When I add one song to the queue, it calls addSong in the player service", function() {
|
||||
spyOn(player, "addSong");
|
||||
|
||||
|
||||
scope.addSongToQueue(song);
|
||||
|
||||
expect(player.addSong).toHaveBeenCalledWith(song);
|
||||
});
|
||||
|
||||
xit("When I add many songs to the queue, it calls addSong in the player service", function() {
|
||||
spyOn(player, "addSong");
|
||||
});
|
||||
|
||||
it("When I remove a song from the queue, it calls removeSong in the player service", function() {
|
||||
spyOn(player, "removeSong");
|
||||
|
||||
scope.removeSongFromQueue(song);
|
||||
|
||||
expect(player.removeSong).toHaveBeenCalledWith(song);
|
||||
});
|
||||
|
||||
it("When I remove all the selected songs from the queue, it calls removeSongs in the player service", function() {
|
||||
spyOn(player, "removeSongs");
|
||||
var secondSong = { id: 6791 };
|
||||
scope.selectedSongs = [song, secondSong];
|
||||
scope.removeSelectedSongsFromQueue();
|
||||
expect(player.removeSongs).toHaveBeenCalledWith([song, secondSong]);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue