Merging local changes
This commit is contained in:
parent
ea8409575c
commit
661053aee2
34 changed files with 1691 additions and 814 deletions
|
@ -27,6 +27,7 @@ https://github.com/tsquillario/Jamstash/issues
|
||||||
|
|
||||||
You will need a Subsonic server to be able to play your own music. Subsonic is a free, web-based media streamer, providing ubiquitous access to your music. Use it to share your music with friends, or to listen to your own music while at work. Please see http://www.subsonic.org
|
You will need a Subsonic server to be able to play your own music. Subsonic is a free, web-based media streamer, providing ubiquitous access to your music. Use it to share your music with friends, or to listen to your own music while at work. Please see http://www.subsonic.org
|
||||||
|
|
||||||
|
* Getting Started https://github.com/tsquillario/Jamstash/wiki/Getting-Started
|
||||||
* Twitter (Release Announcements): https://twitter.com/JamstashApp
|
* Twitter (Release Announcements): https://twitter.com/JamstashApp
|
||||||
* Live Beta: http://jamstash.com/beta
|
* Live Beta: http://jamstash.com/beta
|
||||||
* Github Repo: https://github.com/tsquillario/Jamstash
|
* Github Repo: https://github.com/tsquillario/Jamstash
|
||||||
|
|
225
index.html
225
index.html
|
@ -11,20 +11,29 @@
|
||||||
<link rel="icon" href="images/favicon_32x32.png" sizes="32x32"/>
|
<link rel="icon" href="images/favicon_32x32.png" sizes="32x32"/>
|
||||||
<link href="style/Style.css" rel="stylesheet" type="text/css" data-name="main" />
|
<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="" rel="stylesheet" type="text/css" data-name="theme" />
|
||||||
<link href="js/plugins/jquery.layout-default.css" rel="stylesheet" type="text/css" />
|
|
||||||
<link href="js/plugins/fancybox/jquery.fancybox.css" rel="stylesheet" type="text/css" />
|
<link href="js/plugins/fancybox/jquery.fancybox.css" rel="stylesheet" type="text/css" />
|
||||||
<script src="js/plugins/jquery-1.8.3.js" type="text/javascript"></script>
|
<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.min.js" type="text/javascript"></script>
|
||||||
<script src="js/plugins/angular-cookies.js" type="text/javascript"></script>
|
<script src="js/plugins/angular-sanitize.min.js" type="text/javascript"></script>
|
||||||
<script src="js/plugins/jquery-ui-1.9.2.custom.min.js" type="text/javascript"></script>
|
<script src="js/plugins/angular-cookies.min.js" type="text/javascript"></script>
|
||||||
|
<script src="js/plugins/angular-resource.min.js" type="text/javascript"></script>
|
||||||
|
<!--
|
||||||
|
<script src="../js/plugins/angular.min.js"></script>
|
||||||
|
<script src="../js/plugins/angular-cookies.min.js"></script>
|
||||||
|
<script src="../js/plugins/angular-resource.min.js"></script>
|
||||||
|
<script src="../js/plugins/angular-route.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/fancybox/jquery.fancybox.js" type="text/javascript"></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.base64.js" type="text/javascript"></script>
|
||||||
<script src="js/plugins/jquery.dateFormat-1.0.js" type="text/javascript"></script>
|
<script src="js/plugins/jquery.dateFormat-1.0.js" type="text/javascript"></script>
|
||||||
<script src="js/plugins/jquery.layout-latest.min.js" type="text/javascript"></script>
|
|
||||||
<script src="js/plugins/jquery.scrollTo.min.js" type="text/javascript"></script>
|
<script src="js/plugins/jquery.scrollTo.min.js" type="text/javascript"></script>
|
||||||
<script src="js/plugins/UnityShim.js" type="text/javascript"></script>
|
<script src="js/plugins/UnityShim.js" type="text/javascript"></script>
|
||||||
<script src="js/plugins/jplayer/jquery.jplayer.min.js" type="text/javascript"></script>
|
<script src="js/plugins/jplayer/jquery.jplayer.min.js" type="text/javascript"></script>
|
||||||
<script src="js/app.js" type="text/javascript"></script>
|
<script src="js/app.js" type="text/javascript"></script>
|
||||||
|
<script src="js/service.js" type="text/javascript"></script>
|
||||||
<script src="js/utils.js" type="text/javascript"></script>
|
<script src="js/utils.js" type="text/javascript"></script>
|
||||||
<script src="js/controllers/main.js" type="text/javascript"></script>
|
<script src="js/controllers/main.js" type="text/javascript"></script>
|
||||||
<script src="js/controllers/settings.js" type="text/javascript"></script>
|
<script src="js/controllers/settings.js" type="text/javascript"></script>
|
||||||
|
@ -34,121 +43,121 @@
|
||||||
<script src="js/controllers/archive.js" type="text/javascript"></script>
|
<script src="js/controllers/archive.js" type="text/javascript"></script>
|
||||||
<script src="js/player.js" type="text/javascript"></script>
|
<script src="js/player.js" type="text/javascript"></script>
|
||||||
</head>
|
</head>
|
||||||
|
<!--<body ng-controller="AppCtrl" layout state="bodyState" ng-init="bodyState = 1">-->
|
||||||
<body ng-controller="AppCtrl">
|
<body ng-controller="AppCtrl">
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<div id="messages"></div>
|
<div id="messages"></div>
|
||||||
<div id="loading"></div>
|
<div id="loading"></div>
|
||||||
<a id="jslogo" title="Jamstash"></a>
|
<a id="jslogo" title="Jamstash"></a>
|
||||||
<a id="sslogo" target="_blank" ng-show="settings.Server" ng-href="{{settings.Server}}" title="{{settings.Server}}"></a>
|
<a id="sslogo" target="_blank" ng-show="settings.Server" ng-href="{{settings.Server}}" title="{{settings.Server}}"></a>
|
||||||
<div id="nav">
|
<div id="globalactions">
|
||||||
<ul class="tabs">
|
<a href="" class="button" title="Shuffle Queue" ng-click="queueShuffle()"><img src="images/fork_gd_11x12.png" /></a>
|
||||||
<li><a href="#/library" class="first" title="Library" ng-class="{'active': isActive('/library')}"><img src="images/headphones_gd_16x14.png" /></a></li>
|
<a href="" class="button" id="action_Empty" title="Delete Queue" ng-click="queueEmpty()"><img src="images/trash_fill_gd_12x12.png" /></a>
|
||||||
<li><a href="#/playlists" title="Playlists" ng-class="{'active': isActive('/playlists')}"><img src="images/list_gd_16x14.png" /></a></li>
|
<a href="" class="button" id="action_DeleteSelected" title="Delete Song(s) From Queue" ng-click="queueRemoveSelected()"><img src="images/minus_8x2.png" /></a>
|
||||||
<li><a href="#/podcasts" title="Podcasts" ng-class="{'active': isActive('/podcasts')}"><img src="images/rss_16x16.png" /></a></li>
|
<!--<a href="" class="button buttonvertical" id="action_QueueToPlaylist" title="Create Playlist From Queue"><img src="images/list_gd_12x11.png" /></a>-->
|
||||||
<li><a href="#/archive" class="" title="Archive.org - Live Music Archive" ng-class="{'active': isActive('/archive')}"><img src="images/archive_gd_16x16.png" /></a></li>
|
|
||||||
<li><a href="#/settings" class="last" title="Settings" ng-class="{'active': isActive('/settings')}"><img src="images/cog_16x16.png" /></a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="content">
|
|
||||||
<!-- Main -->
|
|
||||||
<div ng-view></div>
|
|
||||||
|
|
||||||
<div id="SideBar">
|
|
||||||
<div id="NowPlaying">
|
|
||||||
<div class="header"><img src="images/rss_12x12.png" /> Now Playing</div>
|
|
||||||
<div id="NowPlayingList"><span class="user">Loading...</span></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="Chat">
|
<div id="nav">
|
||||||
<div class="header"><img src="images/chat_alt_stroke_12x12.png" /> Chat</div>
|
<ul class="tabs">
|
||||||
<div id="ChatMsgs"></div>
|
<li><a href="#/library" class="first" title="Library" ng-class="{'active': isActive('/library')}"><img src="images/headphones_gd_16x14.png" /></a></li>
|
||||||
</div>
|
<li><a href="#/playlists" title="Playlists" ng-class="{'active': isActive('/playlists')}"><img src="images/list_gd_16x14.png" /></a></li>
|
||||||
<div class="submit"><img src="images/comment_stroke_gl_12x11.png" /><input type="text" id="ChatMsg" class="chat" title="Hit [Enter] to Post" /></div>
|
<li><a href="#/podcasts" title="Podcasts" ng-class="{'active': isActive('/podcasts')}"><img src="images/rss_16x16.png" /></a></li>
|
||||||
</div>
|
<li><a href="#/archive" class="" title="Archive.org - Live Music Archive" ng-class="{'active': isActive('/archive')}"><img src="images/archive_gd_16x16.png" /></a></li>
|
||||||
<!-- Audio Player -->
|
<li><a href="#/settings" class="last" title="Settings" ng-class="{'active': isActive('/settings')}"><img src="images/cog_16x16.png" /></a></li>
|
||||||
<div class="clear"></div>
|
|
||||||
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div id="player">
|
|
||||||
<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" id="PlayTrack" title="Play/Pause" ng-click="defaultPlay()"><img src="images/play_24x32.png" /></a>
|
|
||||||
<a class="button" id="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>
|
|
||||||
</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-unsafe="playingSong.name"></li>
|
|
||||||
<li class="album" ng-bind-html-unsafe="playingSong.album"></li>
|
|
||||||
<li class="specs" ng-bind-html-unsafe="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>
|
|
||||||
<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>
|
</ul>
|
||||||
<div class="vertshade"></div>
|
|
||||||
</div>
|
|
||||||
<div id="playdeck_1"></div>
|
|
||||||
<div id="playdeck_2"></div>
|
|
||||||
<div id="submenu_CurrentPlaylist" class="submenu shadow" style="display: none;">
|
|
||||||
<table id="CurrentPlaylistPreviewContainer" class="simplelist songlist">
|
|
||||||
<thead></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</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 id="content">
|
||||||
<div id="playermiddle">
|
<!-- Main -->
|
||||||
<div id="audiocontainer">
|
<div ng-view></div>
|
||||||
<div class="audiojs" id="audio_wrapper0">
|
|
||||||
<div class="scrubber"><div class="progress"></div><div class="loaded"></div></div>
|
<div id="SideBar">
|
||||||
<div class="time"><em id="played">00:00</em>/<strong id="duration">00:00</strong></div>
|
<div id="NowPlaying">
|
||||||
<div class="error-message"></div>
|
<div class="header"><img src="images/rss_12x12.png" /> Now Playing</div>
|
||||||
|
<div id="NowPlayingList"><span class="user">Loading...</span></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="Chat">
|
||||||
|
<div class="header"><img src="images/chat_alt_stroke_12x12.png" /> Chat</div>
|
||||||
|
<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>
|
</div>
|
||||||
<div id="preview"></div>
|
<!-- Audio Player -->
|
||||||
</div>
|
<div class="clear"></div>
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
<div class="clear"></div>
|
||||||
</div><!-- end #content -->
|
<div id="player">
|
||||||
</div> <!-- End container -->
|
<div id="playerleft" class="floatleft">
|
||||||
<div id="footer">
|
<div class="playeractions floatleft">
|
||||||
<div id="QueuePreview">
|
<a class="button" id="PreviousTrack" title="Previous Track" ng-click="previousTrack()"><img src="images/first_24x24.png" /></a>
|
||||||
<div class="queueactions">
|
<a class="button" id="PlayTrack" title="Play/Pause" ng-click="defaultPlay()"><img src="images/play_24x32.png" /></a>
|
||||||
<a href="" class="button buttonvertical" title="Shuffle Queue" ng-click="queueShuffle()"><img src="images/fork_gd_11x12.png" /></a><br />
|
<a class="button" id="PauseTrack" title="Play/Pause" style="display: none;"><img src="images/pause_24x32.png" /></a>
|
||||||
<a href="" class="button buttonvertical" id="action_Empty" title="Delete Queue" ng-click="queueEmpty()"><img src="images/trash_fill_gd_12x12.png" /></a><br />
|
<a class="button" id="NextTrack" title="Next Track" ng-click="nextTrack()"><img src="images/last_24x24.png" /></a>
|
||||||
<a href="" class="button buttonvertical" id="action_DeleteSelected" title="Delete Song(s) From Queue" ng-click="queueRemoveSelected()"><img src="images/minus_8x2.png" /></a><br />
|
</div>
|
||||||
<!--<a href="" class="button buttonvertical" id="action_QueueToPlaylist" title="Create Playlist From Queue"><img src="images/list_gd_12x11.png" /></a>-->
|
<div id="songdetails">
|
||||||
</div>
|
<div id="coverart"><a class="coverartfancy" href="{{playingSong.coverartfull}}"><img ng-src="{{playingSong.coverartthumb}}" src="images/albumdefault_60.jpg" alt="" /></a></div>
|
||||||
<ul id="QueuePreviewList" class="songlist noselect">
|
<ul>
|
||||||
<li class="row song" ng-repeat="o in queue track by $index" ng-class="{'playing': o.playing, 'selected': o.selected}" ng-click="selectSong(o)" ng-dblclick="playSong(false, o)" id="{{o.id}}" parentid="{{o.parentid}}">
|
<li class="song" id="{{playingSong.id}}" ng-bind-html="playingSong.name"></li>
|
||||||
<div class="albumart"><a class="coverartfancy" href="{{o.coverartfull}}"><img class="" ng-src="{{o.coverartthumb}}" src="images/albumdefault_25.jpg" /></a></div>
|
<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>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div id="playdeck_1"></div>
|
||||||
|
<div id="playdeck_2"></div>
|
||||||
|
<div id="submenu_CurrentPlaylist" class="submenu shadow" style="display: none;">
|
||||||
|
<table id="CurrentPlaylistPreviewContainer" class="simplelist songlist">
|
||||||
|
<thead></thead>
|
||||||
|
<tbody></tbody>
|
||||||
|
</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 id="playermiddle">
|
||||||
|
<div id="audiocontainer">
|
||||||
|
<div class="audiojs" id="audio_wrapper0">
|
||||||
|
<div class="scrubber"><div class="progress"></div><div class="loaded"></div></div>
|
||||||
|
<div class="time"><em id="played">00:00</em>/<strong id="duration">00:00</strong></div>
|
||||||
|
<div class="error-message"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="preview"></div>
|
||||||
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
<div class="title" title="{{ o.track + ' - ' + o.name + ' - ' + o.time }}" ng-bind-html-unsafe="o.name"></div>
|
</div>
|
||||||
<div class="albumtext" title="{{o.album}}" ng-bind-html-unsafe="o.album"></div>
|
</div><!-- end #content -->
|
||||||
<div class="albumtext" title="{{o.artist}}" ng-bind-html-unsafe="o.artist"></div>
|
</div> <!-- End container -->
|
||||||
|
<div id="footer">
|
||||||
|
<ul id="QueuePreview" class="songlist noselect" sortable>
|
||||||
|
<li class="row song" ng-repeat="o in queue track by $index" ng-class="{'playing': o.playing, 'selected': o.selected}" ng-click="selectSong(o)" ng-dblclick="playSong(false, o)" id="{{o.id}}" parentid="{{o.parentid}}">
|
||||||
|
<div class="albumart"><a class="coverartfancy" href="{{o.coverartfull}}"><img class="" ng-src="{{o.coverartthumb}}" src="images/albumdefault_60.jpg" /></a></div>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<div class="title" title="{{ o.track + ' - ' + o.name + ' - ' + o.time }}" ng-bind-html="o.name"></div>
|
||||||
|
<div class="albumtext" title="{{o.album}}" ng-bind-html="o.album"></div>
|
||||||
|
<div class="albumtext" title="{{o.artist}}" ng-bind-html="o.artist"></div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<a id="action_OpenQueue" class="pagetabcenter shadow" title="Open Queue" ng-click="pinQueue()" ng-mouseover="showQueue()"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<script>
|
||||||
<script>
|
(function (i, s, o, g, r, a, m) {
|
||||||
(function (i, s, o, g, r, a, m) {
|
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
|
||||||
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
|
(i[r].q = i[r].q || []).push(arguments)
|
||||||
(i[r].q = i[r].q || []).push(arguments)
|
}, i[r].l = 1 * new Date(); a = s.createElement(o),
|
||||||
}, i[r].l = 1 * new Date(); a = s.createElement(o),
|
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
|
||||||
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
|
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
||||||
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
|
||||||
|
|
||||||
ga('create', 'UA-40174100-1', 'jamstash.com');
|
ga('create', 'UA-40174100-1', 'jamstash.com');
|
||||||
ga('send', 'pageview');
|
ga('send', 'pageview');
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -155,7 +155,7 @@
|
||||||
<script type="text/html" id="album-template">
|
<script type="text/html" id="album-template">
|
||||||
<!-- ko if: flag != 'archive' -->
|
<!-- ko if: flag != 'archive' -->
|
||||||
<ul class="actionlist">
|
<ul class="actionlist">
|
||||||
<li><select data-bind="options: $root.SubsonicAlbumSort, value: $root.selectedSubsonicAlbumSort"></select></li>
|
<li><select data-bind="options: $root.SubsonicSort, value: $root.selectedSubsonicAlbumSort"></select></li>
|
||||||
</ul>
|
</ul>
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
<ul class="simplelist songlist noselect">
|
<ul class="simplelist songlist noselect">
|
||||||
|
|
|
@ -172,7 +172,7 @@
|
||||||
rescanLibrary: self.rescanLibrary,
|
rescanLibrary: self.rescanLibrary,
|
||||||
toggleAZ: self.toggleAZ,
|
toggleAZ: self.toggleAZ,
|
||||||
selectedSubsonicAlbumSort: self.selectedSubsonicAlbumSort,
|
selectedSubsonicAlbumSort: self.selectedSubsonicAlbumSort,
|
||||||
SubsonicAlbumSort: self.SubsonicAlbumSort,
|
SubsonicSort: self.SubsonicSort,
|
||||||
getPodcasts: self.getPodcasts,
|
getPodcasts: self.getPodcasts,
|
||||||
getPodcast: self.getPodcast,
|
getPodcast: self.getPodcast,
|
||||||
getPlaylists: self.getPlaylists,
|
getPlaylists: self.getPlaylists,
|
||||||
|
|
268
js/app.js
268
js/app.js
|
@ -1,5 +1,18 @@
|
||||||
/* Declare app level module */
|
/* Declare app level module */
|
||||||
var JamStash = angular.module('JamStash', ['ngCookies']);
|
var JamStash = angular.module('JamStash', ['ngCookies', 'ngSanitize']);
|
||||||
|
//var JamStash = angular.module('JamStash', ['ngCookies', 'ngRoute']);
|
||||||
|
/*
|
||||||
|
JamStash.config(function ($sceDelegateProvider) {
|
||||||
|
$sceDelegateProvider.resourceUrlWhitelist(['/^\s*(https?|file|ms-appx):/', 'self']);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Given:
|
||||||
|
// URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
|
||||||
|
// Route: /Chapter/:chapterId/Section/:sectionId
|
||||||
|
//
|
||||||
|
// Then
|
||||||
|
$routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
|
||||||
|
*/
|
||||||
JamStash.config(function ($routeProvider) {
|
JamStash.config(function ($routeProvider) {
|
||||||
$routeProvider
|
$routeProvider
|
||||||
.when('/index', { redirectTo: '/library' })
|
.when('/index', { redirectTo: '/library' })
|
||||||
|
@ -25,252 +38,9 @@ JamStash.config(function ($routeProvider) {
|
||||||
$location.path('/settings');
|
$location.path('/settings');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} ]);
|
}]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
JamStash.config(function ($httpProvider) {
|
JamStash.config(function ($httpProvider, globals) {
|
||||||
$httpProvider.interceptors.push(function ($rootScope, $location, $q, globals) {
|
$httpProvider.defaults.timeout = globals.settings.Timeout;
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (!$rootScope.loggedIn && $location.path() != '/settings' && $location.path() != '/archive') {
|
|
||||||
$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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
JamStash.service('model', function (utils) {
|
|
||||||
this.Index = function (name, artist) {
|
|
||||||
this.name = name;
|
|
||||||
this.artist = artist;
|
|
||||||
}
|
|
||||||
this.Artist = function (id, name) {
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
this.Album = function (id, parentid, name, artist, artistId, coverartthumb, coverartfull, date, starred, description, url, type) {
|
|
||||||
this.id = id;
|
|
||||||
this.parentid = parentid;
|
|
||||||
this.name = name;
|
|
||||||
this.artist = artist;
|
|
||||||
this.artistId = artistId;
|
|
||||||
this.coverartthumb = coverartthumb;
|
|
||||||
this.coverartfull = coverartfull;
|
|
||||||
this.date = date;
|
|
||||||
this.starred = starred;
|
|
||||||
this.description = description;
|
|
||||||
this.url = url;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
this.Song = function (id, parentid, track, name, artist, artistId, album, albumId, coverartthumb, coverartfull, duration, rating, starred, suffix, specs, url, position, description) {
|
|
||||||
this.id = id;
|
|
||||||
this.parentid = parentid;
|
|
||||||
this.track = track;
|
|
||||||
this.name = name;
|
|
||||||
this.artist = artist;
|
|
||||||
this.artistId = artistId;
|
|
||||||
this.album = album;
|
|
||||||
this.albumId = albumId;
|
|
||||||
this.coverartthumb = coverartthumb;
|
|
||||||
this.coverartfull = coverartfull;
|
|
||||||
this.duration = duration;
|
|
||||||
this.time = duration == '' ? '00:00' : utils.secondsToTime(duration);
|
|
||||||
this.rating = rating;
|
|
||||||
this.starred = starred;
|
|
||||||
this.suffix = suffix;
|
|
||||||
this.specs = specs;
|
|
||||||
this.url = url;
|
|
||||||
this.position = position;
|
|
||||||
this.selected = false;
|
|
||||||
this.playing = false;
|
|
||||||
this.description = description;
|
|
||||||
this.displayName = this.name + " - " + this.album + " - " + this.artist;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
JamStash.service('globals', function (utils) {
|
|
||||||
this.settings = {
|
|
||||||
// Subsonic
|
|
||||||
/* Demo Server
|
|
||||||
Username: "android-guest"),
|
|
||||||
Password: "guest"),
|
|
||||||
Server: "http://subsonic.org/demo"),
|
|
||||||
*/
|
|
||||||
Url: "http://Jamstash.com/beta/#/archive/",
|
|
||||||
Username: "",
|
|
||||||
Password: "",
|
|
||||||
Server: "",
|
|
||||||
Timeout: 10000,
|
|
||||||
NotificationTimeout: 20000,
|
|
||||||
Protocol: "jsonp",
|
|
||||||
ApplicationName: "Jamstash",
|
|
||||||
ApiVersion: "1.6.0",
|
|
||||||
AutoPlaylists: "",
|
|
||||||
AutoPlaylistSize: 25,
|
|
||||||
AutoAlbumSize: 15,
|
|
||||||
// General
|
|
||||||
HideAZ: false,
|
|
||||||
ScrollTitle: true,
|
|
||||||
NotificationSong: true,
|
|
||||||
NotificationNowPlaying: false,
|
|
||||||
SaveTrackPosition: false,
|
|
||||||
ForceFlash: false,
|
|
||||||
Theme: "Default",
|
|
||||||
DefaultLibraryLayout: "grid",
|
|
||||||
AutoPlay: false,
|
|
||||||
LoopQueue: false,
|
|
||||||
Repeat: false,
|
|
||||||
Debug: false
|
|
||||||
};
|
|
||||||
this.SavedCollections = [];
|
|
||||||
this.SavedGenres = [];
|
|
||||||
this.BaseURL = function () { return this.settings.Server + '/rest'; };
|
|
||||||
this.BaseParams = function () { return 'u=' + this.settings.Username + '&p=' + this.settings.Password + '&f=' + this.settings.Protocol + '&v=' + this.settings.ApiVersion + '&c=' + this.settings.ApplicationName; };
|
|
||||||
});
|
|
||||||
|
|
||||||
// Directives
|
|
||||||
JamStash.directive('stopEvent', function () {
|
|
||||||
return {
|
|
||||||
restrict: 'A',
|
|
||||||
link: function (scope, element, attr) {
|
|
||||||
element.bind(attr.stopEvent, function (e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
JamStash.directive('ngEnter', function () {
|
|
||||||
return function (scope, element, attrs) {
|
|
||||||
element.bind("keydown keypress", function (event) {
|
|
||||||
if (event.which === 13) {
|
|
||||||
scope.$apply(function () {
|
|
||||||
scope.$eval(attrs.ngEnter);
|
|
||||||
});
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
});
|
|
||||||
JamStash.directive('ngDownload', function ($compile) {
|
|
||||||
return {
|
|
||||||
restrict: 'E',
|
|
||||||
scope: { data: '=' },
|
|
||||||
link: function (scope, elm, attrs) {
|
|
||||||
function getUrl() {
|
|
||||||
return URL.createObjectURL(new Blob([JSON.stringify(scope.data)], { type: "application/json" }));
|
|
||||||
}
|
|
||||||
|
|
||||||
elm.append($compile(
|
|
||||||
'<a class="button" download="backup.json"' +
|
|
||||||
'href="' + getUrl() + '">' +
|
|
||||||
'Download' +
|
|
||||||
'</a>'
|
|
||||||
)(scope));
|
|
||||||
|
|
||||||
scope.$watch(scope.data, function () {
|
|
||||||
elm.children()[0].href = getUrl();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Factory */
|
|
||||||
JamStash.factory('json', function ($http) { // Deferred loading
|
|
||||||
return {
|
|
||||||
getCollections: function (callback) {
|
|
||||||
$http.get('js/json_collections.js').success(callback);
|
|
||||||
},
|
|
||||||
getChangeLog: function (callback) {
|
|
||||||
$http.get('js/json_changelog.js').success(callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Filters */
|
|
||||||
JamStash.filter('capitalize', function () {
|
|
||||||
return function (input, scope) {
|
|
||||||
return input.substring(0, 1).toUpperCase() + input.substring(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
JamStash.service('notifications', function ($rootScope, globals) {
|
|
||||||
var msgIndex = 1;
|
|
||||||
this.updateMessage = function (msg, autohide) {
|
|
||||||
if (msg != '') {
|
|
||||||
var id = msgIndex;
|
|
||||||
$('#messages').append('<span id=\"msg_' + id + '\" class="message">' + msg + '</span>');
|
|
||||||
$('#messages').fadeIn();
|
|
||||||
$("#messages").scrollTo('100%');
|
|
||||||
var el = '#msg_' + id;
|
|
||||||
if (autohide) {
|
|
||||||
setTimeout(function () {
|
|
||||||
$(el).fadeOut(function () { $(this).remove(); });
|
|
||||||
}, globals.settings.NotificationTimeout);
|
|
||||||
} else {
|
|
||||||
$(el).click(function () {
|
|
||||||
$(el).fadeOut(function () { $(this).remove(); });
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
msgIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.requestPermissionIfRequired = function () {
|
|
||||||
if (!this.hasNotificationPermission() && (window.webkitNotifications)) {
|
|
||||||
window.webkitNotifications.requestPermission();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.hasNotificationPermission = function () {
|
|
||||||
return !!(window.webkitNotifications) && (window.webkitNotifications.checkPermission() == 0);
|
|
||||||
}
|
|
||||||
var notifications = new Array();
|
|
||||||
this.showNotification = function (pic, title, text, type, bind) {
|
|
||||||
if (this.hasNotificationPermission()) {
|
|
||||||
//closeAllNotifications()
|
|
||||||
var popup;
|
|
||||||
if (type == 'text') {
|
|
||||||
popup = window.webkitNotifications.createNotification(pic, title, text);
|
|
||||||
} else if (type == 'html') {
|
|
||||||
popup = window.webkitNotifications.createHTMLNotification(text);
|
|
||||||
}
|
|
||||||
if (bind = '#NextTrack') {
|
|
||||||
popup.addEventListener('click', function (bind) {
|
|
||||||
//$(bind).click();
|
|
||||||
$rootScope.nextTrack();
|
|
||||||
this.cancel();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
notifications.push(popup);
|
|
||||||
setTimeout(function (notWin) {
|
|
||||||
notWin.cancel();
|
|
||||||
}, globals.settings.NotificationTimeout, popup);
|
|
||||||
popup.show();
|
|
||||||
} else {
|
|
||||||
console.log("showNotification: No Permission");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.closeAllNotifications = function () {
|
|
||||||
for (notification in notifications) {
|
|
||||||
notifications[notification].cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,6 +1,6 @@
|
||||||
JamStash.controller('ArchiveCtrl',
|
JamStash.controller('ArchiveCtrl',
|
||||||
function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils, globals, model, notifications, player, json) {
|
function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils, globals, model, notifications, player, json) {
|
||||||
$("#LayoutContainer").layout($scope.layoutThreeCol);
|
//$("#left-component").layout($scope.layoutThreeCol);
|
||||||
|
|
||||||
$scope.settings = globals.settings;
|
$scope.settings = globals.settings;
|
||||||
$scope.itemType = 'archive';
|
$scope.itemType = 'archive';
|
||||||
|
@ -166,6 +166,7 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
|
||||||
items = data["response"].docs;
|
items = data["response"].docs;
|
||||||
//alert(JSON.stringify(data["response"]));
|
//alert(JSON.stringify(data["response"]));
|
||||||
$scope.album = [];
|
$scope.album = [];
|
||||||
|
$rootScope.song = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$scope.album.push(map(item));
|
$scope.album.push(map(item));
|
||||||
});
|
});
|
||||||
|
@ -180,7 +181,7 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
$scope.mapSong = function (key, song, server, dir, identifier, coverart) {
|
utils.mapSong = function (key, song, server, dir, identifier, coverart) {
|
||||||
var url, time, track, title, rating, starred, contenttype, suffix;
|
var url, time, track, title, rating, starred, contenttype, suffix;
|
||||||
var specs = ''
|
var specs = ''
|
||||||
if (song.format == 'VBR MP3') {
|
if (song.format == 'VBR MP3') {
|
||||||
|
@ -211,18 +212,18 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
|
||||||
var items = data.files;
|
var items = data.files;
|
||||||
if (action == 'add') {
|
if (action == 'add') {
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
var song = $scope.mapSong(key, item, server, dir, identifier, coverart);
|
var song = utils.mapSong(key, item, server, dir, identifier, coverart);
|
||||||
if (song) {
|
if (song) {
|
||||||
$rootScope.queue.push(song);
|
$rootScope.queue.push(song);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(Object.keys(items).length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(Object.keys(items).length + ' Song(s) Added to Queue', true);
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
} else if (action == 'play') {
|
} else if (action == 'play') {
|
||||||
$rootScope.queue = [];
|
$rootScope.queue = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
var song = $scope.mapSong(key, item, server, dir, identifier, coverart);
|
var song = utils.mapSong(key, item, server, dir, identifier, coverart);
|
||||||
if (song) {
|
if (song) {
|
||||||
$rootScope.queue.push(song);
|
$rootScope.queue.push(song);
|
||||||
}
|
}
|
||||||
|
@ -231,12 +232,13 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
|
||||||
$scope.$apply(function () {
|
$scope.$apply(function () {
|
||||||
$rootScope.playSong(false, next);
|
$rootScope.playSong(false, next);
|
||||||
});
|
});
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(Object.keys(items).length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(Object.keys(items).length + ' Song(s) Added to Queue', true);
|
||||||
} else {
|
} else {
|
||||||
|
$scope.album = [];
|
||||||
$rootScope.song = [];
|
$rootScope.song = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
var song = $scope.mapSong(key, item, server, dir, identifier, coverart);
|
var song = utils.mapSong(key, item, server, dir, identifier, coverart);
|
||||||
if (song) {
|
if (song) {
|
||||||
$rootScope.song.push(song);
|
$rootScope.song.push(song);
|
||||||
}
|
}
|
||||||
|
@ -252,7 +254,7 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
|
||||||
$scope.queue.push(item);
|
$scope.queue.push(item);
|
||||||
item.selected = false;
|
item.selected = false;
|
||||||
});
|
});
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage($scope.selectedSongs.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage($scope.selectedSongs.length + ' Song(s) Added to Queue', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
JamStash.controller('SubsonicCtrl',
|
JamStash.controller('SubsonicCtrl',
|
||||||
function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, utils, globals, model, notifications, player) {
|
function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, utils, globals, model, notifications, player) {
|
||||||
$("#SubsonicAlbums").layout($scope.layoutThreeCol);
|
//$("#SubsonicAlbums").layout($scope.layoutThreeCol);
|
||||||
|
|
||||||
$rootScope.song = [];
|
$rootScope.song = [];
|
||||||
//$scope.artistId = $routeParams.artistId;
|
//$scope.artistId = $routeParams.artistId;
|
||||||
|
@ -20,27 +20,40 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
{ id: "frequent", name: "Most Played" },
|
{ id: "frequent", name: "Most Played" },
|
||||||
{ id: "recent", name: "Recently Played" }
|
{ id: "recent", name: "Recently Played" }
|
||||||
];
|
];
|
||||||
$scope.DefaultSearchType = globals.settings.DefaultSearchType;
|
|
||||||
$scope.selectedAutoAlbum;
|
$scope.selectedAutoAlbum;
|
||||||
$scope.selectedArtist;
|
$scope.selectedArtist;
|
||||||
$scope.selectedAlbum;
|
$scope.selectedAlbum;
|
||||||
$scope.selectedSubsonicAlbumSort = globals.settings.DefaultSubsonicAlbumSort;
|
$scope.selectedSubsonicAlbumSort = 'default';
|
||||||
|
$scope.SubsonicSort = [];
|
||||||
$scope.SubsonicAlbumSort = [
|
$scope.SubsonicAlbumSort = [
|
||||||
{ id: "default", name: "Default Sort" },
|
{ id: "default", name: "Default Sort" },
|
||||||
{ id: "artist", name: "Artist" },
|
{ id: "artist", name: "Artist" },
|
||||||
{ id: "album", name: "Album" },
|
{ id: "album", name: "Album" },
|
||||||
{ id: "createdate desc", name: "Created Date - Desc" },
|
{ id: "createdate desc", name: "Date Added" },
|
||||||
];
|
];
|
||||||
|
$scope.SubsonicSongSort = [
|
||||||
|
{ id: "default", name: "Default Sort" },
|
||||||
|
{ id: "track", name: "Track" },
|
||||||
|
{ id: "artist", name: "Artist" },
|
||||||
|
{ id: "album", name: "Album" },
|
||||||
|
{ id: "createdate desc", name: "Date Added" },
|
||||||
|
];
|
||||||
|
$scope.BreadCrumbs = [];
|
||||||
$scope.$watch("selectedSubsonicAlbumSort", function (newValue, oldValue) {
|
$scope.$watch("selectedSubsonicAlbumSort", function (newValue, oldValue) {
|
||||||
if (newValue !== oldValue) {
|
if (newValue !== oldValue) {
|
||||||
$scope.sortSubsonicAlbums(newValue);
|
if ($rootScope.song.length > 0) {
|
||||||
|
$scope.sortSubsonicSongs(newValue);
|
||||||
|
} else if ($scope.album.length > 0) {
|
||||||
|
$scope.sortSubsonicAlbums(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$rootScope.$watch("selectedMusicFolder", function (newValue, oldValue) {
|
||||||
|
if (newValue !== oldValue) {
|
||||||
|
utils.setValue('MusicFolders', angular.toJson(newValue), true);
|
||||||
|
$scope.getArtists(newValue.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$scope.SearchType = globals.settings.DefaultSearchType;
|
|
||||||
$scope.SearchTypeLayout = [
|
|
||||||
{ id: "song", name: "Song" },
|
|
||||||
{ id: "album", name: "Album" },
|
|
||||||
];
|
|
||||||
$scope.selectedLayout = globals.settings.DefaultLibraryLayout;
|
$scope.selectedLayout = globals.settings.DefaultLibraryLayout;
|
||||||
//not sure how to just grab the layouts hash from the settings controller
|
//not sure how to just grab the layouts hash from the settings controller
|
||||||
$scope.Layouts = [
|
$scope.Layouts = [
|
||||||
|
@ -123,6 +136,11 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
$scope.refreshArtists = function (id) {
|
||||||
|
utils.setValue('MusicFolders', null, true);
|
||||||
|
$scope.getArtists();
|
||||||
|
};
|
||||||
|
|
||||||
$scope.mapAlbum = function (data) {
|
$scope.mapAlbum = function (data) {
|
||||||
var album = data;
|
var album = data;
|
||||||
var title, coverartthumb, coverartfull, starred;
|
var title, coverartthumb, coverartfull, starred;
|
||||||
|
@ -140,10 +158,11 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
}
|
}
|
||||||
return new model.Album(album.id, album.parent, title, album.artist, album.artistId, coverartthumb, coverartfull, $.format.date(new Date(album.created), "yyyy-MM-dd h:mm a"), starred, '', '', type);
|
return new model.Album(album.id, album.parent, title, album.artist, album.artistId, coverartthumb, coverartfull, $.format.date(new Date(album.created), "yyyy-MM-dd h:mm a"), starred, '', '', type);
|
||||||
}
|
}
|
||||||
$scope.getAlbums = function (id) {
|
$scope.getAlbums = function (id, name) {
|
||||||
$scope.selectedAutoAlbum = null;
|
$scope.selectedAutoAlbum = null;
|
||||||
$scope.selectedArtist = id;
|
$scope.selectedArtist = id;
|
||||||
$scope.artistId = id;
|
$scope.BreadCrumbs = [];
|
||||||
|
$scope.BreadCrumbs.push({ 'type': 'artist', 'id': id, 'name': name });
|
||||||
var url = globals.BaseURL() + '/getMusicDirectory.view?' + globals.BaseParams() + '&id=' + id;
|
var url = globals.BaseURL() + '/getMusicDirectory.view?' + globals.BaseParams() + '&id=' + id;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: url,
|
url: url,
|
||||||
|
@ -165,13 +184,13 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
if (item.isDir) {
|
if (item.isDir) {
|
||||||
$scope.album.push($scope.mapAlbum(item));
|
$scope.album.push($scope.mapAlbum(item));
|
||||||
} else {
|
} else {
|
||||||
$rootScope.song.push($scope.mapSong(item));
|
$rootScope.song.push(utils.mapSong(item));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if ($scope.selectedSubsonicAlbumSort != "default") {
|
if ($scope.selectedSubsonicAlbumSort != "default") {
|
||||||
$scope.sortSubsonicAlbums($scope.selectedSubsonicAlbumSort);
|
$scope.sortSubsonicAlbums($scope.selectedSubsonicAlbumSort);
|
||||||
}
|
}
|
||||||
//$location.path('/library/' + id);
|
$scope.SubsonicSort = $scope.SubsonicAlbumSort;
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
} else {
|
} else {
|
||||||
notifications.updateMessage('No Albums Returned :(', true);
|
notifications.updateMessage('No Albums Returned :(', true);
|
||||||
|
@ -243,7 +262,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
items[0] = data["subsonic-response"].album.song;
|
items[0] = data["subsonic-response"].album.song;
|
||||||
}
|
}
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.song.push($scope.mapSong(item));
|
$rootScope.song.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
}
|
}
|
||||||
|
@ -255,6 +274,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
var size, url;
|
var size, url;
|
||||||
$scope.selectedArtist = null;
|
$scope.selectedArtist = null;
|
||||||
$scope.selectedAutoAlbum = id;
|
$scope.selectedAutoAlbum = id;
|
||||||
|
$scope.BreadCrumbs = [];
|
||||||
if (offset == 'next') {
|
if (offset == 'next') {
|
||||||
$scope.offset = $scope.offset + globals.settings.AutoAlbumSize;
|
$scope.offset = $scope.offset + globals.settings.AutoAlbumSize;
|
||||||
} else if (offset == 'prev') {
|
} else if (offset == 'prev') {
|
||||||
|
@ -279,6 +299,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
items[0] = data["subsonic-response"].albumList.album;
|
items[0] = data["subsonic-response"].albumList.album;
|
||||||
}
|
}
|
||||||
$scope.album = [];
|
$scope.album = [];
|
||||||
|
$rootScope.song = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
if (item.isDir) {
|
if (item.isDir) {
|
||||||
$scope.album.push($scope.mapAlbum(item));
|
$scope.album.push($scope.mapAlbum(item));
|
||||||
|
@ -286,6 +307,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
$rootScope.song.push($scope.mapAlbum(item));
|
$rootScope.song.push($scope.mapAlbum(item));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
$scope.SubsonicSort = $scope.SubsonicAlbumSort;
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
} else {
|
} else {
|
||||||
notifications.updateMessage('No Albums Returned :(', true);
|
notifications.updateMessage('No Albums Returned :(', true);
|
||||||
|
@ -309,43 +331,53 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
} else {
|
} else {
|
||||||
items[0] = data["subsonic-response"].directory.child;
|
items[0] = data["subsonic-response"].directory.child;
|
||||||
}
|
}
|
||||||
if (typeof data["subsonic-response"].directory.id != 'undefined') {
|
|
||||||
//alert(data["subsonic-response"].directory.id);
|
|
||||||
// Look at bringing back the breadcrumb
|
|
||||||
}
|
|
||||||
//alert(JSON.stringify(getMusicDirectory["subsonic-response"].directory.child));
|
|
||||||
if (action == 'add') {
|
if (action == 'add') {
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.queue.push($scope.mapSong(item));
|
$rootScope.queue.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
||||||
} else if (action == 'play') {
|
} else if (action == 'play') {
|
||||||
$rootScope.queue = [];
|
$rootScope.queue = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.queue.push($scope.mapSong(item));
|
$rootScope.queue.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
var next = $rootScope.queue[0];
|
var next = $rootScope.queue[0];
|
||||||
$scope.$apply(function () {
|
$scope.$apply(function () {
|
||||||
$rootScope.playSong(false, next);
|
$rootScope.playSong(false, next);
|
||||||
});
|
});
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
||||||
|
} else if (action == 'preview') {
|
||||||
|
$scope.songpreview = [];
|
||||||
|
angular.forEach(items, function (item, key) {
|
||||||
|
if (!item.isDir) {
|
||||||
|
$rootScope.songpreview.push(utils.mapSong(item));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$scope.$apply();
|
||||||
} else {
|
} else {
|
||||||
|
if (typeof data["subsonic-response"].directory.id != 'undefined') {
|
||||||
|
var albumId = data["subsonic-response"].directory.id;
|
||||||
|
var albumName = data["subsonic-response"].directory.name;
|
||||||
|
if ($scope.BreadCrumbs.length > 0) { $scope.BreadCrumbs.splice(1, ($scope.BreadCrumbs.length - 1)) };
|
||||||
|
$scope.BreadCrumbs.push({ 'type': 'album', 'id': albumId, 'name': albumName });
|
||||||
|
}
|
||||||
$rootScope.song = [];
|
$rootScope.song = [];
|
||||||
|
$scope.album = [];
|
||||||
var albums = [];
|
var albums = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
if (item.isDir) {
|
if (item.isDir) {
|
||||||
albums.push($scope.mapAlbum(item));
|
albums.push($scope.mapAlbum(item));
|
||||||
} else {
|
} else {
|
||||||
$rootScope.song.push($scope.mapSong(item));
|
$rootScope.song.push(utils.mapSong(item));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (albums.length > 0) {
|
if (albums.length > 0) {
|
||||||
$scope.album = albums;
|
$scope.album = albums;
|
||||||
}
|
}
|
||||||
//$location.path('/library/0/' + id);
|
$scope.SubsonicSort = $scope.SubsonicSongSort;
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -367,8 +399,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
if (data["subsonic-response"].searchResult2 !== "") {
|
if (data["subsonic-response"].searchResult2 !== "") {
|
||||||
var header;
|
var header;
|
||||||
var items = [];
|
var items = [];
|
||||||
if (type === '0') {
|
if (type === 'song') {
|
||||||
type = 'song'; //this could be done better if a way to share data between controllers was implemented
|
|
||||||
if (data["subsonic-response"].searchResult2.song !== undefined) {
|
if (data["subsonic-response"].searchResult2.song !== undefined) {
|
||||||
if (data["subsonic-response"].searchResult2.song.length > 0) {
|
if (data["subsonic-response"].searchResult2.song.length > 0) {
|
||||||
items = data["subsonic-response"].searchResult2.song;
|
items = data["subsonic-response"].searchResult2.song;
|
||||||
|
@ -377,13 +408,12 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
}
|
}
|
||||||
$rootScope.song = [];
|
$rootScope.song = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.song.push($scope.mapSong(item));
|
$rootScope.song.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type === '1') {
|
if (type === 'album') {
|
||||||
type = 'album';
|
|
||||||
if (data["subsonic-response"].searchResult2.album !== undefined) {
|
if (data["subsonic-response"].searchResult2.album !== undefined) {
|
||||||
if (data["subsonic-response"].searchResult2.album.length > 0) {
|
if (data["subsonic-response"].searchResult2.album.length > 0) {
|
||||||
items = data["subsonic-response"].searchResult2.album;
|
items = data["subsonic-response"].searchResult2.album;
|
||||||
|
@ -474,18 +504,14 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
return a.date < b.date ? 1 : -1;
|
return a.date < b.date ? 1 : -1;
|
||||||
};
|
};
|
||||||
$scope.sortArtistFunction = function (a, b) {
|
$scope.sortArtistFunction = function (a, b) {
|
||||||
return a.artist.toLowerCase() > b.artist.toLowerCase() ? -1 : 1;
|
return a.artist.toLowerCase() < b.artist.toLowerCase() ? -1 : 1;
|
||||||
};
|
};
|
||||||
$scope.sortAlbumFunction = function (a, b) {
|
$scope.sortAlbumFunction = function (a, b) {
|
||||||
/*
|
|
||||||
if (a.name < b.name) //sort string ascending
|
|
||||||
return -1
|
|
||||||
if (a.name > b.name)
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
*/
|
|
||||||
return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
|
return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
|
||||||
};
|
};
|
||||||
|
$scope.sortTrackFunction = function (a, b) {
|
||||||
|
return parseInt(a.track) > parseInt(b.track) ? -1 : 1;
|
||||||
|
};
|
||||||
$scope.sortSubsonicAlbums = function (newValue) {
|
$scope.sortSubsonicAlbums = function (newValue) {
|
||||||
if (typeof newValue != 'undefined') {
|
if (typeof newValue != 'undefined') {
|
||||||
//alert(newValue);
|
//alert(newValue);
|
||||||
|
@ -502,6 +528,25 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
$scope.sortSubsonicSongs = function (newValue) {
|
||||||
|
if (typeof newValue != 'undefined') {
|
||||||
|
//alert(newValue);
|
||||||
|
switch (newValue) {
|
||||||
|
case 'createdate desc':
|
||||||
|
$rootScope.song.sort($scope.sortDateFunction);
|
||||||
|
break;
|
||||||
|
case 'artist':
|
||||||
|
$rootScope.song.sort($scope.sortArtistFunction);
|
||||||
|
break;
|
||||||
|
case 'album':
|
||||||
|
$rootScope.song.sort($scope.sortAlbumFunction);
|
||||||
|
break;
|
||||||
|
case 'track':
|
||||||
|
$rootScope.song.sort($scope.sortTrackFunction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* Launch on Startup */
|
/* Launch on Startup */
|
||||||
$scope.getArtists();
|
$scope.getArtists();
|
||||||
|
|
|
@ -10,18 +10,6 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
$rootScope.selectedAutoPlaylist = "";
|
$rootScope.selectedAutoPlaylist = "";
|
||||||
$rootScope.selectedMusicFolder = "";
|
$rootScope.selectedMusicFolder = "";
|
||||||
$rootScope.unity;
|
$rootScope.unity;
|
||||||
|
|
||||||
$rootScope.$watch("selectedMusicFolder", function (newValue, oldValue) {
|
|
||||||
if (newValue !== oldValue) {
|
|
||||||
if (typeof newValue != 'undefined' && newValue != null) {
|
|
||||||
utils.setValue('MusicFolders', angular.toJson(newValue), true);
|
|
||||||
//$scope.getArtists(newValue.id);
|
|
||||||
} else {
|
|
||||||
utils.setValue('MusicFolders', null, true);
|
|
||||||
//$scope.getArtists();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$rootScope.loggedIn = function () {
|
$rootScope.loggedIn = function () {
|
||||||
if (globals.settings.Server != '' && globals.settings.Username != '' && globals.settings.Password != '') {
|
if (globals.settings.Server != '' && globals.settings.Username != '' && globals.settings.Password != '') {
|
||||||
return true;
|
return true;
|
||||||
|
@ -70,7 +58,7 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$("a.coverartfancy").live("click", function () {
|
$(".coverartfancy").on("click", "a", function () {
|
||||||
$("a.coverartfancy").fancybox({
|
$("a.coverartfancy").fancybox({
|
||||||
beforeShow: function () {
|
beforeShow: function () {
|
||||||
//this.title = $('#songdetails_artist').html();
|
//this.title = $('#songdetails_artist').html();
|
||||||
|
@ -117,7 +105,30 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
setTimeout(function () { if (submenu_active == false) $('div.submenu').stop().fadeOut(); }, 10000);
|
setTimeout(function () { if (submenu_active == false) $('div.submenu').stop().fadeOut(); }, 10000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$rootScope.showQueue = function (show) {
|
||||||
|
var submenu = $(QueuePreview);
|
||||||
|
submenu.fadeIn(400);
|
||||||
|
setTimeout(function () { submenu.fadeOut(); }, 20000);
|
||||||
|
}
|
||||||
|
$rootScope.hideQueue = function (show) {
|
||||||
|
submenu.fadeOut();
|
||||||
|
}
|
||||||
|
$scope.toggleQueue = function (show) {
|
||||||
|
var submenu = $(QueuePreview);
|
||||||
|
if (submenu.css('display') !== 'none') {
|
||||||
|
$rootScope.showQueue();
|
||||||
|
} else {
|
||||||
|
$rootScope.hideQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$scope.pinQueue = function () {
|
||||||
|
var submenu = $(QueuePreview);
|
||||||
|
if (submenu.css('display') !== 'none') {
|
||||||
|
submenu.fadeOut();
|
||||||
|
} else {
|
||||||
|
submenu.fadeIn(400);
|
||||||
|
}
|
||||||
|
}
|
||||||
$("a.coverartfancy").fancybox({
|
$("a.coverartfancy").fancybox({
|
||||||
beforeShow: function () {
|
beforeShow: function () {
|
||||||
//this.title = $('#songdetails_artist').html();
|
//this.title = $('#songdetails_artist').html();
|
||||||
|
@ -144,18 +155,7 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
$('.audiojs .scrubber').stop().animate({ height: '4px' });
|
$('.audiojs .scrubber').stop().animate({ height: '4px' });
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.message').live('click', function () { $(this).remove(); });
|
$('.message').on('click', function () { $(this).remove(); });
|
||||||
|
|
||||||
// JQuery UI Sortable - Drag and drop sorting
|
|
||||||
var fixHelper = function (e, ui) {
|
|
||||||
ui.children().each(function () {
|
|
||||||
$(this).width($(this).width());
|
|
||||||
});
|
|
||||||
return ui;
|
|
||||||
};
|
|
||||||
$("#QueuePreview ul.songlist").sortable({
|
|
||||||
helper: fixHelper
|
|
||||||
});
|
|
||||||
|
|
||||||
// Sway.fm Unity Plugin
|
// Sway.fm Unity Plugin
|
||||||
$rootScope.unity = UnityMusicShim();
|
$rootScope.unity = UnityMusicShim();
|
||||||
|
@ -179,76 +179,45 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// JQuery Layout Plugin
|
|
||||||
|
// JQuery UI Sortable - Drag and drop sorting
|
||||||
|
/*
|
||||||
|
var fixHelper = function (e, ui) {
|
||||||
|
ui.children().each(function () {
|
||||||
|
$(this).width($(this).width());
|
||||||
|
});
|
||||||
|
return ui;
|
||||||
|
};
|
||||||
|
$("#QueuePreview ul.songlist").sortable({
|
||||||
|
helper: fixHelper
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
/* JQuery Layout Plugin - I don't think this is used anywhere
|
||||||
function resizePageLayout() {
|
function resizePageLayout() {
|
||||||
var pageLayout = $("body").data("layout");
|
var pageLayout = $("body").data("layout");
|
||||||
if (pageLayout) pageLayout.resizeAll();
|
if (pageLayout) pageLayout.resizeAll();
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
//$( "#nav" ).tabs();
|
|
||||||
var pageLayoutOptions = {
|
|
||||||
name: 'pageLayout', // only for debugging
|
|
||||||
resizeWithWindowDelay: 250, // delay calling resizeAll when window is *still* resizing
|
|
||||||
//, resizeWithWindowMaxDelay: 2000 // force resize every XX ms while window is being resized
|
|
||||||
//center__children: {},
|
|
||||||
//north__paneSelector: "#container",
|
|
||||||
center__paneSelector: "#container",
|
|
||||||
south__paneSelector: "#QueuePreview",
|
|
||||||
south__resizable: false, // No resize
|
|
||||||
//south__closable: false, // No close handle
|
|
||||||
//south__spacing_open: 0, // No resize bar
|
|
||||||
south__size: 145,
|
|
||||||
south__initClosed: true,
|
|
||||||
south__minWidth: 145,
|
|
||||||
south__maxWidth: 145
|
|
||||||
};
|
|
||||||
|
|
||||||
// create the page-layout, which will ALSO create the tabs-wrapper child-layout
|
|
||||||
var pageLayout = $("body").layout(pageLayoutOptions);
|
|
||||||
|
|
||||||
$scope.layoutThreeCol = {
|
|
||||||
east__size: .45,
|
|
||||||
east__minSize: 400,
|
|
||||||
east__maxSize: .5, // 50% of layout width
|
|
||||||
east__initClosed: false,
|
|
||||||
east__initHidden: false,
|
|
||||||
//center__size: 'auto',
|
|
||||||
center__minWidth: .35,
|
|
||||||
center__initClosed: false,
|
|
||||||
center__initHidden: false,
|
|
||||||
west__size: .2,
|
|
||||||
west__minSize: 200,
|
|
||||||
west__initClosed: false,
|
|
||||||
west__initHidden: false,
|
|
||||||
//stateManagement__enabled: true, // automatic cookie load & save enabled by default
|
|
||||||
showDebugMessages: true // log and/or display messages from debugging & testing code
|
|
||||||
//applyDefaultStyles: true
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.layoutTwoCol = {
|
|
||||||
center__size: .8,
|
|
||||||
center__minSize: 400,
|
|
||||||
center__maxSize: .5, // 50% of layout width
|
|
||||||
center__initClosed: false,
|
|
||||||
center__initHidden: false,
|
|
||||||
west__size: .2,
|
|
||||||
west__minSize: 200,
|
|
||||||
west__initClosed: false,
|
|
||||||
west__initHidden: false,
|
|
||||||
//stateManagement__enabled: true, // automatic cookie load & save enabled by default
|
|
||||||
showDebugMessages: true // log and/or display messages from debugging & testing code
|
|
||||||
//applyDefaultStyles: true
|
|
||||||
};
|
|
||||||
|
|
||||||
// Global Functions
|
// Global Functions
|
||||||
window.onbeforeunload = function () {
|
window.onbeforeunload = function () {
|
||||||
if (!self.settings.Debug()) {
|
if (!globals.settings.Debug) {
|
||||||
if (self.queue().length > 0) {
|
if ($rootScope.queue.length > 0) {
|
||||||
return "You're about to end your session, are you sure?";
|
return "You're about to end your session, are you sure?";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$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.keydown(function (e) {
|
$document.keydown(function (e) {
|
||||||
$scope.scrollToIndex(e);
|
$scope.scrollToIndex(e);
|
||||||
});
|
});
|
||||||
|
@ -279,17 +248,17 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
}
|
}
|
||||||
var el = '#' + key.toUpperCase();
|
var el = '#' + key.toUpperCase();
|
||||||
if ($(el).length > 0) {
|
if ($(el).length > 0) {
|
||||||
$('#SubsonicArtists').stop().scrollTo(el, 400);
|
$('#left-component').stop().scrollTo(el, 400);
|
||||||
}
|
}
|
||||||
} else if (unicode == 39 || unicode == 176) { // right arrow
|
} else if (unicode == 39 || unicode == 176) { // right arrow
|
||||||
$rootScope.nextTrack();
|
$rootScope.nextTrack();
|
||||||
} else if (unicode == 37 || unicode == 177) { // back arrow
|
} else if (unicode == 37 || unicode == 177) { // back arrow
|
||||||
$rootScope.previousTrack();
|
$rootScope.previousTrack();
|
||||||
} else if (unicode == 32 || unicode == 179 || unicode == 0179) { // spacebar
|
} else if (unicode == 32 || unicode == 179 || unicode.toString() == '0179') { // spacebar
|
||||||
player.playPauseSong();
|
player.playPauseSong();
|
||||||
return false;
|
return false;
|
||||||
} else if (unicode == 36 && $('#tabLibrary').is(':visible')) { // home
|
} else if (unicode == 36 && $('#tabLibrary').is(':visible')) { // home
|
||||||
$('#SubsonicArtists').stop().scrollTo('#MusicFolders', 400);
|
$('#left-component').stop().scrollTo('#MusicFolders', 400);
|
||||||
}
|
}
|
||||||
if (unicode == 189) { // dash - volume down
|
if (unicode == 189) { // dash - volume down
|
||||||
var volume = utils.getValue('Volume') ? parseFloat(utils.getValue('Volume')) : 1;
|
var volume = utils.getValue('Volume') ? parseFloat(utils.getValue('Volume')) : 1;
|
||||||
|
@ -319,7 +288,7 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
$scope.scrollToIndexName = function (index) {
|
$scope.scrollToIndexName = function (index) {
|
||||||
var el = '#' + index;
|
var el = '#' + index;
|
||||||
if ($(el).length > 0) {
|
if ($(el).length > 0) {
|
||||||
$('#SubsonicArtists').stop().scrollTo(el, 400);
|
$('#left-component').stop().scrollTo(el, 400);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
$scope.scrollToTop = function () {
|
$scope.scrollToTop = function () {
|
||||||
|
@ -331,6 +300,12 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
item.selected = true;
|
item.selected = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
$scope.playAll = function () {
|
||||||
|
$scope.selectAll();
|
||||||
|
$scope.addSongsToQueue();
|
||||||
|
var next = $rootScope.queue[0];
|
||||||
|
$rootScope.playSong(false, next);
|
||||||
|
}
|
||||||
$scope.selectNone = function () {
|
$scope.selectNone = function () {
|
||||||
angular.forEach($rootScope.song, function (item, key) {
|
angular.forEach($rootScope.song, function (item, key) {
|
||||||
$scope.selectedSongs = [];
|
$scope.selectedSongs = [];
|
||||||
|
@ -343,7 +318,7 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
$scope.queue.push(item);
|
$scope.queue.push(item);
|
||||||
item.selected = false;
|
item.selected = false;
|
||||||
});
|
});
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage($scope.selectedSongs.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage($scope.selectedSongs.length + ' Song(s) Added to Queue', true);
|
||||||
$scope.selectedSongs.length = 0;
|
$scope.selectedSongs.length = 0;
|
||||||
}
|
}
|
||||||
|
@ -438,34 +413,15 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
globals.settings.ApiVersion = data["subsonic-response"].version;
|
globals.settings.ApiVersion = data["subsonic-response"].version;
|
||||||
} else {
|
} else {
|
||||||
if (typeof data["subsonic-response"].error != 'undefined') {
|
if (typeof data["subsonic-response"].error != 'undefined') {
|
||||||
alert(data["subsonic-response"].error.message);
|
notifications.updateMessage(data["subsonic-response"].error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function () {
|
error: function () {
|
||||||
alert('Unable to connect to Subsonic server');
|
notifications.updateMessage('Unable to connect to Subsonic server');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
$scope.mapSong = function (data) {
|
|
||||||
var song = data;
|
|
||||||
var url, 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;
|
|
||||||
coverartfull = globals.BaseURL() + '/getCoverArt.view?' + globals.BaseParams() + '&id=' + song.coverArt;
|
|
||||||
}
|
|
||||||
if (typeof song.description == 'undefined') { description = ''; } else { description = song.description; }
|
|
||||||
if (typeof song.track == 'undefined') { track = ' '; } else { track = song.track; }
|
|
||||||
if (typeof song.starred !== 'undefined') { starred = true; } else { starred = false; }
|
|
||||||
if (song.bitRate !== undefined) { specs += song.bitRate + ' Kbps'; }
|
|
||||||
if (song.transcodedSuffix !== undefined) { specs += ', transcoding:' + song.suffix + ' > ' + song.transcodedSuffix; } else { specs += ', ' + song.suffix; }
|
|
||||||
if (song.transcodedSuffix !== undefined) { suffix = song.transcodedSuffix; } else { suffix = song.suffix; }
|
|
||||||
if (suffix == 'ogg') { suffix = 'oga'; }
|
|
||||||
var salt = Math.floor(Math.random() * 100000);
|
|
||||||
url = globals.BaseURL() + '/stream.view?' + globals.BaseParams() + '&id=' + song.id + '&salt=' + salt;
|
|
||||||
return new model.Song(song.id, song.parent, track, song.title, song.artist, song.artistId, song.album, song.albumId, coverartthumb, coverartfull, song.duration, song.userRating, starred, suffix, specs, url, 0, description);
|
|
||||||
}
|
|
||||||
$scope.addSongToQueue = function (data) {
|
$scope.addSongToQueue = function (data) {
|
||||||
$rootScope.queue.push(data);
|
$rootScope.queue.push(data);
|
||||||
}
|
}
|
||||||
|
@ -545,26 +501,26 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
}
|
}
|
||||||
if (action == 'add') {
|
if (action == 'add') {
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.queue.push($scope.mapSong(item));
|
$rootScope.queue.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
||||||
} else if (action == 'play') {
|
} else if (action == 'play') {
|
||||||
$rootScope.queue = [];
|
$rootScope.queue = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.queue.push($scope.mapSong(item));
|
$rootScope.queue.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
var next = $rootScope.queue[0];
|
var next = $rootScope.queue[0];
|
||||||
$scope.$apply(function () {
|
$scope.$apply(function () {
|
||||||
$rootScope.playSong(false, next);
|
$rootScope.playSong(false, next);
|
||||||
});
|
});
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
||||||
} else {
|
} else {
|
||||||
$rootScope.song = [];
|
$rootScope.song = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.song.push($scope.mapSong(item));
|
$rootScope.song.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
}
|
}
|
||||||
|
@ -593,13 +549,14 @@ function AppCtrl($scope, $rootScope, $document, $location, utils, globals, model
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
$scope.toTrusted = function (html) {
|
||||||
|
return $sce.trustAsHtml(html);
|
||||||
|
}
|
||||||
|
|
||||||
/* Launch on Startup */
|
/* Launch on Startup */
|
||||||
$scope.loadSettings();
|
$scope.loadSettings();
|
||||||
utils.switchTheme(globals.settings.Theme);
|
utils.switchTheme(globals.settings.Theme);
|
||||||
if ($scope.loggedIn) {
|
if ($scope.loggedIn()) {
|
||||||
$scope.ping();
|
$scope.ping();
|
||||||
$scope.getMusicFolders();
|
$scope.getMusicFolders();
|
||||||
if (globals.settings.SaveTrackPosition) {
|
if (globals.settings.SaveTrackPosition) {
|
||||||
|
|
52
js/controllers/partial.js
Normal file
52
js/controllers/partial.js
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
JamStash.controller('PartialCtrl',
|
||||||
|
function PartialCtrl($scope, $rootScope, $location, $window, $routeParams, utils, globals) {
|
||||||
|
//$("#SubsonicAlbums").layout($scope.layoutThreeCol);
|
||||||
|
|
||||||
|
$scope.song = [];
|
||||||
|
$scope.itemType = 'ss';
|
||||||
|
$scope.index = [];
|
||||||
|
$scope.shortcut = [];
|
||||||
|
$scope.album = [];
|
||||||
|
$scope.Server = globals.settings.Server;
|
||||||
|
|
||||||
|
$scope.getSongs = function (id) {
|
||||||
|
var url = globals.BaseURL() + '/getMusicDirectory.view?' + globals.BaseParams() + '&id=' + id;
|
||||||
|
$.ajax({
|
||||||
|
url: url,
|
||||||
|
method: 'GET',
|
||||||
|
dataType: globals.settings.Protocol,
|
||||||
|
timeout: globals.settings.Timeout,
|
||||||
|
success: function (data) {
|
||||||
|
var items = [];
|
||||||
|
if (typeof data["subsonic-response"].directory.child != 'undefined') {
|
||||||
|
if (data["subsonic-response"].directory.child.length > 0) {
|
||||||
|
items = data["subsonic-response"].directory.child;
|
||||||
|
} else {
|
||||||
|
items[0] = data["subsonic-response"].directory.child;
|
||||||
|
}
|
||||||
|
$scope.song = [];
|
||||||
|
var albums = [];
|
||||||
|
angular.forEach(items, function (item, key) {
|
||||||
|
if (item.isDir) {
|
||||||
|
//albums.push($scope.mapAlbum(item));
|
||||||
|
} else {
|
||||||
|
$rootScope.song.push(utils.mapSong(item));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//$location.path('/library/0/' + id);
|
||||||
|
$scope.$apply();
|
||||||
|
} else {
|
||||||
|
notifications.updateMessage('No Songs Returned :(', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Launch on Startup */
|
||||||
|
if ($routeParams.albumId) {
|
||||||
|
$scope.getSongs($routeParams.albumId);
|
||||||
|
}
|
||||||
|
/* End Startup */
|
||||||
|
});
|
|
@ -1,6 +1,6 @@
|
||||||
JamStash.controller('PlaylistCtrl',
|
JamStash.controller('PlaylistCtrl',
|
||||||
function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, notifications) {
|
function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, notifications) {
|
||||||
$("#LayoutContainer").layout($scope.layoutTwoCol);
|
//$("#left-component").layout($scope.layoutTwoCol);
|
||||||
|
|
||||||
$rootScope.song = [];
|
$rootScope.song = [];
|
||||||
$scope.itemType = 'pl';
|
$scope.itemType = 'pl';
|
||||||
|
@ -61,26 +61,27 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
|
||||||
}
|
}
|
||||||
if (action == 'add') {
|
if (action == 'add') {
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.queue.push($scope.mapSong(item));
|
$rootScope.queue.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
||||||
} else if (action == 'play') {
|
} else if (action == 'play') {
|
||||||
$rootScope.queue = [];
|
$rootScope.queue = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.queue.push($scope.mapSong(item));
|
$rootScope.queue.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
var next = $rootScope.queue[0];
|
var next = $rootScope.queue[0];
|
||||||
$scope.$apply(function () {
|
$scope.$apply(function () {
|
||||||
$rootScope.playSong(false, next);
|
$rootScope.playSong(false, next);
|
||||||
});
|
});
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
||||||
} else {
|
} else {
|
||||||
|
$scope.album = [];
|
||||||
$rootScope.song = [];
|
$rootScope.song = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.song.push($scope.mapSong(item));
|
$rootScope.song.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
}
|
}
|
||||||
|
@ -130,26 +131,26 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
|
||||||
}
|
}
|
||||||
if (action == 'add') {
|
if (action == 'add') {
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.queue.push($scope.mapSong(item));
|
$rootScope.queue.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
||||||
} else if (action == 'play') {
|
} else if (action == 'play') {
|
||||||
$rootScope.queue = [];
|
$rootScope.queue = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.queue.push($scope.mapSong(item));
|
$rootScope.queue.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
var next = $rootScope.queue[0];
|
var next = $rootScope.queue[0];
|
||||||
$scope.$apply(function () {
|
$scope.$apply(function () {
|
||||||
$rootScope.playSong(false, next);
|
$rootScope.playSong(false, next);
|
||||||
});
|
});
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
||||||
} else {
|
} else {
|
||||||
$rootScope.song = [];
|
$rootScope.song = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
$rootScope.song.push($scope.mapSong(item));
|
$rootScope.song.push(utils.mapSong(item));
|
||||||
});
|
});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
JamStash.controller('PodcastCtrl',
|
JamStash.controller('PodcastCtrl',
|
||||||
function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notifications) {
|
function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notifications) {
|
||||||
$("#LayoutContainer").layout($scope.layoutTwoCol);
|
//$("#left-component").layout($scope.layoutTwoCol);
|
||||||
|
|
||||||
$rootScope.song = [];
|
$rootScope.song = [];
|
||||||
$scope.podcasts = [];
|
$scope.podcasts = [];
|
||||||
|
@ -75,7 +75,7 @@ function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notif
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
||||||
} else if (action == 'play') {
|
} else if (action == 'play') {
|
||||||
$rootScope.queue = [];
|
$rootScope.queue = [];
|
||||||
|
@ -88,9 +88,10 @@ function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notif
|
||||||
$scope.$apply(function () {
|
$scope.$apply(function () {
|
||||||
$rootScope.playSong(false, next);
|
$rootScope.playSong(false, next);
|
||||||
});
|
});
|
||||||
$('body').layout().open('south');
|
$rootScope.showQueue();
|
||||||
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
|
||||||
} else {
|
} else {
|
||||||
|
$scope.album = [];
|
||||||
$rootScope.song = [];
|
$rootScope.song = [];
|
||||||
angular.forEach(items, function (item, key) {
|
angular.forEach(items, function (item, key) {
|
||||||
if (item.status != "skipped") {
|
if (item.status != "skipped") {
|
||||||
|
|
|
@ -13,23 +13,11 @@ function SettingsCtrl($scope, $routeParams, $location, utils, globals, json, not
|
||||||
];
|
];
|
||||||
$scope.Protocols = ["json", "jsonp"];
|
$scope.Protocols = ["json", "jsonp"];
|
||||||
$scope.Themes = ["Default", "Dark"];
|
$scope.Themes = ["Default", "Dark"];
|
||||||
$scope.SearchTypeLayout = [
|
|
||||||
{ id: "song", name: "Song" },
|
|
||||||
{ id: "album", name: "Album" },
|
|
||||||
];
|
|
||||||
$scope.DefaultSearchType = 'song';
|
|
||||||
$scope.LibraryLayouts = [
|
$scope.LibraryLayouts = [
|
||||||
{ id: "list", name: "List" },
|
{ id: "list", name: "List" },
|
||||||
{ id: "grid", name: "Grid" },
|
{ id: "grid", name: "Grid" },
|
||||||
];
|
];
|
||||||
$scope.DefaultLibraryLayout = 'grid';
|
$scope.DefaultLibraryLayout = 'grid';
|
||||||
$scope.DefaultSubsonicAlbumSort = 'list';
|
|
||||||
$scope.SubsonicAlbumSort = [
|
|
||||||
{ id: "default", name: "Default Sort" },
|
|
||||||
{ id: "artist", name: "Artist" },
|
|
||||||
{ id: "album", name: "Album" },
|
|
||||||
{ id: "createdate desc", name: "Created Date - Desc" },
|
|
||||||
];
|
|
||||||
$scope.$watch('settings.HideAZ', function () {
|
$scope.$watch('settings.HideAZ', function () {
|
||||||
if (globals.settings.HideAZ) {
|
if (globals.settings.HideAZ) {
|
||||||
$('#AZIndex').hide();
|
$('#AZIndex').hide();
|
||||||
|
|
|
@ -1,7 +1,15 @@
|
||||||
[
|
[
|
||||||
|
{
|
||||||
|
"date": "1/12/2014", "version": "3.2",
|
||||||
|
"changes": [
|
||||||
|
{ "text": "- Redesigned Queue, moved buttons" },
|
||||||
|
{ "text": "- Added Play button to play current song list" },
|
||||||
|
{ "text": "- Fixed drag & drop sorting, Artist list will refresh on Folder change" }
|
||||||
|
]
|
||||||
|
},
|
||||||
{ "date": "12/5/2013", "version": "3.1.2",
|
{ "date": "12/5/2013", "version": "3.1.2",
|
||||||
"changes": [
|
"changes": [
|
||||||
{ "text": "- Improved linking between tabs, + Playlist fixed, " }
|
{ "text": "- Improved linking between tabs, + Playlist fixed" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "date": "10/31/2013", "version": "3.1.1",
|
{ "date": "10/31/2013", "version": "3.1.1",
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
<a href="" class="button" id="action_AddToQueue" title="Add To Queue" ng-click="addSongsToQueue()">+ Queue</a>
|
<a href="" class="button" id="action_AddToQueue" title="Add To Queue" ng-click="addSongsToQueue()">+ Queue</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
<div id="LayoutContainer" class="section lgsection">
|
<div id="LayoutContainer" class="section lgsection split-pane fixed-left" split>
|
||||||
<div class="ui-layout-west noselect hide" tabindex="0">
|
<div id="left-component" class="split-pane-component smcolumn noselect" tabindex="0">
|
||||||
<!-- Artist -->
|
<!-- Artist -->
|
||||||
<select class="large" id="Collections" ng-disabled="!loadedCollection" ng-model="selectedCollection" ng-options="o for o in AllCollections">
|
<select class="large" id="Collections" ng-disabled="!loadedCollection" ng-model="selectedCollection" ng-options="o for o in AllCollections">
|
||||||
<option value="">Select Collection</option>
|
<option value="">Select Collection</option>
|
||||||
|
@ -27,48 +27,50 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="split-pane-divider" id="my-divider"></div>
|
||||||
<!-- Album -->
|
<!-- Album -->
|
||||||
<div class="ui-layout-center">
|
<div id="right-component" class="split-pane-component lgcolumn">
|
||||||
<ul class="actionlist">
|
<ul class="actionlist">
|
||||||
<li>
|
<li>
|
||||||
<form class="form">
|
<form class="form">
|
||||||
<select ng-model="selectedArchiveAlbumSort" ng-options="o for o in ArchiveAlbumSort"></select>
|
<select ng-model="selectedArchiveAlbumSort" ng-options="o for o in ArchiveAlbumSort"></select>
|
||||||
<select id="Years" ng-model="filter.Year" ng-options="o for o in Years">
|
<select id="Years" ng-model="filter.Year" ng-options="o for o in Years">
|
||||||
<option value="">[Year]</option>
|
<option value="">[Year]</option>
|
||||||
</select>
|
</select>
|
||||||
<input type="text" id="Source" name="Source" class="sm" ng-model="filter.Source" placeholder="Source" title="Source"/>
|
<input type="text" id="Source" name="Source" class="sm" ng-model="filter.Source" placeholder="Source" title="Source" />
|
||||||
<input type="text" id="Description" name="Description" class="m" ng-model="filter.Description" placeholder="Description" title="Description"/>
|
<input type="text" id="Description" name="Description" class="m" ng-model="filter.Description" placeholder="Description" title="Description" />
|
||||||
<a href="" class="button" ng-click="filterSave()">Go</a>
|
<a href="" class="button" ng-click="filterSave()">Go</a>
|
||||||
</form>
|
</form>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
<ul class="simplelist songlist noselect">
|
<ul class="simplelist songlist noselect">
|
||||||
<li class="album" ng-repeat="o in album" id="{{o.id}}" parentid="{{o.parentid}}" ng-class="{'selected': selectedAlbum == o.id}" ng-click="getSongs(o.id, '')">
|
<div class="" ng-repeat="o in album" ng-switch on="o.type">
|
||||||
<div id="{{'AlbumInfo' + $index}}" class="infolink">
|
<li class="album" id="{{o.id}}" parentid="{{o.parentid}}" ng-class="{'selected': selectedAlbum == o.id}" ng-click="getSongs(o.id, '')">
|
||||||
<a href="" class="hover" title="More Info..." ng-click="toggleSubmenu('#submenu_AlbumInfo' + $index, '#AlbumInfo' + $index, 'right', 10)" stop-event="click"><img src="images/info_gl_6x12.png" /></a>
|
<div id="{{'AlbumInfo' + $index}}" class="infolink">
|
||||||
</div>
|
<a href="" class="hover" title="More Info..." ng-click="toggleSubmenu('#submenu_AlbumInfo' + $index, '#AlbumInfo' + $index, 'right', 10)" stop-event="click"><img src="images/info_gl_6x12.png" /></a>
|
||||||
<div id="{{'submenu_AlbumInfo' + $index}}" class="submenu_AlbumInfo submenu shadow" style="display: none;">
|
</div>
|
||||||
<a href="" ng-href="{{o.url}}" title="{{o.url}}" target="_blank" stop-event="click">Source</a><br />
|
<div id="{{'submenu_AlbumInfo' + $index}}" class="submenu_AlbumInfo submenu shadow" style="display: none;">
|
||||||
<a href="" ng-href="{{settings.Url + o.artist + '/' + o.id}}" title="{{settings.Url + o.artist + '/' + o.id}}" target="_blank" stop-event="click">PermaStash</a>
|
<a href="" ng-href="{{o.url}}" title="{{o.url}}" target="_blank" stop-event="click">Source</a><br />
|
||||||
</div>
|
<a href="" ng-href="{{settings.Url + o.artist + '/' + o.id}}" title="{{settings.Url + o.artist + '/' + o.id}}" target="_blank" stop-event="click">PermaStash</a>
|
||||||
<div class="itemactions">
|
</div>
|
||||||
<a class="add" href="" title="Add To Play Queue" ng-click="getSongs(o.id, 'add')" stop-event="click"></a>
|
<div class="itemactions">
|
||||||
<a class="play" href="" title="Play" ng-click="getSongs(o.id, 'play')" stop-event="click"></a>
|
<a class="add" href="" title="Add To Play Queue" ng-click="getSongs(o.id, 'add')" stop-event="click"></a>
|
||||||
<a class="download" href="" title="Download"></a>
|
<a class="play" href="" title="Play" ng-click="getSongs(o.id, 'play')" stop-event="click"></a>
|
||||||
<a href="" title="Favorite" ng-class="{'favorite': o.starred, 'rate': !o.starred}" ng-click="updateFavorite(o)" stop-event="click"></a>
|
<a class="download" href="" title="Download"></a>
|
||||||
</div>
|
<a href="" title="Favorite" ng-class="{'favorite': o.starred, 'rate': !o.starred}" ng-click="updateFavorite(o)" stop-event="click"></a>
|
||||||
<div class="albumart"><img ng-src="{{o.coverart}}" src="images/albumdefault_50.jpg"></div>
|
</div>
|
||||||
<div class="title">{{o.name}}</div>
|
<div class="albumart"><img ng-src="{{o.coverart}}" src="images/albumdefault_50.jpg"></div>
|
||||||
<div class="artist"><a href="" id="{{o.parentid}}" ng-click="getAlbums(o.artist, o.id)" stop-event="click">{{o.artist}}</a></div>
|
<div class="title">{{o.name}}</div>
|
||||||
<!--<div class="details">Created: {{o.date}}</div>-->
|
<div class="artist"><a href="" id="{{o.parentid}}" ng-click="getAlbums(o.artist, o.id)" stop-event="click">{{o.artist}}</a></div>
|
||||||
<div class="description shadow" ng-show="selectedAlbum == o.id" ng-bind-html-unsafe="o.description"></div>
|
<!--<div class="details">Created: {{o.date}}</div>-->
|
||||||
<div class="clear"></div>
|
<div class="description shadow" ng-show="selectedAlbum == o.id" ng-bind-html="o.description"></div>
|
||||||
</li>
|
<div class="clear"></div>
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
|
<div ng-include src="'js/partials/songs.html'"></div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<!-- Song -->
|
|
||||||
<div class="ui-layout-east noselect hide" ng-include src="'js/partials/songs.html'"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
|
|
|
@ -2,15 +2,19 @@
|
||||||
<div id="tab1" class="tabcontent">
|
<div id="tab1" class="tabcontent">
|
||||||
<div id="tabLibrary">
|
<div id="tabLibrary">
|
||||||
<div class="actions floatleft">
|
<div class="actions floatleft">
|
||||||
<a href="" class="button" id="action_RefreshArtists" title="Refresh Artists" ng-click="getArtists()"><img class="pad" src="images/reload_9x11.png" /></a>
|
<a href="" class="button" id="action_RefreshArtists" title="Refresh Artists" ng-click="refreshArtists()"><img class="pad" src="images/reload_9x11.png" /></a>
|
||||||
<a href="" class="button" id="action_RescanLibrary" title="Rescan Library" ng-click="rescanLibrary()"><img class="pad" src="images/loop_alt1_gd_12x9.png" /></a>
|
<a href="" class="button" id="action_RescanLibrary" title="Rescan Library" ng-click="rescanLibrary()"><img class="pad" src="images/loop_alt1_gd_12x9.png" /></a>
|
||||||
</div>
|
</div>
|
||||||
<div id="search">
|
<div id="search">
|
||||||
<input type="text" id="Search" class="medium" title="Wildcards (*) supported" placeholder="Search..." ng-enter="search()"/>
|
<input type="text" id="Search" class="medium" title="Wildcards (*) supported" placeholder="Search..." ng-enter="search()"/>
|
||||||
<select id="SearchType" name="SearchType" ng-model="SearchType" ng-options="o.id as o.name for o in SearchTypeLayout"></select>
|
<select id="SearchType" name="SearchType">
|
||||||
|
<option value="song">Song</option>
|
||||||
|
<option value="album">Album</option>
|
||||||
|
</select>
|
||||||
<a href="" class="button" id="action_Search" title="Search" ng-click="search()"><img class="pad" src="images/magnifying_glass_alt_12x12.png" /></a>
|
<a href="" class="button" id="action_Search" title="Search" ng-click="search()"><img class="pad" src="images/magnifying_glass_alt_12x12.png" /></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="subactions">
|
<div class="subactions">
|
||||||
|
<a href="" class="button" id="action_PlayAlbum" title="Play Album" ng-click="playAll()"><img src="images/play_gl_6x8.png"></a>
|
||||||
<a href="" class="button" id="action_SelectAll" title="Select All" ng-click="selectAll()">All</a>
|
<a href="" class="button" id="action_SelectAll" title="Select All" ng-click="selectAll()">All</a>
|
||||||
<a href="" class="button" id="action_SelectNone" title="Select None" ng-click="selectNone()">None</a>
|
<a href="" class="button" id="action_SelectNone" title="Select None" ng-click="selectNone()">None</a>
|
||||||
<a href="" class="button" id="action_AddToQueue" title="Add To Queue" ng-click="addSongsToQueue()">+ Queue</a>
|
<a href="" class="button" id="action_AddToQueue" title="Add To Queue" ng-click="addSongsToQueue()">+ Queue</a>
|
||||||
|
@ -19,96 +23,99 @@
|
||||||
<a href="" ng-repeat="o in playlistMenu" ng-click="addToPlaylist(o.id)">{{o.name}}</a>
|
<a href="" ng-repeat="o in playlistMenu" ng-click="addToPlaylist(o.id)">{{o.name}}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div id="SubsonicAlbums" class="section lgsection split-pane fixed-left" split>
|
||||||
<div id="SubsonicAlbums" class="section lgsection">
|
<!--<div id="SubsonicAlbums" class="section lgsection" layout state="bodyState" ng-init="bodyState = 3">-->
|
||||||
<div id="SubsonicArtists" class="ui-layout-west noselect hide" tabindex="0">
|
<!--<div id="SubsonicAlbums" class="section lgsection">-->
|
||||||
|
<div id="left-component" class="split-pane-component smcolumn noselect" tabindex="0">
|
||||||
<div id="AZIndex" ng-show="!settings.HideAZ" class="subactionsfixed">
|
<div id="AZIndex" ng-show="!settings.HideAZ" class="subactionsfixed">
|
||||||
<a href="" ng-click="toggleAZ()" stop-event="click">A-Z</a>
|
<a href="" ng-click="toggleAZ()" stop-event="click">A-Z</a>
|
||||||
</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>
|
|
||||||
<li><a href="" class="close" ng-click="scrollToIndexName('AZIndex')">[Top]</a></li>
|
|
||||||
<li><a href="" class="close" ng-click="toggleAZ()">[Close]</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<select id="MusicFolders" class="folders" ng-model="$root.selectedMusicFolder" ng-options="o as o.name for o in MusicFolders">
|
<select id="MusicFolders" class="folders" ng-model="$root.selectedMusicFolder" ng-options="o as o.name for o in MusicFolders">
|
||||||
<option value="">All Folders</option>
|
<option value="">All Folders</option>
|
||||||
</select>
|
</select>
|
||||||
<ul id="AutoAlbumContainer" class="simplelist mainlist noselect">
|
<ul id="AutoAlbumContainer" class="simplelist mainlist noselect">
|
||||||
<li class="index" id="auto">Auto Albums</li>
|
<li class="index" id="auto">Auto Albums</li>
|
||||||
<li class="item" ng-repeat="o in AutoAlbums" id="{{o.id}}" ng-click="getAlbumListBy(o.id)" ng-class="{'selected': selectedAutoAlbum == o.id }"><span>{{o.name}}</span>
|
<li class="item" ng-repeat="o in AutoAlbums" id="{{o.id}}" ng-click="getAlbumListBy(o.id)" ng-class="{'selected': selectedAutoAlbum == o.id }">
|
||||||
<div class="floatright">
|
<span>{{o.name}}</span>
|
||||||
<a href="" class="nextprev hover" id="random" title="Previous" ng-click="getAlbumListBy(o.id, 'prev')" stop-event="click">‹</a>
|
<div class="floatright">
|
||||||
<a href="" class="nextprev hover" id="random" title="Next" ng-click="getAlbumListBy(o.id, 'next')" stop-event="click">›</a>
|
<a href="" class="nextprev hover" id="random" title="Previous" ng-click="getAlbumListBy(o.id, 'prev')" stop-event="click">‹</a>
|
||||||
</div>
|
<a href="" class="nextprev hover" id="random" title="Next" ng-click="getAlbumListBy(o.id, 'next')" stop-event="click">›</a>
|
||||||
</li>
|
</div>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<!-- Shortcut -->
|
<!-- Shortcut -->
|
||||||
<ul class="simplelist mainlist noselect" ng-show="shortcut.length">
|
<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>
|
<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">
|
<ul class="simplelist mainlist noselect" ng-repeat="o in shortcut">
|
||||||
<li class="item" id="{{o.id}}" ng-click="getAlbums(o.id)" ng-class="{'selected': selectedArtist == o.id}"><span ng-bind-html-unsafe="o.name"></span></li>
|
<li class="item" id="{{o.id}}" ng-click="getAlbums(o.id, o.name)" ng-class="{'selected': selectedArtist == o.id}"><span ng-bind-html-unsafe="o.name"></span></li>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
<!-- Artist -->
|
<!-- Artist -->
|
||||||
<ul class="simplelist mainlist noselect" ng-repeat="o in index">
|
<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><span class="floatright">?</span></li>
|
||||||
<ul class="simplelist mainlist noselect">
|
<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 ng-href="" ng-bind-html-unsafe="a.name"></a></li>
|
<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-unsafe="a.name"></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="split-pane-divider" id="my-divider"></div>
|
||||||
<!-- Album -->
|
<!-- Album -->
|
||||||
<div class="ui-layout-center">
|
<div id="right-component" class="split-pane-component lgcolumn">
|
||||||
<ul class="actionlist">
|
<ul class="actionlist">
|
||||||
<li>
|
<li>
|
||||||
<form class="form">
|
<form class="form">
|
||||||
<select id="selectedSubsonicAlbumSort" ng-model="selectedSubsonicAlbumSort" ng-options="o.id as o.name for o in SubsonicAlbumSort"></select>
|
<select id="selectedSubsonicAlbumSort" ng-model="selectedSubsonicAlbumSort" ng-show="SubsonicSort.length" ng-options="o.id as o.name for o in SubsonicSort"></select>
|
||||||
<select id="selectedLayout" ng-model="selectedLayout" ng-options="o.id as o.name for o in Layouts"></select>
|
<!--<select id="selectedLayout" ng-model="selectedLayout" ng-options="o.id as o.name for o in Layouts"></select>-->
|
||||||
</form>
|
</form>
|
||||||
<!--
|
|
||||||
<div id="BreadCrumb">
|
<div id="BreadCrumb">
|
||||||
<a href="#" id="BreadHome"><img src="images/home_gl_12x12.png"></a>
|
<a href="#" id="BreadHome"><img src="images/home_gl_12x12.png"></a>
|
||||||
<div id="BreadCrumbs" class="floatleft"><a ng-show="artistId" ng-href="#/library/{{artistId}}">AC/DC</a> ><a ng-show="albumId" ng-href="#/library/{{albumId}}">Back In Black</a></div>
|
<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> ></div>
|
||||||
|
<div class="crumb" ng-repeat="o in BreadCrumbs | filter:{type:'album'}"><a ng-click="getSongs(o.id, '')">{{o.name}}</a> ></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
-->
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
<ul class="simplelist songlist noselect">
|
<ul class="simplelist songlist noselect">
|
||||||
<div class="animate-switch-container" ng-repeat="o in album" ng-switch on="o.type">
|
<div class="" ng-repeat="o in album" ng-switch on="o.type">
|
||||||
<!--<div class="animate-switch" ng-switch-default>default</div>-->
|
<li class="album" ng-switch-when="byfolder" id="{{o.id}}" ng-class="{'selected': selectedAlbum == o.id, 'albumgrid': selectedLayout == 'grid'}" ng-click="getSongs(o.id, '')" parentid="{{o.parentid}}">
|
||||||
<li class="album" ng-switch-when="byfolder" id="{{o.id}}" ng-class="{'selected': selectedAlbum == o.id, 'albumgrid': selectedLayout == 'grid'}" ng-click="getSongs(o.id, '')" parentid="{{o.parentid}}">
|
<div class="itemactions">
|
||||||
<div class="itemactions">
|
<a class="add" href="" title="Add To Play Queue" ng-click="getSongs(o.id, 'add')" stop-event="click"></a>
|
||||||
<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="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 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 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>
|
||||||
<a class="info hover" href="" title="{{'Created: ' + o.date}}"></a>
|
</div>
|
||||||
</div>
|
<div class="albumart"><img ng-src="{{o.coverartthumb}}" src="images/albumdefault_160.jpg"></div>
|
||||||
<div class="albumart"><img ng-src="{{o.coverartthumb}}" src="images/albumdefault_160.jpg"></div>
|
<div class="albuminfo">
|
||||||
<div class="albuminfo">
|
<div class="title" title="{{o.name}}" ng-bind-html-unsafe="o.name"></div>
|
||||||
<div class="title" title="{{o.name}}" ng-bind-html-unsafe="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-unsafe="o.artist"></a></div>
|
||||||
<div class="artist" title="{{o.artist}}"><a href="" id="{{o.parentid}}" ng-click="getAlbums(o.parentid)" stop-event="click" ng-bind-html-unsafe="o.artist"></a></div>
|
</div>
|
||||||
</div>
|
<div class="clear"></div>
|
||||||
<div class="clear"></div>
|
</li>
|
||||||
</li>
|
<li class="album" ng-switch-when="bytag" id="{{o.id}}" ng-class="{'selected': selectedAlbum == o.id, 'albumgrid': selectedLayout == 'grid'}" ng-click="getAlbumByTag(o.id)">
|
||||||
<li class="album" ng-switch-when="bytag" id="{{o.id}}" ng-class="{'selected': selectedAlbum == o.id, 'albumgrid': selectedLayout == 'grid'}" ng-click="getAlbumByTag(o.id)">
|
<div class="albumart"><img ng-src="{{o.coverartthumb}}" src="images/albumdefault_160.jpg"></div>
|
||||||
<div class="albumart"><img ng-src="{{o.coverartthumb}}" src="images/albumdefault_160.jpg"></div>
|
<div class="albuminfo">
|
||||||
<div class="albuminfo">
|
<div class="title" title="{{o.name}}" ng-bind-html-unsafe="o.name"></div>
|
||||||
<div class="title" title="{{o.name}}" ng-bind-html-unsafe="o.name"></div>
|
<div class="artist" title="{{o.artist}}"><a href="" ng-click="getArtistByTag(o.artistId)" stop-event="click" ng-bind-html-unsafe="o.artist"></a></div>
|
||||||
<div class="artist" title="{{o.artist}}"><a href="" ng-click="getArtistByTag(o.artistId)" stop-event="click" ng-bind-html-unsafe="o.artist"></a></div>
|
</div>
|
||||||
</div>
|
<div class="clear"></div>
|
||||||
<div class="clear"></div>
|
</li>
|
||||||
</li>
|
</div>
|
||||||
</div>
|
<div ng-include src="'js/partials/songs.html'"></div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<!-- Song -->
|
|
||||||
<div class="ui-layout-east noselect hide" ng-include src="'js/partials/songs.html'"></div>
|
|
||||||
</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>
|
||||||
|
<li><a href="" class="close" ng-click="scrollToIndexName('AZIndex')">[Top]</a></li>
|
||||||
|
<li><a href="" class="close" ng-click="toggleAZ()">[Close]</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!--<songpreview class="songpreview"></songpreview>-->
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- End: Library Tab -->
|
<!-- End: Library Tab -->
|
119
js/partials/library_old.html
Normal file
119
js/partials/library_old.html
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
<!-- Start: Library Tab -->
|
||||||
|
<div id="tab1" class="tabcontent">
|
||||||
|
<div id="tabLibrary">
|
||||||
|
<div class="actions floatleft">
|
||||||
|
<a href="" class="button" id="action_RefreshArtists" title="Refresh Artists" ng-click="getArtists()"><img class="pad" src="images/reload_9x11.png" /></a>
|
||||||
|
<a href="" class="button" id="action_RescanLibrary" title="Rescan Library" ng-click="rescanLibrary()"><img class="pad" src="images/loop_alt1_gd_12x9.png" /></a>
|
||||||
|
</div>
|
||||||
|
<div id="search">
|
||||||
|
<input type="text" id="Search" class="medium" title="Wildcards (*) supported" placeholder="Search..." ng-enter="search()"/>
|
||||||
|
<select id="SearchType" name="SearchType">
|
||||||
|
<option value="song">Song</option>
|
||||||
|
<option value="album">Album</option>
|
||||||
|
</select>
|
||||||
|
<a href="" class="button" id="action_Search" title="Search" ng-click="search()"><img class="pad" src="images/magnifying_glass_alt_12x12.png" /></a>
|
||||||
|
</div>
|
||||||
|
<div class="subactions">
|
||||||
|
<a href="" class="button" id="action_SelectAll" title="Select All" ng-click="selectAll()">All</a>
|
||||||
|
<a href="" class="button" id="action_SelectNone" title="Select None" ng-click="selectNone()">None</a>
|
||||||
|
<a href="" class="button" id="action_AddToQueue" title="Add To Queue" ng-click="addSongsToQueue()">+ Queue</a>
|
||||||
|
<a href="" class="button" id="action_AddToPlaylist" title="Add Selected To Playlist" ng-click="loadPlaylistsForMenu()">+ Playlist</a>
|
||||||
|
<div id="submenu_AddToPlaylist" class="submenu shadow" style="display: none;">
|
||||||
|
<a href="" ng-repeat="o in playlistMenu" ng-click="addToPlaylist(o.id)">{{o.name}}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<!--<div id="SubsonicAlbums" class="section lgsection" layout state="bodyState" ng-init="bodyState = 3">-->
|
||||||
|
<div id="SubsonicAlbums" class="section lgsection">
|
||||||
|
<div id="SubsonicArtists" class="ui-layout-west noselect hide" tabindex="0">
|
||||||
|
<div id="AZIndex" ng-show="!settings.HideAZ" class="subactionsfixed">
|
||||||
|
<a href="" ng-click="toggleAZ()" stop-event="click">A-Z</a>
|
||||||
|
</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>
|
||||||
|
<li><a href="" class="close" ng-click="scrollToIndexName('AZIndex')">[Top]</a></li>
|
||||||
|
<li><a href="" class="close" ng-click="toggleAZ()">[Close]</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<select id="MusicFolders" class="folders" ng-model="$root.selectedMusicFolder" ng-options="o as o.name for o in MusicFolders">
|
||||||
|
<option value="">All Folders</option>
|
||||||
|
</select>
|
||||||
|
<ul id="AutoAlbumContainer" class="simplelist mainlist noselect">
|
||||||
|
<li class="index" id="auto">Auto Albums</li>
|
||||||
|
<li class="item" ng-repeat="o in AutoAlbums" id="{{o.id}}" ng-click="getAlbumListBy(o.id)" ng-class="{'selected': selectedAutoAlbum == o.id }">
|
||||||
|
<span>{{o.name}}</span>
|
||||||
|
<div class="floatright">
|
||||||
|
<a href="" class="nextprev hover" id="random" title="Previous" ng-click="getAlbumListBy(o.id, 'prev')" stop-event="click">‹</a>
|
||||||
|
<a href="" class="nextprev hover" id="random" title="Next" ng-click="getAlbumListBy(o.id, 'next')" stop-event="click">›</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<!-- Shortcut -->
|
||||||
|
<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="getAlbums(o.id)" ng-class="{'selected': selectedArtist == o.id}"><span ng-bind-html-unsafe="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><span class="floatright">?</span></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 ng-href="" ng-bind-html-unsafe="a.name"></a></li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!-- Album -->
|
||||||
|
<div class="ui-layout-center">
|
||||||
|
<ul class="actionlist">
|
||||||
|
<li>
|
||||||
|
<form class="form">
|
||||||
|
<select id="selectedSubsonicAlbumSort" ng-model="selectedSubsonicAlbumSort" ng-options="o.id as o.name for o in SubsonicSort"></select>
|
||||||
|
<select id="selectedLayout" ng-model="selectedLayout" ng-options="o.id as o.name for o in Layouts"></select>
|
||||||
|
</form>
|
||||||
|
<!--
|
||||||
|
<div id="BreadCrumb">
|
||||||
|
<a href="#" id="BreadHome"><img src="images/home_gl_12x12.png"></a>
|
||||||
|
<div id="BreadCrumbs" class="floatleft"><a ng-show="artistId" ng-href="#/library/{{artistId}}">AC/DC</a> ><a ng-show="albumId" ng-href="#/library/{{albumId}}">Back In Black</a></div>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<ul class="simplelist songlist noselect">
|
||||||
|
<div class="animate-switch-container" ng-repeat="o in album" ng-switch on="o.type">
|
||||||
|
<!--<div class="animate-switch" ng-switch-default>default</div>-->
|
||||||
|
<li class="album" ng-switch-when="byfolder" id="{{o.id}}" ng-class="{'selected': selectedAlbum == o.id, 'albumgrid': selectedLayout == '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-unsafe="o.name"></div>
|
||||||
|
<div class="artist" title="{{o.artist}}"><a href="" id="{{o.parentid}}" ng-click="getAlbums(o.parentid)" stop-event="click" ng-bind-html-unsafe="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': selectedLayout == '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-unsafe="o.name"></div>
|
||||||
|
<div class="artist" title="{{o.artist}}"><a href="" ng-click="getArtistByTag(o.artistId)" stop-event="click" ng-bind-html-unsafe="o.artist"></a></div>
|
||||||
|
</div>
|
||||||
|
<div class="clear"></div>
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!-- Song -->
|
||||||
|
<div class="ui-layout-east noselect hide" ng-include src="'js/partials/songs.html'"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="clear"></div>
|
||||||
|
</div>
|
||||||
|
<!-- End: Library Tab -->
|
|
@ -14,9 +14,9 @@
|
||||||
<a href="" class="button" id="action_RemoveSongs" title="Remove selected song(s) from playlist" ng-click="removeSelectedSongs()">Remove Song(s)</a>
|
<a href="" class="button" id="action_RemoveSongs" title="Remove selected song(s) from playlist" ng-click="removeSelectedSongs()">Remove Song(s)</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
<div id="LayoutContainer" class="section lgsection">
|
<div id="LayoutContainer" class="section lgsection split-pane fixed-left" split>
|
||||||
<!-- Playlists -->
|
<!-- Playlists -->
|
||||||
<div class="ui-layout-west noselect hide" tabindex="0">
|
<div id="left-component" class="split-pane-component smcolumn noselect" tabindex="0">
|
||||||
<ul class="simplelist mainlist noselect">
|
<ul class="simplelist mainlist noselect">
|
||||||
<li class="index" id="auto">Auto Playlists</li>
|
<li class="index" id="auto">Auto Playlists</li>
|
||||||
<li class="item" ng-click="getStarred('', 'song')" ng-class="{'selected': selectedAutoPlaylist == 'starred'}">
|
<li class="item" ng-click="getStarred('', 'song')" ng-class="{'selected': selectedAutoPlaylist == 'starred'}">
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
<div class="title">{{o.name}}</div>
|
<div class="title">{{o.name}}</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="simplelist mainlist noselect" >
|
<ul class="simplelist mainlist noselect">
|
||||||
<li class="index" id="auto">My Playlists</li>
|
<li class="index" id="auto">My Playlists</li>
|
||||||
<li class="item" ng-repeat="o in playlists" ng-click="getPlaylist(o.id, '')" ng-class="{'selected': o.id == selectedPlaylist}">
|
<li class="item" ng-repeat="o in playlists" ng-click="getPlaylist(o.id, '')" ng-class="{'selected': o.id == selectedPlaylist}">
|
||||||
<div class="itemactions">
|
<div class="itemactions">
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
<div class="title" title="{{'Songs: ' + o.songCount + ', Public: ' + o.public}}">{{o.name}}</div>
|
<div class="title" title="{{'Songs: ' + o.songCount + ', Public: ' + o.public}}">{{o.name}}</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="simplelist mainlist noselect" >
|
<ul class="simplelist mainlist noselect">
|
||||||
<li class="index" id="auto">Shared Playlists</li>
|
<li class="index" id="auto">Shared Playlists</li>
|
||||||
<li class="item" ng-repeat="o in playlistsPublic" ng-click="getPlaylist(o.id, '')" ng-class="{'selected': o.id == selectedPlaylist}">
|
<li class="item" ng-repeat="o in playlistsPublic" ng-click="getPlaylist(o.id, '')" ng-class="{'selected': o.id == selectedPlaylist}">
|
||||||
<div class="itemactions">
|
<div class="itemactions">
|
||||||
|
@ -70,8 +70,11 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="split-pane-divider" id="my-divider"></div>
|
||||||
<!-- Songs -->
|
<!-- Songs -->
|
||||||
<div class="ui-layout-center noselect hide" ng-include src="'js/partials/songs.html'"></div>
|
<div id="right-component" class="split-pane-component lgcolumn noselect">
|
||||||
|
<ul class="songlist simplelist" ng-include src="'js/partials/songs.html'"></ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
<a href="" class="button" id="action_AddToQueue" title="Add To Queue" ng-click="addSongsToQueue()">+ Queue</a>
|
<a href="" class="button" id="action_AddToQueue" title="Add To Queue" ng-click="addSongsToQueue()">+ Queue</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
<div id="LayoutContainer" class="section lgsection">
|
<div id="LayoutContainer" class="section lgsection split-pane fixed-left" split>
|
||||||
<!-- Artist -->
|
<!-- Artist -->
|
||||||
<div class="ui-layout-west noselect hide" tabindex="0">
|
<div id="left-component" class="split-pane-component smcolumn noselect" tabindex="0">
|
||||||
<ul class="simplelist mainlist noselect">
|
<ul class="simplelist mainlist noselect">
|
||||||
<li class="index" id="podcasts">Podcasts</li>
|
<li class="index" id="podcasts">Podcasts</li>
|
||||||
<li class="item" ng-repeat="o in podcasts" ng-click="getPodcast(o.id, '')" ng-class="{ 'selected': o.id == selectedPodcast }">
|
<li class="item" ng-repeat="o in podcasts" ng-click="getPodcast(o.id, '')" ng-class="{ 'selected': o.id == selectedPodcast }">
|
||||||
|
@ -23,8 +23,11 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="split-pane-divider" id="my-divider"></div>
|
||||||
<!-- Song -->
|
<!-- Song -->
|
||||||
<div class="ui-layout-center noselect hide" ng-include src="'js/partials/songs.html'"></div>
|
<div id="right-component" class="split-pane-component lgcolumn noselect">
|
||||||
|
<ul class="songlist simplelist" ng-include src="'js/partials/songs.html'"></ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
|
|
|
@ -1,6 +1,108 @@
|
||||||
<div id="settings" class="tabcontent">
|
<div id="settings" class="tabcontent">
|
||||||
<div class="section fullsection floatleft">
|
<div class="section fullsection floatleft">
|
||||||
<form class="form" id="Settings" ng-include="'js/partials/settingsForm.html'"></form>
|
|
||||||
|
<form class="form" id="Settings">
|
||||||
|
<div class="subsection floatleft">
|
||||||
|
<h3 class="title">Login</h3>
|
||||||
|
<label for="Username">Username <span class="red">*</span></label><br />
|
||||||
|
<input type="text" id="Username" name="Username" class="large" ng-model="settings.Username" /><br />
|
||||||
|
<label for="Password">Password <span class="red">*</span></label><br />
|
||||||
|
<input type="password" id="Password" name="Password" class="large" ng-model="settings.Password" /><br />
|
||||||
|
<label for="Server">Server <span class="red">*</span> (<a href="" title="Connect to Demo Subsonic Server" ng-click="setupDemo()">Demo</a>)</label><br />
|
||||||
|
<input type="text" id="Server" name="Server" class="xlarge" title="Subsonic Server URL Ex: http://host:port/subsonic" ng-model="settings.Server" /><br />
|
||||||
|
<!--<a href="#" class="button" id="action_RequestURL" title="Request Permission for Server URL">Enable URL</a><br />-->
|
||||||
|
<label for="SubsonicVersion">Subsonic API: <span class="apiversion" id="SubsonicVersion">{{settings.ApiVersion}}</span></label><br />
|
||||||
|
<label for="SMStats">Audio State: <span id="SMStats"></span></label><br /><br />
|
||||||
|
<br />
|
||||||
|
<a id="action_Welcome" href="#welcome">Launch Welcome</a>
|
||||||
|
<div id="welcome"><h2>Welcome</h2></div>
|
||||||
|
</div>
|
||||||
|
<div class="subsection floatleft">
|
||||||
|
<h3 class="title">Options</h3>
|
||||||
|
<label for="Theme">Theme</label><br />
|
||||||
|
<select id="Theme" name="Theme" class="large" ng-model="settings.Theme" ng-options="o for o in Themes"></select><br />
|
||||||
|
<!--<label for="AutoFilter">Filter</label><br />
|
||||||
|
<input type="text" id="AutoFilter" name="AutoFilter" class="large" title="Comma separated list of albums for the AutoPilot Filter"/><br />-->
|
||||||
|
<label for="AutoAlbumSize">Auto Album Size</label><br />
|
||||||
|
<input type="text" id="AutoAlbumSize" name="AutoAlbumSize" class="large" title="Number of Albums to Get on the Music Library tab" ng-model="settings.AutoAlbumSize" /><br />
|
||||||
|
<label for="AutoPlaylistSize">Auto Playlist Size</label><br />
|
||||||
|
<input type="text" id="AutoPlaylistSize" name="AutoPlaylistSize" class="large" title="Number of Songs to Get on the Playlist tab" ng-model="settings.AutoPlaylistSize" /><br />
|
||||||
|
<label for="ApplicationName">Application Name</label><br />
|
||||||
|
<input type="text" id="ApplicationName" name="ApplicationName" class="large" title="Custom Player Name" ng-model="settings.ApplicationName" /><br />
|
||||||
|
</div>
|
||||||
|
<div class="subsection floatleft checkboxes">
|
||||||
|
<div class="checkboxes">
|
||||||
|
<fieldset id="General">
|
||||||
|
<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>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<div class="inputwrap"><input type="checkbox" id="LoopQueue" name="LoopQueue" value="1" title="When the Queue has ended, start from beginning" ng-model="settings.LoopQueue" /></div>
|
||||||
|
<label for="LoopQueue">Loop Queue</label>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<div class="inputwrap"><input type="checkbox" id="HideAZ" name="HideAZ" value="1" title="Hide A-Z Artist Picker (Tablet/Touch friendly feature)" ng-model="settings.HideAZ" /></div>
|
||||||
|
<label for="HideAZ">Hide A-Z</label>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<div class="inputwrap"><input type="checkbox" id="ScrollTitle" name="ScrollTitle" value="1" title="Scroll the Title Once" ng-model="settings.ScrollTitle" /></div>
|
||||||
|
<label for="ScrollTitle">Scroll Title</label>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<label for="DefaultLibraryLayout">Default Library Layout</label>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<select id="DefaultLibraryLayout" name="DefaultLibraryLayout" class="" ng-model="settings.DefaultLibraryLayout" ng-options="o.id as o.name for o in LibraryLayouts" title="AJAX Request Library Layout"></select>
|
||||||
|
<div class="clear"></div>
|
||||||
|
</fieldset>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<fieldset id="HTML5">
|
||||||
|
<legend class="aligncenter">HTML5 [Beta]</legend>
|
||||||
|
<span>Notifications</span><br />
|
||||||
|
<div class="clear"></div>
|
||||||
|
<div class="inputwrap"><input type="checkbox" id="NotificationSong" name="NotificationSong" value="1" title="Enable Notifications When Tracks Change" ng-model="settings.NotificationSong" /></div>
|
||||||
|
<label for="NotificationSong">Song Change</label>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<div class="inputwrap"><input type="checkbox" id="NotificationNowPlaying" name="NotificationNowPlaying" value="1" title="Enable Notifications When Other Users Play Songs" ng-model="settings.NotificationNowPlaying" /></div>
|
||||||
|
<label for="NotificationNowPlaying">Now Playing</label>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<span>Local Storage</span><br />
|
||||||
|
<div class="clear"></div>
|
||||||
|
<div class="inputwrap"><input type="checkbox" id="SaveTrackPosition" name="SaveTrackPosition" value="1" title="Saves Play Queue & Track Position Periodically (Uses HTML5: localStorage)" ng-model="settings.SaveTrackPosition" /></div>
|
||||||
|
<label for="SaveTrackPosition">Save Progress</label>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="subsection floatleft">
|
||||||
|
<div class="checkboxes">
|
||||||
|
<fieldset id="Advanced">
|
||||||
|
<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>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<div class="inputwrap"><input type="checkbox" id="ForceFlash" name="ForceFlash" value="1" title="Force Flash Plugin for Audio (Option doesn't work with Chrome App)" ng-model="settings.ForceFlash" /></div>
|
||||||
|
<label for="ForceFlash">Force Flash</label>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<label for="Timeout">Timeout</label>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<select id="Timeout" name="Timeout" class="" ng-model="settings.Timeout" ng-options="o.id as o.name for o in Timeouts" title="AJAX Request Timeout (Seconds)"></select>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<label for="NotificationTimeout">Notification Timeout</label>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<select id="NotificationTimeout" name="NotificationTimeout" class="" ng-model="settings.NotificationTimeout" ng-options="o.id as o.name for o in Timeouts" title="Notification Timeout (Seconds)"></select>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<label for="Protocol">Protocol</label><br />
|
||||||
|
<select id="Protocol" name="Protocol" class="" ng-model="settings.Protocol" ng-options="o for o in Protocols" title="Enable Cross-Domain AJAX Requests (Use if hosted in a different domain than Subsonic)"></select>
|
||||||
|
<!--
|
||||||
|
<div class="clear"></div>
|
||||||
|
<label title="Export these settings to a file">Export Settings</label><br />
|
||||||
|
<ng-download data="settings" />
|
||||||
|
-->
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<div class="submit">
|
||||||
|
<a href="" class="button" ng-click="save()" title="Save Settings">Save</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
<div class="subsection floatleft">
|
<div class="subsection floatleft">
|
||||||
<h3 class="title">Tips</h3>
|
<h3 class="title">Tips</h3>
|
||||||
<ul class="preferences">
|
<ul class="preferences">
|
||||||
|
@ -35,7 +137,7 @@
|
||||||
<h3 class="title">Change Log</h3>
|
<h3 class="title">Change Log</h3>
|
||||||
<ul id="ChangeLog" class="preferences">
|
<ul id="ChangeLog" class="preferences">
|
||||||
<li class="log" ng-repeat="o in changeLog"><span class="version">{{o.date + ' - ' + o.version}}</span>
|
<li class="log" ng-repeat="o in changeLog"><span class="version">{{o.date + ' - ' + o.version}}</span>
|
||||||
<span class="changes" ng-repeat="a in o.changes" ng-bind-html-unsafe="a.text"></span>
|
<span class="changes" ng-repeat="a in o.changes" ng-bind-html="a.text"></span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a href="" ng-click="changeLogShowMore()">Show More</a>
|
<a href="" ng-click="changeLogShowMore()">Show More</a>
|
||||||
|
@ -44,8 +146,9 @@
|
||||||
<div class="subsection floatleft">
|
<div class="subsection floatleft">
|
||||||
<h3 class="title">Links</h3>
|
<h3 class="title">Links</h3>
|
||||||
<ul class="preferences">
|
<ul class="preferences">
|
||||||
<li>GitHub Repo - <a href="https://github.com/tsquillario/Jamstash" target="_blank">https://github.com/tsquillario/Jamstash</a></li>
|
<li>Report Issues - <a href="https://github.com/tsquillario/Jamstash" target="_blank">https://github.com/tsquillario/Jamstash</a></li>
|
||||||
<li>Jamstash Chrome App - <a href="https://chrome.google.com/webstore/detail/jccdpflnecheidefpofmlblgebobbloc" target="_blank">Chrome Web Store</a></li>
|
<li>Jamstash Chrome App - <a href="https://chrome.google.com/webstore/detail/jccdpflnecheidefpofmlblgebobbloc" target="_blank">Chrome Web Store</a></li>
|
||||||
|
<li>Beta Site - <a href="http://jamstash.com/beta" target="_blank">http://jamstash.com/beta</a></li>
|
||||||
<li><a href="https://twitter.com/JamstashApp" target="_blank">Follow @JamstashApp</a>
|
<li><a href="https://twitter.com/JamstashApp" target="_blank">Follow @JamstashApp</a>
|
||||||
</ul>
|
</ul>
|
||||||
<h3 class="title">Thanks</h3>
|
<h3 class="title">Thanks</h3>
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
<div class="subsection floatleft">
|
|
||||||
<h3 class="title">Login</h3>
|
|
||||||
<label for="Username">Username <span class="red">*</span></label><br />
|
|
||||||
<input type="text" id="Username" name="Username" class="large" ng-model="settings.Username"/><br />
|
|
||||||
<label for="Password">Password <span class="red">*</span></label><br />
|
|
||||||
<input type="password" id="Password" name="Password" class="large" ng-model="settings.Password"/><br />
|
|
||||||
<label for="Server">Server <span class="red">*</span> (<a href="" title="Connect to Demo Subsonic Server" ng-click="setupDemo()">Demo</a>)</label><br />
|
|
||||||
<input type="text" id="Server" name="Server" class="xlarge" title="Subsonic Server URL Ex: http://host:port/subsonic" ng-model="settings.Server"/><br />
|
|
||||||
<!--<a href="#" class="button" id="action_RequestURL" title="Request Permission for Server URL">Enable URL</a><br />-->
|
|
||||||
<label for="SubsonicVersion">Subsonic API: <span class="apiversion" id="SubsonicVersion">{{settings.ApiVersion}}</span></label><br />
|
|
||||||
<label for="SMStats">Audio State: <span id="SMStats"></span></label><br /><br />
|
|
||||||
<br />
|
|
||||||
<a id="action_Welcome" href="#welcome">Launch Welcome</a>
|
|
||||||
<div id="welcome"><h2>Welcome</h2></div>
|
|
||||||
</div>
|
|
||||||
<div class="subsection floatleft">
|
|
||||||
<h3 class="title">Options</h3>
|
|
||||||
<label for="Theme">Theme</label><br />
|
|
||||||
<select id="Theme" name="Theme" class="large" ng-model="settings.Theme" ng-options="o for o in Themes"></select><br />
|
|
||||||
<!--<label for="AutoFilter">Filter</label><br />
|
|
||||||
<input type="text" id="AutoFilter" name="AutoFilter" class="large" title="Comma separated list of albums for the AutoPilot Filter"/><br />-->
|
|
||||||
<label for="AutoAlbumSize">Auto Album Size</label><br />
|
|
||||||
<input type="text" id="AutoAlbumSize" name="AutoAlbumSize" class="large" title="Number of Albums to Get on the Music Library tab" ng-model="settings.AutoAlbumSize"/><br />
|
|
||||||
<label for="AutoPlaylistSize">Auto Playlist Size</label><br />
|
|
||||||
<input type="text" id="AutoPlaylistSize" name="AutoPlaylistSize" class="large" title="Number of Songs to Get on the Playlist tab" ng-model="settings.AutoPlaylistSize"/><br />
|
|
||||||
<label for="ApplicationName">Application Name</label><br />
|
|
||||||
<input type="text" id="ApplicationName" name="ApplicationName" class="large" title="Custom Player Name" ng-model="settings.ApplicationName"/><br />
|
|
||||||
</div>
|
|
||||||
<div class="subsection floatleft checkboxes">
|
|
||||||
<div class="checkboxes">
|
|
||||||
<fieldset id="General">
|
|
||||||
<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>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="inputwrap"><input type="checkbox" id="LoopQueue" name="LoopQueue" value="1" title="When the Queue has ended, start from beginning" ng-model="settings.LoopQueue"/></div>
|
|
||||||
<label for="LoopQueue">Loop Queue</label>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="inputwrap"><input type="checkbox" id="HideAZ" name="HideAZ" value="1" title="Hide A-Z Artist Picker (Tablet/Touch friendly feature)" ng-model="settings.HideAZ"/></div>
|
|
||||||
<label for="HideAZ">Hide A-Z</label>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="inputwrap"><input type="checkbox" id="ScrollTitle" name="ScrollTitle" value="1" title="Scroll the Title Once" ng-model="settings.ScrollTitle"/></div>
|
|
||||||
<label for="ScrollTitle">Scroll Title</label>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<label for="DefaultLibraryLayout">Default Library Layout</label>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<select id="DefaultLibraryLayout" name="DefaultLibraryLayout" class="" ng-model="settings.DefaultLibraryLayout" ng-options="o.id as o.name for o in LibraryLayouts" title="AJAX Request Library Layout"></select>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<label for="DefaultSubsonicAlbumSort">Default Album Sort Order</label>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<select id="DefaultSubsonicAlbumSort" name="DefaultSubsonicAlbumSort" class="" ng-model="settings.DefaultSubsonicAlbumSort" ng-options="o.id as o.name for o in SubsonicAlbumSort" title="Subsonic Album Layout"></select>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<label for="DefaultSearchType">Default Search Type</label>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<select id="DefaultSearchType" name="DefaultSearchType" class="" ng-model="settings.DefaultSearchType" ng-options="o.id as o.name for o in SearchTypeLayout" title="Subsonic Album Layout"></select>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</fieldset>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<fieldset id="HTML5">
|
|
||||||
<legend class="aligncenter">HTML5 [Beta]</legend>
|
|
||||||
<span>Notifications</span><br />
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="inputwrap"><input type="checkbox" id="NotificationSong" name="NotificationSong" value="1" title="Enable Notifications When Tracks Change" ng-model="settings.NotificationSong"/></div>
|
|
||||||
<label for="NotificationSong">Song Change</label>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="inputwrap"><input type="checkbox" id="NotificationNowPlaying" name="NotificationNowPlaying" value="1" title="Enable Notifications When Other Users Play Songs" ng-model="settings.NotificationNowPlaying"/></div>
|
|
||||||
<label for="NotificationNowPlaying">Now Playing</label>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<span>Local Storage</span><br />
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="inputwrap"><input type="checkbox" id="SaveTrackPosition" name="SaveTrackPosition" value="1" title="Saves Play Queue & Track Position Periodically (Uses HTML5: localStorage)" ng-model="settings.SaveTrackPosition"/></div>
|
|
||||||
<label for="SaveTrackPosition">Save Progress</label>
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="subsection floatleft">
|
|
||||||
<div class="checkboxes">
|
|
||||||
<fieldset id="Advanced">
|
|
||||||
<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>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="inputwrap"><input type="checkbox" id="ForceFlash" name="ForceFlash" value="1" title="Force Flash Plugin for Audio (Option doesn't work with Chrome App)" ng-model="settings.ForceFlash"/></div>
|
|
||||||
<label for="ForceFlash">Force Flash</label>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<label for="Timeout">Timeout</label>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<select id="Timeout" name="Timeout" class="" ng-model="settings.Timeout" ng-options="o.id as o.name for o in Timeouts" title="AJAX Request Timeout (Seconds)"></select>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<label for="NotificationTimeout">Notification Timeout</label>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<select id="NotificationTimeout" name="NotificationTimeout" class="" ng-model="settings.NotificationTimeout" ng-options="o.id as o.name for o in Timeouts" title="Notification Timeout (Seconds)"></select>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<label for="Protocol">Protocol</label><br />
|
|
||||||
<select id="Protocol" name="Protocol" class="" ng-model="settings.Protocol" ng-options="o for o in Protocols" title="Enable Cross-Domain AJAX Requests (Use if hosted in a different domain than Subsonic)"></select>
|
|
||||||
<!--
|
|
||||||
<div class="clear"></div>
|
|
||||||
<label title="Export these settings to a file">Export Settings</label><br />
|
|
||||||
<ng-download data="settings" />
|
|
||||||
-->
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="submit">
|
|
||||||
<a href="" class="button" ng-click="save()" title="Save Settings">Save</a>
|
|
||||||
</div>
|
|
|
@ -1,19 +1,17 @@
|
||||||
<ul class="simplelist songlist">
|
<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}" data-bind="attr: { id: id, parentid: parentid, title: description }">
|
||||||
<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}" data-bind="attr: { id: id, parentid: parentid, title: description }">
|
<div class="itemactions">
|
||||||
<div class="itemactions">
|
<a class="add" href="" title="Add To Play Queue" ng-click="addSongToQueue(o)" stop-event="click"></a>
|
||||||
<a class="add" href="" title="Add To Play Queue" ng-click="addSongToQueue(o)" stop-event="click"></a>
|
<a class="remove" href="" title="Remove"></a>
|
||||||
<a class="remove" href="" title="Remove"></a>
|
<a class="play" href="" title="Play" ng-click="playSong(false, o)" stop-event="click"></a><a class="download" href="" title="Download"></a>
|
||||||
<a class="play" href="" title="Play" ng-click="playSong(false, o)" stop-event="click"></a><a class="download" href="" title="Download"></a>
|
<a href="" title="Favorite" ng-class="{'favorite': o.starred, 'rate': !o.starred}" ng-click="updateFavorite(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="track floatleft" ng-bind-html-unsafe="o.track"></div>
|
|
||||||
<div class="title floatleft" title="{{o.description}}" ng-bind-html-unsafe="o.name"></div>
|
|
||||||
<span class="albumblock floatleft" ng-show="o.album && itemType === 'ss'" ng-bind-html-unsafe="o.album" title="{{o.album}}"></span>
|
|
||||||
<a ng-href="#/library/0/{{o.albumId}}" class="albumblock floatleft" ng-show="o.album && itemType === 'pl'" stop-event="click" ng-bind-html-unsafe="o.album" title="{{o.album}}"></a>
|
|
||||||
<a ng-href="#/archive/{{o.artist}}/{{o.parentid}}" class="albumblock floatleft" ng-show="o.album && itemType === 'archive'" stop-event="click" ng-bind-html-unsafe="o.album" title="{{o.album}}"></a>
|
|
||||||
<div class="albumblock floatleft" ng-show="!o.album"> </div>
|
|
||||||
<div class="time floatleft">{{o.time}}</div>
|
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
<div class="track floatleft" ng-bind-html="o.track"></div>
|
||||||
|
<div class="title floatleft" title="{{o.description}}" ng-bind-html="o.name"></div>
|
||||||
|
<span class="albumblock floatleft" ng-show="o.album && itemType === 'ss'" ng-bind-html="o.album" title="{{o.album}}"></span>
|
||||||
|
<a ng-href="#/library/0/{{o.albumId}}" class="albumblock floatleft" ng-show="o.album && itemType === 'pl'" stop-event="click" ng-bind-html="o.album" title="{{o.album}}"></a>
|
||||||
|
<a ng-href="#/archive/{{o.artist}}/{{o.parentid}}" class="albumblock floatleft" ng-show="o.album && itemType === 'archive'" stop-event="click" ng-bind-html="o.album" title="{{o.album}}"></a>
|
||||||
|
<div class="albumblock floatleft" ng-show="!o.album"> </div>
|
||||||
|
<div class="time floatleft">{{o.time}}</div>
|
||||||
|
<div class="clear"></div>
|
||||||
|
</li>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<a href="" class="button" id="action_SelectAll" title="Select All" ng-click="selectAll()">All</a>
|
<a href="" class="button" id="action_SelectAll" title="Select All" ng-click="selectAll()">All</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
<div id="LayoutContainer" class="section lgsection">
|
<div id="left-component" class="section lgsection">
|
||||||
<!-- Artist -->
|
<!-- Artist -->
|
||||||
<div class="ui-layout-west noselect hide" tabindex="0">
|
<div class="ui-layout-west noselect hide" tabindex="0">
|
||||||
<ul class="simplelist mainlist noselect">
|
<ul class="simplelist mainlist noselect">
|
||||||
|
|
|
@ -116,7 +116,6 @@
|
||||||
//$rootScope.queue = [];
|
//$rootScope.queue = [];
|
||||||
$rootScope.queue = items;
|
$rootScope.queue = items;
|
||||||
if ($rootScope.queue.length > 0) {
|
if ($rootScope.queue.length > 0) {
|
||||||
//$('body').layout().open('south');
|
|
||||||
notifications.updateMessage($rootScope.queue.length + ' Saved Song(s)', true);
|
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)'); }
|
if (globals.settings.Debug) { console.log('Play Queue Loaded From localStorage: ' + $rootScope.queue.length + ' song(s)'); }
|
||||||
|
@ -173,8 +172,8 @@
|
||||||
}
|
}
|
||||||
// End UnityShim
|
// End UnityShim
|
||||||
}
|
}
|
||||||
$('#Queue').stop().scrollTo('#' + id, 400);
|
$('#QueuePreview').stop().scrollTo('#' + id, 400);
|
||||||
$('#QueuePreviewList').stop().scrollTo('#' + id, 400);
|
$rootScope.showQueue();
|
||||||
var spechtml = '';
|
var spechtml = '';
|
||||||
var data = $(player1).data().jPlayer;
|
var data = $(player1).data().jPlayer;
|
||||||
for (i = 0; i < data.solutions.length; i++) {
|
for (i = 0; i < data.solutions.length; i++) {
|
||||||
|
|
7
js/plugins/angular-cookies.min.js
vendored
Normal file
7
js/plugins/angular-cookies.min.js
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
AngularJS v1.1.4
|
||||||
|
(c) 2010-2012 Google, Inc. http://angularjs.org
|
||||||
|
License: MIT
|
||||||
|
*/
|
||||||
|
(function(m,f,l){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(d,c){var b={},g={},h,i=!1,j=f.copy,k=f.isUndefined;c.addPollFn(function(){var a=c.cookies();h!=a&&(h=a,j(a,g),j(a,b),i&&d.$apply())})();i=!0;d.$watch(function(){var a,e,d;for(a in g)k(b[a])&&c.cookies(a,l);for(a in b)e=b[a],f.isString(e)?e!==g[a]&&(c.cookies(a,e),d=!0):f.isDefined(g[a])?b[a]=g[a]:delete b[a];if(d)for(a in e=c.cookies(),b)b[a]!==e[a]&&(k(e[a])?delete b[a]:b[a]=e[a])});return b}]).factory("$cookieStore",
|
||||||
|
["$cookies",function(d){return{get:function(c){return f.fromJson(d[c])},put:function(c,b){d[c]=f.toJson(b)},remove:function(c){delete d[c]}}}])})(window,window.angular);
|
13
js/plugins/angular-sanitize.min.js
vendored
Normal file
13
js/plugins/angular-sanitize.min.js
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
AngularJS v1.1.4
|
||||||
|
(c) 2010-2012 Google, Inc. http://angularjs.org
|
||||||
|
License: MIT
|
||||||
|
*/
|
||||||
|
(function(I,h){'use strict';function i(a){var d={},a=a.split(","),c;for(c=0;c<a.length;c++)d[a[c]]=!0;return d}function z(a,d){function c(a,b,c,f){b=h.lowercase(b);if(m[b])for(;e.last()&&n[e.last()];)g("",e.last());o[b]&&e.last()==b&&g("",b);(f=p[b]||!!f)||e.push(b);var j={};c.replace(A,function(a,b,d,c,g){j[b]=k(d||c||g||"")});d.start&&d.start(b,j,f)}function g(a,b){var c=0,g;if(b=h.lowercase(b))for(c=e.length-1;c>=0;c--)if(e[c]==b)break;if(c>=0){for(g=e.length-1;g>=c;g--)d.end&&d.end(e[g]);e.length=
|
||||||
|
c}}var b,f,e=[],j=a;for(e.last=function(){return e[e.length-1]};a;){f=!0;if(!e.last()||!q[e.last()]){if(a.indexOf("<\!--")===0)b=a.indexOf("--\>"),b>=0&&(d.comment&&d.comment(a.substring(4,b)),a=a.substring(b+3),f=!1);else if(B.test(a)){if(b=a.match(r))a=a.substring(b[0].length),b[0].replace(r,g),f=!1}else if(C.test(a)&&(b=a.match(s)))a=a.substring(b[0].length),b[0].replace(s,c),f=!1;f&&(b=a.indexOf("<"),f=b<0?a:a.substring(0,b),a=b<0?"":a.substring(b),d.chars&&d.chars(k(f)))}else a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+
|
||||||
|
e.last()+"[^>]*>","i"),function(a,b){b=b.replace(D,"$1").replace(E,"$1");d.chars&&d.chars(k(b));return""}),g("",e.last());if(a==j)throw"Parse Error: "+a;j=a}g()}function k(a){l.innerHTML=a.replace(/</g,"<");return l.innerText||l.textContent||""}function t(a){return a.replace(/&/g,"&").replace(F,function(a){return"&#"+a.charCodeAt(0)+";"}).replace(/</g,"<").replace(/>/g,">")}function u(a){var d=!1,c=h.bind(a,a.push);return{start:function(a,b,f){a=h.lowercase(a);!d&&q[a]&&(d=a);!d&&v[a]==
|
||||||
|
!0&&(c("<"),c(a),h.forEach(b,function(a,b){var d=h.lowercase(b);if(G[d]==!0&&(w[d]!==!0||a.match(H)))c(" "),c(b),c('="'),c(t(a)),c('"')}),c(f?"/>":">"))},end:function(a){a=h.lowercase(a);!d&&v[a]==!0&&(c("</"),c(a),c(">"));a==d&&(d=!1)},chars:function(a){d||c(t(a))}}}var s=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,r=/^<\s*\/\s*([\w:-]+)[^>]*>/,A=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,C=/^</,B=/^<\s*\//,D=/<\!--(.*?)--\>/g,
|
||||||
|
E=/<!\[CDATA\[(.*?)]]\>/g,H=/^((ftp|https?):\/\/|mailto:|tel:|#)/,F=/([^\#-~| |!])/g,p=i("area,br,col,hr,img,wbr"),x=i("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),y=i("rp,rt"),o=h.extend({},y,x),m=h.extend({},x,i("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")),n=h.extend({},y,i("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var")),
|
||||||
|
q=i("script,style"),v=h.extend({},p,m,n,o),w=i("background,cite,href,longdesc,src,usemap"),G=h.extend({},w,i("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,span,start,summary,target,title,type,valign,value,vspace,width")),l=document.createElement("pre");h.module("ngSanitize",[]).value("$sanitize",function(a){var d=[];
|
||||||
|
z(a,u(d));return d.join("")});h.module("ngSanitize").directive("ngBindHtml",["$sanitize",function(a){return function(d,c,g){c.addClass("ng-binding").data("$binding",g.ngBindHtml);d.$watch(g.ngBindHtml,function(b){b=a(b);c.html(b||"")})}}]);h.module("ngSanitize").filter("linky",function(){var a=/((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/,d=/^mailto:/;return function(c,g){if(!c)return c;var b,f=c,e=[],j=u(e),i,k,l={};if(h.isDefined(g))l.target=g;for(;b=f.match(a);)i=
|
||||||
|
b[0],b[2]==b[3]&&(i="mailto:"+i),k=b.index,j.chars(f.substr(0,k)),l.href=i,j.start("a",l),j.chars(b[0].replace(d,"")),j.end("a"),f=f.substring(k+b[0].length);j.chars(f);return e.join("")}})})(window,window.angular);
|
6
js/plugins/jquery-2.0.3.min.js
vendored
Normal file
6
js/plugins/jquery-2.0.3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
99
js/plugins/jquery-split-pane.css
Normal file
99
js/plugins/jquery-split-pane.css
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*!
|
||||||
|
|
||||||
|
Split Pane v0.3
|
||||||
|
|
||||||
|
Copyright (c) 2012 Simon Hagström
|
||||||
|
|
||||||
|
Released under the MIT license
|
||||||
|
https://raw.github.com/shagstrom/split-pane/master/LICENSE
|
||||||
|
|
||||||
|
*/
|
||||||
|
.split-pane {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-pane.fixed-top > .split-pane-component,
|
||||||
|
.split-pane.fixed-bottom > .split-pane-component,
|
||||||
|
.split-pane.horizontal-percent > .split-pane-component {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
top: auto;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-pane.fixed-top > .split-pane-component:first-child,
|
||||||
|
.split-pane.fixed-bottom > .split-pane-component:first-child,
|
||||||
|
.split-pane.horizontal-percent > .split-pane-component:first-child {
|
||||||
|
top: 0;
|
||||||
|
bottom: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-pane.fixed-top > .split-pane-divider,
|
||||||
|
.split-pane.fixed-bottom > .split-pane-divider,
|
||||||
|
.split-pane.horizontal-percent > .split-pane-divider {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
cursor: ns-resize;
|
||||||
|
cursor: n-resize\9;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-pane.fixed-left > .split-pane-component,
|
||||||
|
.split-pane.fixed-right > .split-pane-component,
|
||||||
|
.split-pane.vertical-percent > .split-pane-component {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
left: auto;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-pane.fixed-left > .split-pane-component:first-child,
|
||||||
|
.split-pane.fixed-right > .split-pane-component:first-child,
|
||||||
|
.split-pane.vertical-percent > .split-pane-component:first-child {
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-pane.fixed-left > .split-pane-divider,
|
||||||
|
.split-pane.fixed-right > .split-pane-divider,
|
||||||
|
.split-pane.vertical-percent > .split-pane-divider {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
cursor: ew-resize;
|
||||||
|
cursor: w-resize\9;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-pane-resize-shim {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 10000;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-pane.fixed-left > .split-pane-resize-shim,
|
||||||
|
.split-pane.fixed-right > .split-pane-resize-shim,
|
||||||
|
.split-pane.vertical-percent > .split-pane-resize-shim {
|
||||||
|
cursor: ew-resize;
|
||||||
|
cursor: w-resize\9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-pane.fixed-top > .split-pane-resize-shim,
|
||||||
|
.split-pane.fixed-bottom > .split-pane-resize-shim,
|
||||||
|
.split-pane.horizontal-percent > .split-pane-resize-shim {
|
||||||
|
cursor: ns-resize;
|
||||||
|
cursor: n-resize\9;
|
||||||
|
}
|
236
js/plugins/jquery-split-pane.js
vendored
Normal file
236
js/plugins/jquery-split-pane.js
vendored
Normal file
|
@ -0,0 +1,236 @@
|
||||||
|
/*!
|
||||||
|
|
||||||
|
Split Pane v0.3
|
||||||
|
|
||||||
|
Copyright (c) 2012 Simon Hagström
|
||||||
|
|
||||||
|
Released under the MIT license
|
||||||
|
https://raw.github.com/shagstrom/split-pane/master/LICENSE
|
||||||
|
|
||||||
|
*/
|
||||||
|
(function($) {
|
||||||
|
|
||||||
|
$.fn.splitPane = function() {
|
||||||
|
var $splitPanes = this;
|
||||||
|
$splitPanes.each(setMinHeightAndMinWidth);
|
||||||
|
$splitPanes.append('<div class="split-pane-resize-shim">');
|
||||||
|
$splitPanes.children('.split-pane-divider').bind('mousedown', mousedownHandler);
|
||||||
|
setTimeout(function() {
|
||||||
|
// Doing this later because of an issue with Chrome (v23.0.1271.64) returning split-pane width = 0
|
||||||
|
// and triggering multiple resize events when page is being opened from an <a target="_blank"> .
|
||||||
|
$splitPanes.bind('_splitpaneparentresize', parentresizeHandler);
|
||||||
|
$(window).trigger('resize');
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
var SPLITPANERESIZE_HANDLER = '_splitpaneparentresizeHandler';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A special event that will "capture" a resize event from the parent split-pane or window.
|
||||||
|
* The event will NOT propagate to grandchildren.
|
||||||
|
*/
|
||||||
|
jQuery.event.special._splitpaneparentresize = {
|
||||||
|
setup: function(data, namespaces) {
|
||||||
|
var element = this,
|
||||||
|
parent = $(this).parent().closest('.split-pane')[0] || window;
|
||||||
|
$(this).data(SPLITPANERESIZE_HANDLER, function(event) {
|
||||||
|
var target = event.target === document ? window : event.target;
|
||||||
|
if (target === parent) {
|
||||||
|
event.type = "_splitpaneparentresize";
|
||||||
|
jQuery.event.dispatch.apply(element, arguments);
|
||||||
|
} else {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$(parent).bind('resize', $(this).data(SPLITPANERESIZE_HANDLER));
|
||||||
|
},
|
||||||
|
teardown: function(namespaces) {
|
||||||
|
var parent = $(this).parent().closest('.split-pane')[0] || window;
|
||||||
|
$(parent).unbind('resize', $(this).data(SPLITPANERESIZE_HANDLER));
|
||||||
|
$(this).removeData(SPLITPANERESIZE_HANDLER);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function setMinHeightAndMinWidth() {
|
||||||
|
var $splitPane = $(this),
|
||||||
|
$firstComponent = $splitPane.children('.split-pane-component:first'),
|
||||||
|
$divider = $splitPane.children('.split-pane-divider'),
|
||||||
|
$lastComponent = $splitPane.children('.split-pane-component:last');
|
||||||
|
if ($splitPane.is('.fixed-top, .fixed-bottom, .horizontal-percent')) {
|
||||||
|
$splitPane.css('min-height', (minHeight($firstComponent) + minHeight($lastComponent) + $divider.height()) + 'px');
|
||||||
|
} else {
|
||||||
|
$splitPane.css('min-width', (minWidth($firstComponent) + minWidth($lastComponent) + $divider.width()) + 'px');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousedownHandler(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var $resizeShim = $(this).siblings('.split-pane-resize-shim').show(),
|
||||||
|
mousemove = createMousemove($(this).parent(), event.pageX, event.pageY);
|
||||||
|
$(document).mousemove(mousemove);
|
||||||
|
$(document).one('mouseup', function(event) {
|
||||||
|
$(document).unbind('mousemove', mousemove);
|
||||||
|
$resizeShim.hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function parentresizeHandler() {
|
||||||
|
var $splitPane = $(this),
|
||||||
|
$firstComponent = $splitPane.children('.split-pane-component:first'),
|
||||||
|
$divider = $splitPane.children('.split-pane-divider'),
|
||||||
|
$lastComponent = $splitPane.children('.split-pane-component:last');
|
||||||
|
if ($splitPane.is('.fixed-top')) {
|
||||||
|
var maxfirstComponentHeight = $splitPane.height() - minHeight($lastComponent) - $divider.height();
|
||||||
|
if ($firstComponent.height() > maxfirstComponentHeight) {
|
||||||
|
setTop($splitPane, $firstComponent, $divider, $lastComponent, maxfirstComponentHeight + 'px');
|
||||||
|
} else {
|
||||||
|
$splitPane.resize();
|
||||||
|
}
|
||||||
|
} else if ($splitPane.is('.fixed-bottom')) {
|
||||||
|
var maxLastComponentHeight = $splitPane.height() - minHeight($firstComponent) - $divider.height();
|
||||||
|
if ($lastComponent.height() > maxLastComponentHeight) {
|
||||||
|
setBottom($splitPane, $firstComponent, $divider, $lastComponent, maxLastComponentHeight + 'px')
|
||||||
|
} else {
|
||||||
|
$splitPane.resize();
|
||||||
|
}
|
||||||
|
} else if ($splitPane.is('.horizontal-percent')) {
|
||||||
|
var maxLastComponentHeight = $splitPane.height() - minHeight($firstComponent) - $divider.height();
|
||||||
|
if ($lastComponent.height() > maxLastComponentHeight) {
|
||||||
|
setBottom($splitPane, $firstComponent, $divider, $lastComponent, (maxLastComponentHeight / $splitPane.height() * 100) + '%');
|
||||||
|
} else {
|
||||||
|
var lastComponentMinHeight = minHeight($lastComponent);
|
||||||
|
if ($splitPane.height() - $firstComponent.height() - $divider.height() < lastComponentMinHeight) {
|
||||||
|
setBottom($splitPane, $firstComponent, $divider, $lastComponent, (lastComponentMinHeight / $splitPane.height() * 100) + '%');
|
||||||
|
} else {
|
||||||
|
$splitPane.resize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ($splitPane.is('.fixed-left')) {
|
||||||
|
var maxFirstComponentWidth = $splitPane.width() - minWidth($lastComponent) - $divider.width();
|
||||||
|
if ($firstComponent.width() > maxFirstComponentWidth) {
|
||||||
|
setLeft($splitPane, $firstComponent, $divider, $lastComponent, maxFirstComponentWidth + 'px');
|
||||||
|
} else {
|
||||||
|
$splitPane.resize();
|
||||||
|
}
|
||||||
|
} else if ($splitPane.is('.fixed-right')) {
|
||||||
|
var maxLastComponentWidth = $splitPane.width() - minWidth($firstComponent) - $divider.width();
|
||||||
|
if ($lastComponent.width() > maxLastComponentWidth) {
|
||||||
|
setRight($splitPane, $firstComponent, $divider, $lastComponent, maxLastComponentWidth + 'px')
|
||||||
|
} else {
|
||||||
|
$splitPane.resize();
|
||||||
|
}
|
||||||
|
} else if ($splitPane.is('.vertical-percent')) {
|
||||||
|
var maxLastComponentWidth = $splitPane.width() - minWidth($firstComponent) - $divider.width();
|
||||||
|
if ($lastComponent.width() > maxLastComponentWidth) {
|
||||||
|
setRight($splitPane, $firstComponent, $divider, $lastComponent, (maxLastComponentWidth / $splitPane.width() * 100) + '%');
|
||||||
|
} else {
|
||||||
|
var lastComponentMinWidth = minWidth($lastComponent);
|
||||||
|
if ($splitPane.width() - $firstComponent.width() - $divider.width() < lastComponentMinWidth) {
|
||||||
|
setRight($splitPane, $firstComponent, $divider, $lastComponent, (lastComponentMinWidth / $splitPane.width() * 100) + '%');
|
||||||
|
} else {
|
||||||
|
$splitPane.resize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMousemove($splitPane, pageX, pageY) {
|
||||||
|
var $firstComponent = $splitPane.children('.split-pane-component:first'),
|
||||||
|
$divider = $splitPane.children('.split-pane-divider'),
|
||||||
|
$lastComponent = $splitPane.children('.split-pane-component:last');
|
||||||
|
if ($splitPane.is('.fixed-top')) {
|
||||||
|
var firstComponentMinHeight = minHeight($firstComponent),
|
||||||
|
maxFirstComponentHeight = $splitPane.height() - minHeight($lastComponent) - $divider.height(),
|
||||||
|
topOffset = $divider.position().top - pageY;
|
||||||
|
return function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var top = Math.min(Math.max(firstComponentMinHeight, topOffset + event.pageY), maxFirstComponentHeight);
|
||||||
|
setTop($splitPane, $firstComponent, $divider, $lastComponent, top + 'px')
|
||||||
|
};
|
||||||
|
} else if ($splitPane.is('.fixed-bottom')) {
|
||||||
|
var lastComponentMinHeight = minHeight($lastComponent),
|
||||||
|
maxLastComponentHeight = $splitPane.height() - minHeight($firstComponent) - $divider.height(),
|
||||||
|
bottomOffset = $lastComponent.height() + pageY;
|
||||||
|
return function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var bottom = Math.min(Math.max(lastComponentMinHeight, bottomOffset - event.pageY), maxLastComponentHeight);
|
||||||
|
setBottom($splitPane, $firstComponent, $divider, $lastComponent, bottom + 'px');
|
||||||
|
};
|
||||||
|
} else if ($splitPane.is('.horizontal-percent')) {
|
||||||
|
var splitPaneHeight = $splitPane.height(),
|
||||||
|
lastComponentMinHeight = minHeight($lastComponent),
|
||||||
|
maxLastComponentHeight = splitPaneHeight - minHeight($firstComponent) - $divider.height(),
|
||||||
|
bottomOffset = $lastComponent.height() + pageY;
|
||||||
|
return function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var bottom = Math.min(Math.max(lastComponentMinHeight, bottomOffset - event.pageY), maxLastComponentHeight);
|
||||||
|
setBottom($splitPane, $firstComponent, $divider, $lastComponent, (bottom / splitPaneHeight * 100) + '%');
|
||||||
|
};
|
||||||
|
} else if ($splitPane.is('.fixed-left')) {
|
||||||
|
var firstComponentMinWidth = minWidth($firstComponent),
|
||||||
|
maxFirstComponentWidth = $splitPane.width() - minWidth($lastComponent) - $divider.width(),
|
||||||
|
leftOffset = $divider.position().left - pageX;
|
||||||
|
return function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var left = Math.min(Math.max(firstComponentMinWidth, leftOffset + event.pageX), maxFirstComponentWidth);
|
||||||
|
setLeft($splitPane, $firstComponent, $divider, $lastComponent, left + 'px')
|
||||||
|
};
|
||||||
|
} else if ($splitPane.is('.fixed-right')) {
|
||||||
|
var lastComponentMinWidth = minWidth($lastComponent),
|
||||||
|
maxLastComponentWidth = $splitPane.width() - minWidth($firstComponent) - $divider.width(),
|
||||||
|
rightOffset = $lastComponent.width() + pageX;
|
||||||
|
return function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var right = Math.min(Math.max(lastComponentMinWidth, rightOffset - event.pageX), maxLastComponentWidth);
|
||||||
|
setRight($splitPane, $firstComponent, $divider, $lastComponent, right + 'px');
|
||||||
|
};
|
||||||
|
} else if ($splitPane.is('.vertical-percent')) {
|
||||||
|
var splitPaneWidth = $splitPane.width(),
|
||||||
|
lastComponentMinWidth = minWidth($lastComponent),
|
||||||
|
maxLastComponentWidth = splitPaneWidth - minWidth($firstComponent) - $divider.width(),
|
||||||
|
rightOffset = $lastComponent.width() + pageX;
|
||||||
|
return function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var right = Math.min(Math.max(lastComponentMinWidth, rightOffset - event.pageX), maxLastComponentWidth);
|
||||||
|
setRight($splitPane, $firstComponent, $divider, $lastComponent, (right / splitPaneWidth * 100) + '%');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function minHeight($element) {
|
||||||
|
return parseInt($element.css('min-height')) || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function minWidth($element) {
|
||||||
|
return parseInt($element.css('min-width')) || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTop($splitPane, $firstComponent, $divider, $lastComponent, top) {
|
||||||
|
$firstComponent.css('height', top);
|
||||||
|
$divider.css('top', top);
|
||||||
|
$lastComponent.css('top', top);
|
||||||
|
$splitPane.resize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setBottom($splitPane, $firstComponent, $divider, $lastComponent, bottom) {
|
||||||
|
$firstComponent.css('bottom', bottom);
|
||||||
|
$divider.css('bottom', bottom);
|
||||||
|
$lastComponent.css('height', bottom);
|
||||||
|
$splitPane.resize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLeft($splitPane, $firstComponent, $divider, $lastComponent, left) {
|
||||||
|
$firstComponent.css('width', left);
|
||||||
|
$divider.css('left', left);
|
||||||
|
$lastComponent.css('left', left);
|
||||||
|
$splitPane.resize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setRight($splitPane, $firstComponent, $divider, $lastComponent, right) {
|
||||||
|
$firstComponent.css('right', right);
|
||||||
|
$divider.css('right', right);
|
||||||
|
$lastComponent.css('width', right);
|
||||||
|
$splitPane.resize();
|
||||||
|
}
|
||||||
|
|
||||||
|
})(jQuery);
|
6
js/plugins/jquery-ui-1.10.3.custom.min.js
vendored
Normal file
6
js/plugins/jquery-ui-1.10.3.custom.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
js/plugins/jquery.layout-latest.min.js
vendored
6
js/plugins/jquery.layout-latest.min.js
vendored
|
@ -106,18 +106,18 @@ l=r[e],u=q[e],v=u.content;if(!m||!p||!m.is(":visible"))return!0;if(!p.length&&(S
|
||||||
visibility:"visible"});0<x&&0<l.innerWidth()?l.data("autoHidden")&&(l.show().data("autoHidden",!1),G.mozilla||l.css(k.hidden).css(k.visible)):l.data("autoHidden")||l.hide().data("autoHidden",!0);v.height=m}q.initialized&&C("onsizecontent_end",e)}})}},qa=function(a){a=(a=A.call(this,a))?a.split(","):k.borderPanes;b.each(a,function(a,d){var e=r[d],g=q[d],h=y[d],j=F[d],p=P[d],u;if(h&&j){var l=k[d].dir,x=g.isClosed?"_closed":"_open",B=e["spacing"+x],z=e["togglerAlign"+x],x=e["togglerLength"+x],A;if(0===
|
visibility:"visible"});0<x&&0<l.innerWidth()?l.data("autoHidden")&&(l.show().data("autoHidden",!1),G.mozilla||l.css(k.hidden).css(k.visible)):l.data("autoHidden")||l.hide().data("autoHidden",!0);v.height=m}q.initialized&&C("onsizecontent_end",e)}})}},qa=function(a){a=(a=A.call(this,a))?a.split(","):k.borderPanes;b.each(a,function(a,d){var e=r[d],g=q[d],h=y[d],j=F[d],p=P[d],u;if(h&&j){var l=k[d].dir,x=g.isClosed?"_closed":"_open",B=e["spacing"+x],z=e["togglerAlign"+x],x=e["togglerLength"+x],A;if(0===
|
||||||
B)j.hide();else{!g.noRoom&&!g.isHidden&&j.show();"horz"===l?(A=v.innerWidth,g.resizerLength=A,h=b.layout.cssNum(h,"left"),j.css({width:Q(j,A),height:O(j,B),left:-9999<h?h:v.inset.left})):(A=h.outerHeight(),g.resizerLength=A,j.css({height:O(j,A),width:Q(j,B),top:v.inset.top+ga("north",!0)}));da(e,j);if(p){if(0===x||g.isSliding&&e.hideTogglerOnSlide){p.hide();return}p.show();if(!(0<x)||"100%"===x||x>A)x=A,z=0;else if(f(z))switch(z){case "top":case "left":z=0;break;case "bottom":case "right":z=A-x;break;
|
B)j.hide();else{!g.noRoom&&!g.isHidden&&j.show();"horz"===l?(A=v.innerWidth,g.resizerLength=A,h=b.layout.cssNum(h,"left"),j.css({width:Q(j,A),height:O(j,B),left:-9999<h?h:v.inset.left})):(A=h.outerHeight(),g.resizerLength=A,j.css({height:O(j,A),width:Q(j,B),top:v.inset.top+ga("north",!0)}));da(e,j);if(p){if(0===x||g.isSliding&&e.hideTogglerOnSlide){p.hide();return}p.show();if(!(0<x)||"100%"===x||x>A)x=A,z=0;else if(f(z))switch(z){case "top":case "left":z=0;break;case "bottom":case "right":z=A-x;break;
|
||||||
default:z=c((A-x)/2)}else h=parseInt(z,10),z=0<=z?h:A-x+h;if("horz"===l){var D=Q(p,x);p.css({width:D,height:O(p,B),left:z,top:0});p.children(".content").each(function(){u=b(this);u.css("marginLeft",c((D-u.outerWidth())/2))})}else{var C=O(p,x);p.css({height:C,width:Q(p,B),top:z,left:0});p.children(".content").each(function(){u=b(this);u.css("marginTop",c((C-u.outerHeight())/2))})}da(0,p)}if(!q.initialized&&(e.initHidden||g.isHidden))j.hide(),p&&p.hide()}}})},pb=function(a){if(H()){var b=A.call(this,
|
default:z=c((A-x)/2)}else h=parseInt(z,10),z=0<=z?h:A-x+h;if("horz"===l){var D=Q(p,x);p.css({width:D,height:O(p,B),left:z,top:0});p.children(".content").each(function(){u=b(this);u.css("marginLeft",c((D-u.outerWidth())/2))})}else{var C=O(p,x);p.css({height:C,width:Q(p,B),top:z,left:0});p.children(".content").each(function(){u=b(this);u.css("marginTop",c((C-u.outerHeight())/2))})}da(0,p)}if(!q.initialized&&(e.initHidden||g.isHidden))j.hide(),p&&p.hide()}}})},pb=function(a){if(H()){var b=A.call(this,
|
||||||
a);a=P[b];var d=r[b];a&&(d.closable=!0,a.bind("click."+K,function(a){a.stopPropagation();na(b)}).css("visibility","visible").css("cursor","pointer").attr("title",q[b].isClosed?d.tips.Open:d.tips.Close).show())}},Va=function(a,d){b.layout.plugins.buttons&&b.each(q[a].pins,function(c,f){b.layout.buttons.setPinState(z,b(f),a,d)})},u=b(this).eq(0);if(!u.length)return ca(r.errors.containerMissing);if(u.data("layoutContainer")&&u.data("layout"))return u.data("layout");var y={},U={},F={},P={},ea=b([]),v=
|
a);a=P[b];var d=r[b];a&&(d.closable=!0,a.bind("click."+K,function(a){a.stopPropagation();na(b)}).css("visibility","visible").css("cursor","pointer").attr("title",q[b].isClosed?d.tips.Open:d.tips.Close).show())}},Va=function(a,d){b.layout.plugins.buttons&&b.each(q[a].pins,function(c,f){b.layout.buttons.setPinState(z,b(f),a,d)})},u=b(this).eq(0);if(!u.length)return ca(r.errors.containerMissing);if(u.data("left-component")&&u.data("layout"))return u.data("layout");var y={},U={},F={},P={},ea=b([]),v=
|
||||||
q.container,K=q.id,z={options:r,state:q,container:u,panes:y,contents:U,resizers:F,togglers:P,hide:Ta,show:Fa,toggle:na,open:ra,close:ja,slideOpen:sb,slideClose:Wa,slideToggle:function(a){a=A.call(this,a);na(a,!0)},setSizeLimits:Y,_sizePane:ka,sizePane:Ca,sizeContent:pa,swapPanes:function(a,c){function f(a){var d=y[a],c=U[a];return!d?!1:{pane:a,P:d?d[0]:!1,C:c?c[0]:!1,state:b.extend(!0,{},q[a]),options:b.extend(!0,{},r[a])}}function h(a,c){if(a){var e=a.P,f=a.C,g=a.pane,j=k[c],m=b.extend(!0,{},q[c]),
|
q.container,K=q.id,z={options:r,state:q,container:u,panes:y,contents:U,resizers:F,togglers:P,hide:Ta,show:Fa,toggle:na,open:ra,close:ja,slideOpen:sb,slideClose:Wa,slideToggle:function(a){a=A.call(this,a);na(a,!0)},setSizeLimits:Y,_sizePane:ka,sizePane:Ca,sizeContent:pa,swapPanes:function(a,c){function f(a){var d=y[a],c=U[a];return!d?!1:{pane:a,P:d?d[0]:!1,C:c?c[0]:!1,state:b.extend(!0,{},q[a]),options:b.extend(!0,{},r[a])}}function h(a,c){if(a){var e=a.P,f=a.C,g=a.pane,j=k[c],m=b.extend(!0,{},q[c]),
|
||||||
n=r[c],w={resizerCursor:n.resizerCursor};b.each(["fxName","fxSpeed","fxSettings"],function(a,b){w[b+"_open"]=n[b+"_open"];w[b+"_close"]=n[b+"_close"];w[b+"_size"]=n[b+"_size"]});y[c]=b(e).data({layoutPane:z[c],layoutEdge:c}).css(k.hidden).css(j.cssReq);U[c]=f?b(f):!1;r[c]=b.extend(!0,{},a.options,w);q[c]=b.extend(!0,{},a.state);e.className=e.className.replace(RegExp(n.paneClass+"-"+g,"g"),n.paneClass+"-"+c);Pa(c);j.dir!=k[g].dir?(e=p[c]||0,Y(c),e=d(e,q[c].minSize),Ca(c,e,!0,!0)):F[c].css(j.side,v.inset[j.side]+
|
n=r[c],w={resizerCursor:n.resizerCursor};b.each(["fxName","fxSpeed","fxSettings"],function(a,b){w[b+"_open"]=n[b+"_open"];w[b+"_close"]=n[b+"_close"];w[b+"_size"]=n[b+"_size"]});y[c]=b(e).data({layoutPane:z[c],layoutEdge:c}).css(k.hidden).css(j.cssReq);U[c]=f?b(f):!1;r[c]=b.extend(!0,{},a.options,w);q[c]=b.extend(!0,{},a.state);e.className=e.className.replace(RegExp(n.paneClass+"-"+g,"g"),n.paneClass+"-"+c);Pa(c);j.dir!=k[g].dir?(e=p[c]||0,Y(c),e=d(e,q[c].minSize),Ca(c,e,!0,!0)):F[c].css(j.side,v.inset[j.side]+
|
||||||
(q[c].isVisible?ga(c):0));a.state.isVisible&&!m.isVisible?Ua(c,!0):(Da(c),ma(c,!0));a=null}}if(H()){var g=A.call(this,a);q[g].edge=c;q[c].edge=g;if(!1===C("onswap_start",g)||!1===C("onswap_start",c))q[g].edge=g,q[c].edge=c;else{var j=f(g),n=f(c),p={};p[g]=j?j.state.size:0;p[c]=n?n.state.size:0;y[g]=!1;y[c]=!1;q[g]={};q[c]={};P[g]&&P[g].remove();P[c]&&P[c].remove();F[g]&&F[g].remove();F[c]&&F[c].remove();F[g]=F[c]=P[g]=P[c]=!1;h(j,c);h(n,g);j=n=p=null;y[g]&&y[g].css(k.visible);y[c]&&y[c].css(k.visible);
|
(q[c].isVisible?ga(c):0));a.state.isVisible&&!m.isVisible?Ua(c,!0):(Da(c),ma(c,!0));a=null}}if(H()){var g=A.call(this,a);q[g].edge=c;q[c].edge=g;if(!1===C("onswap_start",g)||!1===C("onswap_start",c))q[g].edge=g,q[c].edge=c;else{var j=f(g),n=f(c),p={};p[g]=j?j.state.size:0;p[c]=n?n.state.size:0;y[g]=!1;y[c]=!1;q[g]={};q[c]={};P[g]&&P[g].remove();P[c]&&P[c].remove();F[g]&&F[g].remove();F[c]&&F[c].remove();F[g]=F[c]=P[g]=P[c]=!1;h(j,c);h(n,g);j=n=p=null;y[g]&&y[g].css(k.visible);y[c]&&y[c].css(k.visible);
|
||||||
oa();C("onswap_end",g);C("onswap_end",c)}}},showMasks:va,hideMasks:za,initContent:Sa,addPane:ib,removePane:Ra,createChildren:Qa,refreshChildren:Ba,enableClosable:pb,disableClosable:function(a,b){if(H()){var c=A.call(this,a),d=P[c];d&&(r[c].closable=!1,q[c].isClosed&&ra(c,!1,!0),d.unbind("."+K).css("visibility",b?"hidden":"visible").css("cursor","default").attr("title",""))}},enableSlidable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&b.data("draggable")&&(r[a].slidable=!0,q[a].isClosed&&ma(a,
|
oa();C("onswap_end",g);C("onswap_end",c)}}},showMasks:va,hideMasks:za,initContent:Sa,addPane:ib,removePane:Ra,createChildren:Qa,refreshChildren:Ba,enableClosable:pb,disableClosable:function(a,b){if(H()){var c=A.call(this,a),d=P[c];d&&(r[c].closable=!1,q[c].isClosed&&ra(c,!1,!0),d.unbind("."+K).css("visibility",b?"hidden":"visible").css("cursor","default").attr("title",""))}},enableSlidable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&b.data("draggable")&&(r[a].slidable=!0,q[a].isClosed&&ma(a,
|
||||||
!0))}},disableSlidable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&(r[a].slidable=!1,q[a].isSliding?ja(a,!1,!0):(ma(a,!1),b.css("cursor","default").attr("title",""),da(null,b[0])))}},enableResizable:function(a){if(H()){a=A.call(this,a);var b=F[a],c=r[a];b&&b.data("draggable")&&(c.resizable=!0,b.draggable("enable"),q[a].isClosed||b.css("cursor",c.resizerCursor).attr("title",c.tips.Resize))}},disableResizable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&b.data("draggable")&&(r[a].resizable=
|
!0))}},disableSlidable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&(r[a].slidable=!1,q[a].isSliding?ja(a,!1,!0):(ma(a,!1),b.css("cursor","default").attr("title",""),da(null,b[0])))}},enableResizable:function(a){if(H()){a=A.call(this,a);var b=F[a],c=r[a];b&&b.data("draggable")&&(c.resizable=!0,b.draggable("enable"),q[a].isClosed||b.css("cursor",c.resizerCursor).attr("title",c.tips.Resize))}},disableResizable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&b.data("draggable")&&(r[a].resizable=
|
||||||
!1,b.draggable("disable").css("cursor","default").attr("title",""),da(null,b[0]))}},allowOverflow:x,resetOverflow:X,destroy:function(a,c){b(window).unbind("."+K);b(document).unbind("."+K);"object"===typeof a?A(a):c=a;u.clearQueue().removeData("layout").removeData("layoutContainer").removeClass(r.containerClass).unbind("."+K);ea.remove();b.each(k.allPanes,function(a,b){Ra(b,!1,!0,c)});u.data("layoutCSS")&&!u.data("layoutRole")&&u.css(u.data("layoutCSS")).removeData("layoutCSS");"BODY"===v.tagName&&
|
!1,b.draggable("disable").css("cursor","default").attr("title",""),da(null,b[0]))}},allowOverflow:x,resetOverflow:X,destroy:function(a,c){b(window).unbind("."+K);b(document).unbind("."+K);"object"===typeof a?A(a):c=a;u.clearQueue().removeData("layout").removeData("left-component").removeClass(r.containerClass).unbind("."+K);ea.remove();b.each(k.allPanes,function(a,b){Ra(b,!1,!0,c)});u.data("layoutCSS")&&!u.data("layoutRole")&&u.css(u.data("layoutCSS")).removeData("layoutCSS");"BODY"===v.tagName&&
|
||||||
(u=b("html")).data("layoutCSS")&&u.css(u.data("layoutCSS")).removeData("layoutCSS");j(z,b.layout.onDestroy);mb();for(var d in z)d.match(/^(container|options)$/)||delete z[d];z.destroyed=!0;return z},initPanes:H,resizeAll:oa,runCallbacks:C,hasParentLayout:!1,children:ba,north:!1,south:!1,west:!1,east:!1,center:!1},Xa;var V,Ya,N,Ha,la,sa,W;h=b.layout.transformData(h,!0);h=b.layout.backwardCompatibility.renameAllOptions(h);if(!b.isEmptyObject(h.panes)){V=b.layout.optionsMap.noDefault;la=0;for(sa=V.length;la<
|
(u=b("html")).data("layoutCSS")&&u.css(u.data("layoutCSS")).removeData("layoutCSS");j(z,b.layout.onDestroy);mb();for(var d in z)d.match(/^(container|options)$/)||delete z[d];z.destroyed=!0;return z},initPanes:H,resizeAll:oa,runCallbacks:C,hasParentLayout:!1,children:ba,north:!1,south:!1,west:!1,east:!1,center:!1},Xa;var V,Ya,N,Ha,la,sa,W;h=b.layout.transformData(h,!0);h=b.layout.backwardCompatibility.renameAllOptions(h);if(!b.isEmptyObject(h.panes)){V=b.layout.optionsMap.noDefault;la=0;for(sa=V.length;la<
|
||||||
sa;la++)N=V[la],delete h.panes[N];V=b.layout.optionsMap.layout;la=0;for(sa=V.length;la<sa;la++)N=V[la],delete h.panes[N]}V=b.layout.optionsMap.layout;var Bb=b.layout.config.optionRootKeys;for(N in h)Ha=h[N],0>b.inArray(N,Bb)&&0>b.inArray(N,V)&&(h.panes[N]||(h.panes[N]=b.isPlainObject(Ha)?b.extend(!0,{},Ha):Ha),delete h[N]);b.extend(!0,r,h);b.each(k.allPanes,function(a,c){k[c]=b.extend(!0,{},k.panes,k[c]);Ya=r.panes;W=r[c];if("center"===c){V=b.layout.optionsMap.center;a=0;for(sa=V.length;a<sa;a++)if(N=
|
sa;la++)N=V[la],delete h.panes[N];V=b.layout.optionsMap.layout;la=0;for(sa=V.length;la<sa;la++)N=V[la],delete h.panes[N]}V=b.layout.optionsMap.layout;var Bb=b.layout.config.optionRootKeys;for(N in h)Ha=h[N],0>b.inArray(N,Bb)&&0>b.inArray(N,V)&&(h.panes[N]||(h.panes[N]=b.isPlainObject(Ha)?b.extend(!0,{},Ha):Ha),delete h[N]);b.extend(!0,r,h);b.each(k.allPanes,function(a,c){k[c]=b.extend(!0,{},k.panes,k[c]);Ya=r.panes;W=r[c];if("center"===c){V=b.layout.optionsMap.center;a=0;for(sa=V.length;a<sa;a++)if(N=
|
||||||
V[a],!h.center[N]&&(h.panes[N]||!W[N]))W[N]=Ya[N]}else{W=r[c]=b.extend(!0,{},Ya,W);var d=r[c],f=r.panes;d.fxSettings||(d.fxSettings={});f.fxSettings||(f.fxSettings={});b.each(["_open","_close","_size"],function(a,e){var h="fxName"+e,j="fxSpeed"+e,k="fxSettings"+e,l=d[h]=d[h]||f[h]||d.fxName||f.fxName||"none",p=b.effects&&(b.effects[l]||b.effects.effect&&b.effects.effect[l]);if("none"===l||!r.effects[l]||!p)l=d[h]="none";l=r.effects[l]||{};h=l.all||null;l=l[c]||null;d[j]=d[j]||f[j]||d.fxSpeed||f.fxSpeed||
|
V[a],!h.center[N]&&(h.panes[N]||!W[N]))W[N]=Ya[N]}else{W=r[c]=b.extend(!0,{},Ya,W);var d=r[c],f=r.panes;d.fxSettings||(d.fxSettings={});f.fxSettings||(f.fxSettings={});b.each(["_open","_close","_size"],function(a,e){var h="fxName"+e,j="fxSpeed"+e,k="fxSettings"+e,l=d[h]=d[h]||f[h]||d.fxName||f.fxName||"none",p=b.effects&&(b.effects[l]||b.effects.effect&&b.effects.effect[l]);if("none"===l||!r.effects[l]||!p)l=d[h]="none";l=r.effects[l]||{};h=l.all||null;l=l[c]||null;d[j]=d[j]||f[j]||d.fxSpeed||f.fxSpeed||
|
||||||
null;d[k]=b.extend(!0,{},h,l,f.fxSettings,d.fxSettings,f[k],d[k])});delete d.fxName;delete d.fxSpeed;delete d.fxSettings;W.resizerClass||(W.resizerClass="ui-layout-resizer");W.togglerClass||(W.togglerClass="ui-layout-toggler")}W.paneClass||(W.paneClass="ui-layout-pane")});var Ia=h.zIndex,xa=r.zIndexes;0<Ia&&(xa.pane_normal=Ia,xa.content_mask=d(Ia+1,xa.content_mask),xa.resizer_normal=d(Ia+2,xa.resizer_normal));delete r.panes;var Cb=r,tb=q;tb.creatingLayout=!0;j(z,b.layout.onCreate);if(!1===C("onload_start"))Xa=
|
null;d[k]=b.extend(!0,{},h,l,f.fxSettings,d.fxSettings,f[k],d[k])});delete d.fxName;delete d.fxSpeed;delete d.fxSettings;W.resizerClass||(W.resizerClass="ui-layout-resizer");W.togglerClass||(W.togglerClass="ui-layout-toggler")}W.paneClass||(W.paneClass="ui-layout-pane")});var Ia=h.zIndex,xa=r.zIndexes;0<Ia&&(xa.pane_normal=Ia,xa.content_mask=d(Ia+1,xa.content_mask),xa.resizer_normal=d(Ia+2,xa.resizer_normal));delete r.panes;var Cb=r,tb=q;tb.creatingLayout=!0;j(z,b.layout.onCreate);if(!1===C("onload_start"))Xa=
|
||||||
"cancel";else{var Za=u[0],$=b("html"),ub=v.tagName=Za.tagName,vb=v.id=Za.id,wb=v.className=Za.className,L=r,Ja=L.name,$a={},Ka=u.data("parentLayout"),La=u.data("layoutEdge"),ab=Ka&&La,ta=b.layout.cssNum,bb,aa;v.selector=u.selector.split(".slice")[0];v.ref=(L.name?L.name+" layout / ":"")+ub+(vb?"#"+vb:wb?".["+wb+"]":"");v.isBody="BODY"===ub;!ab&&!v.isBody&&(bb=u.closest("."+b.layout.defaults.panes.paneClass),Ka=bb.data("parentLayout"),La=bb.data("layoutEdge"),ab=Ka&&La);u.data({layout:z,layoutContainer:K}).addClass(L.containerClass);
|
"cancel";else{var Za=u[0],$=b("html"),ub=v.tagName=Za.tagName,vb=v.id=Za.id,wb=v.className=Za.className,L=r,Ja=L.name,$a={},Ka=u.data("parentLayout"),La=u.data("layoutEdge"),ab=Ka&&La,ta=b.layout.cssNum,bb,aa;v.selector=u.selector.split(".slice")[0];v.ref=(L.name?L.name+" layout / ":"")+ub+(vb?"#"+vb:wb?".["+wb+"]":"");v.isBody="BODY"===ub;!ab&&!v.isBody&&(bb=u.closest("."+b.layout.defaults.panes.paneClass),Ka=bb.data("parentLayout"),La=bb.data("layoutEdge"),ab=Ka&&La);u.data({layout:z,left-component:K}).addClass(L.containerClass);
|
||||||
var xb={destroy:"",initPanes:"",resizeAll:"resizeAll",resize:"resizeAll"};for(Ja in xb)u.bind("layout"+Ja.toLowerCase()+"."+K,z[xb[Ja]||Ja]);ab&&(z.hasParentLayout=!0,Ka.refreshChildren(La,z));u.data("layoutCSS")||(v.isBody?(u.data("layoutCSS",b.extend(D(u,"position,margin,padding,border"),{height:u.css("height"),overflow:u.css("overflow"),overflowX:u.css("overflowX"),overflowY:u.css("overflowY")})),$.data("layoutCSS",b.extend(D($,"padding"),{height:"auto",overflow:$.css("overflow"),overflowX:$.css("overflowX"),
|
var xb={destroy:"",initPanes:"",resizeAll:"resizeAll",resize:"resizeAll"};for(Ja in xb)u.bind("layout"+Ja.toLowerCase()+"."+K,z[xb[Ja]||Ja]);ab&&(z.hasParentLayout=!0,Ka.refreshChildren(La,z));u.data("layoutCSS")||(v.isBody?(u.data("layoutCSS",b.extend(D(u,"position,margin,padding,border"),{height:u.css("height"),overflow:u.css("overflow"),overflowX:u.css("overflowX"),overflowY:u.css("overflowY")})),$.data("layoutCSS",b.extend(D($,"padding"),{height:"auto",overflow:$.css("overflow"),overflowX:$.css("overflowX"),
|
||||||
overflowY:$.css("overflowY")}))):u.data("layoutCSS",D(u,"position,margin,padding,border,top,bottom,left,right,width,height,overflow,overflowX,overflowY")));try{$a={overflow:"hidden",overflowX:"hidden",overflowY:"hidden"};u.css($a);L.inset&&!b.isPlainObject(L.inset)&&(aa=parseInt(L.inset,10)||0,L.inset={top:aa,bottom:aa,left:aa,right:aa});if(v.isBody)L.outset?b.isPlainObject(L.outset)||(aa=parseInt(L.outset,10)||0,L.outset={top:aa,bottom:aa,left:aa,right:aa}):L.outset={top:ta($,"paddingTop"),bottom:ta($,
|
overflowY:$.css("overflowY")}))):u.data("layoutCSS",D(u,"position,margin,padding,border,top,bottom,left,right,width,height,overflow,overflowX,overflowY")));try{$a={overflow:"hidden",overflowX:"hidden",overflowY:"hidden"};u.css($a);L.inset&&!b.isPlainObject(L.inset)&&(aa=parseInt(L.inset,10)||0,L.inset={top:aa,bottom:aa,left:aa,right:aa});if(v.isBody)L.outset?b.isPlainObject(L.outset)||(aa=parseInt(L.outset,10)||0,L.outset={top:aa,bottom:aa,left:aa,right:aa}):L.outset={top:ta($,"paddingTop"),bottom:ta($,
|
||||||
"paddingBottom"),left:ta($,"paddingLeft"),right:ta($,"paddingRight")},$.css($a).css({height:"100%",border:"none",padding:0,margin:0}),G.isIE6?(u.css({width:"100%",height:"100%",border:"none",padding:0,margin:0,position:"relative"}),L.inset||(L.inset=R(u).inset)):(u.css({width:"auto",height:"auto",margin:0,position:"absolute"}),u.css(L.outset)),b.extend(v,R(u,L.inset));else{var yb=u.css("position");(!yb||!yb.match(/(fixed|absolute|relative)/))&&u.css("position","relative");u.is(":visible")&&(b.extend(v,
|
"paddingBottom"),left:ta($,"paddingLeft"),right:ta($,"paddingRight")},$.css($a).css({height:"100%",border:"none",padding:0,margin:0}),G.isIE6?(u.css({width:"100%",height:"100%",border:"none",padding:0,margin:0,position:"relative"}),L.inset||(L.inset=R(u).inset)):(u.css({width:"auto",height:"auto",margin:0,position:"absolute"}),u.css(L.outset)),b.extend(v,R(u,L.inset));else{var yb=u.css("position");(!yb||!yb.match(/(fixed|absolute|relative)/))&&u.css("position","relative");u.is(":visible")&&(b.extend(v,
|
||||||
|
|
463
js/service.js
Normal file
463
js/service.js
Normal file
|
@ -0,0 +1,463 @@
|
||||||
|
JamStash.service('model', function () {
|
||||||
|
secondsToTime = function (secs) {
|
||||||
|
// secs = 4729
|
||||||
|
var times = new Array(3600, 60, 1);
|
||||||
|
var time = '';
|
||||||
|
var tmp;
|
||||||
|
for (var i = 0; i < times.length; i++) {
|
||||||
|
tmp = Math.floor(secs / times[i]);
|
||||||
|
// 0: 4729/3600 = 1
|
||||||
|
// 1: 1129/60 = 18
|
||||||
|
// 2: 49/1 = 49
|
||||||
|
if (tmp < 1) {
|
||||||
|
tmp = '00';
|
||||||
|
}
|
||||||
|
else if (tmp < 10) {
|
||||||
|
tmp = '0' + tmp;
|
||||||
|
}
|
||||||
|
if (i == 0 && tmp == '00') {
|
||||||
|
} else {
|
||||||
|
time += tmp;
|
||||||
|
if (i < 2) {
|
||||||
|
time += ':';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
secs = secs % times[i];
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
this.Index = function (name, artist) {
|
||||||
|
this.name = name;
|
||||||
|
this.artist = artist;
|
||||||
|
}
|
||||||
|
this.Artist = function (id, name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
this.Album = function (id, parentid, name, artist, artistId, coverartthumb, coverartfull, date, starred, description, url, type) {
|
||||||
|
this.id = id;
|
||||||
|
this.parentid = parentid;
|
||||||
|
this.name = name;
|
||||||
|
this.artist = artist;
|
||||||
|
this.artistId = artistId;
|
||||||
|
this.coverartthumb = coverartthumb;
|
||||||
|
this.coverartfull = coverartfull;
|
||||||
|
this.date = date;
|
||||||
|
this.starred = starred;
|
||||||
|
this.description = description;
|
||||||
|
this.url = url;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
this.Song = function (id, parentid, track, name, artist, artistId, album, albumId, coverartthumb, coverartfull, duration, rating, starred, suffix, specs, url, position, description) {
|
||||||
|
this.id = id;
|
||||||
|
this.parentid = parentid;
|
||||||
|
this.track = track;
|
||||||
|
this.name = name;
|
||||||
|
this.artist = artist;
|
||||||
|
this.artistId = artistId;
|
||||||
|
this.album = album;
|
||||||
|
this.albumId = albumId;
|
||||||
|
this.coverartthumb = coverartthumb;
|
||||||
|
this.coverartfull = coverartfull;
|
||||||
|
this.duration = duration;
|
||||||
|
this.time = duration == '' ? '00:00' : secondsToTime(duration);
|
||||||
|
this.rating = rating;
|
||||||
|
this.starred = starred;
|
||||||
|
this.suffix = suffix;
|
||||||
|
this.specs = specs;
|
||||||
|
this.url = url;
|
||||||
|
this.position = position;
|
||||||
|
this.selected = false;
|
||||||
|
this.playing = false;
|
||||||
|
this.description = description;
|
||||||
|
this.displayName = this.name + " - " + this.album + " - " + this.artist;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JamStash.service('globals', function () {
|
||||||
|
this.settings = {
|
||||||
|
// Subsonic
|
||||||
|
/* Demo Server
|
||||||
|
Username: "android-guest"),
|
||||||
|
Password: "guest"),
|
||||||
|
Server: "http://subsonic.org/demo"),
|
||||||
|
*/
|
||||||
|
Url: "http://Jamstash.com/beta/#/archive/",
|
||||||
|
Username: "tsquillario",
|
||||||
|
Password: "Elephant1!",
|
||||||
|
Server: "https://tsquillario.dyndns.org:8443/subsonic",
|
||||||
|
Timeout: 10000,
|
||||||
|
NotificationTimeout: 20000,
|
||||||
|
Protocol: "jsonp",
|
||||||
|
ApplicationName: "Jamstash",
|
||||||
|
ApiVersion: "1.6.0",
|
||||||
|
AutoPlaylists: "",
|
||||||
|
AutoPlaylistSize: 25,
|
||||||
|
AutoAlbumSize: 15,
|
||||||
|
// General
|
||||||
|
HideAZ: false,
|
||||||
|
ScrollTitle: true,
|
||||||
|
NotificationSong: true,
|
||||||
|
NotificationNowPlaying: false,
|
||||||
|
SaveTrackPosition: false,
|
||||||
|
ForceFlash: false,
|
||||||
|
Theme: "Default",
|
||||||
|
DefaultLibraryLayout: "grid",
|
||||||
|
AutoPlay: false,
|
||||||
|
LoopQueue: false,
|
||||||
|
Repeat: false,
|
||||||
|
Debug: false
|
||||||
|
};
|
||||||
|
this.SavedCollections = [];
|
||||||
|
this.SavedGenres = [];
|
||||||
|
this.BaseURL = function () { return this.settings.Server + '/rest'; };
|
||||||
|
this.BaseParams = function () { return 'u=' + this.settings.Username + '&p=' + this.settings.Password + '&f=' + this.settings.Protocol + '&v=' + this.settings.ApiVersion + '&c=' + this.settings.ApplicationName; };
|
||||||
|
});
|
||||||
|
|
||||||
|
// Directives
|
||||||
|
JamStash.directive('layout', function () {
|
||||||
|
return {
|
||||||
|
|
||||||
|
link: function (scope, elm, attrs) {
|
||||||
|
|
||||||
|
var pageLayoutOptions = {
|
||||||
|
name: 'pageLayout', // only for debugging
|
||||||
|
resizeWithWindowDelay: 250, // delay calling resizeAll when window is *still* resizing
|
||||||
|
//, resizeWithWindowMaxDelay: 2000 // force resize every XX ms while window is being resized
|
||||||
|
//center__children: {},
|
||||||
|
//north__paneSelector: "#container",
|
||||||
|
center__paneSelector: "#container",
|
||||||
|
south__paneSelector: "#QueuePreview",
|
||||||
|
south__resizable: false, // No resize
|
||||||
|
//south__closable: false, // No close handle
|
||||||
|
//south__spacing_open: 0, // No resize bar
|
||||||
|
south__size: 145,
|
||||||
|
south__initClosed: true,
|
||||||
|
south__minWidth: 145,
|
||||||
|
south__maxWidth: 145
|
||||||
|
};
|
||||||
|
|
||||||
|
var layoutThreeCol = {
|
||||||
|
east__size: .42,
|
||||||
|
east__minSize: 400,
|
||||||
|
east__maxSize: .5, // 50% of layout width
|
||||||
|
east__initClosed: false,
|
||||||
|
east__initHidden: false,
|
||||||
|
//center__size: 'auto',
|
||||||
|
center__minWidth: .38,
|
||||||
|
center__initClosed: false,
|
||||||
|
center__initHidden: false,
|
||||||
|
west__size: .2,
|
||||||
|
west__minSize: 200,
|
||||||
|
west__initClosed: false,
|
||||||
|
west__initHidden: false,
|
||||||
|
//stateManagement__enabled: true, // automatic cookie load & save enabled by default
|
||||||
|
showDebugMessages: true // log and/or display messages from debugging & testing code
|
||||||
|
//applyDefaultStyles: true
|
||||||
|
};
|
||||||
|
|
||||||
|
var layoutTwoCol = {
|
||||||
|
center__size: .8,
|
||||||
|
center__minSize: 400,
|
||||||
|
center__maxSize: .5, // 50% of layout width
|
||||||
|
center__initClosed: false,
|
||||||
|
center__initHidden: false,
|
||||||
|
west__size: .2,
|
||||||
|
west__minSize: 200,
|
||||||
|
west__initClosed: false,
|
||||||
|
west__initHidden: false,
|
||||||
|
//stateManagement__enabled: true, // automatic cookie load & save enabled by default
|
||||||
|
showDebugMessages: true // log and/or display messages from debugging & testing code
|
||||||
|
//applyDefaultStyles: true
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.$watch(attrs.state, function (state) {
|
||||||
|
if (state == 1) {
|
||||||
|
var layout = elm.layout(pageLayoutOptions);
|
||||||
|
}
|
||||||
|
if (state == 2) {
|
||||||
|
var layout = elm.layout(layoutTwoCol);
|
||||||
|
//scope.layout.sizePane('east', 120);
|
||||||
|
//scope.layout.show('west');
|
||||||
|
//scope.layout.show('south');
|
||||||
|
} else if (state == 3) {
|
||||||
|
var layout = elm.layout(layoutThreeCol);
|
||||||
|
//scope.layout.sizePane('east', 60);
|
||||||
|
//scope.layout.hide('west');
|
||||||
|
//scope.layout.hide('south');
|
||||||
|
}
|
||||||
|
scope.layout = layout;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
JamStash.directive('sortable', function () {
|
||||||
|
return {
|
||||||
|
link: function (scope, elm, attrs) {
|
||||||
|
elm.sortable({
|
||||||
|
start: scope.dragStart,
|
||||||
|
update: scope.dragEnd
|
||||||
|
});
|
||||||
|
elm.disableSelection();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
JamStash.directive('split', function () {
|
||||||
|
return {
|
||||||
|
|
||||||
|
link: function (scope, elm, attrs) {
|
||||||
|
elm.splitPane();
|
||||||
|
/*
|
||||||
|
//elm.first().resizable({
|
||||||
|
$('#SubsonicAlbums > div:first').resizable({
|
||||||
|
handles: 'e',
|
||||||
|
minWidth: '100',
|
||||||
|
maxWidth: '400',
|
||||||
|
resize: function () {
|
||||||
|
alert('foo');
|
||||||
|
var remainingSpace = $(this).parent().width() - $(this).outerWidth();
|
||||||
|
var divTwo = $(this).next();
|
||||||
|
var divTwoWidth = remainingSpace - (divTwo.outerWidth() - divTwo.width());
|
||||||
|
divTwo.css('width', divTwoWidth + 'px');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
scope.$watch(attrs.state, function (state) {
|
||||||
|
if (state == 1) {
|
||||||
|
var layout = elm.layout(pageLayoutOptions);
|
||||||
|
}
|
||||||
|
if (state == 2) {
|
||||||
|
var layout = elm.layout(layoutTwoCol);
|
||||||
|
//scope.layout.sizePane('east', 120);
|
||||||
|
//scope.layout.show('west');
|
||||||
|
//scope.layout.show('south');
|
||||||
|
} else if (state == 3) {
|
||||||
|
var layout = elm.layout(layoutThreeCol);
|
||||||
|
//scope.layout.sizePane('east', 60);
|
||||||
|
//scope.layout.hide('west');
|
||||||
|
//scope.layout.hide('south');
|
||||||
|
}
|
||||||
|
scope.layout = layout;
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
JamStash.directive('fancybox', function ($compile) {
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
replace: false,
|
||||||
|
link: function($scope, element, attrs) {
|
||||||
|
$scope.fancyboxOpen = function() {
|
||||||
|
var el = angular.element(element.html()),
|
||||||
|
compiled = $compile(el);
|
||||||
|
$.fancybox.open(el);
|
||||||
|
compiled($scope);
|
||||||
|
};
|
||||||
|
$scope.fancyboxOpenUrl = function () {
|
||||||
|
var el = angular.element(element.html()),
|
||||||
|
compiled = $compile(el);
|
||||||
|
$.fancybox.open(el);
|
||||||
|
compiled($scope);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
JamStash.directive('songpreview', function ($compile, subsonic) {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
templateUrl: 'js/partials/songs.html',
|
||||||
|
replace: false,
|
||||||
|
// pass these two names from attrs into the template scope
|
||||||
|
scope: {
|
||||||
|
song: '@'
|
||||||
|
},
|
||||||
|
link: function (scope, element, attrs) {
|
||||||
|
subsonic.getSongTemplate(function (data) {
|
||||||
|
scope.song = data;
|
||||||
|
//var el = angular.element(element.html()),
|
||||||
|
//var el = element.html(),
|
||||||
|
//compiled = $compile(el);
|
||||||
|
$.fancybox.open(element);
|
||||||
|
//compiled($scope);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
JamStash.directive('stopEvent', function () {
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
link: function (scope, element, attr) {
|
||||||
|
element.bind(attr.stopEvent, function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
JamStash.directive('ngEnter', function () {
|
||||||
|
return function (scope, element, attrs) {
|
||||||
|
element.bind("keydown keypress", function (event) {
|
||||||
|
if (event.which === 13) {
|
||||||
|
scope.$apply(function () {
|
||||||
|
scope.$eval(attrs.ngEnter);
|
||||||
|
});
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
JamStash.directive('ngDownload', function ($compile) {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
scope: { data: '=' },
|
||||||
|
link: function (scope, elm, attrs) {
|
||||||
|
function getUrl() {
|
||||||
|
return URL.createObjectURL(new Blob([JSON.stringify(scope.data)], { type: "application/json" }));
|
||||||
|
}
|
||||||
|
|
||||||
|
elm.append($compile(
|
||||||
|
'<a class="button" download="backup.json"' +
|
||||||
|
'href="' + getUrl() + '">' +
|
||||||
|
'Download' +
|
||||||
|
'</a>'
|
||||||
|
)(scope));
|
||||||
|
|
||||||
|
scope.$watch(scope.data, function () {
|
||||||
|
elm.children()[0].href = getUrl();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Factory */
|
||||||
|
JamStash.factory('json', function ($http) { // Deferred loading
|
||||||
|
return {
|
||||||
|
getCollections: function (callback) {
|
||||||
|
$http.get('js/json_collections.js').success(callback);
|
||||||
|
},
|
||||||
|
getChangeLog: function (callback) {
|
||||||
|
$http.get('js/json_changelog.js').success(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
JamStash.factory('template', function ($http, $compile, $http, $templateCache) { // Deferred loading
|
||||||
|
return {
|
||||||
|
getCollections: function (callback) {
|
||||||
|
$http.get('js/json_collections.js', { cache: $templateCache }).success(callback);
|
||||||
|
},
|
||||||
|
getChangeLog: function (callback) {
|
||||||
|
$http.get('js/json_changelog.js', { cache: $templateCache }).success(callback);
|
||||||
|
},
|
||||||
|
getSongs: function (callback) {
|
||||||
|
templateUrl = 'js/partials/songs.html';
|
||||||
|
$http.get(templateUrl, { cache: $templateCache }).success(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
JamStash.factory('subsonic', function ($http, globals, utils) {
|
||||||
|
return {
|
||||||
|
getSongTemplate: function (callback) {
|
||||||
|
var id = '16608';
|
||||||
|
var url = globals.BaseURL() + '/getMusicDirectory.view?' + globals.BaseParams() + '&id=' + id;
|
||||||
|
/*
|
||||||
|
$.ajax({
|
||||||
|
url: url,
|
||||||
|
method: 'GET',
|
||||||
|
dataType: globals.settings.Protocol,
|
||||||
|
timeout: globals.settings.Timeout,
|
||||||
|
success: function (data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
$http.get(url).success(function (data) {
|
||||||
|
var items = [];
|
||||||
|
var song = [];
|
||||||
|
if (typeof data["subsonic-response"].directory.child != 'undefined') {
|
||||||
|
if (data["subsonic-response"].directory.child.length > 0) {
|
||||||
|
items = data["subsonic-response"].directory.child;
|
||||||
|
} else {
|
||||||
|
items[0] = data["subsonic-response"].directory.child;
|
||||||
|
}
|
||||||
|
angular.forEach(items, function (item, key) {
|
||||||
|
if (!item.isDir) {
|
||||||
|
song.push(utils.mapSong(item));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
callback(song);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Filters */
|
||||||
|
JamStash.filter('capitalize', function () {
|
||||||
|
return function (input, scope) {
|
||||||
|
return input.substring(0, 1).toUpperCase() + input.substring(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JamStash.service('notifications', function ($rootScope, globals) {
|
||||||
|
var msgIndex = 1;
|
||||||
|
this.updateMessage = function (msg, autohide) {
|
||||||
|
if (msg != '') {
|
||||||
|
var id = msgIndex;
|
||||||
|
$('#messages').append('<span id=\"msg_' + id + '\" class="message">' + msg + '</span>');
|
||||||
|
$('#messages').fadeIn();
|
||||||
|
$("#messages").scrollTo('100%');
|
||||||
|
var el = '#msg_' + id;
|
||||||
|
if (autohide) {
|
||||||
|
setTimeout(function () {
|
||||||
|
$(el).fadeOut(function () { $(this).remove(); });
|
||||||
|
}, globals.settings.NotificationTimeout);
|
||||||
|
}
|
||||||
|
$(el).click(function () {
|
||||||
|
$(el).fadeOut(function () { $(this).remove(); });
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
msgIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.requestPermissionIfRequired = function () {
|
||||||
|
if (!this.hasNotificationPermission() && (window.webkitNotifications)) {
|
||||||
|
window.webkitNotifications.requestPermission();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.hasNotificationPermission = function () {
|
||||||
|
return !!(window.webkitNotifications) && (window.webkitNotifications.checkPermission() == 0);
|
||||||
|
}
|
||||||
|
var notifications = new Array();
|
||||||
|
this.showNotification = function (pic, title, text, type, bind) {
|
||||||
|
if (this.hasNotificationPermission()) {
|
||||||
|
//closeAllNotifications()
|
||||||
|
var popup;
|
||||||
|
if (type == 'text') {
|
||||||
|
popup = window.webkitNotifications.createNotification(pic, title, text);
|
||||||
|
} else if (type == 'html') {
|
||||||
|
popup = window.webkitNotifications.createHTMLNotification(text);
|
||||||
|
}
|
||||||
|
if (bind = '#NextTrack') {
|
||||||
|
popup.addEventListener('click', function (bind) {
|
||||||
|
//$(bind).click();
|
||||||
|
$rootScope.nextTrack();
|
||||||
|
this.cancel();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
notifications.push(popup);
|
||||||
|
setTimeout(function (notWin) {
|
||||||
|
notWin.cancel();
|
||||||
|
}, globals.settings.NotificationTimeout, popup);
|
||||||
|
popup.show();
|
||||||
|
} else {
|
||||||
|
console.log("showNotification: No Permission");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.closeAllNotifications = function () {
|
||||||
|
for (notification in notifications) {
|
||||||
|
notifications[notification].cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
28
js/utils.js
28
js/utils.js
|
@ -1,4 +1,4 @@
|
||||||
JamStash.service('utils', function ($cookieStore) {
|
JamStash.service('utils', function ($cookieStore, globals, model) {
|
||||||
this.safeApply = function (fn) {
|
this.safeApply = function (fn) {
|
||||||
var phase = this.$root.$$phase;
|
var phase = this.$root.$$phase;
|
||||||
if (phase == '$apply' || phase == '$digest') {
|
if (phase == '$apply' || phase == '$digest') {
|
||||||
|
@ -46,6 +46,26 @@ JamStash.service('utils', function ($cookieStore) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
this.mapSong = function (data) {
|
||||||
|
var song = data;
|
||||||
|
var url, title, 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;
|
||||||
|
coverartfull = globals.BaseURL() + '/getCoverArt.view?' + globals.BaseParams() + '&id=' + song.coverArt;
|
||||||
|
}
|
||||||
|
if (typeof song.description == 'undefined') { description = ''; } else { description = song.description; }
|
||||||
|
if (typeof song.title == 'undefined') { title = ' '; } else { title = song.title.toString(); }
|
||||||
|
if (typeof song.track == 'undefined') { track = ' '; } else { track = song.track.toString(); }
|
||||||
|
if (typeof song.starred !== 'undefined') { starred = true; } else { starred = false; }
|
||||||
|
if (song.bitRate !== undefined) { specs += song.bitRate + ' Kbps'; }
|
||||||
|
if (song.transcodedSuffix !== undefined) { specs += ', transcoding:' + song.suffix + ' > ' + song.transcodedSuffix; } else { specs += ', ' + song.suffix; }
|
||||||
|
if (song.transcodedSuffix !== undefined) { suffix = song.transcodedSuffix; } else { suffix = song.suffix; }
|
||||||
|
if (suffix == 'ogg') { suffix = 'oga'; }
|
||||||
|
var salt = Math.floor(Math.random() * 100000);
|
||||||
|
url = globals.BaseURL() + '/stream.view?' + globals.BaseParams() + '&id=' + song.id + '&salt=' + salt;
|
||||||
|
return new model.Song(song.id, song.parent, track, title, song.artist, song.artistId, song.album, song.albumId, coverartthumb, coverartfull, song.duration, song.userRating, starred, suffix, specs, url, 0, description);
|
||||||
|
}
|
||||||
this.confirmDelete = function (text) {
|
this.confirmDelete = function (text) {
|
||||||
var question = confirm(text);
|
var question = confirm(text);
|
||||||
if (question) {
|
if (question) {
|
||||||
|
@ -132,6 +152,12 @@ JamStash.service('utils', function ($cookieStore) {
|
||||||
}
|
}
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
this.arrayObjectIndexOf = function (myArray, searchTerm, property) {
|
||||||
|
for (var i = 0, len = myArray.length; i < len; i++) {
|
||||||
|
if (myArray[i][property] === searchTerm) return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
this.logObjectProperties = function (obj) {
|
this.logObjectProperties = function (obj) {
|
||||||
$.each(obj, function (key, value) {
|
$.each(obj, function (key, value) {
|
||||||
var parent = key;
|
var parent = key;
|
||||||
|
|
|
@ -174,7 +174,7 @@ ul.simplelist li
|
||||||
ul.simplelist li a
|
ul.simplelist li a
|
||||||
{
|
{
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #545454;
|
color: #d6d469;
|
||||||
}
|
}
|
||||||
ul.simplelist li:hover
|
ul.simplelist li:hover
|
||||||
{
|
{
|
||||||
|
|
108
style/Style.css
108
style/Style.css
|
@ -168,6 +168,27 @@ span.apiversion
|
||||||
{
|
{
|
||||||
background: url('../images/favicon_32x32.png') no-repeat 0 1px;
|
background: url('../images/favicon_32x32.png') no-repeat 0 1px;
|
||||||
}
|
}
|
||||||
|
.pagetabcenter
|
||||||
|
{
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 66px;
|
||||||
|
height: 22px;
|
||||||
|
background: url('../images/favicon_32x32.png') no-repeat center center #f9f9f9;
|
||||||
|
border-top: 1px solid #C3C3C3;
|
||||||
|
border-right: 1px solid #C3C3C3;
|
||||||
|
border-left: 1px solid #C3C3C3;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 200;
|
||||||
|
}
|
||||||
|
.pagetabcenter:hover
|
||||||
|
{
|
||||||
|
height: 20px;
|
||||||
|
opacity: .8;
|
||||||
|
}
|
||||||
#sslogo
|
#sslogo
|
||||||
{
|
{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -198,6 +219,20 @@ span.apiversion
|
||||||
{
|
{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
.smcolumn
|
||||||
|
{
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
|
outline: none;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.lgcolumn
|
||||||
|
{
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
|
outline: none;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
.lgsection
|
.lgsection
|
||||||
{
|
{
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
@ -472,8 +507,8 @@ ul.mainlist li.item a.add:hover
|
||||||
}
|
}
|
||||||
#BreadCrumb
|
#BreadCrumb
|
||||||
{
|
{
|
||||||
float: right;
|
float: left;
|
||||||
margin: 5px 0 0 0;
|
margin: 13px 0 0 0;
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
color: #AEAEA7;
|
color: #AEAEA7;
|
||||||
background: #f6f6f6;
|
background: #f6f6f6;
|
||||||
|
@ -498,6 +533,10 @@ ul.mainlist li.item a.add:hover
|
||||||
{
|
{
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
#BreadCrumbs .crumb
|
||||||
|
{
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
#BreadHome a
|
#BreadHome a
|
||||||
{
|
{
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -637,7 +676,7 @@ ul.songlist .albumgrid
|
||||||
height: 230px;
|
height: 230px;
|
||||||
float: left;
|
float: left;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.25);
|
||||||
}
|
}
|
||||||
ul.songlist .albumgrid .title
|
ul.songlist .albumgrid .title
|
||||||
{
|
{
|
||||||
|
@ -825,6 +864,12 @@ ul.songlist li:hover
|
||||||
{
|
{
|
||||||
background-color: #EEF4FA;
|
background-color: #EEF4FA;
|
||||||
}
|
}
|
||||||
|
.songpreview li {
|
||||||
|
list-style-type: none;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 8px;
|
||||||
|
border-bottom: 1px solid #f2f2f2;
|
||||||
|
}
|
||||||
.fillheight {
|
.fillheight {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
/*top: 41px;*/
|
/*top: 41px;*/
|
||||||
|
@ -910,10 +955,18 @@ ul.songlist li:hover
|
||||||
{
|
{
|
||||||
height: 29px;
|
height: 29px;
|
||||||
/* width: 660px; */
|
/* width: 660px; */
|
||||||
margin: 5px 68px 0 0;
|
margin: 5px 205px 0 0;
|
||||||
padding: 0 0 0 5px;
|
padding: 0 0 0 5px;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
#globalactions
|
||||||
|
{
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
right: 65px;
|
||||||
|
height: 29px;
|
||||||
|
margin: 5px 0 0 0;
|
||||||
|
}
|
||||||
#search
|
#search
|
||||||
{
|
{
|
||||||
margin: 6px 0 0 0;
|
margin: 6px 0 0 0;
|
||||||
|
@ -1071,33 +1124,23 @@ ul.songlist li:hover
|
||||||
width: 100%; /* As wide as it's allowed */
|
width: 100%; /* As wide as it's allowed */
|
||||||
}
|
}
|
||||||
#QueuePreview {
|
#QueuePreview {
|
||||||
height: 150px;
|
height: 140px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 999;
|
z-index: 100;
|
||||||
display: none;
|
/*background: #5b5b4e; */
|
||||||
background: #ffffff;
|
background: rgba(91, 91, 78, 0.4) ;
|
||||||
}
|
|
||||||
#QueuePreview ul {
|
|
||||||
height: 135px;
|
|
||||||
padding: 4px;
|
|
||||||
margin: 0;
|
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
overflow-x: auto;
|
overflow-x: scroll;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
background: #5b5b4e;
|
display: none;
|
||||||
}
|
}
|
||||||
#QueuePreview li {
|
#QueuePreview li {
|
||||||
height: 120px;
|
|
||||||
}
|
|
||||||
#QueuePreview .queueactions {
|
|
||||||
padding: 0 5px;
|
|
||||||
float: left;
|
|
||||||
border-right: 1px solid #cbcbcb;
|
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
#QueuePreview li.selected {
|
#QueuePreview li.selected {
|
||||||
background-color: #D4E2F1;
|
background-color: #D4E2F1;
|
||||||
|
@ -1110,8 +1153,9 @@ ul.songlist li:hover
|
||||||
}
|
}
|
||||||
#QueuePreview .row {
|
#QueuePreview .row {
|
||||||
width: 92px;
|
width: 92px;
|
||||||
|
height: 119px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0 1px;
|
margin: 1px 1px;
|
||||||
padding: 4px 5px;
|
padding: 4px 5px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -1755,3 +1799,19 @@ legend
|
||||||
.ui-layout-west {
|
.ui-layout-west {
|
||||||
z-index: 900 !important;
|
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 */
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue