Refactor breadcrumbs into a directive.
We can now display as many levels of breadcrumbs as needed, meaning we support folders deeper than 2 levels.
This commit is contained in:
parent
91dbb868ed
commit
b4ab303cb5
12 changed files with 452 additions and 80 deletions
|
@ -21,6 +21,7 @@
|
|||
<!-- build:css(app) styles/concat.min.css -->
|
||||
<link rel="stylesheet" href="player/player.css" />
|
||||
<link rel="stylesheet" href="player/repeat-directive/repeat-directive.css" />
|
||||
<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)'}">
|
||||
|
@ -111,6 +112,8 @@
|
|||
<script src="common/main-controller.js"></script>
|
||||
<script src="subsonic/subsonic.js"></script>
|
||||
<script src="subsonic/subsonic-service.js"></script>
|
||||
<script src="subsonic/breadcrumbs-directive/breadcrumbs-service.js"></script>
|
||||
<script src="subsonic/breadcrumbs-directive/breadcrumbs-directive.js"></script>
|
||||
<script src="archive/archive.js"></script>
|
||||
<script src="archive/archive-service.js"></script>
|
||||
<script src="player/player.js"></script>
|
||||
|
|
|
@ -621,39 +621,6 @@ ul.tablist li a:hover
|
|||
{
|
||||
color: #bbb;
|
||||
}
|
||||
#BreadCrumb
|
||||
{
|
||||
float: left;
|
||||
margin: 16px 0 0 0;
|
||||
padding: 2px 0;
|
||||
color: #AEAEA7;
|
||||
border-radius: .4em;
|
||||
}
|
||||
#BreadCrumb img
|
||||
{
|
||||
padding: 2px 0px 2px 0;
|
||||
float: left;
|
||||
}
|
||||
#BreadCrumbs span
|
||||
{
|
||||
margin: 0 2px 0 6px;
|
||||
}
|
||||
#BreadCrumbs a
|
||||
{
|
||||
margin: 0 2px 0 6px;
|
||||
text-decoration: none;
|
||||
color: #829FC0;
|
||||
font-size: 14px;
|
||||
}
|
||||
#BreadCrumbs a:hover
|
||||
{
|
||||
text-decoration: underline;
|
||||
}
|
||||
#BreadCrumbs .crumb
|
||||
{
|
||||
float: left;
|
||||
}
|
||||
|
||||
#TrackContainer
|
||||
{
|
||||
margin: 5px 5px 5px 0;
|
||||
|
|
24
app/subsonic/breadcrumbs-directive/breadcrumbs-directive.css
Normal file
24
app/subsonic/breadcrumbs-directive/breadcrumbs-directive.css
Normal file
|
@ -0,0 +1,24 @@
|
|||
.breadcrumbs {
|
||||
float: left;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.breadcrumb a {
|
||||
margin: 0 2px 0 6px;
|
||||
text-decoration: none;
|
||||
color: #829FC0;
|
||||
font-size: 14px;
|
||||
;
|
||||
}
|
||||
|
||||
.breadcrumb:not(:last-child)::after {
|
||||
content: " >";
|
||||
}
|
||||
|
||||
.breadcrumb a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<div class="breadcrumbs">
|
||||
<div class="breadcrumb">
|
||||
<a ng-click="toggleArtists()" title="Toggle Artists">Artists</a>
|
||||
</div>
|
||||
<div class="breadcrumb" ng-repeat="item in vm.getBreadcrumbs()">
|
||||
<a ng-click="vm.displaySongs(item)">{{item.name}}</a>
|
||||
</div>
|
||||
</div>
|
61
app/subsonic/breadcrumbs-directive/breadcrumbs-directive.js
Normal file
61
app/subsonic/breadcrumbs-directive/breadcrumbs-directive.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* jamstash.breadcrumbs.directive Module
|
||||
*
|
||||
* Displays the breadcrumbs, a list of directory names. Can be a genre name, an artist name, an album name,
|
||||
* or whatever really, dependending on the user's library layout.
|
||||
*/
|
||||
angular.module('jamstash.breadcrumbs.directive', [
|
||||
'ngLodash',
|
||||
'jamstash.breadcrumbs.service'
|
||||
])
|
||||
|
||||
.directive('jamstashBreadcrumbs', [
|
||||
'lodash',
|
||||
'breadcrumbs',
|
||||
'subsonic',
|
||||
'notifications',
|
||||
function (
|
||||
_,
|
||||
breadcrumbs,
|
||||
subsonic,
|
||||
notifications
|
||||
) {
|
||||
'use strict';
|
||||
var directive = {
|
||||
controller: breadcrumbsController,
|
||||
controllerAs: 'vm',
|
||||
restrict: 'E',
|
||||
templateUrl: 'subsonic/breadcrumbs-directive/breadcrumbs-directive.html',
|
||||
replace: true
|
||||
};
|
||||
|
||||
breadcrumbsController.$inject = ['$scope'];
|
||||
function breadcrumbsController($scope) {
|
||||
var self = this;
|
||||
|
||||
_.extend(self, {
|
||||
getBreadcrumbs: breadcrumbs.get,
|
||||
displaySongs: function (item) {
|
||||
var promise = subsonic.getSongs(item.id);
|
||||
$scope.handleErrors(promise).then(function (data) {
|
||||
$scope.album = data.directories;
|
||||
$scope.song = data.songs;
|
||||
breadcrumbs.popUntil(item);
|
||||
$scope.selectedAutoAlbum = null;
|
||||
$scope.selectedArtist = null;
|
||||
$scope.selectedAlbum = item.id;
|
||||
$scope.selectedAutoPlaylist = null;
|
||||
$scope.selectedPlaylist = null;
|
||||
$scope.selectedPodcast = null;
|
||||
if ($scope.SelectedAlbumSort.id !== "default") {
|
||||
$scope.sortSubsonicAlbums($scope.SelectedAlbumSort.id);
|
||||
}
|
||||
}, function (error) {
|
||||
notifications.updateMessage(error.reason, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return directive;
|
||||
}]);
|
|
@ -0,0 +1,80 @@
|
|||
describe("breadcrumbs directive", function() {
|
||||
'use strict';
|
||||
|
||||
var $q, deferred, element, scope, controller, subsonic, notifications, breadcrumbs;
|
||||
|
||||
beforeEach(module ('templates'));
|
||||
beforeEach(function() {
|
||||
module('jamstash.breadcrumbs.directive', function($provide) {
|
||||
subsonic = jasmine.createSpyObj("subsonic", ["getSongs"]);
|
||||
$provide.value('subsonic', subsonic);
|
||||
notifications = jasmine.createSpyObj("notifications", ["updateMessage"]);
|
||||
$provide.value('notifications', notifications);
|
||||
breadcrumbs = jasmine.createSpyObj("breadcrumbs", ["popUntil"]);
|
||||
$provide.value('breadcrumbs', breadcrumbs);
|
||||
});
|
||||
|
||||
inject(function ($rootScope, $compile, _$q_) {
|
||||
$q = _$q_;
|
||||
deferred = $q.defer();
|
||||
// Compile the directive
|
||||
scope = $rootScope.$new();
|
||||
element = '<jamstash-breadcrumbs></jamstash-breadcrumbs>';
|
||||
element = $compile(element)(scope);
|
||||
scope.$digest();
|
||||
controller = element.controller('jamstashBreadcrumbs');
|
||||
});
|
||||
|
||||
subsonic.getSongs.and.returnValue(deferred.promise);
|
||||
scope.handleErrors = jasmine.createSpy("handleErrors").and.returnValue(deferred.promise);
|
||||
scope.SelectedAlbumSort = {
|
||||
id: "default"
|
||||
};
|
||||
});
|
||||
|
||||
it("Given a music directory that contained 2 songs and 1 subdirectory and given its id and name, when I display its songs, then subsonic service will be called, the breadcrumbs will be popped until they only display the directory and the songs and directory will be published to the scope", function() {
|
||||
controller.displaySongs({
|
||||
id: 680,
|
||||
name: "henchman unstormy"
|
||||
});
|
||||
deferred.resolve({
|
||||
directories: [{ id: 569, type: 'byfolder' }],
|
||||
songs: [
|
||||
{ id: 549 },
|
||||
{ id: 390 }
|
||||
]
|
||||
});
|
||||
scope.$apply();
|
||||
|
||||
expect(subsonic.getSongs).toHaveBeenCalledWith(680);
|
||||
expect(scope.album).toEqual([
|
||||
{ id: 569, type: 'byfolder' }
|
||||
]);
|
||||
expect(scope.song).toEqual([
|
||||
{ id: 549 },
|
||||
{ id: 390 }
|
||||
]);
|
||||
expect(breadcrumbs.popUntil).toHaveBeenCalledWith({
|
||||
id: 680,
|
||||
name: "henchman unstormy"
|
||||
});
|
||||
});
|
||||
|
||||
it("Given a music directory, when I display it, then handleErrors will handle HTTP and Subsonic errors", function() {
|
||||
controller.displaySongs({
|
||||
id: 628
|
||||
});
|
||||
expect(scope.handleErrors).toHaveBeenCalledWith(deferred.promise);
|
||||
});
|
||||
|
||||
it("Given a music directory that didn't contain anything, when I display it, then an error notification will be displayed", function() {
|
||||
controller.displaySongs({
|
||||
id: 242,
|
||||
name: "discinoid"
|
||||
});
|
||||
deferred.reject({reason: 'This directory is empty.'});
|
||||
scope.$apply();
|
||||
|
||||
expect(notifications.updateMessage).toHaveBeenCalledWith('This directory is empty.', true);
|
||||
});
|
||||
});
|
49
app/subsonic/breadcrumbs-directive/breadcrumbs-service.js
Normal file
49
app/subsonic/breadcrumbs-directive/breadcrumbs-service.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* jamstash.breadcrumbs.service Module
|
||||
*
|
||||
* Provides operations to read the Breadcrumbs' state and add or remove
|
||||
* items to the list.
|
||||
*/
|
||||
angular.module('jamstash.breadcrumbs.service', ['ngLodash'])
|
||||
|
||||
.factory('breadcrumbs', ['lodash', function (_) {
|
||||
'use strict';
|
||||
|
||||
var list = [];
|
||||
|
||||
var service = {
|
||||
get: function () {
|
||||
return list;
|
||||
},
|
||||
push: function (item) {
|
||||
var breadcrumb = {
|
||||
id: item.id,
|
||||
name: item.name
|
||||
};
|
||||
list.push(breadcrumb);
|
||||
return service;
|
||||
},
|
||||
popUntil: function (item) {
|
||||
var found = _.find(list, function (crumb) {
|
||||
return equalBreadcrumb(crumb, item);
|
||||
});
|
||||
if (! found) {
|
||||
return service;
|
||||
}
|
||||
list = _.dropRightWhile(list, function (crumb) {
|
||||
return !(equalBreadcrumb(crumb, item));
|
||||
});
|
||||
return service;
|
||||
},
|
||||
reset: function () {
|
||||
list = [];
|
||||
return service;
|
||||
}
|
||||
};
|
||||
|
||||
function equalBreadcrumb(first, second) {
|
||||
return first.id === second.id && first.name === second.name;
|
||||
}
|
||||
|
||||
return service;
|
||||
}]);
|
165
app/subsonic/breadcrumbs-directive/breadcrumbs-service_test.js
Normal file
165
app/subsonic/breadcrumbs-directive/breadcrumbs-service_test.js
Normal file
|
@ -0,0 +1,165 @@
|
|||
describe("Breadcrumbs service -", function() {
|
||||
'use strict';
|
||||
|
||||
var breadcrumbs;
|
||||
beforeEach(function() {
|
||||
module('jamstash.breadcrumbs.service');
|
||||
|
||||
inject(function(_breadcrumbs_) {
|
||||
breadcrumbs = _breadcrumbs_;
|
||||
});
|
||||
});
|
||||
|
||||
describe("push() -", function() {
|
||||
it("Given an item with an id and a name and given the breadcrumbs were empty, when I push it to the breadcrumbs and I get them, then an array of 1 item containing an id and name will be returned", function() {
|
||||
breadcrumbs.push({
|
||||
id: 240,
|
||||
name: "Renee Stuekerjuerge"
|
||||
});
|
||||
|
||||
expect(breadcrumbs.get()).toEqual([
|
||||
{
|
||||
id: 240,
|
||||
name: "Renee Stuekerjuerge"
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("Given an item with an id and a name and given the breadcrumbs already contained another item, when I push the item to the breadcrumbs and I get them, then an array of 2 items will be returned and the item I pushed will be the second one", function() {
|
||||
breadcrumbs.push({
|
||||
id: 150,
|
||||
name: "Collen Kampmann"
|
||||
}).push({
|
||||
id: 201,
|
||||
name: "Leonardo Berdan"
|
||||
});
|
||||
|
||||
expect(breadcrumbs.get()).toEqual([
|
||||
{
|
||||
id: 150,
|
||||
name: "Collen Kampmann"
|
||||
}, {
|
||||
id: 201,
|
||||
name: "Leonardo Berdan"
|
||||
}
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("popUntil() -", function() {
|
||||
it("Given an item with an id and a name, and given the breadcrumbs already contained this item as first element and 2 others, when I pop breadcrumbs until finding the provided item, then an array containing only the provided item will be returned", function() {
|
||||
breadcrumbs.push({
|
||||
id: 979,
|
||||
name: "telescopic Sivatheriinae"
|
||||
}).push({
|
||||
id: 542,
|
||||
name: "fibrinoalbuminous pawnee"
|
||||
}).push({
|
||||
id: 163,
|
||||
name: "semimarking polysarcia"
|
||||
});
|
||||
|
||||
var list = breadcrumbs.popUntil({
|
||||
id: 979,
|
||||
name: "telescopic Sivatheriinae"
|
||||
}).get();
|
||||
|
||||
expect(list).toEqual([
|
||||
{
|
||||
id: 979,
|
||||
name: "telescopic Sivatheriinae"
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("Given an item with an id and a name, and given the breadcrumbs already contained this item as last element and 2 others, when I pop breadcrumbs until finding the provided item, then an array containing all 3 items will be returned", function() {
|
||||
breadcrumbs.push({
|
||||
id: 474,
|
||||
name: "Kolinsky"
|
||||
}).push({
|
||||
id: 69,
|
||||
name: "Hulburt"
|
||||
}).push({
|
||||
id: 851,
|
||||
name: "Perkerson"
|
||||
});
|
||||
|
||||
var list = breadcrumbs.popUntil({
|
||||
id: 851,
|
||||
name: "Perkerson"
|
||||
}).get();
|
||||
|
||||
expect(list).toEqual([
|
||||
{
|
||||
id: 474,
|
||||
name: "Kolinsky"
|
||||
}, {
|
||||
id: 69,
|
||||
name: "Hulburt"
|
||||
}, {
|
||||
id: 851,
|
||||
name: "Perkerson"
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("Given an item with an id and a name that didn't exist in the breadcrumbs, and given the breadcrumbs contained 3 items, when I pop breadcrumbs until finding the provided item, then an array containing all 3 breadcrumbs will be returned", function() {
|
||||
breadcrumbs.push({
|
||||
id: 46,
|
||||
name: "Cordell"
|
||||
}).push({
|
||||
id: 540,
|
||||
name: "Delia"
|
||||
}).push({
|
||||
id: 571,
|
||||
name: "Lashawnda"
|
||||
});
|
||||
|
||||
var list = breadcrumbs.popUntil({
|
||||
id: 803,
|
||||
name: "Wilfredo"
|
||||
}).get();
|
||||
|
||||
expect(list).toEqual([
|
||||
{
|
||||
id: 46,
|
||||
name: "Cordell"
|
||||
}, {
|
||||
id: 540,
|
||||
name: "Delia"
|
||||
}, {
|
||||
id: 571,
|
||||
name: "Lashawnda"
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("Given an item with an id and a name, and given the breadcrumbs were empty, when I pop breadcrumbs until finding the provided item, then an empty array will be returned", function() {
|
||||
var list = breadcrumbs.popUntil({
|
||||
id: 605,
|
||||
name: "spacecraft"
|
||||
}).get();
|
||||
|
||||
expect(list).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("reset() -", function () {
|
||||
it("Given a breadcrumb had been previously set, when I reset the breadcrumbs, then they will be empty", function() {
|
||||
breadcrumbs.push({
|
||||
id: 350,
|
||||
name: "exterritoriality dubious"
|
||||
});
|
||||
|
||||
var list = breadcrumbs.reset().get();
|
||||
|
||||
expect(list).toEqual([]);
|
||||
});
|
||||
|
||||
it("Given the breadcrumbs were empty, when I reset them, then they will be empty", function() {
|
||||
var list = breadcrumbs.reset().get();
|
||||
|
||||
expect(list).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -70,13 +70,14 @@ angular.module('jamstash.subsonic.service', [
|
|||
// Extend the provided config (if it exists) with our params
|
||||
// Otherwise we create a config object
|
||||
var actualConfig = config || {};
|
||||
var params = actualConfig.params || {};
|
||||
params.u = globals.settings.Username;
|
||||
params.p = globals.settings.Password;
|
||||
params.f = globals.settings.Protocol;
|
||||
params.v = globals.settings.ApiVersion;
|
||||
params.c = globals.settings.ApplicationName;
|
||||
actualConfig.params = params;
|
||||
actualConfig.params = actualConfig.params || {};
|
||||
_.extend(actualConfig.params, {
|
||||
u: globals.settings.Username,
|
||||
p: globals.settings.Password,
|
||||
f: globals.settings.Protocol,
|
||||
v: globals.settings.ApiVersion,
|
||||
c: globals.settings.ApplicationName
|
||||
});
|
||||
actualConfig.timeout = globals.settings.Timeout;
|
||||
|
||||
var httpPromise;
|
||||
|
|
|
@ -37,22 +37,16 @@
|
|||
<form class="form">
|
||||
<select id="SelectedAlbumSort" ng-model="SelectedAlbumSort.id" ng-show="AlbumSort.length" ng-options="o.id as o.name for o in AlbumSort"></select>
|
||||
</form>
|
||||
<div id="BreadCrumb">
|
||||
<div id="BreadCrumbs" class="floatleft">
|
||||
<div class="crumb"><a ng-click="toggleArtists()" title="Toggle Artists">Artists</a> ></div>
|
||||
<div class="crumb" ng-repeat="o in BreadCrumbs | filter:{type:'artist'}"><a ng-click="getSongs('display', o.id, o.name)">{{o.name}}</a> ></div>
|
||||
<div class="crumb" ng-repeat="o in BreadCrumbs | filter:{type:'album'}"><a ng-click="getSongs('display', o.id, o.name)">{{o.name}}</a> ></div>
|
||||
</div>
|
||||
</div>
|
||||
<jamstash-breadcrumbs>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clear"></div>
|
||||
<ul class="simplelist songlist noselect">
|
||||
<div class="" ng-repeat="o in album" ng-switch on="o.type">
|
||||
<li class="album" ng-switch-when="byfolder" id="{{o.id}}" ng-class="{'selected': selectedAlbum == o.id, 'albumgrid': settings.DefaultLibraryLayout.id == 'grid'}" ng-click="getSongs('display', o.id, o.name)" parentid="{{o.parentid}}">
|
||||
<li class="album" ng-switch-when="byfolder" id="{{o.id}}" ng-class="{'selected': selectedAlbum == o.id, 'albumgrid': settings.DefaultLibraryLayout.id == 'grid'}" ng-click="getSongs('display', o.id, o.name, 'forward')" parentid="{{o.parentid}}">
|
||||
<div class="itemactions">
|
||||
<a class="add hover" href="" title="Add To Play Queue" ng-click="getSongs('add', o.id, o.name)" stop-event="click"></a>
|
||||
<a class="play hover" href="" title="Play" ng-click="getSongs('play', o.id, o.name)" stop-event="click"></a>
|
||||
<a class="add hover" href="" title="Add To Play Queue" ng-click="getSongs('add', o.id, o.name, 'forward')" stop-event="click"></a>
|
||||
<a class="play hover" href="" title="Play" ng-click="getSongs('play', o.id, o.name, 'forward')" stop-event="click"></a>
|
||||
<a class="download hover" href="" ng-click="download(o.id)" title="Download" stop-event="click"></a>
|
||||
<a class="hover" href="" title="Star" ng-class="{'favorite': o.starred, 'rate': !o.starred}" ng-click="toggleStar(o)" stop-event="click"></a>
|
||||
<a class="info hover" href="" title="{{'Created: ' + o.date}}"></a>
|
||||
|
@ -60,7 +54,7 @@
|
|||
<div class="albumart"><img ng-src="{{o.coverartthumb}}" src="images/albumdefault_160.jpg"></div>
|
||||
<div class="albuminfo">
|
||||
<div class="title" title="{{o.name}}" ng-bind-html="o.name"></div>
|
||||
<div class="artist" title="{{o.artist}}"><a href="" id="{{o.parentid}}" ng-click="getSongs('display', o.parentid, o.artist)" stop-event="click" ng-bind-html="o.artist"></a></div>
|
||||
<div class="artist" title="{{o.artist}}"><a href="" id="{{o.parentid}}" ng-click="getSongs('display', o.parentid, o.artist, 'forward')" stop-event="click" ng-bind-html="o.artist"></a></div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</li>
|
||||
|
@ -107,14 +101,14 @@
|
|||
<ul class="simplelist mainlist noselect" ng-show="shortcut.length">
|
||||
<li class="index" title="Scroll to Top" data-bind="click: $root.scrollToTop"><a>Shortcuts</a></li>
|
||||
<ul class="simplelist mainlist noselect" ng-repeat="o in shortcut">
|
||||
<li class="item" id="{{o.id}}" ng-click="getSongs('display', o.id, o.name)" ng-class="{'selected': selectedArtist == o.id}"><span ng-bind-html="o.name"></span></li>
|
||||
<li class="item" id="{{o.id}}" ng-click="getSongs('display', o.id, o.name, 'root')" ng-class="{'selected': selectedArtist == o.id}"><span ng-bind-html="o.name"></span></li>
|
||||
</ul>
|
||||
</ul>
|
||||
<!-- Artist -->
|
||||
<ul class="simplelist mainlist noselect" ng-repeat="o in index">
|
||||
<li class="index" title="Scroll to Top" id="{{o.name}}" ng-click="scrollToTop()"><a>{{o.name}}</a></li>
|
||||
<ul class="simplelist mainlist noselect">
|
||||
<li class="item" id="{{a.id}}" ng-repeat="a in o.artist" ng-class="{'selected': selectedArtist == a.id}" ng-click="getSongs('display', a.id, a.name)"><a ng-href="" ng-bind-html="a.name"></a></li>
|
||||
<li class="item" id="{{a.id}}" ng-repeat="a in o.artist" ng-class="{'selected': selectedArtist == a.id}" ng-click="getSongs('display', a.id, a.name, 'root')"><a ng-href="" ng-bind-html="a.name"></a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -8,7 +8,9 @@ angular.module('jamstash.subsonic.controller', [
|
|||
'ngLodash',
|
||||
'jamstash.subsonic.service',
|
||||
'jamstash.player.service',
|
||||
'jamstash.persistence'
|
||||
'jamstash.persistence',
|
||||
'jamstash.breadcrumbs.directive',
|
||||
'jamstash.breadcrumbs.service'
|
||||
])
|
||||
|
||||
.controller('SubsonicController', [
|
||||
|
@ -24,6 +26,7 @@ angular.module('jamstash.subsonic.controller', [
|
|||
'notifications',
|
||||
'player',
|
||||
'persistence',
|
||||
'breadcrumbs',
|
||||
function (
|
||||
$scope,
|
||||
$rootScope,
|
||||
|
@ -36,7 +39,8 @@ angular.module('jamstash.subsonic.controller', [
|
|||
subsonic,
|
||||
notifications,
|
||||
player,
|
||||
persistence
|
||||
persistence,
|
||||
breadcrumbs
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
|
@ -330,8 +334,18 @@ angular.module('jamstash.subsonic.controller', [
|
|||
return promise;
|
||||
};
|
||||
|
||||
$scope.getSongs = function (action, id, name) {
|
||||
notifications.updateMessage('getSongs' + id + ' ' + name, true);
|
||||
/**
|
||||
* Get songs from the subsonic server. Provide with the id of the directory and its name.
|
||||
* If action is 'play' or 'add', the songs will be retrieved recursively until all sub-directories
|
||||
* of the provided one have been called.
|
||||
* level is the level in the breadcrumbs. Can be 'root' which resets the breadcrumbs to one level
|
||||
* or can be 'forward' which adds a level to the breadcrumbs.
|
||||
* @param {String} action 'play', 'add' or 'display'
|
||||
* @param {int} id the id of the directory to get songs from
|
||||
* @param {String} name the name of the directory to get songs from
|
||||
* @param {String} level 'root' or 'forward'
|
||||
*/
|
||||
$scope.getSongs = function (action, id, name, level) {
|
||||
var promise;
|
||||
if (action === 'play' || action === 'add') {
|
||||
promise = subsonic.recursiveGetSongs(id);
|
||||
|
@ -341,10 +355,17 @@ angular.module('jamstash.subsonic.controller', [
|
|||
$scope.handleErrors(promise).then(function (data) {
|
||||
$scope.album = data.directories;
|
||||
$scope.song = data.songs;
|
||||
if ($scope.BreadCrumbs.length > 0) {
|
||||
$scope.BreadCrumbs.splice(1, ($scope.BreadCrumbs.length - 1));
|
||||
if (level === "root") {
|
||||
breadcrumbs.reset().push({
|
||||
id: id,
|
||||
name: name
|
||||
});
|
||||
} else if (level === "forward") {
|
||||
breadcrumbs.push({
|
||||
id: id,
|
||||
name: name
|
||||
});
|
||||
}
|
||||
$scope.BreadCrumbs.push({'type': 'album', 'id': id, 'name': name});
|
||||
$scope.selectedAutoAlbum = null;
|
||||
$scope.selectedArtist = null;
|
||||
$scope.selectedAlbum = id;
|
||||
|
|
|
@ -2,7 +2,7 @@ describe("Subsonic controller", function() {
|
|||
'use strict';
|
||||
|
||||
var scope, $rootScope, $controller, $window,
|
||||
_, subsonic, notifications, player, utils, persistence, controllerParams, deferred;
|
||||
_, subsonic, notifications, player, utils, persistence, breadcrumbs, controllerParams, deferred;
|
||||
|
||||
beforeEach(function() {
|
||||
jasmine.addCustomEqualityTester(angular.equals);
|
||||
|
@ -26,6 +26,11 @@ describe("Subsonic controller", function() {
|
|||
"saveSelectedMusicFolder",
|
||||
"deleteSelectedMusicFolder"
|
||||
]);
|
||||
breadcrumbs = jasmine.createSpyObj("breadcrumbs", [
|
||||
"reset",
|
||||
"push"
|
||||
]);
|
||||
breadcrumbs.reset.and.returnValue(breadcrumbs);
|
||||
|
||||
// Mock the subsonic service
|
||||
subsonic = jasmine.createSpyObj("subsonic", [
|
||||
|
@ -74,7 +79,8 @@ describe("Subsonic controller", function() {
|
|||
subsonic: subsonic,
|
||||
notifications: notifications,
|
||||
player: player,
|
||||
persistence: persistence
|
||||
persistence: persistence,
|
||||
breadcrumbs: breadcrumbs
|
||||
};
|
||||
});
|
||||
});
|
||||
|
@ -88,7 +94,6 @@ describe("Subsonic controller", function() {
|
|||
|
||||
describe("getSongs -", function() {
|
||||
beforeEach(function() {
|
||||
scope.BreadCrumbs = [];
|
||||
scope.SelectedAlbumSort= {
|
||||
id: "default"
|
||||
};
|
||||
|
@ -98,7 +103,7 @@ describe("Subsonic controller", function() {
|
|||
});
|
||||
|
||||
it("Given a music directory that contained 3 songs and given its id and name, when I display it, then subsonic-service will be called, the breadcrumbs will be updated and the songs will be published to the scope", function() {
|
||||
scope.getSongs('display', 87, 'Covetous Dadayag');
|
||||
scope.getSongs('display', 87, 'Covetous Dadayag', "root");
|
||||
deferred.resolve({
|
||||
directories: [],
|
||||
songs: [
|
||||
|
@ -116,11 +121,11 @@ describe("Subsonic controller", function() {
|
|||
{ id: 859 },
|
||||
{ id: 545 }
|
||||
]);
|
||||
expect(scope.BreadCrumbs).toEqual([{
|
||||
type: 'album',
|
||||
expect(breadcrumbs.reset).toHaveBeenCalled();
|
||||
expect(breadcrumbs.push).toHaveBeenCalledWith({
|
||||
id: 87,
|
||||
name: 'Covetous Dadayag'
|
||||
}]);
|
||||
name: "Covetous Dadayag"
|
||||
});
|
||||
expect(scope.selectedAutoAlbum).toBeNull();
|
||||
expect(scope.selectedArtist).toBeNull();
|
||||
expect(scope.selectedAlbum).toBe(87);
|
||||
|
@ -137,24 +142,18 @@ describe("Subsonic controller", function() {
|
|||
name: 'Evan Mestanza'
|
||||
}
|
||||
];
|
||||
scope.getSongs('display', 883, 'Pitiedly preutilizable');
|
||||
scope.getSongs('display', 883, 'Pitiedly preutilizable', "forward");
|
||||
deferred.resolve({
|
||||
directories: [],
|
||||
songs: []
|
||||
});
|
||||
scope.$apply();
|
||||
|
||||
expect(scope.BreadCrumbs).toEqual([
|
||||
{
|
||||
type: 'artist',
|
||||
id: 73,
|
||||
name: 'Evan Mestanza'
|
||||
}, {
|
||||
type: 'album',
|
||||
id: 883,
|
||||
name: 'Pitiedly preutilizable'
|
||||
}
|
||||
]);
|
||||
expect(breadcrumbs.reset).not.toHaveBeenCalled();
|
||||
expect(breadcrumbs.push).toHaveBeenCalledWith({
|
||||
id: 883,
|
||||
name: "Pitiedly preutilizable"
|
||||
});
|
||||
});
|
||||
|
||||
it("Given a music directory that contained 2 songs and 1 subdirectory and given its id and name, when I display it, then subsonic-service will be called, the songs and directory will be published to the scope", function() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue