Rewrites the entire player component.
Not finished ! This is still work in progress and fairly broken in this commit. The jquery jplayer is now wrapped in an angular directive. The queue is no longer being managed in rootScope but is a part of the player service. It can be accessed like before and emptied / filled. The player controller also uses the player service now.
This commit is contained in:
parent
e51961c167
commit
88b1e6a6e6
10 changed files with 132 additions and 63 deletions
|
@ -474,7 +474,7 @@
|
|||
//$scope.ping();
|
||||
if (globals.settings.SaveTrackPosition) {
|
||||
loadTrackPosition();
|
||||
player.startSaveTrackPosition();
|
||||
//FIXME: player.startSaveTrackPosition();
|
||||
}
|
||||
}
|
||||
/* End Startup */
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
-->
|
||||
</div>
|
||||
<!-- Player -->
|
||||
<jamstash-player ng-controller="PlayerController"></jamstash-player>
|
||||
<div ng-include src="'player/player.html'" ng-controller="PlayerController"></div>
|
||||
</div> <!-- End container -->
|
||||
<script>
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
|
|
|
@ -1,21 +1,79 @@
|
|||
angular.module('jamstash.player.directive', [])
|
||||
angular.module('jamstash.player.directive', ['jamstash.settings'])
|
||||
|
||||
.directive('jamstashPlayer', function(){
|
||||
'use strict';
|
||||
// Runs during compile
|
||||
return {
|
||||
name: 'jamstash.player',
|
||||
// priority: 1,
|
||||
// terminal: true,
|
||||
scope: true, // {} = isolate, true = child, false/undefined = no change
|
||||
// controller: function($scope, $element, $attrs, $transclude) {},
|
||||
// require: 'ngModel', // Array = multiple requires, ? = optional, ^ = check parent elements
|
||||
restrict: 'E',
|
||||
// template: '',
|
||||
templateUrl: 'player/player.html',
|
||||
replace: true,
|
||||
// transclude: true,
|
||||
// compile: function(tElement, tAttrs, function transclude(function(scope, cloneLinkingFn){ return function linking(scope, elm, attrs){}})),
|
||||
// link: function($scope, iElm, iAttrs, controller) {}
|
||||
};
|
||||
});
|
||||
.directive('jplayer', ['player', 'globals', function(playerService, globals) {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'EA',
|
||||
template: '<div></div>',
|
||||
link: function(scope, element, attrs) {
|
||||
|
||||
var $player = element.children('div'),
|
||||
cls = 'pause';
|
||||
console.log($player);
|
||||
var audioSolution = 'html,flash';
|
||||
if (globals.settings.ForceFlash) {
|
||||
audioSolution = 'flash,html';
|
||||
}
|
||||
|
||||
var updatePlayer = function() {
|
||||
$player.jPlayer({
|
||||
// Flash fallback for outdated browser not supporting HTML5 audio/video tags
|
||||
// http://jplayer.org/download/
|
||||
swfPath: 'bower_components/jplayer/jquery.jplayer/Jplayer.swf',
|
||||
wmode: 'window',
|
||||
solution: audioSolution,
|
||||
supplied: 'mp3',
|
||||
preload: 'auto',
|
||||
cssSelectorAncestor: '#player',
|
||||
cssSelector: {
|
||||
play: '.PlayTrack',
|
||||
pause: '.PauseTrack',
|
||||
seekBar: '#audiocontainer .scrubber',
|
||||
playBar: '#audiocontainer .progress',
|
||||
mute: '#action_Mute',
|
||||
unmute: '#action_UnMute',
|
||||
volumeMax: '#action_VolumeMax',
|
||||
currentTime: '#played',
|
||||
duration: '#duration'
|
||||
},
|
||||
ready: function() {
|
||||
$player
|
||||
.jPlayer('setMedia', {
|
||||
mp3: 'shot_2.mp3'
|
||||
});
|
||||
},
|
||||
play: function() {
|
||||
console.log('jplayer play');
|
||||
element.addClass(cls);
|
||||
},
|
||||
pause: function() {
|
||||
console.log('jplayer pause');
|
||||
element.removeClass(cls);
|
||||
},
|
||||
stop: function() {
|
||||
console.log('jplayer stop');
|
||||
element.removeClass(cls);
|
||||
},
|
||||
ended: function() {
|
||||
console.log('jplayer ended');
|
||||
element.removeClass(cls);
|
||||
}
|
||||
})
|
||||
.end()
|
||||
.unbind('click').click(function(e) {
|
||||
$player.jPlayer(element.hasClass(cls) ? 'stop' : 'play');
|
||||
});
|
||||
};
|
||||
|
||||
updatePlayer();
|
||||
|
||||
scope.$watch(function () {
|
||||
return playerService.playingSong;
|
||||
}, function (newVal) {
|
||||
console.log('playingSong changed !');
|
||||
$player.jPlayer('setMedia', {'mp3': newVal.url})
|
||||
.jPlayer('play');
|
||||
});
|
||||
} //end link
|
||||
};
|
||||
}]);
|
||||
|
|
|
@ -10,37 +10,42 @@ angular.module('jamstash.player.service', ['jamstash.settings'])
|
|||
|
||||
var player = {
|
||||
queue: [],
|
||||
currentlyPlayingIndex: -1,
|
||||
playingIndex: -1,
|
||||
playingSong: {},
|
||||
|
||||
play: function(song) {
|
||||
song.playing = true;
|
||||
console.log('play()');
|
||||
//song.playing = true;
|
||||
player.playingSong = song;
|
||||
console.log('player service - play()', song);
|
||||
},
|
||||
|
||||
load: function(song) {
|
||||
|
||||
console.log('player service - load()');
|
||||
},
|
||||
|
||||
restart: function() {
|
||||
console.log('restart()');
|
||||
console.log('player service - restart()');
|
||||
},
|
||||
|
||||
nextTrack: function() {
|
||||
if((player.currentlyPlayingIndex + 1) < player.queue.length) {
|
||||
var nextTrack = player.queue[player.currentlyPlayingIndex + 1];
|
||||
player.currentlyPlayingIndex++;
|
||||
console.log('player service - nextTrack()');
|
||||
if((player.playingIndex + 1) < player.queue.length) {
|
||||
var nextTrack = player.queue[player.playingIndex + 1];
|
||||
player.playingIndex++;
|
||||
player.play(nextTrack);
|
||||
}
|
||||
},
|
||||
|
||||
previousTrack: function() {
|
||||
if((player.currentlyPlayingIndex - 1) > 0) {
|
||||
var previousTrack = player.queue[player.currentlyPlayingIndex - 1];
|
||||
player.currentlyPlayingIndex--;
|
||||
console.log(('player service - previousTrack()'));
|
||||
if((player.playingIndex - 1) > 0) {
|
||||
var previousTrack = player.queue[player.playingIndex - 1];
|
||||
player.playingIndex--;
|
||||
player.play(previousTrack);
|
||||
} else if (player.queue.length > 0) {
|
||||
player.currentlyPlayingIndex = 0;
|
||||
player.play(player.queue[player.currentlyPlayingIndex]);
|
||||
player.playingIndex = 0;
|
||||
var firstTrack = player.queue[0];
|
||||
player.play(firstTrack);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -39,25 +39,25 @@ describe("Player service", function() {
|
|||
it("and no song is playing, it plays the first song", function() {
|
||||
player.nextTrack();
|
||||
|
||||
expect(player.currentlyPlayingIndex).toBe(0);
|
||||
expect(player.playingIndex).toBe(0);
|
||||
expect(player.play).toHaveBeenCalledWith(player.queue[0]);
|
||||
});
|
||||
|
||||
it("and the first song is playing, it plays the second song", function() {
|
||||
player.currentlyPlayingIndex = 0;
|
||||
player.playingIndex = 0;
|
||||
|
||||
player.nextTrack();
|
||||
|
||||
expect(player.currentlyPlayingIndex).toBe(1);
|
||||
expect(player.playingIndex).toBe(1);
|
||||
expect(player.play).toHaveBeenCalledWith(player.queue[1]);
|
||||
});
|
||||
|
||||
it("and the last song is playing, it does nothing", function() {
|
||||
player.currentlyPlayingIndex = 2;
|
||||
player.playingIndex = 2;
|
||||
|
||||
player.nextTrack();
|
||||
|
||||
expect(player.currentlyPlayingIndex).toBe(2);
|
||||
expect(player.playingIndex).toBe(2);
|
||||
expect(player.play).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@ -66,25 +66,25 @@ describe("Player service", function() {
|
|||
it("and no song is playing, it plays the first song", function() {
|
||||
player.previousTrack();
|
||||
|
||||
expect(player.currentlyPlayingIndex).toBe(0);
|
||||
expect(player.playingIndex).toBe(0);
|
||||
expect(player.play).toHaveBeenCalledWith(player.queue[0]);
|
||||
});
|
||||
|
||||
it("and the first song is playing, it restarts the first song", function() {
|
||||
player.currentlyPlayingIndex = 0;
|
||||
player.playingIndex = 0;
|
||||
|
||||
player.previousTrack();
|
||||
|
||||
expect(player.currentlyPlayingIndex).toBe(0);
|
||||
expect(player.playingIndex).toBe(0);
|
||||
expect(player.play).toHaveBeenCalledWith(player.queue[0]);
|
||||
});
|
||||
|
||||
it("and the last song is playing, it plays the second song", function() {
|
||||
player.currentlyPlayingIndex = 2;
|
||||
player.playingIndex = 2;
|
||||
|
||||
player.previousTrack();
|
||||
|
||||
expect(player.currentlyPlayingIndex).toBe(1);
|
||||
expect(player.playingIndex).toBe(1);
|
||||
expect(player.play).toHaveBeenCalledWith(player.queue[1]);
|
||||
});
|
||||
});
|
||||
|
@ -106,14 +106,17 @@ describe("Player service", function() {
|
|||
it("when I play it, the song is marked as playing", function() {
|
||||
player.play(song);
|
||||
|
||||
expect(player.playingSong).toBe(song);
|
||||
expect(song.playing).toBeTruthy();
|
||||
});
|
||||
|
||||
it("when I restart playback, the song is still marked as playing", function() {
|
||||
song.playing = true;
|
||||
player.playingSong = song;
|
||||
|
||||
player.restart();
|
||||
|
||||
expect(player.playingSong).toBe(song);
|
||||
expect(song.playing).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -122,20 +125,20 @@ describe("Player service", function() {
|
|||
|
||||
beforeEach(function() {
|
||||
player.queue = [];
|
||||
player.currentlyPlayingIndex = -1;
|
||||
player.playingIndex = -1;
|
||||
spyOn(player, "play").and.stub();
|
||||
});
|
||||
|
||||
it("when I call nextTrack, it does nothing", function() {
|
||||
player.nextTrack();
|
||||
expect(player.play).not.toHaveBeenCalled();
|
||||
expect(player.currentlyPlayingIndex).toBe(-1);
|
||||
expect(player.playingIndex).toBe(-1);
|
||||
});
|
||||
|
||||
it("when I call previousTrack, it does nothing", function() {
|
||||
player.previousTrack();
|
||||
expect(player.play).not.toHaveBeenCalled();
|
||||
expect(player.currentlyPlayingIndex).toBe(-1);
|
||||
expect(player.playingIndex).toBe(-1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
<a class="hover" id="PreviousTrack" title="Previous Track" ng-click="previousTrack()">
|
||||
<img src="images/first_alt_24x24.png" height="24" width="24" alt="Previous track" />
|
||||
</a>
|
||||
<a class="hover PlayTrack" title="Play/Pause" ng-click="defaultPlay()">
|
||||
<a class="hover PlayTrack" title="Play/Pause" ng-click="play()">
|
||||
<img src="images/play_alt_24x24.png" height="24" width="24" alt="Play" />
|
||||
</a>
|
||||
<a class="hover PauseTrack" title="Play/Pause" ng-click="defaultPlay()" style="display: none;">
|
||||
<a class="hover PauseTrack" title="Play/Pause" ng-click="play()" style="display: none;">
|
||||
<img src="images/pause_alt_24x24.png" height="24" width="24" alt="Pause" />
|
||||
</a>
|
||||
<a class="hover" id="NextTrack" title="Next Track" ng-click="nextTrack()">
|
||||
|
@ -35,7 +35,7 @@
|
|||
<!--<div class="jp-volume-bar"><div class="jp-volume-bar-value"></div></div><a href="" id="action_VolumeMax" class="volume" title="Max Volume"></a>-->
|
||||
</div>
|
||||
</div>
|
||||
<div id="playdeck_1"></div>
|
||||
<div id="playdeck_1" jplayer></div>
|
||||
<div id="playdeck_2"></div>
|
||||
<div id="submenu_CurrentPlaylist" class="submenu shadow" style="display: none;">
|
||||
<table id="CurrentPlaylistPreviewContainer" class="simplelist songlist">
|
||||
|
|
|
@ -8,6 +8,8 @@ angular.module('jamstash.player.controller', ['jamstash.player.service', 'jamsta
|
|||
.controller('PlayerController', ['$scope', 'player', function($scope, player){
|
||||
'use strict';
|
||||
|
||||
$scope.playingSong = player.playingSong;
|
||||
|
||||
$scope.previousTrack = function () {
|
||||
player.previousTrack();
|
||||
};
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
angular.module('jamstash.queue.controller', ['jamstash.player.service'])
|
||||
|
||||
.controller('QueueController', ['$scope', '$rootScope', 'globals', 'player',
|
||||
function ($scope, $rootScope, globals, player) {
|
||||
.controller('QueueController', ['$scope', 'globals', 'player',
|
||||
function ($scope, globals, player) {
|
||||
'use strict';
|
||||
$scope.settings = globals.settings;
|
||||
$scope.song = $rootScope.queue;
|
||||
$scope.song = player.queue;
|
||||
//angular.copy($rootScope.queue, $scope.song);
|
||||
$scope.itemType = 'pl';
|
||||
|
||||
|
|
|
@ -281,11 +281,12 @@ angular.module('jamstash.subsonic.controller', ['jamstash.subsonic.service', 'ja
|
|||
mappedSongs.push(map.mapSong(randomStarredSongs[i]));
|
||||
}
|
||||
if(action === 'play') {
|
||||
$rootScope.queue = [].concat(mappedSongs);
|
||||
player.queue = [].concat(mappedSongs);
|
||||
notifications.updateMessage(mappedSongs.length + ' Song(s) Added to Queue', true);
|
||||
player.play($rootScope.queue[0]);
|
||||
console.log('subjs', player.queue);
|
||||
player.play(player.queue[0]);
|
||||
} else if (action === 'add') {
|
||||
$rootScope.queue = $rootScope.queue.concat(mappedSongs);
|
||||
player.queue = player.queue.concat(mappedSongs);
|
||||
notifications.updateMessage(mappedSongs.length + ' Song(s) Added to Queue', true);
|
||||
} else if (action === 'display') {
|
||||
$scope.album = [];
|
||||
|
|
|
@ -24,7 +24,7 @@ describe("Subsonic controller", function() {
|
|||
});
|
||||
spyOn(notifications, 'updateMessage').and.stub();
|
||||
spyOn(player, 'play').and.stub();
|
||||
$rootScope.queue = [];
|
||||
player.queue = [];
|
||||
|
||||
$controller('SubsonicController', {
|
||||
$scope: scope,
|
||||
|
@ -64,14 +64,14 @@ describe("Subsonic controller", function() {
|
|||
$rootScope.$apply();
|
||||
|
||||
expect(subsonic.getRandomStarredSongs).toHaveBeenCalled();
|
||||
expect($rootScope.queue).toEqual([
|
||||
expect(player.queue).toEqual([
|
||||
{id: "2548"}, {id: "8986"}, {id: "2986"}
|
||||
]);
|
||||
expect(notifications.updateMessage).toHaveBeenCalledWith('3 Song(s) Added to Queue', true);
|
||||
});
|
||||
|
||||
it("when playing random starred songs, it plays the first selected song, empties the queue and fills it with the selected songs, and notifies the user", function() {
|
||||
$rootScope.queue = [{id: "7666"}];
|
||||
player.queue = [{id: "7666"}];
|
||||
|
||||
scope.getRandomStarredSongs('play');
|
||||
deferred.resolve(response);
|
||||
|
@ -79,7 +79,7 @@ describe("Subsonic controller", function() {
|
|||
|
||||
expect(subsonic.getRandomStarredSongs).toHaveBeenCalled();
|
||||
expect(player.play).toHaveBeenCalledWith({id: "2548"});
|
||||
expect($rootScope.queue).toEqual([
|
||||
expect(player.queue).toEqual([
|
||||
{id: "2548"}, {id: "8986"}, {id: "2986"}
|
||||
]);
|
||||
expect(notifications.updateMessage).toHaveBeenCalledWith('3 Song(s) Added to Queue', true);
|
||||
|
@ -88,7 +88,7 @@ describe("Subsonic controller", function() {
|
|||
});
|
||||
|
||||
it("given that I don't have any starred song in my library, when getting random starred songs, it notifies the user with an error message, does not play a song and does not touch the queue", function() {
|
||||
$rootScope.queue = [{id: "7666"}];
|
||||
player.queue = [{id: "7666"}];
|
||||
|
||||
scope.getRandomStarredSongs('whatever action');
|
||||
deferred.reject({reason: 'No starred songs found on the Subsonic server.'});
|
||||
|
@ -96,7 +96,7 @@ describe("Subsonic controller", function() {
|
|||
|
||||
expect(subsonic.getRandomStarredSongs).toHaveBeenCalled();
|
||||
expect(player.play).not.toHaveBeenCalled();
|
||||
expect($rootScope.queue).toEqual([{id: "7666"}]);
|
||||
expect(player.queue).toEqual([{id: "7666"}]);
|
||||
expect(notifications.updateMessage).toHaveBeenCalledWith('No starred songs found on the Subsonic server.', true);
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue