4.0.1 commit

This commit is contained in:
Trevor Squillario 2014-11-08 14:03:28 -05:00
parent ccca94e8ba
commit 0bdb803966
24 changed files with 425 additions and 347 deletions

BIN
images/cloud_w_12x8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

BIN
images/first_alt_24x24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
images/last_alt_24x24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
images/loop_alt3_w_12x9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

BIN
images/pause_alt_24x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
images/play_alt_24x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 840 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 843 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

BIN
images/volume_w_12x9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

View file

@ -12,7 +12,7 @@
<link href="style/Style.css" rel="stylesheet" type="text/css" data-name="main" />
<link href="" rel="stylesheet" type="text/css" data-name="theme" />
<link href="js/plugins/fancybox/jquery.fancybox.css" rel="stylesheet" type="text/css" />
<link href="js/plugins/jquery-split-pane.css" rel="stylesheet" />
<!--<link href="js/plugins/jquery-split-pane.css" rel="stylesheet" />-->
<script src="js/plugins/jquery-2.0.3.min.js" type="text/javascript"></script>
<script src="js/plugins/angular.min.js" type="text/javascript"></script>
<script src="js/plugins/angular-route.min.js"></script>
@ -23,7 +23,7 @@
<script src="js/plugins/angular-ui-router.min.js"></script>
-->
<script src="js/plugins/jquery-ui-1.10.3.custom.min.js" type="text/javascript"></script>
<script src="js/plugins/jquery-split-pane.js"></script>
<!--<script src="js/plugins/jquery-split-pane.js"></script>-->
<script src="js/plugins/fancybox/jquery.fancybox.js" type="text/javascript"></script>
<script src="js/plugins/jquery.base64.js" type="text/javascript"></script>
<script src="js/plugins/jquery.dateFormat-1.0.js" type="text/javascript"></script>
@ -49,12 +49,11 @@
<a id="jslogo" title="Jamstash" class="showQueue" href=""></a>
<a id="sslogo" target="_blank" ng-show="settings.Server" ng-href="{{settings.Server}}" title="{{settings.Server}}"></a>
<div id="globalactions">
<a href="" class="button" id="action_ToggleSideBar" title="Toggle Side Bar"><img src="images/arrow_right_gl_8x8.png" /></a>
</div>
<div id="nav">
<ul class="tabs">
<li><a href="" class="first showQueue" id="action_Queue" title="Queue" class="active" ng-class="{'active': isActive('/queue')}"><img src="images/play_alt_gd_16x16.png"></a></li>
<li><a href="#/library" id="action_Library" title="Library" ng-class="{'active': isActive('/library')}"><img src="images/headphones_gd_16x14.png" /></a></li>
<li><a href="#/library" class="first" id="action_Library" title="Library" ng-class="{'active': isActive('/library')}"><img src="images/headphones_gd_16x14.png" /></a></li>
<!--<li><a href="#/playlists" id="action_Playlists" title="Playlists" ng-class="{'active': isActive('/playlists')}"><img src="images/list_gd_16x14.png" /></a></li>-->
<!--<li><a href="#/podcasts" id="action_Podcasts" title="Podcasts" ng-class="{'active': isActive('/podcasts')}"><img src="images/rss_16x16.png" /></a></li>-->
<li><a href="#/archive" id="action_Archive" class="" title="Archive.org - Live Music Archive" ng-class="{'active': isActive('/archive')}"><img src="images/archive_gd_16x16.png" /></a></li>
@ -65,8 +64,24 @@
<div id="content">
<!-- Main -->
<div ng-view></div>
<!-- Audio Player -->
<div class="clear"></div>
<div class="clear"></div>
</div><!-- end #content -->
<div id="SideBar">
<div class="headeractions">
<a class="buttonimg" title="Shuffle Queue" ng-click="queueShuffle()"><img src="images/fork_gd_11x12.png"></a>
<a class="buttonimg" id="action_Empty" title="Delete Queue" ng-click="queueEmpty()"><img src="images/trash_fill_gd_12x12.png"></a>
<a class="buttonimg" id="action_DeleteSelected" title="Remove Selected From Queue" ng-click="queueRemoveSelected()"><img src="images/x_11x11.png"></a>
</div>
<div class="header">Queue</div>
<div id="SideQueue">
<ul class="simplelist songlist noselect" ng-if="queue.length > 0">
<div ng-repeat="song in [queue] track by $index" class="songs" ng-include src="'js/partials/songs_lite.html'" sortable></div>
</ul>
</div>
<!--
<div id="NowPlaying">
<div class="header"><img src="images/rss_12x12.png" /> Now Playing</div>
<div id="NowPlayingList"><span class="user">Loading...</span></div>
@ -76,38 +91,34 @@
<div id="ChatMsgs"></div>
</div>
<div class="submit"><img src="images/comment_stroke_gl_12x11.png" /><input type="text" id="ChatMsg" class="chat" title="Hit [Enter] to Post" /></div>
-->
</div>
<!-- Audio Player -->
<div class="clear"></div>
<div class="clear"></div>
</div><!-- end #content -->
<!-- Player -->
<div id="player">
<div id="playercontainer">
<div id="playerleft" class="floatleft">
<div class="playeractions floatleft">
<a class="button" id="PreviousTrack" title="Previous Track" ng-click="previousTrack()"><img src="images/first_24x24.png" /></a>
<a class="button PlayTrack" title="Play/Pause" ng-click="defaultPlay()"><img src="images/play_24x32.png" /></a>
<a class="button PauseTrack" title="Play/Pause" style="display: none;"><img src="images/pause_24x32.png" /></a>
<a class="button" id="NextTrack" title="Next Track" ng-click="nextTrack()"><img src="images/last_24x24.png" /></a>
<a class="hover" id="PreviousTrack" title="Previous Track" ng-click="previousTrack()"><img src="images/first_alt_24x24.png" /></a>
<a class="hover PlayTrack" title="Play/Pause" ng-click="defaultPlay()"><img src="images/play_alt_24x32.png" /></a>
<a class="hover PauseTrack" title="Play/Pause" style="display: none;"><img src="images/pause_alt_24x32.png" /></a>
<a class="hover" id="NextTrack" title="Next Track" ng-click="nextTrack()"><img src="images/last_alt_24x24.png" /></a>
</div>
<div id="songdetails">
<div id="coverart"><a class="coverartfancy" href="{{playingSong.coverartfull}}"><img ng-src="{{playingSong.coverartthumb}}" src="images/albumdefault_60.jpg" alt="" /></a></div>
<ul>
<li class="song" id="{{playingSong.id}}" ng-bind-html="playingSong.name"></li>
<li class="song" id="{{playingSong.id}}" ng-bind-html="playingSong.name" title="{{playingSong.specs}}"></li>
<li class="album" ng-bind-html="playingSong.album"></li>
<li class="specs" ng-bind-html="playingSong.specs"></li>
<li id="songdetails_controls">
<a href="" id="action_Mute" class="mute first" title="Mute"></a>
<a href="" id="action_UnMute" class="unmute first" title="Unmute" style="display: none;"></a>
<div class="jp-volume-bar"><div class="jp-volume-bar-value"></div></div><a href="" id="action_VolumeMax" class="volume" title="Max Volume"></a>
</ul>
<div id="songdetails_controls">
<a href="" class="jukebox" title="Jukebox Mode [Beta]" ng-click="toggleSetting('Jukebox')" ng-class="{'hoverSelected': !settings.Jukebox }"></a>
<a href="" class="loop" title="Repeat" ng-click="toggleSetting('Repeat')" ng-class="{'hoverSelected': !settings.Repeat }"></a>
<a href="" id="action_SaveProgress" class="lock" title="Save Track Position: On" ng-show="settings.SaveTrackPosition"></a>
<a title="Favorite" href="" ng-class="{'favorite': playingSong.starred, 'rate': !playingSong.starred}" ng-click="updateFavorite(playingSong)" stop-event="click"></a>
</li>
</ul>
<div class="vertshade"></div>
<a href="" id="action_Mute" class="mute" title="Mute"></a>
<a href="" id="action_UnMute" class="unmute" title="Unmute" style="display: none;"></a>
<!--<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 class="vertshade"></div>-->
</div>
<div id="playdeck_1"></div>
<div id="playdeck_2"></div>
@ -118,7 +129,7 @@
</table>
</div>
</div>
<div class="playeractionssmall"><!--<a href="" class="button" id="action_ToggleSideBar" title="Toggle Side Bar"><img src="images/arrow_right_gl_12x12.png" /></a>--></div>
<div class="playeractionssmall"></div>
<div id="playermiddle">
<div id="audiocontainer">
<div class="audiojs" id="audio_wrapper0">
@ -133,21 +144,6 @@
</div>
</div>
</div> <!-- End container -->
<div id="queue">
<div class="queueactions">
<!--<a href="" class="button buttonvertical" id="action_QueueToPlaylist" title="Create Playlist From Queue"><img src="images/list_gd_12x11.png" /></a>-->
<a class="button" id="PreviousTrack" title="Previous Track" ng-click="previousTrack()"><img src="images/first_12x12.png" /></a>
<a class="button PlayTrack" title="Play/Pause" ng-click="defaultPlay()"><img src="images/play_12x16.png" /></a>
<a class="button PauseTrack" title="Play/Pause" style="display: none;"><img src="images/pause_12x16.png" /></a>
<a class="button" id="NextTrack" title="Next Track" ng-click="nextTrack()"><img src="images/last_12x12.png" /></a>
<a class="button" title="Shuffle Queue" ng-click="queueShuffle()">Shuffle</a>
<a class="button" id="action_Empty" title="Delete Queue" ng-click="queueEmpty()">Empty</a>
<a class="button" id="action_DeleteSelected" title="Remove Selected From Queue" ng-click="queueRemoveSelected()">Remove Song(s)</a>
</div>
<ul class="simplelist songlist noselect" style="width: 1200px;" ng-if="queue.length > 0">
<div ng-repeat="song in [queue] track by $index" class="songs" ng-include src="'js/partials/songs.html'" sortable></div>
</ul>
</div>
<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {

View file

@ -119,7 +119,11 @@ JamStash.config(function ($httpProvider) {
if (globals.settings.Username != "" && globals.settings.Password != "" && globals.settings.Server != "") {
$rootScope.loggedIn = true;
}
if (!$rootScope.loggedIn && $location.path() != '/settings' && $location.path() != '/archive') {
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;

View file

@ -124,7 +124,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, $htt
timeout: globals.settings.Timeout,
success: function (data) {
if (data["subsonic-response"].user.adminRole === true) {
$.get(globals.settings.Server + '/musicFolderSettings.view?scanNow');
$.post(globals.settings.Server + '/musicFolderSettings.view?scanNow');
} else {
alert('You are not logged in as an admin user!');
}

View file

@ -204,7 +204,9 @@ function AppCtrl($scope, $rootScope, $document, $window, $location, $cookieStore
$('.audiojs .scrubber').stop().animate({ height: '4px' });
});
$('.message').on('click', function () { $(this).remove(); });
$(document).on("click", ".message", function(){
$(this).remove();
});
// Sway.fm Unity Plugin
$rootScope.unity = UnityMusicShim();
@ -337,7 +339,7 @@ function AppCtrl($scope, $rootScope, $document, $window, $location, $cookieStore
}
};
$scope.scrollToTop = function () {
$('#Artists').stop().scrollTo('#auto', 400);
$('#left-component').stop().scrollTo('#MusicFolders', 400);
};
$rootScope.selectAll = function (songs) {
angular.forEach(songs, function (item, key) {
@ -381,6 +383,9 @@ function AppCtrl($scope, $rootScope, $document, $window, $location, $cookieStore
notifications.updateMessage($scope.selectedSongs.length + ' Song(s) Added to Queue', true);
$scope.selectedSongs.length = 0;
}
};
$scope.addSongToQueue = function (data) {
$rootScope.queue.push(data);
};
$rootScope.removeSong = function (item, songs) {
var index = songs.indexOf(item)
@ -473,9 +478,6 @@ function AppCtrl($scope, $rootScope, $document, $window, $location, $cookieStore
}
});
};
$scope.addSongToQueue = function (data) {
$rootScope.queue.push(data);
};
$scope.queueRemoveSelected = function (data, event) {
angular.forEach($scope.selectedSongs, function (item, key) {
var index = $rootScope.queue.indexOf(item);
@ -514,6 +516,23 @@ function AppCtrl($scope, $rootScope, $document, $window, $location, $cookieStore
data.selected = true;
}
};
$rootScope.addToJukebox = function (id) {
if (globals.settings.Debug) { console.log("LOAD JUKEBOX"); }
$.ajax({
url: globals.BaseURL() + '/jukeboxControl.view?' + globals.BaseParams() + '&action=set&id=' + id,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
/*
if (data["subsonic-response"].podcasts.channel !== undefined) {
}
deferred.resolve(podcasts);
*/
$.get(globals.BaseURL() + '/jukeboxControl.view?' + globals.BaseParams() + '&action=start');
}
});
};
$scope.updateFavorite = function (item) {
var id = item.id;
var starred = item.starred;

View file

@ -1,6 +1,6 @@
JamStash.controller('SettingsCtrl',
function SettingsCtrl($rootScope, $scope, $routeParams, $location, utils, globals, json, notifications, player) {
$scope.settings = globals.settings;
$scope.settings = globals.settings; /* See service.js */
$scope.Timeouts = [
{ id: 10000, name: 10 },
{ id: 20000, name: 20 },

View file

@ -1,4 +1,13 @@
[
{
"date": "10/18/2014", "version": "4.0.1",
"changes": [
{ "text": "- Moved Queue to the right side. You don't have to click to see it now!" },
{ "text": "- Style refresh, thanks to <a href=\"https://twitter.com/erase_me\" target=\"_blank\">@erase_me</a> for the CSS magic :)" },
{ "text": "- Fixed \"Rescan Library\" button" },
{ "text": "- Jukebox support added [Beta]" }
]
},
{
"date": "7/28/2014", "version": "3.4.2",
"changes": [

View file

@ -29,6 +29,52 @@
<a href="" class="button" id="action_NewPlaylist" title="New Playlist" ng-click="newPlaylist()">+ New</a>
</div>
<div id="SubsonicAlbums" class="section lgsection split-pane fixed-left" split>
<!-- Album -->
<div id="right-component" class="split-pane-component lgcolumn">
<ul class="actionlist">
<li>
<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" ng-repeat="o in BreadCrumbs | filter:{type:'artist'}"><a ng-click="getAlbums(o.id, o.name)">{{o.name}}</a> &gt;</div>
<div class="crumb" ng-repeat="o in BreadCrumbs | filter:{type:'album'}"><a ng-click="getSongs(o.id, '')">{{o.name}}</a> &gt;</div>
</div>
</div>
</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(o.id, '')" parentid="{{o.parentid}}">
<div class="itemactions">
<a class="add" href="" title="Add To Play Queue" ng-click="getSongs(o.id, 'add')" stop-event="click"></a>
<a class="play" href="" title="Play" ng-click="getSongs(o.id, 'play')" stop-event="click"></a>
<a class="download" href="" ng-click="download(o.id)" title="Download" stop-event="click"></a>
<a title="Favorite" href="" ng-class="{'favorite': o.starred, 'rate': !o.starred}" ng-click="updateFavorite(o)" stop-event="click"></a>
<a class="info hover" href="" title="{{'Created: ' + o.date}}"></a>
</div>
<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="getAlbums(o.parentid, o.artist)" stop-event="click" ng-bind-html="o.artist"></a></div>
</div>
<div class="clear"></div>
</li>
<li class="album" ng-switch-when="bytag" id="{{o.id}}" ng-class="{'selected': selectedAlbum == o.id, 'albumgrid': settings.DefaultLibraryLayout.id == 'grid'}" ng-click="getAlbumByTag(o.id)">
<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="" ng-click="getArtistByTag(o.artistId)" stop-event="click" ng-bind-html="o.artist"></a></div>
</div>
<div class="clear"></div>
</li>
</div>
<div ng-if="song.length > 0" ng-include src="'js/partials/songs.html'"></div>
</ul>
</div>
</div>
<div id="left-component" class="split-pane-component smcolumn noselect" tabindex="0">
<ul class="tablist">
<li class="" ng-click="toggleIndex()"><a href="">Artists</a></li>
@ -60,7 +106,7 @@
</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><span class="floatright">?</span></li>
<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="getAlbums(a.id, a.name)"><a ng-href="" ng-bind-html="a.name"></a></li>
</ul>
@ -134,53 +180,6 @@
</ul>
</div>
</div>
<div class="split-pane-divider" id="my-divider"></div>
<!-- Album -->
<div id="right-component" class="split-pane-component lgcolumn">
<ul class="actionlist">
<li>
<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" ng-repeat="o in BreadCrumbs | filter:{type:'artist'}"><a ng-click="getAlbums(o.id, o.name)">{{o.name}}</a> &gt;</div>
<div class="crumb" ng-repeat="o in BreadCrumbs | filter:{type:'album'}"><a ng-click="getSongs(o.id, '')">{{o.name}}</a> &gt;</div>
</div>
</div>
</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(o.id, '')" parentid="{{o.parentid}}">
<div class="itemactions">
<a class="add" href="" title="Add To Play Queue" ng-click="getSongs(o.id, 'add')" stop-event="click"></a>
<a class="play" href="" title="Play" ng-click="getSongs(o.id, 'play')" stop-event="click"></a>
<a class="download" href="" ng-click="download(o.id)" title="Download" stop-event="click"></a>
<a title="Favorite" href="" ng-class="{'favorite': o.starred, 'rate': !o.starred}" ng-click="updateFavorite(o)" stop-event="click"></a>
<a class="info hover" href="" title="{{'Created: ' + o.date}}"></a>
</div>
<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="getAlbums(o.parentid, o.artist)" stop-event="click" ng-bind-html="o.artist"></a></div>
</div>
<div class="clear"></div>
</li>
<li class="album" ng-switch-when="bytag" id="{{o.id}}" ng-class="{'selected': selectedAlbum == o.id, 'albumgrid': settings.DefaultLibraryLayout.id == 'grid'}" ng-click="getAlbumByTag(o.id)">
<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="" ng-click="getArtistByTag(o.artistId)" stop-event="click" ng-bind-html="o.artist"></a></div>
</div>
<div class="clear"></div>
</li>
</div>
<div ng-if="song.length > 0" ng-include src="'js/partials/songs.html'"></div>
</ul>
</div>
</div>
<div id="submenu_AZIndex" class="submenu shadow" style="display: none;">
<ul>
<li ng-repeat="o in index"><a href="" ng-click="scrollToIndexName(o.name)">{{o.name}}</a></li>

View file

@ -30,7 +30,7 @@
</div>
<div class="subsection floatleft checkboxes">
<div class="checkboxes">
<fieldset id="General">
<fieldset>
<legend class="aligncenter">General</legend>
<div class="inputwrap"><input type="checkbox" id="AutoPlay" name="AutoPlay" value="1" title="When the Queue has ended, load random songs" ng-model="settings.AutoPlay" /></div>
<label for="AutoPlay">Auto Play</label>
@ -73,7 +73,14 @@
</div>
<div class="subsection floatleft">
<div class="checkboxes">
<fieldset id="Advanced">
<fieldset>
<legend class="aligncenter">Jukebox</legend>
<div class="inputwrap"><input type="checkbox" id="Jukebox" name="Jukebox" value="1" title="Enable Jukebox Mode [Beta]" ng-model="settings.Jukebox" /></div>
<label for="Jukebox">Enable</label>
</fieldset>
</div>
<div class="checkboxes">
<fieldset>
<legend class="aligncenter">Advanced</legend>
<div class="inputwrap"><input type="checkbox" id="Debug" name="Debug" value="1" title="Enable Debug Mode (Events will be logged to the Javascript Console)" ng-model="settings.Debug" /></div>
<label for="Debug">Debug Mode</label>

View file

@ -0,0 +1,10 @@
<li class="row song" ng-repeat="o in song" ng-click="selectSong(o)" ng-dblclick="playSong(false, o)" ng-class="{'selected': o.selected, 'playing': o.playing}">
<div class="itemactions">
<a class="remove" href="" title="Remove Song" ng-click="removeSongFromQueue(o)" stop-event="click"></a>
<a href="" title="Favorite" ng-class="{'favorite': o.starred, 'rate': !o.starred}" ng-click="updateFavorite(o)" stop-event="click"></a>
<div class="clear"></div>
</div>
<div class="title floatleft" title="{{o.description}}" ng-bind-html="o.name"></div>
<div class="time floatleft">{{o.time}}</div>
<div class="clear"></div>
</li>

View file

@ -60,6 +60,17 @@
}, 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");
@ -163,6 +174,11 @@
$('#songdetails').css('visibility', 'visible');
$rootScope.loadjPlayer(player1, url, suffix, loadonly, position);
if (globals.settings.Jukebox) {
$rootScope.addToJukebox(id);
}
if (!loadonly) {
// Sway.fm UnityShim
var playerState = {
@ -177,9 +193,7 @@
}
// End UnityShim
}
if ($rootScope.queue.length > 0) {
$('#queue').stop().scrollTo('#' + id, 400);
}
var spechtml = '';
var data = $(player1).data().jPlayer;
for (i = 0; i < data.solutions.length; i++) {
@ -198,6 +212,10 @@
$('#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');
}
@ -224,6 +242,8 @@
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({
@ -232,6 +252,7 @@
solution: audioSolution,
supplied: suffix,
volume: volume,
muted: muted,
errorAlerts: false,
warningAlerts: false,
cssSelectorAncestor: "",
@ -260,10 +281,6 @@
$(this).jPlayer("setMedia", {
mp3: url
});
} else if (suffix == 'm4a') {
$(this).jPlayer("setMedia", {
m4a: url
});
}
if (!loadonly) { // Start playing
$(this).jPlayer("play");

View file

@ -122,6 +122,7 @@ JamStash.service('globals', function () {
DefaultSearchType: this.SearchTypes[0],
DefaultAlbumSort: this.AlbumSorts[0],
DefaultArchiveAlbumSort: "date desc",
Jukebox: false,
AutoPlay: false,
LoopQueue: false,
Repeat: false,
@ -215,6 +216,7 @@ JamStash.directive('sortable', function () {
}
};
});
/*
JamStash.directive('split', function () {
return {
link: function (scope, elm, attrs) {
@ -222,6 +224,7 @@ JamStash.directive('split', function () {
}
};
});
*/
JamStash.directive('fancybox', function ($compile) {
return {
restrict: 'A',
@ -406,7 +409,7 @@ JamStash.service('map', function ($http, globals, utils, model) {
var url, title, artist, track, rating, starred, contenttype, suffix, description;
var specs = '', coverartthumb = '', coverartfull = '';
if (typeof song.coverArt != 'undefined') {
coverartthumb = globals.BaseURL() + '/getCoverArt.view?' + globals.BaseParams() + '&size=60&id=' + song.coverArt;
coverartthumb = globals.BaseURL() + '/getCoverArt.view?' + globals.BaseParams() + '&size=30&id=' + song.coverArt;
coverartfull = globals.BaseURL() + '/getCoverArt.view?' + globals.BaseParams() + '&id=' + song.coverArt;
} else {
coverartthumb = 'images/albumdefault_60.jpg';
@ -1250,7 +1253,7 @@ JamStash.factory('subsonic', function ($rootScope, $http, $q, globals, utils, ma
}
});
return deferred.promise;
}
},
// End subsonic
};
});

View file

@ -42,10 +42,19 @@ span.apiversion
border-right: 1px solid #1a1a1a;
border-left: 1px solid #1a1a1a;
}
.smsection
.smcolumn
{
background: none;
/*border-right: 1px solid #5A5A5A;*/
border-right: 1px solid #1D1D1D;
}
ul.tablist li {
background: #232323;
border-top: 1px solid #171717;
border-left: 1px solid #171717;
border-right: 1px solid #171717;
}
.leftsubsection {
border-top: 1px solid #171717;
}
#nav a
{

View file

@ -221,20 +221,32 @@ span.apiversion
}
.smcolumn
{
min-height: 100%;
height: 100%;
overflow-y: scroll;
overflow-y: auto;
outline: none;
width: 312px;
/*
float: left;
margin-left: -100%;
*/
border-right: 1px solid #ddd;
position: absolute;
top: 40px;
left: 0;
margin-bottom: -40px;
}
.lgcolumn
{
height: 100%;
overflow-y: scroll;
overflow-y: auto;
outline: none;
float: left;
margin-left: 312px;
margin-right: 350px;
}
.lgsection
{
height: 100%;
background: #fff;
border-top: 1px solid #cbcbcb;
border-bottom: 1px solid #cbcbcb;
@ -242,7 +254,45 @@ span.apiversion
overflow: hidden;
position: absolute;
top: 40px;
/*
bottom: 84px;
*/
margin-bottom: -42px;
}
#SideBar
{
/*display: none;*/
min-height: 100%;
height: 100%;
overflow-y: auto;
width: 350px;
background: none repeat scroll 0 0 #fcfcfc;
border-left: 1px solid #ddd;
position: absolute;
top: 41px;
right: 0;
margin-bottom: -42px;
}
#SideBar .header
{
padding: 10px 4px 6px 4px;
font-size: 12px;
color: #bbb;
font-variant: small-caps;
font-weight: bold;
text-align: center;
}
#SideBar .headeractions
{
position: fixed;
right: 10px;
padding: 2px 2px 0 0;
}
#SideBar .submit
{
padding: 0 2px;
position: absolute;
bottom: 0;
}
.fullsection
{
@ -454,13 +504,13 @@ ul.simplelist li:hover
}
ul.simplelist li.index
{
background: #F0F0F0;
border-bottom: 1px solid #DDDDDD;
color: #A7A7A7;
color: #bbb;
font-size: 11px;
font-weight: bold;
margin: 2px 0;
padding: 1px 4px;
padding: 6px 4px;
text-align: center;
border: none;
}
ul.simplelist li.index a
{
@ -545,23 +595,26 @@ ul.tablist
ul.tablist li
{
float: left;
background: #F0F0F0;
background: #f8f8f8;
border-top: 1px solid #DDDDDD;
border-left: 1px solid #DDDDDD;
border-right: 1px solid #DDDDDD;
color: #A7A7A7;
font-size: 13px;
font-weight: bold;
margin: 0 2px 0 0;
padding: 8px 4px;
margin: 0 3px 0 0;
padding: 8px 6px;
}
ul.tablist li a
{
color: #7EA8D5;
color: #6B6B6B;
font-variant: small-caps;
font-size: 15px;
text-decoration: none;
}
ul.tablist li a:hover
{
color: #bbb;
}
#BreadCrumb
{
float: left;
@ -657,14 +710,11 @@ ul.songlist .album .albumart
{
padding: 0;
float: left;
overflow: hidden;
max-height: 170px;
}
ul.songlist .album .albumart img
{
margin: 3px 10px 0 10px;
padding: 2px;
border: 1px solid #DEDEDE;
width: 50px;
}
ul.songlist .album .title
@ -727,11 +777,12 @@ ul.songlist .album a.info
}
ul.songlist .albumgrid
{
width: 185px;
height: 230px;
width: 195px;
height: 200px;
float: left;
margin: 5px;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.25);
border: none;
padding: 4px 4px 26px 4px;
}
ul.songlist .albumgrid .title
{
@ -740,20 +791,38 @@ ul.songlist .albumgrid .title
white-space: nowrap;
display: block;
height: 18px;
background: -webkit-linear-gradient(right, #eee 0%, #333 40%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-overflow: ellipsis;
font-weight: 500;
color: #222;
font-size: 12px;
position: relative;
top: 4px;
}
ul.songlist .albumgrid .albumart img
{
ul.songlist .albumgrid .albumart img {
width: 160px;
height: 160px;
background: url(../images/albumdefault_160.jpg) no-repeat;
margin: 3px 18px 0 18px;
padding: 0px;
-webkit-box-reflect: below 1px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(80%, transparent), to(rgba(255,255,255,0.2)));
}
ul.songlist li:hover .albumgrid .albumart img {
border: 4px solid #ccc;
position: relative;
top: -4px;
left: -4px;
}
ul.songlist .albumgrid .albuminfo
{
float: left;
margin: 0 10px;
overflow: hidden;
width: 165px;
width: 175px;
text-align: center;
}
ul.songlist li:hover .albumgrid .albuminfo {
position: relative;
top: -8px;
}
ul.songlist .albumgrid .itemactions
{
@ -789,7 +858,6 @@ ul.songlist .row span.albumblock
}
ul.songlist .row img
{
border: 1px solid #DEDEDE;
display: block;
float: left;
margin: 0 5px;
@ -799,9 +867,9 @@ ul.songlist .row img
}
ul.songlist .row .itemactions
{
width: 15%;
/*width: 15%;*/
float: left;
padding: 6px 0 0 16px;
padding: 6px 20px 0 16px;
}
ul.songlist .row .itemactions a
{
@ -895,7 +963,7 @@ ul.songlist .row a.remove:hover
{
background: url('../images/minus_8x2.png') no-repeat 6px center #DEECFB;
}
ul.songlist li:nth-child(odd) { background-color:#f4f4f4; }
ul.songlist li:nth-child(odd) { background-color:#f7f7f7; }
ul.songlist li:nth-child(even) { background-color:#fff; }
ul.songlist li.playing
{
@ -909,13 +977,13 @@ ul.songlist li.selected
background-image: url('../images/check_8x7.png');
background-position: 10px 19px;
background-repeat: no-repeat;
border-bottom: 1px solid #C0D5EB;
}
ul.songlist li.selected:hover {
background-color: #D4E2F1;
}
ul.songlist li.album {
background-image: none;
background-color: transparent
}
ul.songlist li:hover
{
@ -1012,7 +1080,7 @@ ul.songlist li:hover
{
height: 29px;
/* width: 660px; */
margin: 5px 75px 0 0;
margin: 5px 105px 0 0;
padding: 0 0 0 5px;
float: right;
}
@ -1067,34 +1135,21 @@ ul.songlist li:hover
overflow-x: hidden;
border: solid 1px gainsboro;
}
#SideBar
#SideQueue
{
display: none;
width: 200px;
min-height: 350px;
background: none repeat scroll 0 0 #fcfcfc;
border: 1px solid #CBCBCB;
border-right: none;
position: absolute;
top: 40px;
bottom: 200px;
right: 0;
opacity: .85;
}
#SideBar .header
{
padding: 5px;
#SideQueue .row {
display: block;
margin: 0 0px;
padding: 4px;
font-size: 12px;
color: #545454;
font-variant: small-caps;
font-weight: bold;
text-align: left;
overflow: hidden;
float: none;
border: none;
}
#SideBar .submit
{
padding: 0 2px;
position: absolute;
bottom: 0;
#SideQueue .row .title {
width: 65%
}
#ChatMsgs
{
@ -1168,19 +1223,6 @@ ul.songlist li:hover
{
}
#queue {
width: 1200px;
display: none;
}
#queue .songlist {
padding: 35px 0 0 0;
}
.queueactions {
padding: 0;
text-align: left;
position: fixed;
}
#songs {
width: 1200px;
display: none;
@ -1203,7 +1245,7 @@ ul.songlist li:hover
z-index: 100;
}
#playercontainer {
background: #fff;
background: linear-gradient(to bottom, #000000 0%,#3d3d3d 100%);
}
#audiocontainer
{
@ -1211,7 +1253,7 @@ ul.songlist li:hover
.audiojs
{
width: auto;
height: 56px;
height: 45px;
margin: 0;
background: none;
font-family: inherit;
@ -1226,7 +1268,7 @@ ul.songlist li:hover
.audiojs .scrubber
{
height: 4px;
margin: 35px 5px 0px 5px;
margin: 20px 5px 0px 5px;
float: none;
width: auto;
position: relative;
@ -1278,8 +1320,8 @@ ul.songlist li:hover
}
.playeractions
{
margin: 16px 12px 7px 20px;
width: 160px;
margin: 12px 9px 7px 20px;
width: 85px;
}
.playeractionssmall
{
@ -1292,16 +1334,16 @@ ul.songlist li:hover
width: 100%;
visibility: hidden;
}
#preview { display: none; }
#coverart
{
width: 60px;
height: 60px;
width: 30px;
height: 30px;
overflow: hidden;
margin: 1px 8px 0 1px;
float: left;
padding: 2px;
}
#preview { display: none; }
#songdetails
{
width: 322px;
@ -1309,13 +1351,12 @@ ul.songlist li:hover
float: left;
cursor: pointer;
padding: 0;
border: 1px solid #fff;
visibility: hidden;
text-align: left;
color: #fff;
}
#songdetails.hover
{
border: solid 1px gainsboro;
background: -webkit-gradient(linear, center top, center bottom, from(rgba(255, 255, 255, 0)), to(rgba(244, 244, 244, .2)));
}
#songdetails .jp-volume-bar {
@ -1337,8 +1378,7 @@ ul.songlist li:hover
list-style-type: none;
margin: 4px 0 2px 0;
padding: 0;
height: 58px;
width: 215px;
width: 205px;
overflow: hidden;
white-space: nowrap;
float: left;
@ -1360,12 +1400,6 @@ ul.songlist li:hover
font-size: 11px;
line-height: 14px;
}
#songdetails li.specs
{
opacity: .6;
font-size: 10px;
line-height: 14px;
}
#songdetails li span.label
{
color: #B6B6B6;
@ -1381,13 +1415,11 @@ ul.songlist li:hover
width: 12px;
margin: 2px;
display: block;
background: url('../images/star_lgo_12x12.png') 0 center no-repeat;
background-color: #ffffff;
background: url('../images/star_w_12x12.png') 0 center no-repeat;
}
#songdetails a.rate:hover
{
background: url('../images/star_lg_12x12.png') 0 center no-repeat;
background-color: #ffffff;
background: url('../images/star_wo_12x12.png') 0 center no-repeat;
}
#songdetails a.favorite
{
@ -1405,7 +1437,7 @@ ul.songlist li:hover
height: 12px;
width: 16px;
display: block;
background: url('../images/volume_mute_gd_12x9.png') 0 center no-repeat;
background: url('../images/volume_mute_gl_12x9.png') 0 center no-repeat;
}
#songdetails a.unmute
{
@ -1414,7 +1446,7 @@ ul.songlist li:hover
height: 12px;
width: 16px;
display: block;
background: url('../images/volume_mute_gl_12x9.png') 0 center no-repeat;
background: url('../images/volume_gl_12x9.png') 0 center no-repeat;
}
#songdetails a.volume
{
@ -1441,7 +1473,16 @@ ul.songlist li:hover
height: 9px;
width: 12px;
display: block;
background: url('../images/loop_alt3_gd_12x9.png') 0 center no-repeat;
background: url('../images/loop_alt3_w_12x9.png') 0 center no-repeat;
}
#songdetails a.jukebox
{
float: left;
margin: 4px 2px;
height: 9px;
width: 12px;
display: block;
background: url('../images/cloud_w_12x8.png') 0 center no-repeat;
}
#songdetails a.shuffle
{
@ -1580,6 +1621,15 @@ a.button:active {
color: #000;
border-color: #444;
}
a.buttonimg {
text-decoration: none;
padding: 6px;
cursor: pointer;
display: inline-block;
}
a.buttonimg:hover {
opacity: .6;
}
a.buttonvertical {
margin: 2px 0;
}
@ -1624,11 +1674,11 @@ a.hoverSelected { opacity: .6; }
}
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 2px rgba(0,0,0,0.2);
-webkit-border-radius: 5px;
/*-webkit-border-radius: 5px;*/
background: #f2f2f2;
}
::-webkit-scrollbar-thumb {
-webkit-border-radius: 5px;
/*-webkit-border-radius: 5px;*/
-webkit-background-clip: padding-box;
background-clip: padding-box;
background-color: rgba(51,51,51, 0.5);
@ -1776,49 +1826,4 @@ legend
font-weight: bold;
}
/* jQuery Accordion Style */
.accordion .accordionItem {
}
.accordion .accordionItemContents {
display: none;
margin: 5px 0 0 0;
}
.accordion .accordionItemTitle {
cursor: pointer;
padding: 12px;
font-size: 14px;
background: #FBFBFB;
border-bottom: 1px solid #cbcbcb;
}
.accordion .accordionItemTitle:hover {
background: #ffffff;
}
.accordion .accordionOpenedContent {
display: block;
}
.ui-layout-pane {
outline: none;
}
.ui-layout-center {
z-index: 100 !important;
}
.ui-layout-west {
z-index: 900 !important;
}
.split-pane-divider {
background: #aaa;
}
#left-component {
width: 20em;
}
#my-divider {
left: 20em; /* Same as left component width */
width: 5px;
}
#right-component {
left: 20em; /* Same as left component width */
margin-left: 5px; /* Same as divider width */
}