Moves drag & drop support from main-controller.js to queue.js

Adds a indexOfSong method to player-service. It is used in play, nextTrack and previousTrack so the player can adapt to changes to the queue order. Previously it wasn't taken into account and when we changed the order of the queue (through drag & drop or shuffle), the next song wasn't what we expected it to be.
This commit is contained in:
Hyzual 2015-01-12 22:08:28 +01:00
parent 09fb66f2fe
commit 8b3a12f052
6 changed files with 107 additions and 23 deletions

View file

@ -105,7 +105,6 @@ angular.module('JamStash')
$scope.$watchCollection(function () {
return player.queue;
}, function(newQueue) {
console.log('newQueue', newQueue);
if (newQueue !== undefined && newQueue.length > 0 && globals.settings.ShowQueue) {
$scope.showQueue();
}
@ -172,16 +171,6 @@ angular.module('JamStash')
}
};
$rootScope.showIndex = false;
$scope.dragStart = function (e, ui) {
ui.item.data('start', ui.item.index());
};
$scope.dragEnd = function (e, ui) {
var start = ui.item.data('start'),
end = ui.item.index();
player.queue.splice(end, 0,
player.queue.splice(start, 1)[0]);
$scope.$apply();
};
$(document).on( 'click', 'message', function() {
$(this).fadeOut(function () { $(this).remove(); });
return false;

View file

@ -17,16 +17,9 @@ angular.module('jamstash.player.service', ['jamstash.settings', 'angular-undersc
loadSong: false,
play: function(song) {
// Default value in case we don't find the song in the queue
player._playingIndex = -1;
// Find the song's index in the queue, if it's in there
for (var i = player.queue.length - 1; i >= 0; i--) {
if (angular.equals(song, player.queue[i])) {
player._playingIndex = i;
break;
}
}
var index = player.indexOfSong(song);
player._playingIndex = (index !== undefined) ? index : -1;
if(player._playingSong === song) {
// We call restart because the _playingSong hasn't changed and the directive won't
// play the song again
@ -67,6 +60,10 @@ angular.module('jamstash.player.service', ['jamstash.settings', 'angular-undersc
},
nextTrack: function() {
// Find the song's index in the queue, in case it changed (with a drag & drop)
var index = player.indexOfSong(player._playingSong);
player._playingIndex = (index !== undefined) ? index : -1;
if((player._playingIndex + 1) < player.queue.length) {
var nextTrack = player.queue[player._playingIndex + 1];
player._playingIndex++;
@ -75,6 +72,10 @@ angular.module('jamstash.player.service', ['jamstash.settings', 'angular-undersc
},
previousTrack: function() {
// Find the song's index in the queue, in case it changed (with a drag & drop)
var index = player.indexOfSong(player._playingSong);
player._playingIndex = (index !== undefined) ? index : -1;
if((player._playingIndex - 1) > 0) {
var previousTrack = player.queue[player._playingIndex - 1];
player._playingIndex--;
@ -121,6 +122,15 @@ angular.module('jamstash.player.service', ['jamstash.settings', 'angular-undersc
isLastSongPlaying: function() {
return ((player._playingIndex +1) === player.queue.length);
},
indexOfSong: function(song) {
for (var i = player.queue.length - 1; i >= 0; i--) {
if (angular.equals(song, player.queue[i])) {
return i;
}
}
return undefined;
}
};

View file

@ -18,7 +18,7 @@ describe("Player service -", function() {
});
});
describe("Given that I have 3 songs in my playing queue", function() {
describe("Given that I have 3 songs in my playing queue,", function() {
beforeEach(function() {
firstSong = {
@ -62,6 +62,7 @@ describe("Player service -", function() {
it("and the first song is playing, it plays the second song", function() {
player._playingIndex = 0;
player._playingSong = firstSong;
player.nextTrack();
@ -71,6 +72,7 @@ describe("Player service -", function() {
it("and the last song is playing, it does nothing", function() {
player._playingIndex = 2;
player._playingSong = thirdSong;
player.nextTrack();
@ -93,6 +95,7 @@ describe("Player service -", function() {
it("and the first song is playing, it restarts the first song", function() {
player._playingIndex = 0;
player._playingSong = firstSong;
player.previousTrack();
@ -102,6 +105,7 @@ describe("Player service -", function() {
it("and the last song is playing, it plays the second song", function() {
player._playingIndex = 2;
player._playingSong = thirdSong;
player.previousTrack();
@ -134,6 +138,14 @@ describe("Player service -", function() {
expect(player.queue).toEqual([]);
});
it("when I get the index of the first song, it returns 0", function() {
expect(player.indexOfSong(firstSong)).toBe(0);
});
it("when I get the index of a song that isn't in the playing queue, it returns undefined", function() {
expect(player.indexOfSong(newSong)).toBeUndefined();
});
it("when I add a song to the queue, it is appended to the end of the playing queue", function() {
player.addSong(newSong);
expect(player.queue).toEqual([firstSong, secondSong, thirdSong, newSong]);

View file

@ -51,5 +51,18 @@ angular.module('jamstash.queue.controller', ['jamstash.player.service'])
}
});
/**
* Change the queue's order through jQuery UI's sortable
*/
$scope.dragStart = function (e, ui) {
ui.item.data('start', ui.item.index());
};
$scope.dragEnd = function (e, ui) {
var start = ui.item.data('start'),
end = ui.item.index();
player.queue.splice(end, 0, player.queue.splice(start, 1)[0]);
};
//TODO: Hyz: updateFavorite - leave in rootScope ?
}]);

View file

@ -18,6 +18,7 @@ describe("Queue controller", function() {
});
});
song = { id: 7310 };
player.queue = [];
});
it("When I play a song, it calls play in the player service", function() {
@ -77,4 +78,57 @@ describe("Queue controller", function() {
expect($.fn.scrollTo).toHaveBeenCalled();
});
describe("reorders the queue by drag and drop - ", function() {
var mockUI;
beforeEach(function() {
player.queue = [
{id: 2246},
{id: 8869},
{id: 285}
];
mockUI = {
item: {}
};
});
it("given a song in the queue, when I start dragging it, it records what its starting position in the queue was", function() {
mockUI.item.index = jasmine.createSpy("index").and.returnValue('1');
mockUI.item.data = jasmine.createSpy("data");
scope.dragStart({}, mockUI);
expect(mockUI.item.index).toHaveBeenCalled();
expect(mockUI.item.data).toHaveBeenCalledWith('start', '1');
});
it("given a song in the queue that I started dragging, when I drop it, its position in the queue has changed", function() {
mockUI.item.index = jasmine.createSpy("index").and.returnValue('0');
mockUI.item.data = jasmine.createSpy("data").and.returnValue('1');
scope.dragEnd({}, mockUI);
expect(mockUI.item.index).toHaveBeenCalled();
expect(mockUI.item.data).toHaveBeenCalledWith('start');
// The second song should now be first
expect(player.queue).toEqual([
{id: 8869},
{id: 2246},
{id: 285}
]);
});
// TODO: Hyz: Maybe it should be an end-to-end test
it("given that the player is playing the second song (B), when I swap the first (A) and the second song (B), the player's next song should be A", function() {
player.play({id: 8869});
mockUI.item.index = jasmine.createSpy("index").and.returnValue('0');
mockUI.item.data = jasmine.createSpy("data").and.returnValue('1');
scope.dragEnd({}, mockUI);
player.nextTrack();
expect(player._playingIndex).toBe(1);
expect(player._playingSong).toEqual({id: 2246});
});
});
});

View file

@ -188,7 +188,11 @@ describe("Subsonic controller", function() {
describe("reorders playlists by drag and drop - ", function() {
var mockUI;
beforeEach(function() {
scope.song = [{id: "1084"}, {id: "6810"}, {id: "214"}];
scope.song = [
{id: 1084},
{id: 6810},
{id: 214}
];
mockUI = {
item: {}
};
@ -214,7 +218,9 @@ describe("Subsonic controller", function() {
expect(mockUI.item.data).toHaveBeenCalledWith('start');
// The second song should now be first
expect(scope.song).toEqual([
{id: "6810"}, {id: "1084"}, {id: "214"}
{id: 6810},
{id: 1084},
{id: 214}
]);
});
});