diff --git a/.jshintrc b/.jshintrc
index e7e5d2b..dc1d78b 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -18,6 +18,7 @@
"smarttabs": true,
"globals": {
"_": false,
+ "affix": false,
"after": false,
"afterEach": false,
"angular": false,
@@ -32,6 +33,6 @@
"spyOn": false
},
"browser": true,
- "node": true,
- "jquery": true
+ "jquery": true,
+ "node": true
}
diff --git a/app/app.js b/app/app.js
index 66085f1..5af6e04 100755
--- a/app/app.js
+++ b/app/app.js
@@ -1,54 +1,51 @@
-
-/* Declare app level module */
-angular.module('JamStash', ['ngCookies', 'ngRoute', 'ngSanitize',
- 'jamstash.subsonic.ctrl', 'jamstash.archive.ctrl'])
-
-.config(['$routeProvider',function($routeProvider) {
- 'use strict';
-
- $routeProvider
- .when('/index', { redirectTo: '/library' })
- .when('/settings', { templateUrl: 'settings/settings.html', controller: 'SettingsCtrl' })
- .when('/queue', { templateUrl: 'queue/queue.html', controller: 'QueueCtrl' })
- .when('/library', { templateUrl: 'subsonic/subsonic.html', controller: 'SubsonicCtrl' })
- .when('/library/:artistId', { templateUrl: 'subsonic/subsonic.html', controller: 'SubsonicCtrl', reloadOnSearch: false })
- .when('/library/:artistId/:albumId', { templateUrl: 'subsonic/subsonic.html', controller: 'SubsonicCtrl', reloadOnSearch: false })
- .when('/podcasts', { templateUrl: 'podcasts/podcasts.html', controller: 'PodcastCtrl' })
- .when('/archive', { templateUrl: 'archive/archive.html', controller: 'ArchiveCtrl' })
- .when('/archive/:artist', { templateUrl: 'archive/archive.html', controller: 'ArchiveCtrl' })
- .when('/archive/:artist/:album', { templateUrl: 'archive/archive.html', controller: 'ArchiveCtrl' })
- .otherwise({ redirectTo: '/index' });
-}])
-
-.config(['$httpProvider',function($httpProvider) {
- 'use strict';
-
- $httpProvider.interceptors.push(['$rootScope', '$location', '$q', 'globals', function ($rootScope, $location, $q, globals) {
- return {
- 'request': function (request) {
- // if we're not logged-in to the AngularJS app, redirect to login page
- //$rootScope.loggedIn = $rootScope.loggedIn || globals.settings.Username;
- $rootScope.loggedIn = false;
- if (globals.settings.Username != "" && globals.settings.Password != "" && globals.settings.Server != "") {
- $rootScope.loggedIn = true;
- }
- var path = '';
- path = $location.path();
- if (globals.settings.Debug) { console.log('Logged In: ' + $rootScope.loggedIn); }
- if (globals.settings.Debug) { console.log('Current Path: ' + path); }
- if (!$rootScope.loggedIn && path != '/settings' && path.search('archive') < 0) {
- $location.path('/settings');
- }
- return request;
- },
- 'responseError': function (rejection) {
- // if we're not logged-in to the web service, redirect to login page
- if (rejection.status === 401 && $location.path() != '/settings') {
- $rootScope.loggedIn = false;
- $location.path('/settings');
- }
- return $q.reject(rejection);
- }
- };
- }]);
-}]);
\ No newline at end of file
+'use strict';
+
+/* Declare app level module */
+angular.module('JamStash', ['ngCookies', 'ngRoute', 'ngSanitize',
+ 'jamstash.subsonic.controller', 'jamstash.archive.controller', 'jamstash.player.controller', 'jamstash.queue.controller', 'jamstash.persistence'])
+
+.config(['$routeProvider',function($routeProvider) {
+ $routeProvider
+ .when('/index', { redirectTo: '/library' })
+ .when('/settings', { templateUrl: 'settings/settings.html', controller: 'SettingsController' })
+ .when('/queue', { templateUrl: 'queue/queue.html', controller: 'QueueController' })
+ .when('/library', { templateUrl: 'subsonic/subsonic.html', controller: 'SubsonicController' })
+ .when('/library/:artistId', { templateUrl: 'subsonic/subsonic.html', controller: 'SubsonicController', reloadOnSearch: false })
+ .when('/library/:artistId/:albumId', { templateUrl: 'subsonic/subsonic.html', controller: 'SubsonicController', reloadOnSearch: false })
+ .when('/podcasts', { templateUrl: 'podcasts/podcasts.html', controller: 'PodcastController' })
+ .when('/archive', { templateUrl: 'archive/archive.html', controller: 'ArchiveController' })
+ .when('/archive/:artist', { templateUrl: 'archive/archive.html', controller: 'ArchiveController' })
+ .when('/archive/:artist/:album', { templateUrl: 'archive/archive.html', controller: 'ArchiveController' })
+ .otherwise({ redirectTo: '/index' });
+}])
+
+.config(['$httpProvider',function($httpProvider) {
+ $httpProvider.interceptors.push(['$rootScope', '$location', '$q', 'globals', function ($rootScope, $location, $q, globals) {
+ return {
+ 'request': function (request) {
+ // if we're not logged-in to the AngularJS app, redirect to login page
+ //$rootScope.loggedIn = $rootScope.loggedIn || globals.settings.Username;
+ $rootScope.loggedIn = false;
+ if (globals.settings.Username != "" && globals.settings.Password != "" && globals.settings.Server != "") {
+ $rootScope.loggedIn = true;
+ }
+ var path = '';
+ path = $location.path();
+ if (globals.settings.Debug) { console.log('Logged In: ' + $rootScope.loggedIn); }
+ if (globals.settings.Debug) { console.log('Current Path: ' + path); }
+ if (!$rootScope.loggedIn && path != '/settings' && path.search('archive') < 0) {
+ $location.path('/settings');
+ }
+ return request;
+ },
+ 'responseError': function (rejection) {
+ // if we're not logged-in to the web service, redirect to login page
+ if (rejection.status === 401 && $location.path() != '/settings') {
+ $rootScope.loggedIn = false;
+ $location.path('/settings');
+ }
+ return $q.reject(rejection);
+ }
+ };
+ }]);
+}]);
diff --git a/app/archive/archive-service.js b/app/archive/archive-service.js
index 141359d..d20b42a 100644
--- a/app/archive/archive-service.js
+++ b/app/archive/archive-service.js
@@ -3,10 +3,11 @@
*
* Access Archive.org
*/
-angular.module('jamstash.archive.service', ['jamstash.settings', 'jamstash.model', 'jamstash.notifications'])
+angular.module('jamstash.archive.service', ['jamstash.settings', 'jamstash.model', 'jamstash.notifications',
+ 'jamstash.player.service'])
-.factory('archive', ['$rootScope', '$http', '$q', '$sce', 'globals', 'model', 'utils', 'map', 'notifications',
- function($rootScope, $http, $q, $sce, globals, model, utils, map, notifications) {
+.factory('archive', ['$rootScope', '$http', '$q', '$sce', 'globals', 'model', 'utils', 'map', 'notifications', 'player',
+ function($rootScope, $http, $q, $sce, globals, model, utils, map, notifications, player) {
'use strict';
var index = { shortcuts: [], artists: [] };
@@ -179,20 +180,20 @@ angular.module('jamstash.archive.service', ['jamstash.settings', 'jamstash.model
angular.forEach(items, function (item, key) {
var song = mapSong(key, item, server, dir, identifier, coverart);
if (song) {
- $rootScope.queue.push(song);
+ player.queue.push(song);
}
});
notifications.updateMessage(Object.keys(items).length + ' Song(s) Added to Queue', true);
} else if (action == 'play') {
- $rootScope.queue = [];
+ player.queue = [];
angular.forEach(items, function (item, key) {
var song = mapSong(key, item, server, dir, identifier, coverart);
if (song) {
- $rootScope.queue.push(song);
+ player.queue.push(song);
}
});
- var next = $rootScope.queue[0];
- $rootScope.playSong(false, next);
+ var next = player.queue[0];
+ player.play(next);
notifications.updateMessage(Object.keys(items).length + ' Song(s) Added to Queue', true);
} else {
content.album = [];
@@ -213,4 +214,4 @@ angular.module('jamstash.archive.service', ['jamstash.settings', 'jamstash.model
return deferred.promise;
}
};
-}]);
\ No newline at end of file
+}]);
diff --git a/app/archive/archive.js b/app/archive/archive.js
index fd6592b..fe12d8a 100644
--- a/app/archive/archive.js
+++ b/app/archive/archive.js
@@ -1,11 +1,11 @@
-/**
-* jamstash.archive.ctrl Module
+/**
+* jamstash.archive.controller Module
*
* Access Archive.org
*/
-angular.module('jamstash.archive.ctrl', ['jamstash.archive.service'])
+angular.module('jamstash.archive.controller', ['jamstash.archive.service'])
-.controller('ArchiveCtrl', ['$scope', '$rootScope', '$location', '$routeParams', '$http', '$timeout', 'utils', 'globals', 'model', 'notifications', 'player', 'archive', 'json',
+.controller('ArchiveController', ['$scope', '$rootScope', '$location', '$routeParams', '$http', '$timeout', 'utils', 'globals', 'model', 'notifications', 'player', 'archive', 'json',
function($scope, $rootScope, $location, $routeParams, $http, $timeout, utils, globals, model, notifications, player, archive, json){
'use strict';
@@ -179,4 +179,4 @@ angular.module('jamstash.archive.ctrl', ['jamstash.archive.service'])
$scope.addSavedCollection($routeParams.artist);
}
/* End Startup */
-}]);
\ No newline at end of file
+}]);
diff --git a/app/common/main-controller.js b/app/common/main-controller.js
index 377db03..2418001 100644
--- a/app/common/main-controller.js
+++ b/app/common/main-controller.js
@@ -1,18 +1,18 @@
-angular.module('JamStash')
-.controller('AppCtrl', ['$scope', '$rootScope', '$document', '$window', '$location', '$cookieStore', '$http', 'utils', 'globals', 'model', 'notifications', 'player',
- function($scope, $rootScope, $document, $window, $location, $cookieStore, $http, utils, globals, model, notifications, player) {
+angular.module('JamStash')
+.controller('AppController', ['$scope', '$rootScope', '$document', '$window', '$location', '$cookieStore', '$http', 'utils', 'globals', 'model', 'notifications', 'player', 'persistence', 'Page',
+ function($scope, $rootScope, $document, $window, $location, $cookieStore, $http, utils, globals, model, notifications, player, persistence, Page) {
'use strict';
$rootScope.settings = globals.settings;
$rootScope.song = [];
- $rootScope.queue = [];
$rootScope.playingSong = null;
$rootScope.MusicFolders = [];
$rootScope.Genres = [];
$rootScope.Messages = [];
-
+
$rootScope.SelectedMusicFolder = "";
$rootScope.unity = null;
+ $scope.Page = Page;
$rootScope.loggedIn = function () {
if (globals.settings.Server !== '' && globals.settings.Username !== '' && globals.settings.Password !== '') {
return true;
@@ -27,13 +27,6 @@
$rootScope.go = function (path) {
$location.path(path);
};
- /*
- $scope.playSong = function (loadonly, data) {
- $scope.$apply(function () {
- $rootScope.playSong(loadonly, data);
- });
- }
- */
// Reads cookies and sets globals.settings values
$scope.loadSettings = function () {
@@ -109,18 +102,14 @@
}
};
- $scope.$watchCollection('queue', function(newItem, oldItem) {
- if (oldItem.length != newItem.length
- && globals.settings.ShowQueue) {
- $rootScope.showQueue();
+ $scope.$watchCollection(function () {
+ return player.queue;
+ }, function(newQueue) {
+ if (newQueue !== undefined && newQueue.length > 0 && globals.settings.ShowQueue) {
+ $scope.showQueue();
}
- /*
- for (var index in newCol) {
- var item = newCol[index];
- item.order = parseInt(index) + 1;
- }
- */
});
+
$rootScope.showQueue = function () {
$('#SideBar').css('display', 'block');
$('#right-component').removeClass('lgcolumn_expanded');
@@ -130,14 +119,7 @@
$('#right-component').addClass('lgcolumn_expanded');
};
$scope.toggleQueue = function () {
- if ($('#SideBar').css('display') == 'none') {
- $rootScope.showQueue();
- } else {
- $rootScope.hideQueue();
- }
- };
- $scope.toggleQueue = function () {
- if ($('#SideBar').css('display') == 'none') {
+ if ($('#SideBar').css('display') === 'none') {
$rootScope.showQueue();
} else {
$rootScope.hideQueue();
@@ -160,16 +142,22 @@
};
$scope.fancyboxOpenImage = function (url) {
- utils.fancyboxOpenImage(url);
+ $.fancybox.open({
+ helpers : {
+ overlay : {
+ css : {
+ 'background' : 'rgba(0, 0, 0, 0.15)'
+ }
+ }
+ },
+ hideOnContentClick: true,
+ type: 'image',
+ openEffect: 'none',
+ closeEffect: 'none',
+ href: url
+ });
};
- $('#audiocontainer .scrubber').mouseover(function (e) {
- $('.audiojs .scrubber').stop().animate({ height: '8px' });
- });
- $('#audiocontainer .scrubber').mouseout(function (e) {
- $('.audiojs .scrubber').stop().animate({ height: '4px' });
- });
-
$(document).on("click", ".message", function(){
$(this).remove();
});
@@ -177,23 +165,13 @@
// Global Functions
window.onbeforeunload = function () {
if (!globals.settings.Debug) {
- if ($rootScope.queue.length > 0) {
+ if (player.queue.length > 0) {
return "You're about to end your session, are you sure?";
}
}
};
$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();
- $rootScope.queue.splice(end, 0,
- $rootScope.queue.splice(start, 1)[0]);
- $scope.$apply();
- };
- $(document).on( 'click', 'message', function() {
+ $(document).on( 'click', 'message', function() {
$(this).fadeOut(function () { $(this).remove(); });
return false;
})
@@ -226,9 +204,9 @@
$('#left-component').stop().scrollTo(el, 400);
}
} else if (unicode == 39 || unicode == 176) { // right arrow
- $rootScope.nextTrack();
+ player.nextTrack();
} else if (unicode == 37 || unicode == 177) { // back arrow
- $rootScope.previousTrack();
+ player.previousTrack();
} else if (unicode == 32 || unicode == 179 || unicode.toString() == '0179') { // spacebar
player.playPauseSong();
return false;
@@ -282,13 +260,15 @@
});
};
$rootScope.playAll = function (songs) {
- $rootScope.queue = [];
+ // TODO: Hyz: Replace
+ player.queue = [];
$rootScope.selectAll(songs);
$rootScope.addSongsToQueue();
- var next = $rootScope.queue[0];
- $rootScope.playSong(false, next);
+ var next = player.queue[0];
+ player.play(next);
};
$rootScope.playFrom = function (index, songs) {
+ // TODO: Hyz: Replace
var from = songs.slice(index,songs.length);
$scope.selectedSongs = [];
angular.forEach(from, function (item, key) {
@@ -296,33 +276,28 @@
item.selected = true;
});
if ($scope.selectedSongs.length > 0) {
- $rootScope.queue = [];
+ player.queue = [];
$rootScope.addSongsToQueue();
- var next = $rootScope.queue[0];
- $rootScope.playSong(false, next);
+ var next = player.queue[0];
+ player.play(next);
}
};
$rootScope.addSongsToQueue = function () {
+ // TODO: Hyz: Replace
if ($scope.selectedSongs.length !== 0) {
angular.forEach($scope.selectedSongs, function (item, key) {
- $rootScope.queue.push(item);
+ player.queue.push(item);
item.selected = false;
});
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) {
+ // TODO: Hyz: Replace
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();
};
@@ -351,33 +326,6 @@
}
});
};
- $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 () {
- //self.selectedSongs([]);
- $rootScope.queue = [];
- $.fancybox.close();
- };
- $scope.queueTotal = function () {
- var total = 0;
- utils.arrayForEach(self.queue(), function (item) {
- total += parseInt(item.duration());
- });
- if (self.queue().length > 0) {
- return self.queue().length + ' song(s), ' + utils.secondsToTime(total) + ' total time';
- } else {
- return '0 song(s), 00:00:00 total time';
- }
- };
- $scope.queueShuffle = function () {
- $rootScope.queue.sort(function () { return 0.5 - Math.random(); });
- };
$scope.selectedSongs = [];
$scope.selectSong = function (data) {
var i = $scope.selectedSongs.indexOf(data);
@@ -417,6 +365,7 @@
}
});
};
+
$scope.updateFavorite = function (item) {
var id = item.id;
var starred = item.starred;
@@ -441,7 +390,6 @@
$scope.toTrusted = function (html) {
return $sce.trustAsHtml(html);
};
-
/* Launch on Startup */
$scope.loadSettings();
@@ -454,8 +402,8 @@
if ($scope.loggedIn()) {
//$scope.ping();
if (globals.settings.SaveTrackPosition) {
- player.loadTrackPosition();
- player.startSaveTrackPosition();
+ persistence.loadQueue();
+ persistence.loadTrackPosition();
}
}
/* End Startup */
diff --git a/app/common/main-controller_test.js b/app/common/main-controller_test.js
new file mode 100644
index 0000000..73655d7
--- /dev/null
+++ b/app/common/main-controller_test.js
@@ -0,0 +1,81 @@
+describe("Main controller", function() {
+ 'use strict';
+
+ var scope, mockGlobals, player, utils;
+ beforeEach(function() {
+ mockGlobals = {
+ settings: {
+ ShowQueue: false,
+ Debug: true
+ }
+ };
+
+ module('JamStash', function($provide) {
+ $provide.value('globals', mockGlobals);
+ });
+
+ inject(function ($controller, $rootScope, _$document_, _$window_, _$location_, _$cookieStore_, _utils_, globals, _model_, _notifications_, _player_, _locker_, _Page_) {
+ scope = $rootScope.$new();
+ player = _player_;
+ utils = _utils_;
+
+ spyOn(utils, "switchTheme");
+
+ $controller('AppController', {
+ $scope: scope,
+ $rootScope: $rootScope,
+ $document: _$document_,
+ $window: _$window_,
+ $location: _$location_,
+ $cookieStore: _$cookieStore_,
+ utils: utils,
+ globals: globals,
+ model: _model_,
+ notifications: _notifications_,
+ player: player,
+ locker: _locker_,
+ Page: _Page_
+ });
+ });
+ player.queue = [];
+ });
+
+ xdescribe("updateFavorite -", function() {
+
+ xit("when starring a song, it notifies the user that the star was saved", function() {
+
+ });
+
+ xit("when starring an album, it notifies the user that the star was saved", function() {
+
+ });
+
+ xit("when starring an artist, it notifies the user that the star was saved", function() {
+
+ });
+
+ xit("given that the Subsonic server returns an error, when starring something, it notifies the user with the error message", function() {
+ //TODO: move to higher level
+ });
+
+ xit("given that the Subsonic server is unreachable, when starring something, it notifies the user with the HTTP error code", function() {
+ //TODO: move to higher level
+ });
+ });
+
+ xdescribe("toggleSetting -", function() {
+
+ });
+
+ it("given that the global setting 'ShowQueue' is true, when the playing queue's length changes and is not empty, it shows the queue", function() {
+ mockGlobals.settings.ShowQueue = true;
+ player.queue = [{
+ id: 684
+ }];
+ spyOn(scope, "showQueue");
+
+ scope.$apply();
+
+ expect(scope.showQueue).toHaveBeenCalled();
+ });
+});
diff --git a/app/common/notification-service.js b/app/common/notification-service.js
index 45a53fe..98cb152 100644
--- a/app/common/notification-service.js
+++ b/app/common/notification-service.js
@@ -3,12 +3,12 @@
*
* Provides access to the notification UI.
*/
-angular.module('jamstash.notifications', [])
+angular.module('jamstash.notifications', ['jamstash.player.service', 'jamstash.utils'])
-.service('notifications', ['$rootScope', 'globals', function($rootScope, globals) {
+.service('notifications', ['$rootScope', '$window', '$interval', 'globals', 'player', 'utils',
+ function($rootScope, $window, $interval, globals, player, utils) {
'use strict';
- var msgIndex = 1;
this.updateMessage = function (msg, autohide) {
if (msg !== '') {
var id = $rootScope.Messages.push(msg) - 1;
@@ -21,47 +21,34 @@ angular.module('jamstash.notifications', [])
}
};
this.requestPermissionIfRequired = function () {
- if (window.Notify.isSupported() && window.Notify.needsPermission()) {
+ if (this.isSupported() && !this.hasPermission()) {
window.Notify.requestPermission();
}
};
- this.hasNotificationPermission = function () {
- return (window.Notify.needsPermission() === false);
+ this.hasPermission = function () {
+ return !$window.Notify.needsPermission();
};
- this.hasNotificationSupport = function () {
+ this.isSupported = function () {
return window.Notify.isSupported();
};
- var notifications = [];
- this.showNotification = function (pic, title, text, type, bind) {
- if (this.hasNotificationPermission()) {
- //closeAllNotifications()
- var settings = {};
- if (bind = '#NextTrack') {
- settings.notifyClick = function () {
- $rootScope.nextTrack();
+ this.showNotification = function (song) {
+ if (this.hasPermission()) {
+ var notification = new Notify(utils.toHTML.un(song.name), {
+ body: utils.toHTML.un(song.artist + " - " + song.album),
+ icon: song.coverartthumb,
+ notifyClick: function () {
+ player.nextTrack();
this.close();
- };
- }
- if (type === 'text') {
- settings.body = text;
- settings.icon = pic;
- } else if (type === 'html') {
- settings.body = text;
- }
- var notification = new Notify(title, settings);
- notifications.push(notification);
- setTimeout(function (notWin) {
- notWin.close();
- }, globals.settings.Timeout, notification);
+ $rootScope.$apply();
+ }
+ });
+ $interval(function() {
+ notification.close();
+ }, globals.settings.Timeout);
notification.show();
} else {
console.log("showNotification: No Permission");
}
};
- this.closeAllNotifications = function () {
- for (var notification in notifications) {
- notifications[notification].close();
- }
- };
-}]);
\ No newline at end of file
+}]);
diff --git a/app/common/notification-service_test.js b/app/common/notification-service_test.js
new file mode 100644
index 0000000..ac5e569
--- /dev/null
+++ b/app/common/notification-service_test.js
@@ -0,0 +1,108 @@
+describe("Notifications service - ", function() {
+ 'use strict';
+
+ var notifications, $window, $interval, player, utils, mockGlobals,
+ NotificationObj;
+ beforeEach(function() {
+ mockGlobals = {
+ settings: {
+ Timeout: 30000
+ }
+ };
+
+ module('jamstash.notifications', function ($provide) {
+ $provide.value('globals', mockGlobals);
+ });
+
+ inject(function (_notifications_, _$window_, _$interval_, _player_, _utils_) {
+ notifications = _notifications_;
+ $window = _$window_;
+ player = _player_;
+ utils = _utils_;
+ $interval = _$interval_;
+ });
+
+ spyOn(player, "nextTrack");
+ spyOn(utils.toHTML, "un").and.callFake(function (arg) { return arg; });
+
+ // Mock the Notify object
+ $window.Notify = jasmine.createSpyObj("Notify", ["isSupported", "needsPermission", "requestPermission"]);
+ NotificationObj = jasmine.createSpyObj("Notification", ["show", "close"]);
+ spyOn($window, "Notify").and.callFake(function (title, settings) {
+ NotificationObj.simulateClick = settings.notifyClick;
+ return NotificationObj;
+ });
+ });
+
+ it("can check whether we have the permission to display notifications in the current browser", function() {
+ $window.Notify.needsPermission.and.returnValue(false);
+
+ expect(notifications.hasPermission()).toBeTruthy();
+ expect($window.Notify.needsPermission).toHaveBeenCalled();
+ });
+
+ it("can check whether the current browser supports notifications", function() {
+ $window.Notify.isSupported.and.returnValue(true);
+
+ expect(notifications.isSupported()).toBeTruthy();
+ expect($window.Notify.isSupported).toHaveBeenCalled();
+ });
+
+ it("can request Notification permission for the current browser", function() {
+ spyOn(notifications, "isSupported").and.returnValue(true);
+ spyOn(notifications, "hasPermission").and.returnValue(false);
+
+ notifications.requestPermissionIfRequired();
+
+ expect($window.Notify.requestPermission).toHaveBeenCalled();
+ });
+
+ describe("When I show a notification, given a song,", function() {
+ var song;
+ beforeEach(function() {
+ song = {
+ coverartthumb: "https://backjaw.com/overquantity/outpitch?a=redredge&b=omnivoracious#promotement",
+ name: "Unhorny",
+ artist: "Saturnina Koster",
+ album: "Trepidate"
+ };
+ spyOn(notifications, "hasPermission").and.returnValue(true);
+ });
+ it("it checks the permissions, displays the title, the artist's name and the album picture in a notification", function() {
+ notifications.showNotification(song);
+
+ expect(notifications.hasPermission).toHaveBeenCalled();
+ expect($window.Notify).toHaveBeenCalledWith(song.name, {
+ body: song.artist + " - " + song.album,
+ icon: song.coverartthumb,
+ notifyClick: jasmine.any(Function)
+ });
+ expect(NotificationObj.show).toHaveBeenCalled();
+ });
+
+ it("when I click on it, it plays the next track of the queue", function() {
+ notifications.showNotification(song);
+ NotificationObj.simulateClick();
+
+ expect(player.nextTrack).toHaveBeenCalled();
+ expect(NotificationObj.close).toHaveBeenCalled();
+ });
+
+ it("given that the global Timeout setting is set to 10 seconds, it closes itself after 10 seconds", function() {
+ mockGlobals.settings.Timeout = 10000;
+
+ notifications.showNotification(song);
+ $interval.flush(10001);
+
+ expect(NotificationObj.close).toHaveBeenCalled();
+ });
+
+ it("if we don't have the permission to display notifications, nothing happens", function() {
+ notifications.hasPermission.and.returnValue(false);
+
+ notifications.showNotification(song);
+
+ expect(NotificationObj.show).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/app/common/page-service.js b/app/common/page-service.js
new file mode 100644
index 0000000..89747da
--- /dev/null
+++ b/app/common/page-service.js
@@ -0,0 +1,64 @@
+/**
+* jamstash.page Module
+*
+* Set the page's title from anywhere, the angular way
+*/
+angular.module('jamstash.page', ['jamstash.settings', 'jamstash.utils'])
+
+.factory('Page', ['$interval', 'globals', 'utils', function($interval, globals, utils){
+ 'use strict';
+
+ var title = 'Jamstash';
+ var timer;
+ return {
+ title: function() { return title; },
+ setTitle: function(newTitle) {
+ title = newTitle;
+ return this;
+ },
+ setTitleSong: function(song) {
+ if (song.artist !== undefined && song.name !== undefined) {
+ title = utils.toHTML.un(song.artist) + " - " + utils.toHTML.un(song.name);
+ } else {
+ title = 'Jamstash';
+ }
+ if (globals.settings.ScrollTitle) {
+ this.scrollTitle();
+ }
+
+ return this;
+ },
+ scrollTitle: function() {
+ var shift = {
+ "left": function (a) {
+ a.push(a.shift());
+ },
+ "right": function (a) {
+ a.unshift(a.pop());
+ }
+ };
+ var opts = {
+ text: title,
+ dir: "left",
+ speed: 1200
+ };
+
+ var t = (opts.text).split("");
+ if (!t) {
+ return;
+ }
+ t.push(" ");
+ if (timer !== undefined) {
+ $interval.cancel(timer);
+ }
+ timer = $interval(function () {
+ var f = shift[opts.dir];
+ if (f) {
+ f(t);
+ title = t.join("");
+ }
+ }, opts.speed);
+ return this;
+ }
+ };
+}]);
diff --git a/app/common/page-service_test.js b/app/common/page-service_test.js
new file mode 100644
index 0000000..b1994d2
--- /dev/null
+++ b/app/common/page-service_test.js
@@ -0,0 +1,54 @@
+describe("Page service", function() {
+ 'use strict';
+
+ var mockGlobals, Page, utils, $interval;
+ beforeEach(function() {
+
+ mockGlobals = {
+ settings: {
+ ScrollTitle: false
+ }
+ };
+
+ module('jamstash.page', function ($provide) {
+ $provide.value('globals', mockGlobals);
+ });
+
+ inject(function (_Page_, _utils_, _$interval_) {
+ Page = _Page_;
+ utils = _utils_;
+ $interval = _$interval_;
+ });
+ spyOn(utils.toHTML, "un").and.callFake(function (arg) { return arg; });
+ });
+
+ describe("Given a song,", function() {
+ var song;
+ beforeEach(function() {
+ song = {
+ artist: 'Merlyn Nurse',
+ name: 'Exsiccator tumble'
+ };
+ });
+
+ it("it displays its artist and its name as the page's title", function() {
+ Page.setTitleSong(song);
+ expect(Page.title()).toBe('Merlyn Nurse - Exsiccator tumble');
+ });
+
+ it("if the global setting 'ScrollTitle' is true, it scrolls the page title", function() {
+ spyOn(Page, "scrollTitle");
+ mockGlobals.settings.ScrollTitle = true;
+
+ Page.setTitleSong(song);
+
+ expect(Page.scrollTitle).toHaveBeenCalled();
+ });
+ });
+
+ it("Given a title, it can scroll it", function() {
+ Page.setTitle('unbeloved omnificent supergravitate').scrollTitle();
+ $interval.flush(1201);
+ expect(Page.title()).toBe('nbeloved omnificent supergravitate u');
+ });
+});
diff --git a/app/common/persistence-service.js b/app/common/persistence-service.js
new file mode 100644
index 0000000..a77cded
--- /dev/null
+++ b/app/common/persistence-service.js
@@ -0,0 +1,58 @@
+'use strict';
+/**
+* jamstash.persistence Module
+*
+* Provides load, save and delete operations for the current song and queue.
+* Data storage provided by HTML5 localStorage.
+*/
+angular.module('jamstash.persistence', ['jamstash.settings', 'jamstash.player.service', 'jamstash.notifications', 'angular-locker'])
+
+.config(['lockerProvider', function (lockerProvider) {
+ lockerProvider.setDefaultDriver('local')
+ .setDefaultNamespace('jamstash')
+ .setEventsEnabled(false);
+}])
+
+.service('persistence', ['globals', 'player', 'notifications', 'locker', function(globals, player, notifications, locker){
+ this.loadTrackPosition = function () {
+ // Load Saved Song
+ var song = locker.get('CurrentSong');
+ if (song) {
+ player.load(song);
+ }
+ if (globals.settings.Debug) { console.log('Current Position Loaded from localStorage: ', song); }
+ };
+
+ this.saveTrackPosition = function (song) {
+ locker.put('CurrentSong', song);
+ if (globals.settings.Debug) { console.log('Saving Current Position: ', song); }
+ };
+
+ this.deleteTrackPosition = function () {
+ locker.forget('CurrentSong');
+ if (globals.settings.Debug) { console.log('Removing Current Position from localStorage'); }
+ };
+
+ this.loadQueue = function () {
+ // load Saved queue
+ var queue = locker.get('CurrentQueue');
+ if (queue) {
+ player.addSongs(queue);
+ if (player.queue.length > 0) {
+ notifications.updateMessage(player.queue.length + ' Saved Song(s)', true);
+ }
+ if (globals.settings.Debug) { console.log('Play Queue Loaded from localStorage: ' + player.queue.length + ' song(s)'); }
+ }
+ };
+
+ this.saveQueue = function () {
+ locker.put('CurrentQueue', player.queue);
+ if (globals.settings.Debug) { console.log('Saving Queue: ' + player.queue.length + ' songs'); }
+ };
+
+ this.deleteQueue = function () {
+ locker.forget('CurrentQueue');
+ if (globals.settings.Debug) { console.log('Removing Play Queue from localStorage'); }
+ };
+}]);
+
diff --git a/app/common/persistence-service_test.js b/app/common/persistence-service_test.js
new file mode 100644
index 0000000..4bb9d48
--- /dev/null
+++ b/app/common/persistence-service_test.js
@@ -0,0 +1,126 @@
+describe("Persistence service", function() {
+ 'use strict';
+
+ var persistence, player, notifications, locker;
+ var song;
+ beforeEach(function() {
+ module('jamstash.persistence');
+
+ inject(function (_persistence_, _player_, _notifications_, _locker_) {
+ persistence = _persistence_;
+ player = _player_;
+ notifications = _notifications_;
+ locker = _locker_;
+ });
+
+ song = {
+ id: 8626,
+ name: 'Pectinatodenticulate',
+ artist: 'Isiah Hosfield',
+ album: 'Tammanyize'
+ };
+ player.queue = [];
+ });
+
+ describe("load from localStorage -", function() {
+ var fakeStorage;
+ beforeEach(function() {
+ fakeStorage = {};
+
+ spyOn(locker, "get").and.callFake(function(key) {
+ return fakeStorage[key];
+ });
+ });
+
+ describe("loadTrackPosition -", function() {
+ beforeEach(function() {
+ spyOn(player, "load");
+ });
+
+ it("Given that we previously saved the current track's position in local Storage, it loads the song we saved into the player", function() {
+ fakeStorage = { 'CurrentSong': song };
+
+ persistence.loadTrackPosition();
+
+ expect(locker.get).toHaveBeenCalledWith('CurrentSong');
+ expect(player.load).toHaveBeenCalledWith(song);
+ });
+
+ it("Given that we didn't save anything in local Storage, it doesn't load anything", function() {
+ persistence.loadTrackPosition();
+ expect(locker.get).toHaveBeenCalledWith('CurrentSong');
+ expect(player.load).not.toHaveBeenCalled();
+ });
+ });
+
+ describe("loadQueue -", function() {
+ beforeEach(function() {
+ spyOn(notifications, "updateMessage");
+ spyOn(player, "addSongs").and.callFake(function (songs) {
+ // Update the queue length so that notifications work
+ player.queue.length += songs.length;
+ });
+ });
+
+ it("Given that we previously saved the playing queue in local Storage, it fills the player's queue with what we saved and notifies the user", function() {
+ var queue = [
+ { id: 8705 },
+ { id: 1617 },
+ { id: 9812 }
+ ];
+ fakeStorage = { 'CurrentQueue': queue };
+
+ persistence.loadQueue();
+
+ expect(locker.get).toHaveBeenCalledWith('CurrentQueue');
+ expect(player.addSongs).toHaveBeenCalledWith(queue);
+ expect(notifications.updateMessage).toHaveBeenCalledWith('3 Saved Song(s)', true);
+ });
+
+ it("Given that we didn't save anything in local Storage, it doesn't load anything", function() {
+ persistence.loadQueue();
+
+ expect(locker.get).toHaveBeenCalledWith('CurrentQueue');
+ expect(player.addSongs).not.toHaveBeenCalled();
+ expect(notifications.updateMessage).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe("save from localStorage -", function() {
+ beforeEach(function() {
+ spyOn(locker, "put");
+ });
+
+ it("it saves the current track's position in local Storage", function() {
+ persistence.saveTrackPosition(song);
+ expect(locker.put).toHaveBeenCalledWith('CurrentSong', song);
+ });
+
+ it("it saves the playing queue in local Storage", function() {
+ player.queue = [
+ { id: 1245 },
+ { id: 7465 },
+ { id: 948 }
+ ];
+ persistence.saveQueue();
+ expect(locker.put).toHaveBeenCalledWith('CurrentQueue', player.queue);
+ });
+ });
+
+ describe("remove from localStorage -", function() {
+ beforeEach(function() {
+ spyOn(locker, "forget");
+ });
+
+ it("it deletes the current track from local Storage", function() {
+ persistence.deleteTrackPosition();
+ expect(locker.forget).toHaveBeenCalledWith('CurrentSong');
+ });
+
+ it("it deletes the saved playing queue from local Storage", function() {
+ persistence.deleteQueue();
+ expect(locker.forget).toHaveBeenCalledWith('CurrentQueue');
+ });
+ });
+});
diff --git a/app/common/player-service.js b/app/common/player-service.js
deleted file mode 100644
index c0db6d7..0000000
--- a/app/common/player-service.js
+++ /dev/null
@@ -1,415 +0,0 @@
-angular.module('JamStash')
-
-.service('player', ['$rootScope', '$window', 'utils', 'globals', 'model', 'notifications',
- function ($rootScope, $window, utils, globals, model, notifications) {
-
- 'use strict';
- var player1 = globals.Player1;
- var player2 = '#playdeck_2';
- var scrobbled = false;
- var timerid = 0;
- $rootScope.defaultPlay = function (data, event) {
- if (typeof $(player1).data("jPlayer") == 'undefined') {
- $rootScope.nextTrack();
- }
- if (typeof $(player1).data("jPlayer") != 'undefined' && globals.settings.Jukebox) {
- if ($(player1).data("jPlayer").status.paused) {
- $rootScope.sendToJukebox('start');
- } else {
- $rootScope.sendToJukebox('stop');
- }
- }
- };
- $rootScope.nextTrack = function () {
- var next = getNextSong();
- if (next) {
- $rootScope.playSong(false, next);
- }
- };
- $rootScope.previousTrack = function () {
- var next = getNextSong(true);
- if (next) {
- $rootScope.playSong(false, next);
- } else {
- $rootScope.restartSong();
- }
- };
- function getNextSong (previous) {
- var song;
- if (globals.settings.Debug) { console.log('Getting Next Song > ' + 'Queue length: ' + $rootScope.queue.length); }
- if ($rootScope.queue.length > 0) {
- angular.forEach($rootScope.queue, function (item, key) {
- if (item.playing === true) {
- song = item;
- } else {
- item.playing = false;
- }
- });
- var index = $rootScope.queue.indexOf(song);
- var next;
- if (previous) {
- next = $rootScope.queue[index - 1];
- } else {
- next = $rootScope.queue[index + 1];
- }
- if (typeof next != 'undefined') {
- if (globals.settings.Debug) { console.log('Next Song: ' + next.id); }
- return next;
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
- function internalScrobbleSong(submission) {
- if ($rootScope.loggedIn && submission) {
- var id = $rootScope.playingSong.id;
- if (globals.settings.Debug) { console.log('Scrobble Song: ' + id); }
- $.ajax({
- url: globals.BaseURL() + '/scrobble.view?' + globals.BaseParams() + '&id=' + id + "&submission=" + submission,
- method: 'GET',
- dataType: globals.settings.Protocol,
- timeout: 10000,
- success: function () {
- scrobbled = true;
- }
- });
- }
- }
- this.startSaveTrackPosition = function () {
- if (globals.settings.SaveTrackPosition) {
- if (timerid !== 0) {
- clearInterval(timerid);
- }
- timerid = $window.setInterval(function () {
- if (globals.settings.SaveTrackPosition) {
- this.saveTrackPosition();
- }
- }, 30000);
- }
- };
- this.toggleMute = function () {
- //var audio = typeof $(player1).data("jPlayer") != 'undefined' ? true : false;
- var audio = $(player1).data("jPlayer");
- if (typeof audio != 'undefined') {
- if (audio.options.muted) {
- audio.options.muted = false;
- } else {
- audio.options.muted = true;
- }
- }
- }
- this.saveTrackPosition = function () {
- //var audio = typeof $(player1).data("jPlayer") != 'undefined' ? true : false;
- var audio = $(player1).data("jPlayer");
- if (typeof audio != 'undefined') {
- if (audio.status.currentTime > 0 && audio.status.paused === false) {
- var song;
- angular.forEach($rootScope.queue, function (item, key) {
- if (item.playing === true) {
- song = item;
- }
- });
- if (song) {
- var position = audio.status.currentTime;
- if (position !== null) {
- $('#action_SaveProgress').fadeTo("slow", 0).delay(500).fadeTo("slow", 1).delay(500).fadeTo("slow", 0).delay(500).fadeTo("slow", 1);
- song.position = position;
- // Save Queue
- if (utils.browserStorageCheck()) {
- try {
- var songStr = angular.toJson(song);
- localStorage.setItem('CurrentSong', songStr);
- if (globals.settings.Debug) { console.log('Saving Current Position: ' + songStr); }
- var html = localStorage.getItem('CurrentQueue');
- if ($rootScope.queue.length > 0) {
- var current = $rootScope.queue;
- if (current != html) {
- localStorage.setItem('CurrentQueue', angular.toJson(current));
- if (globals.settings.Debug) { console.log('Saving Queue: ' + current.length + ' characters'); }
- }
- }
- } catch (e) {
- if (e == QUOTA_EXCEEDED_ERR) {
- alert('Quota exceeded!');
- }
- }
- } else {
- if (globals.settings.Debug) { console.log('HTML5::loadStorage not supported on your browser'); }
- }
- }
- }
- }
- } else {
- if (globals.settings.Debug) { console.log('Saving Queue: No Audio Loaded'); }
- }
- };
- this.loadTrackPosition = function () {
- if (utils.browserStorageCheck()) {
- // Load Saved Song
- var song = angular.fromJson(localStorage.getItem('CurrentSong'));
- if (song) {
- $rootScope.playSong(true, song);
- // Load Saved Queue
- var items = angular.fromJson(localStorage.getItem('CurrentQueue'));
- if (items) {
- //$rootScope.queue = [];
- $rootScope.queue = items;
- if ($rootScope.queue.length > 0) {
- notifications.updateMessage($rootScope.queue.length + ' Saved Song(s)', true);
- }
- if (globals.settings.Debug) { console.log('Play Queue Loaded From localStorage: ' + $rootScope.queue.length + ' song(s)'); }
- }
- }
- } else {
- if (globals.settings.Debug) { console.log('HTML5::loadStorage not supported on your browser'); }
- }
- };
- this.deleteCurrentQueue = function (data) {
- if (utils.browserStorageCheck()) {
- localStorage.removeItem('CurrentQueue');
- utils.setValue('CurrentSong', null, false);
- if (globals.settings.Debug) { console.log('Removing Play Queue'); }
- } else {
- if (globals.settings.Debug) { console.log('HTML5::loadStorage not supported on your browser, ' + html.length + ' characters'); }
- }
- };
- $rootScope.restartSong = function (loadonly, data) {
- var audio = $(player1).data("jPlayer");
- audio.play(0);
- };
- $rootScope.playSong = function (loadonly, data) {
- if (globals.settings.Debug) { console.log('Play: ' + JSON.stringify(data, null, 2)); }
- angular.forEach($rootScope.queue, function(item, key) {
- item.playing = false;
- });
- data.playing = true;
- data.selected = false;
-
- if ($rootScope.playingSong != null && data.id != $rootScope.playingSong.id && $.fancybox.isOpen) {
- utils.fancyboxOpenImage(data.coverartfull);
- }
-
- $rootScope.playingSong = data;
-
- var id = data.id;
- var url = data.url;
- var position = data.position;
- var title = data.name;
- var album = data.album;
- var artist = data.artist;
- var suffix = data.suffix;
- var specs = data.specs;
- var coverartthumb = data.coverartthumb;
- var coverartfull = data.coverartfull;
- var starred = data.starred;
- $('#playermiddle').css('visibility', 'visible');
- $('#songdetails').css('visibility', 'visible');
-
- if (globals.settings.Jukebox) {
- $rootScope.addToJukebox(id);
- $rootScope.loadjPlayer(player1, url, suffix, true, position);
- } else {
- $rootScope.loadjPlayer(player1, url, suffix, loadonly, position);
- }
-
- var spechtml = '';
- var data = $(player1).data().jPlayer;
- for (var i = 0; i < data.solutions.length; i++) {
- var solution = data.solutions[i];
- if (data[solution].used) {
- spechtml += "" + solution + " is";
- spechtml += " currently being used with";
- angular.forEach(data[solution].support, function (format) {
- if (data[solution].support[format]) {
- spechtml += " " + format + "";
- }
- });
- spechtml += " support";
- }
- }
- $('#SMStats').html(spechtml);
- scrobbled = false;
-
- if ($rootScope.queue.length > 0) {
- $('#queue').stop().scrollTo('#' + id, 400);
- }
-
- if (globals.settings.NotificationSong && !loadonly) {
- notifications.showNotification(coverartthumb, utils.toHTML.un(title), utils.toHTML.un(artist + ' - ' + album), 'text', '#NextTrack');
- }
- if (globals.settings.ScrollTitle) {
- utils.scrollTitle(utils.toHTML.un(artist) + ' - ' + utils.toHTML.un(title));
- } else {
- utils.setTitle(utils.toHTML.un(artist) + ' - ' + utils.toHTML.un(title));
- }
- //utils.safeApply();
- if(!$rootScope.$root.$$phase) {
- $rootScope.$apply();
- }
- };
- $rootScope.loadjPlayer = function (el, url, suffix, loadonly, position) {
- // jPlayer Setup
- var volume = 1;
- if (utils.getValue('Volume')) {
- volume = parseFloat(utils.getValue('Volume'));
- }
- var audioSolution = "html,flash";
- if (globals.settings.ForceFlash) {
- audioSolution = "flash,html";
- }
- if (globals.settings.Debug) { console.log('Setting Audio Solution: ' + audioSolution); }
- //var salt = Math.floor(Math.random() * 100000);
- //url += '&salt=' + salt;
- var muted = false;
- if (globals.settings.Jukebox) { muted = true;}
- $(el).jPlayer("destroy");
- $.jPlayer.timeFormat.showHour = true;
- $(el).jPlayer({
- swfPath: "js/plugins/jplayer",
- wmode: "window",
- solution: audioSolution,
- supplied: suffix,
- volume: volume,
- muted: muted,
- errorAlerts: false,
- warningAlerts: false,
- cssSelectorAncestor: "",
- 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 () {
- console.log("File Suffix: " + suffix);
- if (suffix == 'oga') {
- $(this).jPlayer("setMedia", {
- oga: url
- });
- } else if (suffix == 'm4a') {
- $(this).jPlayer("setMedia", {
- m4a: url
- });
- } else if (suffix == 'mp3') {
- $(this).jPlayer("setMedia", {
- mp3: url
- });
- }
- if (!loadonly) { // Start playing
- $(this).jPlayer("play");
- } else { // Loadonly
- //$('#' + songid).addClass('playing');
- $(this).jPlayer("pause", position);
- }
- if (globals.settings.Debug) {
- console.log('[jPlayer Version Info]');
- utils.logObjectProperties($(el).data("jPlayer").version);
- console.log('[HTML5 Debug Info]');
- utils.logObjectProperties($(el).data("jPlayer").html);
- console.log('[Flash Debug Info]');
- utils.logObjectProperties($(el).data("jPlayer").flash);
- console.log('[jPlayer Options Info]');
- utils.logObjectProperties($(el).data("jPlayer").options);
- }
- },
- timeupdate: function (event) {
- // Scrobble song once percentage is reached
- var p = event.jPlayer.status.currentPercentAbsolute;
- if (!scrobbled && p > 30) {
- if (globals.settings.Debug) { console.log('LAST.FM SCROBBLE - Percent Played: ' + p); }
- internalScrobbleSong(true);
- }
- },
- volumechange: function (event) {
- utils.setValue('Volume', event.jPlayer.options.volume, true);
- },
- ended: function (event) {
- if (globals.settings.Repeat) { // Repeat current track if enabled
- $(this).jPlayer("play");
- } else {
- if (!getNextSong()) { // Action if we are at the last song in queue
- if (globals.settings.LoopQueue) { // Loop to first track in queue if enabled
- var next = $rootScope.queue[0];
- $rootScope.playSong(false, next);
- } else if (globals.settings.AutoPlay) { // Load more tracks if enabled
- $rootScope.getRandomSongs('play', '', '');
- notifications.updateMessage('Auto Play Activated...', true);
- }
- } else {
- $rootScope.nextTrack();
- }
- }
- },
- error: function (event) {
- var time = $(player1).data("jPlayer").status.currentTime;
- $(player1).jPlayer("play", time);
- if (globals.settings.Debug) {
- console.log("Error Type: " + event.jPlayer.error.type);
- console.log("Error Context: " + event.jPlayer.error.context);
- console.log("Error Message: " + event.jPlayer.error.message);
- console.log("Stream interrupted, retrying from position: " + time);
- }
- }
- });
- return;
- };
- this.playPauseSong = function () {
- if (typeof $(player1).data("jPlayer") != 'undefined') {
- if ($(player1).data("jPlayer").status.paused) {
- $(player1).jPlayer("play");
- } else {
- $(player1).jPlayer("pause");
- }
- }
- };
- this.playVideo = function (id, bitrate) {
- var w, h;
- bitrate = parseInt(bitrate);
- if (bitrate <= 600) {
- w = 320; h = 240;
- } else if (bitrate <= 1000) {
- w = 480; h = 360;
- } else {
- w = 640; h = 480;
- }
- //$("#jPlayerSelector").jPlayer("option", "fullScreen", true);
- $("#videodeck").jPlayer({
- ready: function () {
- /*
- $.fancybox({
- autoSize: false,
- width: w + 10,
- height: h + 10,
- content: $('#videodeck')
- });
- */
- $(this).jPlayer("setMedia", {
- m4v: 'https://&id=' + id + '&salt=83132'
- }).jPlayer("play");
- $('#videooverlay').show();
- },
- swfPath: "js/jplayer",
- solution: "html, flash",
- supplied: "m4v"
- });
- };
- this.scrobbleSong = internalScrobbleSong;
- this.rateSong = function (songid, rating) {
- $.ajax({
- url: baseURL + '/setRating.view?' + baseParams + '&id=' + songid + "&rating=" + rating,
- method: 'GET',
- dataType: protocol,
- timeout: 10000,
- success: function () {
- updateMessage('Rating Updated!', true);
- }
- });
- };
-}]);
diff --git a/app/common/songs.html b/app/common/songs.html
index c2ab466..37c442c 100644
--- a/app/common/songs.html
+++ b/app/common/songs.html
@@ -1,6 +1,6 @@
-
+
@@ -18,4 +18,4 @@
{{o.time}}
-
\ No newline at end of file
+
diff --git a/app/common/songs_lite.html b/app/common/songs_lite.html
index e5f8ba8..9997004 100644
--- a/app/common/songs_lite.html
+++ b/app/common/songs_lite.html
@@ -1,10 +1,10 @@
-
+
-
+
{{o.time}}
-
\ No newline at end of file
+
diff --git a/app/common/utils-service.js b/app/common/utils-service.js
index c10de56..c2b9e01 100644
--- a/app/common/utils-service.js
+++ b/app/common/utils-service.js
@@ -8,22 +8,6 @@ angular.module('jamstash.utils', ['jamstash.settings'])
.service('utils', ['$rootScope', 'globals', function ($rootScope, globals) {
'use strict';
- this.fancyboxOpenImage = function (url) {
- $.fancybox.open({
- helpers : {
- overlay : {
- css : {
- 'background' : 'rgba(0, 0, 0, 0.15)'
- }
- }
- },
- hideOnContentClick: true,
- type: 'image',
- openEffect: 'none',
- closeEffect: 'none',
- href: url
- });
- };
this.safeApply = function (fn) {
var phase = $rootScope.$root.$$phase;
if (phase === '$apply' || phase === '$digest') {
@@ -100,14 +84,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;
@@ -259,41 +235,6 @@ angular.module('jamstash.utils', ['jamstash.settings'])
var u = strurl.substring(0, strurl.indexOf('?'));
return u;
};
- this.setTitle = function (text) {
- if (text !== "") {
- document.title = text;
- }
- };
- var timer = 0;
- this.scrollTitle = function (text) {
- var shift = {
- "left": function (a) {
- a.push(a.shift());
- },
- "right": function (a) {
- a.unshift(a.pop());
- }
- };
- var opts = {
- text: text,
- dir: "left",
- speed: 1200
- };
-
- var t = (opts.text || document.title).split("");
- if (!t) {
- return;
- }
- t.push(" ");
- clearInterval(timer);
- timer = setInterval(function () {
- var f = shift[opts.dir];
- if (f) {
- f(t);
- document.title = t.join("");
- }
- }, opts.speed);
- };
this.parseVersionString = function (str) {
if (typeof (str) !== 'string') { return false; }
var x = str.split('.');
@@ -353,4 +294,4 @@ angular.module('jamstash.utils', ['jamstash.settings'])
var newDate = months[month] + " " + dateParts[2] + ", " + dateParts[0];
return newDate;
};
-}]);
\ No newline at end of file
+}]);
diff --git a/app/images/pause_alt_24x32.png b/app/images/pause_alt_24x24.png
similarity index 100%
rename from app/images/pause_alt_24x32.png
rename to app/images/pause_alt_24x24.png
diff --git a/app/images/play_alt_24x32.png b/app/images/play_alt_24x24.png
similarity index 100%
rename from app/images/play_alt_24x32.png
rename to app/images/play_alt_24x24.png
diff --git a/app/index.html b/app/index.html
index c0f2e1e..c4322b9 100755
--- a/app/index.html
+++ b/app/index.html
@@ -1,175 +1,121 @@
-
-
-
-
-
-
-
-
- Jamstash
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-