Merge branch 'kingosticks-upgrade-streamuris' into develop

This commit is contained in:
Nick Steel 2016-02-04 13:57:27 +00:00
commit d6310202bb
13 changed files with 330 additions and 333 deletions

View File

@ -79,6 +79,9 @@ v2.1.0 (UNRELEASED)
- Add application cache manifest file for quicker loads and to allow client devices to detect when local caches should - Add application cache manifest file for quicker loads and to allow client devices to detect when local caches should
be invalidated. be invalidated.
- Use standard Mopidy mixer methods to mute / un-mute playback. - Use standard Mopidy mixer methods to mute / un-mute playback.
- Added event handling for 'muteChanged' event. (Fixes: `#141 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/141>`_).
- Streams are now saved to the '[Radio Streams].m3u' playlist and are accessible from all clients.
Users with existing streamUris stored as browser cookies will be prompted to convert them to the new m3u backed scheme.
**Fixes** **Fixes**
@ -100,6 +103,11 @@ v2.1.0 (UNRELEASED)
`#135 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/135>`_). `#135 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/135>`_).
- Fix Javascript syntax errors. (Fixes: `#122 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/122>`_). - Fix Javascript syntax errors. (Fixes: `#122 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/122>`_).
- Fix vertical alignment of playback control buttons in footer. - Fix vertical alignment of playback control buttons in footer.
- Increase width of header so that more text can be rendered in the title bar.
(Fixes: `#144 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/144>`_).
- Re-align the menu and search buttons in the title bar.
(Fixes: `#148 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/148>`_).
- Use explicit Mopidy.js calling convention. (Fixes: `#79 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/79>`_).
v2.0.0 (2015-03-26) v2.0.0 (2015-03-26)

View File

@ -2451,9 +2451,9 @@ input.ui-input-text.ui-slider-input {
outline: 0; outline: 0;
} }
.ui-slider-track.ui-mini .ui-slider-handle { .ui-slider-track.ui-mini .ui-slider-handle {
height: 22px; height: 14px;
width: 22px; width: 14px;
margin: -12px 0 0 -12px; margin: -8px 0 0 -7px;
} }
.ui-slider-handle .ui-btn-inner { .ui-slider-handle .ui-btn-inner {
padding: 0; padding: 0;

File diff suppressed because one or more lines are too long

View File

@ -18,52 +18,58 @@
.header-breakpoint.ui-grid-b .ui-block-a { .header-breakpoint.ui-grid-b .ui-block-a {
width: 30%; width: 30%;
} }
.header-breakpoint.ui-grid-b .ui-block-b { .header-breakpoint.ui-grid-b .ui-block-b {
width: 30%; width: 30%;
} }
.header-breakpoint.ui-grid-b .ui-block-c { .header-breakpoint.ui-grid-b .ui-block-c {
width: 30.1%; width: 30.1%;
} }
/*playlists*/ /*playlists*/
.pl-breakpoint.ui-grid-a .ui-block-a { .pl-breakpoint.ui-grid-a .ui-block-a {
width: 32.95%; width: 32.95%;
} }
.pl-breakpoint.ui-grid-a .ui-block-b { .pl-breakpoint.ui-grid-a .ui-block-b {
width: 65.4%; width: 65.4%;
} }
.pl-breakpoint.ui-grid-a .ui-block-a { .pl-breakpoint.ui-grid-a .ui-block-a {
clear: left; clear: left;
} }
.pl-breakpoint.ui-grid-a .ui-block-a { .pl-breakpoint.ui-grid-a .ui-block-a {
clear: left; clear: left;
} }
#playlisttracksdiv { #playlisttracksdiv {
margin-left: 10px; margin-left: 10px;
} }
#playlisttracksback { #playlisttracksback {
display:none; display:none;
} }
#playlisttracksdiv { #playlisttracksdiv {
display:block; display:block;
} }
#playlistslistdiv { #playlistslistdiv {
display:block; display:block;
} }
/*search*/ /*search*/
.srch-breakpoint.ui-grid-a .ui-block-b { .srch-breakpoint.ui-grid-a .ui-block-b {
margin-left: .5em; margin-left: .5em;
} }
.srch-breakpoint.ui-grid-a .ui-block-a, .srch-breakpoint.ui-grid-a .ui-block-b { .srch-breakpoint.ui-grid-a .ui-block-a, .srch-breakpoint.ui-grid-a .ui-block-b {
width: 49%; width: 49%;
} }
/* .scroll {
overflow-y: auto;
overflow-x: hidden;
}
*/
} }
/* phone landscape */ /* phone landscape */
@media all and (max-width: 960px) { @media all and (max-width: 960px) {
/*header*/ /*header*/
@ -71,45 +77,50 @@
width: 35%; width: 35%;
clear: left; clear: left;
} }
.header-breakpoint.ui-grid-b .ui-block-b { .header-breakpoint.ui-grid-b .ui-block-b {
display: none; display: none;
} }
.header-breakpoint.ui-grid-b .ui-block-c { .header-breakpoint.ui-grid-b .ui-block-c {
width: 33%; width: 33%;
} }
/*playlists*/ /*playlists*/
.pl-breakpoint .ui-block-a, .pl-breakpoint .ui-block-b { .pl-breakpoint .ui-block-a, .pl-breakpoint .ui-block-b {
width: 100%; width: 100%;
} }
/*search*/ /*search*/
.srch-breakpoint.ui-grid-a .ui-block-a, .srch-breakpoint.ui-grid-a .ui-block-b { .srch-breakpoint.ui-grid-a .ui-block-a, .srch-breakpoint.ui-grid-a .ui-block-b {
width: 100%; width: 100%;
} }
/* .scroll {
width: 100%;
heigth: 99%;
}
*/
#playlisttracksback { #playlisttracksback {
display:block; display:block;
} }
#playlisttracksdiv { #playlisttracksdiv {
display:none; display:none;
} }
#playlistslistdiv { #playlistslistdiv {
display:block; display:block;
} }
} }
/*********** /*****************************
* Side Panel and Navigation * Side Panel and Navigation *
*/ *****************************/
.mainNav .fa{ .mainNav .fa{
float: right; float: right;
} }
.mainNav .navtxt{ .mainNav .navtxt{
float: left; float: left;
} }
.mainNav .navtxt:after{ .mainNav .navtxt:after{
clear: left; clear: left;
} }
@ -127,23 +138,19 @@
#contentHeadline a { #contentHeadline a {
color:white; color:white;
margin-left: 20%;
} }
#headermenubtn{ #headermenubtn {
width: 50px; padding-top: 2px;
} }
#headersearchbtn{
text-align: right; #headersearchbtn span {
}
#headersearchbtn .ui-btn-inner{
padding: 6px;
font-size: 15px; font-size: 15px;
} }
/*********************** /******************
* Track Slider * Track Slider *
***********************/ ******************/
#trackslider { #trackslider {
display: inline; display: inline;
@ -161,6 +168,12 @@
margin-right: 35px; margin-right: 35px;
} }
.ui-slider-track.ui-mini .ui-slider-handle {
height: 22px;
width: 22px;
margin: -12px 0 0 -12px;
}
.ui-slider-input { .ui-slider-input {
display: none !important; display: none !important;
} }
@ -184,9 +197,9 @@
display: inline; display: inline;
} }
/*********** /********************
* pages, content * Pages, content *
*/ ********************/
#page{ #page{
background-color: #fff; background-color: #fff;
} }
@ -199,16 +212,13 @@
display: none; display: none;
} }
#artistviewimage, #albumviewcover { #artistviewimage, #albumviewcover {
float: right; float: right;
heigth: 90px; height: 90px;
max-width: 90%; max-width: 90%;
} }
/*** home ***/ /*** home ***/
#homerows div { #homerows div {
text-align:center; text-align:center;
background-color: #2C3E50; background-color: #2C3E50;
@ -221,9 +231,9 @@
#homerows div i { #homerows div i {
font-size: 28px; font-size: 28px;
} }
/********************* /***************
* listviews * listviews *
********************/ ***************/
.table li a { .table li a {
color: #555 !important; color: #555 !important;
font-size: 80% !important; font-size: 80% !important;
@ -245,22 +255,7 @@
list-style-type:none; list-style-type:none;
} }
/*.table li:first-child { */
/*-moz-border-radius-topleft: 2px;*/
/*-moz-border-radius-topright: 2px;*/
/*-webkit-border-top-left-radius: 2px;*/
/*-webkit-border-top-right-radius: 2px;*/
/*border-top-right-radius: 2px;*/
/*border-top-left-radius: 2px;*/
/*}*/
.table li:last-child { .table li:last-child {
/*-moz-border-radius-bottomleft: 2px;*/
/*-moz-border-radius-bottomright: 2px;*/
/*-webkit-border-bottom-left-radius: 2px;*/
/*-webkit-border-bottom-right-radius: 2px;*/
/*border-bottom-left-radius: 2px;*/
/*border-bottom-right-radius: 2px;*/
border-bottom: 1px solid #CECECE; border-bottom: 1px solid #CECECE;
} }
@ -269,12 +264,12 @@
} }
.albumdivider { .albumdivider {
background-color: #ddd !important; background-color: #ddd !important;
} }
.smalldivider { .smalldivider {
font-size: 25% !important; font-size: 25% !important;
heigth: 5px !important; height: 5px !important;
background-color: #ddd !important; background-color: #ddd !important;
} }
@ -285,7 +280,6 @@
#playlistslist, #playlisttracks { #playlistslist, #playlisttracks {
margin: 0 !important; margin: 0 !important;
padding: 0 !important; padding: 0 !important;
/* border: 1px solid blue; */
} }
.albumli { .albumli {
@ -299,7 +293,7 @@
.artistcover { .artistcover {
float: right; float: right;
width: 30px; width: 30px;
heigth: 30px; height: 30px;
margin-right: 3px; margin-right: 3px;
margin-top: 3px; margin-top: 3px;
} }
@ -331,9 +325,9 @@
} }
/******************* /**********************
* Now Playing area * Now Playing area *
*******************/ **********************/
#nowPlayingFooter{ #nowPlayingFooter{
height: 50px; height: 50px;
@ -350,7 +344,7 @@
.footerControls div span { .footerControls div span {
padding-left: 3px; padding-left: 3px;
padding-right: 3px; padding-right: 3px;
height=100%; height: 100%;
vertical-align: middle; vertical-align: middle;
} }
@ -360,10 +354,9 @@
margin-right: 10px; margin-right: 10px;
} }
/************
/******************* * Popups *
* Popups ************/
*******************/
#modalalbum a, #modalartist a { #modalalbum a, #modalartist a {
color: #444; color: #444;
text-decoration: none; text-decoration: none;
@ -411,14 +404,12 @@
.ui-input-clear-hidden { .ui-input-clear-hidden {
display:block !important; display:block !important;
} }
/*************** /****************
* common use * Common use *
***************/ ****************/
#playlistspane { #playlistspane {
/* height: 90% !important;*/
margin: 0px !important; margin: 0px !important;
} }
@ -452,7 +443,7 @@ a {
float: right; float: right;
} }
/********************** /**********************
* Song information * Song information *
**********************/ **********************/
.ui-footer{ .ui-footer{
border: 0px; border: 0px;
@ -468,7 +459,7 @@ a {
#infoname { #infoname {
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
font: bold; font-weight: bold;
font-size: 14px; font-size: 14px;
} }
@ -507,9 +498,7 @@ a {
text-align: center; text-align: center;
} }
/*helper*/ /*helper*/
.hidden{ .hidden{
display: none; display: none;
} }
@ -517,7 +506,6 @@ a {
color: #efefef; color: #efefef;
} }
.settingscoll label { .settingscoll label {
font-size: 120%; font-size: 120%;
font-weight: bold; font-weight: bold;
@ -532,12 +520,14 @@ a {
.ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-open.ui-panel-content-wrap-display-reveal { .ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-open.ui-panel-content-wrap-display-reveal {
margin-right: 17em; margin-right: 17em;
} }
.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-open.ui-panel-content-wrap-display-push.ui-panel-content-fixed-toolbar-position-right, .ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-open.ui-panel-content-wrap-display-push.ui-panel-content-fixed-toolbar-position-right,
.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-open.ui-panel-content-wrap-display-reveal.ui-panel-content-fixed-toolbar-position-right, .ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-open.ui-panel-content-wrap-display-reveal.ui-panel-content-fixed-toolbar-position-right,
.ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-open.ui-panel-content-wrap-display-push.ui-panel-content-wrap-position-right, .ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-open.ui-panel-content-wrap-display-push.ui-panel-content-wrap-position-right,
.ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-open.ui-panel-content-wrap-display-reveal.ui-panel-content-wrap-position-right { .ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-open.ui-panel-content-wrap-display-reveal.ui-panel-content-wrap-position-right {
margin: 0 0 0 17em; margin: 0 0 0 17em;
} }
.ui-responsive-panel .ui-panel-dismiss-display-reveal { .ui-responsive-panel .ui-panel-dismiss-display-reveal {
display: none; display: none;
} }
@ -547,29 +537,34 @@ a {
#nowPlayingpane{ #nowPlayingpane{
padding: 15px 25px 0px 25px; padding: 15px 25px 0px 25px;
} }
#nowPlayingpane #controlspopupimage{ #nowPlayingpane #controlspopupimage{
max-width:90%; max-width:90%;
max-height:90%; max-height:90%;
} }
.nowPlaying-artistInfo { .nowPlaying-artistInfo {
font-size: 12px; font-size: 12px;
} }
.nowPlaying-artistInfo h4{ .nowPlaying-artistInfo h4{
margin: 0px; margin: 0px;
font-weight: normal; font-weight: normal;
font-size: 12px; font-size: 12px;
} }
.nowPlaying-artistInfo h3{ .nowPlaying-artistInfo h3{
margin: 0px 0px 3px 00px; margin: 0px 0px 3px 00px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
} }
#controlspopupimage{ #controlspopupimage{
max-width:90%; max-width:90%;
max-height:90%; max-height:90%;
margin-bottom: 3px; margin-bottom: 3px;
} }
#nowPlayingpane #slidercontainer { #nowPlayingpane #slidercontainer {
margin-left: -5px; margin-left: -5px;
margin-right: -5px; margin-right: -5px;
@ -583,7 +578,6 @@ a {
} }
/* disable text selection for mouse swipe */ /* disable text selection for mouse swipe */
body * { body * {
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
@ -591,23 +585,16 @@ body * {
-o-user-select: none; -o-user-select: none;
user-select: none; user-select: none;
} }
/* but fix for text input (safari certainly needs it)*/ /* but fix for text input (safari certainly needs it)*/
input[type=text] { input[type=text] {
-moz-user-select: text; -webkit-user-select: text;
-webkit-user-select: text; -moz-user-select: text;
-ms-user-select: text;
-o-user-select: text; -o-user-select: text;
user-select: text; user-select: text;
} }
/* type/source of media in listviews */
/*a[id^="spotify"] {
margin-left:20px;
background-image: url('../images/icons/play_alt_12x12.png');
border: 2px solid black;
display:block;
}
*/
.mediaicon { .mediaicon {
float: right; float: right;
} }

View File

@ -4,7 +4,6 @@
<meta charset="utf-8"> <meta charset="utf-8">
<script src="js/jquery-1.11.1.min.js"></script> <script src="js/jquery-1.11.1.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/jquery.mobile.flatui.min.css"/> <link rel="stylesheet" type="text/css" href="css/jquery.mobile.flatui.min.css"/>
<!-- <script type='application/javascript' src='js/fastclick.js'></script> -->
<script> <script>
//configuration //configuration
var isMusicBox = '{{musicbox}}' == 'True'; // Remove MusicBox only content (e.g. settings, system pages) var isMusicBox = '{{musicbox}}' == 'True'; // Remove MusicBox only content (e.g. settings, system pages)
@ -56,7 +55,7 @@
<meta name="author" content="Wouter van Wijk" /> <meta name="author" content="Wouter van Wijk" />
<meta name="copyright" content="(c) 2012-2015 Wouter van Wijk" /> <meta name="copyright" content="(c) 2012-2015 Wouter van Wijk" />
<link href="css/webclient.css" rel="stylesheet" /> <link href="css/webclient.css" rel="stylesheet" />
<link href="css/jquery.mobile.iscrollview.min.css" rel="stylesheet" /> <link href="css/jquery.mobile.iscrollview.css" rel="stylesheet" />
<link rel="stylesheet" href="css/font-awesome.min.css" /> <link rel="stylesheet" href="css/font-awesome.min.css" />
</head> </head>
@ -117,7 +116,7 @@
</li> </li>
<li id="" data-icon="false"> <li id="" data-icon="false">
<div><!-- slider for volume --> <div><!-- slider for volume -->
<a href="#" onclick="toggleMute(); return false;"><span title="Toggle mute"><i id="mutebt" class="fa fa-volume-up"></i></span></a> <a href="#" onclick="doMute(); return false;"><span title="Toggle mute"><i id="mutebt" class="fa fa-volume-up"></i></span></a>
<label for="volumeslider" class="ui-hidden-accessible">Volume</label> <label for="volumeslider" class="ui-hidden-accessible">Volume</label>
<input id="volumeslider" data-highlight="true" name="volumeslider" data-mini="true" type="range" min="0" <input id="volumeslider" data-highlight="true" name="volumeslider" data-mini="true" type="range" min="0"
value="0" max="100" onchange="doVolume(this.value);"/> value="0" max="100" onchange="doVolume(this.value);"/>
@ -223,11 +222,10 @@
<div data-role="header" data-tap-toggle="false" id="header" data-position="fixed" class="ui-grid-b header-breakpoint headerbtn"> <div data-role="header" data-tap-toggle="false" id="header" data-position="fixed" class="header-breakpoint headerbtn">
<a href="#panel" style="margin-left: -12px; padding-top: 2px;" id="headermenubtn"><i class="fa fa-align-justify"></i></a> <a id="headermenubtn" href="#panel"><i class="fa fa-align-justify"></i></a>
<h1 id="contentHeadline">Musicbox</h1> <h1 id="contentHeadline">Musicbox</h1>
<a id="headersearchbtn" href="#" class="ui-btn-icon-right headerbtn" onclick="switchContent('search' ); return false;" title="Search"> <a id="headersearchbtn" href="#" onclick="switchContent('search' ); return false;" title="Search"><i class="fa fa-search"></i></a>
<i class="fa fa-search"></i></a>
</div> </div>
<!-- /header --> <!-- /header -->
@ -476,15 +474,12 @@
<!-- /page one --> <!-- /page one -->
<script type="text/javascript" src="../mopidy/mopidy.min.js"></script> <script type="text/javascript" src="../mopidy/mopidy.min.js"></script>
<script type="text/javascript" src="js/iscroll-lite.js"></script> <script type="text/javascript" src="js/iscroll-lite.js"></script>
<!-- <script type="text/javascript" src="js/jquery.mobile.iscrollview-closure-min.js"></script> -->
<script src="js/jquery.cookie.js"></script> <script src="js/jquery.cookie.js"></script>
<script src="js/jquery.truncate.min.js"></script> <script src="js/jquery.truncate.min.js"></script>
<!-- <script type="text/javascript" src="js/add2home.js" charset="utf-8"></script> -->
<script src="js/controls.js"></script> <script src="js/controls.js"></script>
<script src="js/library.js"></script> <script src="js/library.js"></script>
<script src="js/functionsvars.js"></script> <script src="js/functionsvars.js"></script>
<script src="js/process_ws.js"></script> <script src="js/process_ws.js"></script>
<script src="js/streamuris.js"></script>
<!-- use lastfm --> <!-- use lastfm -->
<script type="text/javascript" src="js/lastfm.api.md5.js"></script> <script type="text/javascript" src="js/lastfm.api.md5.js"></script>

View File

@ -1,6 +1,6 @@
/******************************************************** /***********************************
* play tracks from a browse list * play tracks from a browse list *
*********************************************************/ ***********************************/
function playBrowsedTracks(action, trackIndex) { function playBrowsedTracks(action, trackIndex) {
$('#popupBrowse').popup('close'); $('#popupBrowse').popup('close');
toast('Loading...'); toast('Loading...');
@ -32,7 +32,7 @@ function playBrowsedTracks(action, trackIndex) {
var maybePlay = function(tlTracks) { var maybePlay = function(tlTracks) {
if (action === PLAY_NOW || action === PLAY_ALL) { if (action === PLAY_NOW || action === PLAY_ALL) {
var playIndex = (action === PLAY_ALL) ? trackIndex : 0; var playIndex = (action === PLAY_ALL) ? trackIndex : 0;
mopidy.playback.play(tlTracks[playIndex]); mopidy.playback.play({'tl_track': tlTracks[playIndex]});
} }
}; };
@ -40,13 +40,13 @@ function playBrowsedTracks(action, trackIndex) {
case PLAY_NOW: case PLAY_NOW:
case PLAY_NEXT: case PLAY_NEXT:
mopidy.tracklist.index().then(function (currentIndex) { mopidy.tracklist.index().then(function (currentIndex) {
mopidy.tracklist.add(null, currentIndex + 1, null, trackUris).then(maybePlay); mopidy.tracklist.add({'at_position': currentIndex + 1, 'uris': trackUris}).then(maybePlay);
}); });
break; break;
case ADD_THIS_BOTTOM: case ADD_THIS_BOTTOM:
case ADD_ALL_BOTTOM: case ADD_ALL_BOTTOM:
case PLAY_ALL: case PLAY_ALL:
mopidy.tracklist.add(null, null, null, trackUris).then(maybePlay); mopidy.tracklist.add({'uris': trackUris}).then(maybePlay);
break; break;
default: default:
break; break;
@ -54,10 +54,9 @@ function playBrowsedTracks(action, trackIndex) {
return false; return false;
} }
/*********************************
/******************************************************** * play an uri from a tracklist *
* play an uri from a tracklist *********************************/
*********************************************************/
function playTrack(action) { function playTrack(action) {
var hash = document.location.hash.split('?'); var hash = document.location.hash.split('?');
var divid = hash[0].substr(1); var divid = hash[0].substr(1);
@ -92,21 +91,21 @@ function playTrack(action) {
case PLAY_NOW: case PLAY_NOW:
case PLAY_NOW_SEARCH: case PLAY_NOW_SEARCH:
mopidy.tracklist.clear().then( mopidy.tracklist.clear().then(
mopidy.tracklist.add(null, null, null, trackUris).then( mopidy.tracklist.add({'uris': trackUris}).then(
function(tlTracks) { function(tlTracks) {
mopidy.playback.play(tlTracks[selected]) mopidy.playback.play({'tl_track': tlTracks[selected]})
} }
) )
); );
break; break;
case PLAY_NEXT: case PLAY_NEXT:
mopidy.tracklist.index().then(function(currentIndex) { mopidy.tracklist.index().then(function(currentIndex) {
mopidy.tracklist.add(null, currentIndex + 1, null, trackUris); mopidy.tracklist.add({'at_position': currentIndex + 1, 'uris': trackUris});
}); });
break; break;
case ADD_THIS_BOTTOM: case ADD_THIS_BOTTOM:
case ADD_ALL_BOTTOM: case ADD_ALL_BOTTOM:
mopidy.tracklist.add(null, null, null, trackUris); mopidy.tracklist.add({'uris': trackUris});
break; break;
} }
return false; return false;
@ -123,7 +122,7 @@ function playTrackByUri(track_uri, playlist_uri) {
// Find track that was selected // Find track that was selected
for (var selected = 0; selected < tltracks.length; selected++) { for (var selected = 0; selected < tltracks.length; selected++) {
if (tltracks[selected].track.uri == track_uri) { if (tltracks[selected].track.uri == track_uri) {
mopidy.playback.play(tltracks[selected]); mopidy.playback.play({'tl_track': tltracks[selected]});
return; return;
} }
} }
@ -142,11 +141,11 @@ function playTrackByUri(track_uri, playlist_uri) {
toast('Loading...'); toast('Loading...');
mopidy.tracklist.add(null, null, playlist_uri).then(function(tltracks) { mopidy.tracklist.add({'uris': [playlist_uri]}).then(function(tltracks) {
// Can fail for all sorts of reasons. If so, just add individually. // Can fail for all sorts of reasons. If so, just add individually.
if (tltracks.length == 0) { if (tltracks.length == 0) {
var trackUris = getTracksFromUri(playlist_uri, false); var trackUris = getTracksFromUri(playlist_uri, false);
mopidy.tracklist.add(null, null, null, trackUris).then(findAndPlayTrack); mopidy.tracklist.add({'uris': trackUris}).then(findAndPlayTrack);
} else { } else {
findAndPlayTrack(tltracks); findAndPlayTrack(tltracks);
} }
@ -165,7 +164,6 @@ function playTrackByUri(track_uri, playlist_uri) {
* @returns {boolean} * @returns {boolean}
*/ */
function playTrackQueueByTlid(uri, tlid) { function playTrackQueueByTlid(uri, tlid) {
// console.log('playquuri');
//stop directly, for user feedback //stop directly, for user feedback
mopidy.playback.stop(); mopidy.playback.stop();
$('#popupQueue').popup('close'); $('#popupQueue').popup('close');
@ -177,7 +175,7 @@ function playTrackQueueByTlid(uri, tlid) {
}).then( }).then(
function(tltracks) { function(tltracks) {
if (tltracks.length > 0) { if (tltracks.length > 0) {
mopidy.playback.play(tltracks[0]); mopidy.playback.play({'tl_track': tltracks[0]});
return; return;
} }
console.log('Failed to play selected track ', tlid); console.log('Failed to play selected track ', tlid);
@ -191,22 +189,21 @@ function playTrackQueueByTlid(uri, tlid) {
* @returns {boolean} * @returns {boolean}
*/ */
function playTrackQueue() { function playTrackQueue() {
// console.log('playqu');
uri = $('#popupQueue').data("track"); uri = $('#popupQueue').data("track");
tlid = $('#popupQueue').data("tlid"); tlid = $('#popupQueue').data("tlid");
return playTrackQueueByTlid(uri, tlid); return playTrackQueueByTlid(uri, tlid);
} }
/******************************************************** /***********************************
* remove a track from the queue * remove a track from the queue *
*********************************************************/ ***********************************/
function removeTrack() { function removeTrack() {
$('#popupQueue').popup('close'); $('#popupQueue').popup('close');
toast('Deleting...'); toast('Deleting...');
tlid = parseInt($('#popupQueue').data("tlid")); tlid = parseInt($('#popupQueue').data("tlid"));
console.log(tlid); console.log(tlid);
mopidy.tracklist.remove({'tlid':[tlid]}); mopidy.tracklist.remove({'tlid': [tlid]});
} }
function clearQueue() { function clearQueue() {
@ -228,9 +225,9 @@ function saveQueue() {
exists = exists || existing[i].uri.indexOf("m3u:") == 0 || existing[i].uri.indexOf("local:") == 0; exists = exists || existing[i].uri.indexOf("m3u:") == 0 || existing[i].uri.indexOf("local:") == 0;
} }
if (!exists || window.confirm("Overwrite existing playlist \"" + plname + "\"?")) { if (!exists || window.confirm("Overwrite existing playlist \"" + plname + "\"?")) {
mopidy.playlists.create(plname, "local").then(function(playlist) { mopidy.playlists.create({'name': plname, 'uri_scheme': "local"}).then(function(playlist) {
playlist.tracks = tracks; playlist.tracks = tracks;
mopidy.playlists.save(playlist).then(); mopidy.playlists.save({'playlist': playlist}).then();
getPlaylists(); getPlaylists();
}); });
} }
@ -241,15 +238,14 @@ function saveQueue() {
return false; return false;
} }
function refreshPlaylists() { function refreshPlaylists() {
mopidy.playlists.refresh(); mopidy.playlists.refresh();
return false; return false;
} }
/********************** /*************
* Buttons * Buttons *
*/ *************/
function doShuffle() { function doShuffle() {
mopidy.playback.stop(); mopidy.playback.stop();
@ -303,10 +299,9 @@ function backbt() {
return false; return false;
} }
/*************** /*************
* Options * Options *
***************/ *************/
function setTracklistOption(name, new_value) { function setTracklistOption(name, new_value) {
if (!new_value) { if (!new_value) {
$("#"+name+"bt").attr('style', 'color:#2489ce'); $("#"+name+"bt").attr('style', 'color:#2489ce');
@ -341,27 +336,26 @@ function setSingle(nwsingle) {
} }
function doRandom() { function doRandom() {
mopidy.tracklist.setRandom(!random).then(); mopidy.tracklist.setRandom({'value': !random}).then();
} }
function doRepeat() { function doRepeat() {
mopidy.tracklist.setRepeat(!repeat).then(); mopidy.tracklist.setRepeat({'value': !repeat}).then();
} }
function doConsume() { function doConsume() {
mopidy.tracklist.setConsume(!consume).then(); mopidy.tracklist.setConsume({'value': !consume}).then();
} }
function doSingle() { function doSingle() {
mopidy.tracklist.setSingle(!single).then(); mopidy.tracklist.setSingle({'value': !single}).then();
} }
/********************* /***********************************************
* Track Slider * Track Slider *
* Use a timer to prevent looping of commands * Use a timer to prevent looping of commands *
*********************/ ***********************************************/
function doSeekPos(value) { function doSeekPos(value) {
var val = $("#trackslider").val(); var val = $("#trackslider").val();
newposition = Math.round(val); newposition = Math.round(val);
@ -377,10 +371,7 @@ function doSeekPos(value) {
function triggerPos() { function triggerPos() {
if (mopidy) { if (mopidy) {
posChanging = true; posChanging = true;
// mopidy.playback.pause(); mopidy.playback.seek({'time_position': newposition});
// console.log(newposition);
mopidy.playback.seek(newposition);
// mopidy.playback.resume();
resumePosTimer(); resumePosTimer();
posChanging = false; posChanging = false;
} }
@ -402,10 +393,10 @@ function setPosition(pos) {
$("#songelapsed").html(timeFromSeconds(currentposition / 1000)); $("#songelapsed").html(timeFromSeconds(currentposition / 1000));
} }
/******************** /***********************************************
* Volume slider * Volume slider *
* Use a timer to prevent looping of commands * Use a timer to prevent looping of commands *
*/ ***********************************************/
function setVolume(value) { function setVolume(value) {
if ($("#volumeslider").val() != value) { if ($("#volumeslider").val() != value) {
@ -420,30 +411,33 @@ function doVolume(value) {
} }
function triggerVolume() { function triggerVolume() {
mopidy.playback.setVolume(parseInt(volumeChanging)); mopidy.playback.setVolume({'volume': parseInt(volumeChanging)});
volumeChanging = 0; volumeChanging = 0;
} }
function toggleMute() { function setMute(nwmute) {
mopidy.mixer.getMute().then(function(mute) { if (mute != nwmute) {
mopidy.mixer.setMute(!mute); mute = nwmute;
if (mute) { if (mute) {
$("#mutebt").attr('class', 'fa fa-volume-up');
} else {
$("#mutebt").attr('class', 'fa fa-volume-off'); $("#mutebt").attr('class', 'fa fa-volume-off');
} else {
$("#mutebt").attr('class', 'fa fa-volume-up');
} }
}); }
} }
/******* function doMute() {
* Track position timer mopidy.mixer.setMute({'mute': !mute});
*/ }
/**************************
* Track position timer *
**************************/
//timer function to update interface //timer function to update interface
function updatePosTimer() { function updatePosTimer() {
currentposition += TRACK_TIMER; currentposition += TRACK_TIMER;
setPosition(currentposition); setPosition(currentposition);
// $("#songelapsed").html(timeFromSeconds(currentposition / 1000));
} }
function resumePosTimer() { function resumePosTimer() {
@ -463,9 +457,9 @@ function pausePosTimer() {
clearInterval(posTimer); clearInterval(posTimer);
} }
/********************************* /************
* Stream * Stream *
*********************************/ ************/
function streamPressed(key) { function streamPressed(key) {
if (key == 13) { if (key == 13) {
playStreamUri(); playStreamUri();
@ -489,7 +483,7 @@ function playStreamUri(uri) {
document.activeElement.blur(); document.activeElement.blur();
clearQueue(); clearQueue();
$("input").blur(); $("input").blur();
mopidy.tracklist.add(null, null, nwuri); mopidy.tracklist.add({'uris': [nwuri]});
mopidy.playback.play(); mopidy.playback.play();
} else { } else {
toast('No valid url!'); toast('No valid url!');
@ -510,27 +504,40 @@ function getCurrentlyPlaying() {
return true; return true;
} }
function getUriSchemes() {
uriSchemes = {};
return mopidy.getUriSchemes().then(function(schemes) {
for (var i = 0; i < schemes.length; i++) {
uriSchemes[schemes[i].toLowerCase()] = true;
}
});
}
function getPlaylistByName(name, scheme, create) { function getPlaylistByName(name, scheme, create) {
var uri_scheme = scheme || ''; var uri_scheme = scheme || '';
var uri = ''; var uri = '';
if (uri_scheme && !uriSchemes[uri_scheme]) {
return Mopidy.when(false);
}
return mopidy.playlists.asList().catch(console.error.bind(console)).then(function(plists) { return mopidy.playlists.asList().catch(console.error.bind(console)).then(function(plists) {
for (var i = 0; i < plists.length; i++) { for (var i = 0; i < plists.length; i++) {
if ((plists[i].name === name) && (scheme === '' || getScheme(plists[i].uri) === scheme)) { if ((plists[i].name === name) && (uri_scheme === '' || getScheme(plists[i].uri) === uri_scheme)) {
return plists[i]; return plists[i];
} }
} }
if (create) { if (create) {
return mopidy.playlists.create(name, scheme).done(function(plist) { return mopidy.playlists.create({'name': name, 'uri_scheme': uri_scheme}).done(function(plist) {
console.log("Created playlist '%s'", plist.name); console.log("Created playlist '%s'", plist.name);
return plist; return plist;
}); });
} }
console.log("Can't find playist '%s", name); console.log("Can't find playist '%s", name);
return Mopidy.when(false);
}); });
} }
function getPlaylistFull(uri) { function getPlaylistFull(uri) {
return mopidy.playlists.lookup(uri).then(function(pl) { return mopidy.playlists.lookup({'uri': uri}).then(function(pl) {
playlists[uri] = pl; playlists[uri] = pl;
return pl; return pl;
}); });
@ -540,33 +547,39 @@ function getFavourites() {
return getPlaylistByName(STREAMS_PLAYLIST_NAME, return getPlaylistByName(STREAMS_PLAYLIST_NAME,
STREAMS_PLAYLIST_SCHEME, STREAMS_PLAYLIST_SCHEME,
true).then(function(playlist) { true).then(function(playlist) {
return getPlaylistFull(playlist.uri); if (playlist) {
return getPlaylistFull(playlist.uri);
}
return Mopidy.when(false);
});
}
function addToFavourites(newTracks) {
getFavourites().catch(console.error.bind(console)).then(function(favourites) {
if (favourites) {
if (favourites.tracks) {
Array.prototype.push.apply(favourites.tracks, newTracks)
} else {
favourites.tracks = newTracks;
}
mopidy.playlists.save({'playlist': favourites}).then(function(s) {
showFavourites();
});
}
}); });
} }
function addFavourite(uri, name) { function addFavourite(uri, name) {
var uri = uri || $('#streamuriinput').val().trim(); var uri = uri || $('#streamuriinput').val().trim();
var name = name || $('#streamnameinput').val().trim(); var name = name || $('#streamnameinput').val().trim();
mopidy.library.lookup(null, [uri]).then(function(results) { mopidy.library.lookup({'uris': [uri]}).then(function(results) {
var newTracks = results[uri]; var newTracks = results[uri];
if (newTracks.length == 1) { if (newTracks.length == 1) {
// TODO: Supporting adding an entire playlist? // TODO: Supporting adding an entire playlist?
if (name) { if (name) {
newTracks[0].name = name; // User overrides name. newTracks[0].name = name; // User overrides name.
} }
getFavourites().then(function(favourites) { addToFavourites(newTracks);
if (favourites) {
if (favourites.tracks) {
//Array.prototype.push.apply(favourites.tracks, newTracks)
favourites.tracks.push(newTracks[0]);
} else {
favourites.tracks = [newTracks[0]];
}
mopidy.playlists.save(favourites).then(function(s) {
showFavourites();
});
}
});
} else { } else {
if (newTracks.length == 0) { if (newTracks.length == 0) {
console.log('No tracks to add'); console.log('No tracks to add');
@ -583,7 +596,7 @@ function deleteFavourite(index) {
var name = favourites.tracks[index].name; var name = favourites.tracks[index].name;
if (confirm("Are you sure you want to remove '" + name + "'?")) { if (confirm("Are you sure you want to remove '" + name + "'?")) {
favourites.tracks.splice(index, 1); favourites.tracks.splice(index, 1);
mopidy.playlists.save(favourites).then(function(s) { mopidy.playlists.save({'playlist': favourites}).then(function(s) {
showFavourites(); showFavourites();
}); });
} }
@ -594,22 +607,65 @@ function deleteFavourite(index) {
function showFavourites() { function showFavourites() {
$('#streamuristable').empty(); $('#streamuristable').empty();
getFavourites().then(function(favourites) { getFavourites().then(function(favourites) {
if (favourites && favourites.tracks) { if (!favourites) {
tracks = favourites.tracks; return;
var tmp = ''; }
var tmp = '';
$.cookie.json = true;
if ($.cookie('streamUris')) {
tmp = '<button class="btn" style="padding: 5px; width: 100%" type="button" onclick="return upgradeStreamUrisToFavourites();">Convert StreamUris</button>'
}
if (favourites.tracks) {
var child = ''; var child = '';
for (var i = 0; i < tracks.length; i++) { for (var i = 0; i < favourites.tracks.length; i++) {
child = '<li><span class="ui-icon ui-icon-delete ui-icon-shadow" style="float:right; margin: .5em; margin-top: .8em;"><a href="#" onclick="return deleteFavourite(\'' + i + '\');">&nbsp;</a></span>' + child = '<li><span class="ui-icon ui-icon-delete ui-icon-shadow" style="float:right; margin: .5em; margin-top: .8em;"><a href="#" onclick="return deleteFavourite(\'' + i + '\');">&nbsp;</a></span>' +
'<i class="fa fa-rss" style="float: left; padding: .5em; padding-top: 1em;"></i>' + '<i class="fa fa-rss" style="float: left; padding: .5em; padding-top: 1em;"></i>' +
' <a style="margin-left: 20px" href="#" onclick="return playStreamUri(\'' + tracks[i].uri + '\');">'; ' <a style="margin-left: 20px" href="#" onclick="return playStreamUri(\'' + favourites.tracks[i].uri + '\');">';
child += '<h1>' + tracks[i].name + '</h1></a></li>'; child += '<h1>' + favourites.tracks[i].name + '</h1></a></li>';
tmp += child; tmp += child;
} }
$('#streamuristable').html(tmp);
} }
$('#streamuristable').html(tmp);
}); });
} }
// TODO: Remove this upgrade path in next major release.
function upgradeStreamUrisToFavourites() {
toast('Converting streamUris...');
$.cookie.json = true;
var streamUris = $.cookie('streamUris'); // Read the cookie.
if (streamUris) {
var uris = []; // Prepare a list of uris to lookup.
for (var key in streamUris) {
var rs = streamUris[key];
if (rs) {
uris.push(rs[1]);
}
}
mopidy.library.lookup({'uris': uris}).then(function(results) {
var tracks = []; // Prepare a list of tracks to add.
for (var key in streamUris) {
var rs = streamUris[key];
if (rs) {
var track = results[rs[1]][0];
if (track) {
track.name = rs[0] || track.name; // Use custom name if provided.
tracks.push(track);
} else {
console.log("Skipping unplayable streamUri " + rs[1]);
}
}
}
addToFavourites(tracks);
$.cookie('streamUris', null); // Delete the cookie now we're done.
console.log(tracks.length + " streamUris added to favourites");
});
} else {
console.log("No streamUris cookie found");
}
}
function haltSystem() { function haltSystem() {
$.post("/settings/shutdown"); $.post("/settings/shutdown");
toast('Stopping system...', 10000); toast('Stopping system...', 10000);

View File

@ -13,7 +13,7 @@ var repeat;
var consume; var consume;
var single; var single;
var currentVolume = -1; var currentVolume = -1;
var muteVolume = -1; var mute;
var volumeChanging = false; var volumeChanging = false;
var posChanging = false; var posChanging = false;
@ -28,7 +28,7 @@ var songlength = 0;
var artistshtml = ''; var artistshtml = '';
var artiststext = ''; var artiststext = '';
var songname = ''; var songname = '';
var songdata = {'track':{}, 'tlid':-1}; var songdata = {'track': {}, 'tlid': -1};
var newposition = 0; var newposition = 0;
var playlisttracksScroll; var playlisttracksScroll;
@ -36,6 +36,7 @@ var playlistslistScroll;
var STREAMS_PLAYLIST_NAME = '[Radio Streams]'; var STREAMS_PLAYLIST_NAME = '[Radio Streams]';
var STREAMS_PLAYLIST_SCHEME = 'm3u'; var STREAMS_PLAYLIST_SCHEME = 'm3u';
var uriSchemes = {};
//array of cached playlists (not only user-playlists, also search, artist, album-playlists) //array of cached playlists (not only user-playlists, also search, artist, album-playlists)
var playlists = {}; var playlists = {};
@ -53,7 +54,6 @@ var ua = navigator.userAgent,
//constants //constants
PROGRAM_NAME = 'MusicBox'; PROGRAM_NAME = 'MusicBox';
//PROGRAM_NAME = 'Mopidy';
ARTIST_TABLE = '#artiststable'; ARTIST_TABLE = '#artiststable';
ALBUM_TABLE = '#albumstable'; ALBUM_TABLE = '#albumstable';
PLAYLIST_TABLE = '#playlisttracks'; PLAYLIST_TABLE = '#playlisttracks';
@ -127,10 +127,6 @@ function scrollToTop() {
} }
function scrollToTracklist() { function scrollToTracklist() {
/* if (isMobileWebkit) {
playlistslistScroll.refresh();
}
*/
var divtop = $("#playlisttracksdiv").offset().top - 120; var divtop = $("#playlisttracksdiv").offset().top - 120;
$('body,html').animate({ $('body,html').animate({
scrollTop: divtop scrollTop: divtop
@ -198,12 +194,10 @@ function renderSongLi(song, liID, uri) {
} else { } else {
name = song.name; name = song.name;
} }
// var iconClass = getMediaClass(liID.split('-')[1]);
songLi = '<li class="song albumli" id="' + liID + '">' + songLi = '<li class="song albumli" id="' + liID + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\',\'' + song.uri + '\');">' + '<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\',\'' + song.uri + '\');">' +
'<i class="fa fa-ellipsis-v"></i></a>' + '<i class="fa fa-ellipsis-v"></i></a>' +
'<a href="#" onclick="return playTrackByUri(\'' + song.uri + '\',\'' + uri + '\');">' + '<a href="#" onclick="return playTrackByUri(\'' + song.uri + '\',\'' + uri + '\');">' +
// '<h1 class="trackname"><i class="' + iconClass + '"></i> ' + name + '</h1>' +
'<h1 class="trackname">' + name + '</h1></a>' + '<h1 class="trackname">' + name + '</h1></a>' +
'</li>'; '</li>';
return songLi; return songLi;
@ -217,12 +211,10 @@ function renderQueueSongLi(song, liID, uri, tlid) {
} else { } else {
name = song.name; name = song.name;
} }
// var iconClass = getMediaClass(liID.split('-')[1]);
songLi = '<li class="song albumli" id="' + liID + '" tlid="' + tlid + '">' + songLi = '<li class="song albumli" id="' + liID + '" tlid="' + tlid + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\',\'' + song.uri + '\',\'' + tlid + '\');">' + '<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\',\'' + song.uri + '\',\'' + tlid + '\');">' +
'<i class="fa fa-ellipsis-v"></i></a>' + '<i class="fa fa-ellipsis-v"></i></a>' +
'<a href="#" onclick="return playTrackQueueByTlid(\'' + song.uri + '\',\'' + tlid + '\');">' + '<a href="#" onclick="return playTrackQueueByTlid(\'' + song.uri + '\',\'' + tlid + '\');">' +
// '<h1 class="trackname"><i class="' + iconClass + '"></i> ' + name + '</h1>' +
'<h1 class="trackname">' + name + '</h1></a>' + '<h1 class="trackname">' + name + '</h1></a>' +
'</li>'; '</li>';
return songLi; return songLi;
@ -310,7 +302,6 @@ function resultsToTables(results, target, uri) {
'<h1><i class="' + iconClass + '"></i> ' + newalbum[0].name + "</h1><p>"; '<h1><i class="' + iconClass + '"></i> ' + newalbum[0].name + "</h1><p>";
} }
/* '<span style="float: right;">' + timeFromSeconds(newalbum[0].length / 1000) + '</span>'; */
if (newalbum[0].artists) { if (newalbum[0].artists) {
for (j = 0; j < newalbum[0].artists.length; j++) { for (j = 0; j < newalbum[0].artists.length; j++) {
html += newalbum[0].artists[j].name; html += newalbum[0].artists[j].name;
@ -333,7 +324,6 @@ function resultsToTables(results, target, uri) {
newtlids = []; newtlids = [];
} else { //newalbum length } else { //newalbum length
if (results[i].album.uri && results[i].album.name) { if (results[i].album.uri && results[i].album.name) {
// iconClass = getMediaClass(results[i].album.uri);
iconClass = getMediaClass(newalbum[0].uri); iconClass = getMediaClass(newalbum[0].uri);
html += '<li class="albumdivider">'; html += '<li class="albumdivider">';
html += '<a href="#" onclick="return showAlbum(\'' + results[i].album.uri + '\');"><img id="' + html += '<a href="#" onclick="return showAlbum(\'' + results[i].album.uri + '\');"><img id="' +
@ -353,8 +343,6 @@ function resultsToTables(results, target, uri) {
html += '</p></a></li>'; html += '</p></a></li>';
for (j = 0; j < newalbum.length; j++) { for (j = 0; j < newalbum.length; j++) {
popupData[newalbum[j].uri] = newalbum[j]; popupData[newalbum[j].uri] = newalbum[j];
// html += '<li class="albumli" id="' + targetmin + '-' + newalbum[j].uri + '"><a href="#" onclick="return ' + popupMenu + '(event, \'' + uri + '\',\'' + newalbum[j].uri + '\');">';
//hERE! //hERE!
var liID = targetmin + '-' + newalbum[j].uri; var liID = targetmin + '-' + newalbum[j].uri;
if (target == CURRENT_PLAYLIST_TABLE) { if (target == CURRENT_PLAYLIST_TABLE) {
@ -362,9 +350,6 @@ function resultsToTables(results, target, uri) {
} else { } else {
html += renderSongLi(newalbum[j], liID, uri); html += renderSongLi(newalbum[j], liID, uri);
} }
//html += '<li class="albumli" id="' + targetmin + '-' + newalbum[j].uri + '"><a href="#" onclick="return popupTracks(event, \'' + uri + '\',\'' + newalbum[j].uri + '\');">';
//html += '<p class="pright">' + timeFromSeconds(newalbum[j].length / 1000) + '</p><h1>' + newalbum[j].name + '</h1></a></li>';
} }
newalbum = []; newalbum = [];
newtlids = []; newtlids = [];
@ -383,7 +368,6 @@ function resultsToTables(results, target, uri) {
$(target).attr('data', uri); $(target).attr('data', uri);
//retreive albumcovers //retreive albumcovers
for (i = 0; i < coversList.length; i++) { for (i = 0; i < coversList.length; i++) {
// console.log(coversList[i]);
getCover(coversList[i][0], target + '-cover-' + coversList[i][1], 'small'); getCover(coversList[i][0], target + '-cover-' + coversList[i][1], 'small');
} }
} }
@ -401,7 +385,6 @@ function playlisttotable(pl, target, uri) {
child += '<h1>' + pl[i].name + "</h1>"; child += '<h1>' + pl[i].name + "</h1>";
child += '<p>'; child += '<p>';
child += '<span style="float: right;">' + timeFromSeconds(pl[i].length / 1000) + '</span>'; child += '<span style="float: right;">' + timeFromSeconds(pl[i].length / 1000) + '</span>';
// <span class="ui-icon ui-icon-arrow-r ui-icon-shadow">&nbsp;</span>
for (var j = 0; j < pl[i].artists.length; j++) { for (var j = 0; j < pl[i].artists.length; j++) {
if (pl[i].artists[j]) { if (pl[i].artists[j]) {
child += pl[i].artists[j].name; child += pl[i].artists[j].name;
@ -428,8 +411,8 @@ function getPlaylistTracks(uri) {
return Mopidy.when(playlists[uri].tracks); return Mopidy.when(playlists[uri].tracks);
} else { } else {
showLoading(true); showLoading(true);
return mopidy.playlists.getItems(uri).then(function(refs) { return mopidy.playlists.getItems({'uri': uri}).then(function(refs) {
return processPlaylistItems({'uri':uri, 'items':refs}); return processPlaylistItems({'uri': uri, 'items': refs});
}, console.error); }, console.error);
} }
} }
@ -463,7 +446,6 @@ function timeFromSeconds(length) {
return ((h > 0 ? h + ":" : "") + (m > 0 ? (h > 0 && m < 10 ? "0" : "") + m + ":" : "0:") + (s < 10 ? "0" : "") + s); return ((h > 0 ? h + ":" : "") + (m > 0 ? (h > 0 && m < 10 ? "0" : "") + m + ":" : "0:") + (s < 10 ? "0" : "") + s);
} }
/******* Toast ***/ /******* Toast ***/
function toast(message, delay, textOnly) { function toast(message, delay, textOnly) {
textOnl = textOnly || false; textOnl = textOnly || false;
@ -482,9 +464,9 @@ function toast(message, delay, textOnly) {
} }
} }
/***************** /******************
* Modal dialogs * Modal dialogs *
*****************/ ******************/
function showLoading(on) { function showLoading(on) {
if (on) { if (on) {
$("body").css("cursor", "progress"); $("body").css("cursor", "progress");
@ -515,7 +497,6 @@ function showOffline(on) {
// from http://dzone.com/snippets/validate-url-regexp // from http://dzone.com/snippets/validate-url-regexp
function validUri(str) { function validUri(str) {
var regexp = /^(mms|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ var regexp = /^(mms|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
// return regexp.test(str) || isServiceUri(str);
return regexp.test(str); return regexp.test(str);
} }

View File

@ -4,7 +4,7 @@
* show- functions do both * show- functions do both
*/ */
/******************** /********************
* Song Info Sreen * Song Info Sreen *
********************/ ********************/
function resetSong() { function resetSong() {
if (!posChanging) { if (!posChanging) {
@ -148,9 +148,9 @@ function setSongInfo(data) {
resizeMb(); resizeMb();
} }
/*************** /******************
* display popups * display popups *
*/ ******************/
function closePopups() { function closePopups() {
$('#popupTracks').popup('close'); $('#popupTracks').popup('close');
$('#artistpopup').popup('close'); $('#artistpopup').popup('close');
@ -159,7 +159,6 @@ function closePopups() {
$('#controlspopup').popup('close'); $('#controlspopup').popup('close');
} }
function popupTracks(e, listuri, trackuri, tlid) { function popupTracks(e, listuri, trackuri, tlid) {
if (!e) if (!e)
var e = window.event; var e = window.event;
@ -222,9 +221,9 @@ function showAlbumPopup(popupId) {
showAlbum(popupData[uri].album.uri); showAlbum(popupData[uri].album.uri);
} }
/********************* /**********************
* initialize sockets * initialize sockets *
*********************/ **********************/
function initSocketevents() { function initSocketevents() {
mopidy.on("state:online", function() { mopidy.on("state:online", function() {
@ -232,7 +231,9 @@ function initSocketevents() {
getCurrentPlaylist(); getCurrentPlaylist();
updateStatusOfAll(); updateStatusOfAll();
getPlaylists(); getPlaylists();
showFavourites(); getUriSchemes().then(function() {
showFavourites();
});
getBrowseDir(); getBrowseDir();
getSearchSchemes(); getSearchSchemes();
showLoading(false); showLoading(false);
@ -254,7 +255,6 @@ function initSocketevents() {
}); });
mopidy.on("event:trackPlaybackPaused", function(data) { mopidy.on("event:trackPlaybackPaused", function(data) {
//setSongInfo(data.tl_track);
pausePosTimer(); pausePosTimer();
setPlayState(false); setPlayState(false);
}); });
@ -270,6 +270,10 @@ function initSocketevents() {
} }
}); });
mopidy.on("event:muteChanged", function(data) {
setMute(data["mute"]);
});
mopidy.on("event:playbackStateChanged", function(data) { mopidy.on("event:playbackStateChanged", function(data) {
switch (data["new_state"]) { switch (data["new_state"]) {
case "stopped": case "stopped":
@ -301,9 +305,9 @@ $(document).bind("pageinit", function() {
}); });
/************************ /**************
* gui stuff * gui stuff *
************************/ **************/
function enterFullscreen() { function enterFullscreen() {
if (isMobileSafari) { alert ("To get this app in Full Screen, you have to add it to your home-screen using the Share button."); exit(); } if (isMobileSafari) { alert ("To get this app in Full Screen, you have to add it to your home-screen using the Share button."); exit(); }
var elem = document.querySelector("#page"); var elem = document.querySelector("#page");
@ -320,6 +324,7 @@ function enterFullscreen() {
} }
} }
} }
function exitFullscreen() { function exitFullscreen() {
document.webkitExitFullscreen(); document.webkitExitFullscreen();
document.mozCancelFullscreen(); document.mozCancelFullscreen();
@ -345,7 +350,6 @@ function switchContent(divid, uri) {
if (uri) { if (uri) {
hash += "?" + uri; hash += "?" + uri;
} }
// $.mobile.changePage("#" + hash);
location.hash = "#" + hash; location.hash = "#" + hash;
} }
@ -360,7 +364,6 @@ function setHeadline(site){
//update timer //update timer
function updateStatusTimer() { function updateStatusTimer() {
// console.log('statustimer');
mopidy.playback.getCurrentTlTrack().then(processCurrenttrack, console.error); mopidy.playback.getCurrentTlTrack().then(processCurrenttrack, console.error);
mopidy.playback.getTimePosition().then(processCurrentposition, console.error); mopidy.playback.getTimePosition().then(processCurrentposition, console.error);
//TODO check offline? //TODO check offline?
@ -383,6 +386,7 @@ function updateStatusOfAll() {
updateOptions() updateOptions()
mopidy.playback.getVolume().then(processVolume, console.error); mopidy.playback.getVolume().then(processVolume, console.error);
mopidy.mixer.getMute().then(processMute, console.error);
} }
function locationHashChanged() { function locationHashChanged() {
@ -442,7 +446,6 @@ function locationHashChanged() {
break; break;
} }
//switch the footer //switch the footer
switch(divid) { switch(divid) {
case 'nowPlaying': case 'nowPlaying':
@ -458,9 +461,9 @@ function locationHashChanged() {
return false; return false;
} }
/********************** /***********************
* initialize software * initialize software *
**********************/ ***********************/
$(document).ready(function(event) { $(document).ready(function(event) {
//check for websockets //check for websockets
if (!window.WebSocket) { if (!window.WebSocket) {
@ -478,13 +481,13 @@ $(document).ready(function(event) {
// Connect to server // Connect to server
if (websocketUrl) { if (websocketUrl) {
mopidy = new Mopidy({ mopidy = new Mopidy({
webSocketUrl: websocketUrl // wslocation is set in index.html from the extention config. webSocketUrl: websocketUrl, // wslocation is set in index.html from the extention config.
callingConvention: 'by-position-or-by-name'
}); });
} else { } else {
mopidy = new Mopidy(); mopidy = new Mopidy({callingConvention: 'by-position-or-by-name'});
} }
// mopidy.on(console.log.bind(console)); // Log all events
// mopidy.on(console.error.bind(console));
//initialize events //initialize events
initSocketevents(); initSocketevents();
@ -494,7 +497,6 @@ $(document).ready(function(event) {
switchContent("home"); switchContent("home");
} }
initgui = false; initgui = false;
window.onhashchange = locationHashChanged; window.onhashchange = locationHashChanged;
@ -580,7 +582,6 @@ $(document).ready(function(event) {
$.event.special.swipe.horizontalDistanceThreshold = 125; // (default: 30px) Swipe horizontal displacement must be more than this. $.event.special.swipe.horizontalDistanceThreshold = 125; // (default: 30px) Swipe horizontal displacement must be more than this.
$.event.special.swipe.verticalDistanceThreshold = 50; // (default: 75px) Swipe vertical displacement must be less than this. $.event.special.swipe.verticalDistanceThreshold = 50; // (default: 75px) Swipe vertical displacement must be less than this.
// $.event.special.swipe.scrollSupressionThreshold = 20;
$.event.special.swipe.durationThreshold = 500; $.event.special.swipe.durationThreshold = 500;
// swipe songinfo and panel // swipe songinfo and panel
@ -619,6 +620,7 @@ function updatePlayIcons (uri, tlid) {
$(this).removeClass("currenttrack2"); $(this).removeClass("currenttrack2");
} }
}); });
$('#trackresulttable li').each(function() { $('#trackresulttable li').each(function() {
if (this.id == 'trackresulttable-' + uri) { if (this.id == 'trackresulttable-' + uri) {
$(this).addClass('currenttrack2'); $(this).addClass('currenttrack2');

View File

@ -2,14 +2,13 @@
* @author Wouter van Wijk * @author Wouter van Wijk
*/ */
API_KEY= 'b6d34c3af91d62ab0ae00ab1b6fa8733'; API_KEY = 'b6d34c3af91d62ab0ae00ab1b6fa8733';
API_SECRET = '2c631802c2285d5d5d1502462fe42a2b'; API_SECRET = '2c631802c2285d5d5d1502462fe42a2b';
var fmcache; var fmcache;
var lastfm; var lastfm;
$(window).load(function () {
$(window).load(function() {
// create a Cache object // create a Cache object
fmcache = new LastFMCache(); fmcache = new LastFMCache();
// create a LastFM object // create a LastFM object
@ -20,42 +19,40 @@ $(window).load(function() {
}); });
}); });
function getCover(album, images, size) { function getCover(album, images, size) {
var defUrl = 'images/default_cover.png'; var defUrl = 'images/default_cover.png';
$(images).attr('src', defUrl); $(images).attr('src', defUrl);
if (!album) { if (!album) {
return; return;
} }
var albumname = album.name || ''; var albumname = album.name || '';
var artistname = ''; var artistname = '';
if ( album.artists && (album.artists.length > 0) ) { if ( album.artists && (album.artists.length > 0) ) {
artistname = album.artists[0].name; artistname = album.artists[0].name;
} }
// console.log(album, images); if (album.images && (album.images.length > 0) ) {
if (album.images && (album.images.length > 0) ) { $(images).attr('src', album.images[0]);
$(images).attr('src', album.images[0]); } else {
} else { lastfm.album.getInfo( {artist: artistname, album: albumname},
lastfm.album.getInfo( {artist: artistname, album: albumname}, { success: function(data){
{ success: function(data){ for (var i = 0; i < data.album.image.length; i++) {
for (var i = 0; i < data.album.image.length; i++) { if ( data.album.image[i]['size'] == size) {
if ( data.album.image[i]['size'] == size) { $(images).attr('src', data.album.image[i]['#text'] || defUrl);
$(images).attr('src', data.album.image[i]['#text'] || defUrl);
}
} }
} }
}); }
});
} }
} }
function getArtistImage(nwartist, image, size) { function getArtistImage(nwartist, image, size) {
var defUrl = 'images/user_24x32.png'; var defUrl = 'images/user_24x32.png';
lastfm.artist.getInfo({artist: nwartist}, {success: function(data){ lastfm.artist.getInfo({artist: nwartist}, {success: function(data){
for (var i = 0; i < data.artist.image.length; i++) { for (var i = 0; i < data.artist.image.length; i++) {
if ( data.artist.image[i]['size'] == size) { if ( data.artist.image[i]['size'] == size) {
$(image).attr('src', data.artist.image[i]['#text'] || defUrl); $(image).attr('src', data.artist.image[i]['#text'] || defUrl);
}
} }
}}); }
}});
} }

View File

@ -30,7 +30,7 @@ function initSearch() {
$("#searchresults").hide(); $("#searchresults").hide();
if (searchService != 'all') { if (searchService != 'all') {
mopidy.library.search({any:[value]}, [searchService + ':']).then(processSearchResults, console.error); mopidy.library.search({'query': {any:[value]}, 'uris': [searchService + ':']}).then(processSearchResults, console.error);
} else { } else {
mopidy.getUriSchemes().then(function (schemes) { mopidy.getUriSchemes().then(function (schemes) {
var query = {}, var query = {},
@ -48,7 +48,7 @@ function initSearch() {
} else { } else {
query = {any: [value]}; query = {any: [value]};
} }
mopidy.library.search(query, uris).then(processSearchResults, console.error); mopidy.library.search({'query': query, 'uris': uris}).then(processSearchResults, console.error);
}); });
} }
} }
@ -79,15 +79,6 @@ function processSearchResults(resultArr) {
var results = {'tracks': [], 'artists': [], 'albums': []}; var results = {'tracks': [], 'artists': [], 'albums': []};
var j, emptyResult = true; var j, emptyResult = true;
/* for (var i = 0; i < resultArr.length; ++i) {
for (var prop in results) {
if (resultArr[i][prop] && resultArr[i][prop].length) {
results[prop] = results[prop].concat(resultArr[i][prop]);
emptyResult = false;
}
}
}
*/
for (var i = 0; i < resultArr.length; i++) { for (var i = 0; i < resultArr.length; i++) {
if (resultArr[i].tracks) { if (resultArr[i].tracks) {
for (j = 0; j < resultArr[i].tracks.length; j++) { for (j = 0; j < resultArr[i].tracks.length; j++) {
@ -109,10 +100,6 @@ function processSearchResults(resultArr) {
} }
} }
// console.log(resultArr, results);
customTracklists[URI_SCHEME+':trackresultscache'] = results.tracks; customTracklists[URI_SCHEME+':trackresultscache'] = results.tracks;
if (emptyResult) { if (emptyResult) {
@ -196,7 +183,6 @@ function processSearchResults(resultArr) {
$('#expandsearch').show(); $('#expandsearch').show();
// Track results // Track results
// playlisttotable(results.tracks, SEARCH_TRACK_TABLE, URI_SCHEME+':trackresultscache');
resultsToTables(results.tracks, SEARCH_TRACK_TABLE, URI_SCHEME+':trackresultscache'); resultsToTables(results.tracks, SEARCH_TRACK_TABLE, URI_SCHEME+':trackresultscache');
showLoading(false); showLoading(false);
@ -225,7 +211,10 @@ function getBrowseDir(rootdir) {
} else { } else {
browseStack.push(rootdir); browseStack.push(rootdir);
} }
mopidy.library.browse(rootdir).then(processBrowseDir, console.error); if (!rootdir) {
rootdir = null;
}
mopidy.library.browse({'uri': rootdir}).then(processBrowseDir, console.error);
} }
function getCurrentPlaylist() { function getCurrentPlaylist() {
@ -261,7 +250,6 @@ function showTracklist(uri) {
$(this).addClass('playlistactive'); $(this).addClass('playlistactive');
} }
}); });
// scrollToTracklist();
return false; return false;
} }
@ -274,12 +262,12 @@ function showArtist(nwuri) {
$('#popupTracks').popup('close'); $('#popupTracks').popup('close');
$('#controlsmodal').popup('close'); $('#controlsmodal').popup('close');
$(ARTIST_TABLE).empty(); $(ARTIST_TABLE).empty();
//fill from cache
// var pl = getTracksFromUri(nwuri);
//TODO cache //TODO cache
$('#h_artistname').html(''); $('#h_artistname').html('');
showLoading(true); showLoading(true);
mopidy.library.lookup(nwuri).then(function(resultArr) { mopidy.library.lookup({'uris': [nwuri]}).then(function(resultDict) {
var resultArr = resultDict[nwuri];
resultArr.uri = nwuri; resultArr.uri = nwuri;
processArtistResults(resultArr); processArtistResults(resultArr);
}, console.error); }, console.error);
@ -304,16 +292,17 @@ function showAlbum(uri) {
$('#coverpopupalbumname').html(albumname); $('#coverpopupalbumname').html(albumname);
$('#coverpopupartist').html(artistname); $('#coverpopupartist').html(artistname);
showLoading(false); showLoading(false);
mopidy.library.lookup(uri).then(function(resultArr) { mopidy.library.lookup({'uris': [uri]}).then(function(resultDict) {
var resultArr = resultDict[uri];
resultArr.uri = uri; resultArr.uri = uri;
processAlbumResults(resultArr); processAlbumResults(resultArr);
}, console.error); }, console.error);
// getCover(pl, '#albumviewcover, #coverpopupimage', 'extralarge');
} else { } else {
showLoading(true); showLoading(true);
$('#h_albumname').html(''); $('#h_albumname').html('');
$('#h_albumartist').html(''); $('#h_albumartist').html('');
mopidy.library.lookup(uri).then(function(resultArr) { mopidy.library.lookup({'uris': [uri]}).then(function(resultDict) {
var resultArr = resultDict[uri];
resultArr.uri = uri; resultArr.uri = uri;
processAlbumResults(resultArr); processAlbumResults(resultArr);
}, console.error); }, console.error);

View File

@ -21,6 +21,13 @@ function processVolume(data) {
} }
} }
/********************************************************
* process results of mute
*********************************************************/
function processMute(data) {
setMute(data);
}
/******************************************************** /********************************************************
* process results of a repeat * process results of a repeat
*********************************************************/ *********************************************************/
@ -111,9 +118,10 @@ function processBrowseDir(resultArr) {
iconClass = getMediaClass(resultArr[i].uri); iconClass = getMediaClass(resultArr[i].uri);
if (resultArr[i].type == 'track') { if (resultArr[i].type == 'track') {
//console.log(resultArr[i]); //console.log(resultArr[i]);
mopidy.library.lookup(resultArr[i].uri).then(function (resultArr) { mopidy.library.lookup({'uris': [resultArr[i].uri]}).then(function (resultDict) {
popupData[resultArr[0].uri] = resultArr[0]; var lookup_uri = Object.keys(resultDict)[0];
browseTracks.push(resultArr[0]); popupData[lookup_uri] = resultDict[lookup_uri][0];
browseTracks.push(resultDict[lookup_uri][0]);
}, console.error); }, console.error);
child += '<li class="song albumli" id="browselisttracks-' + resultArr[i].uri + '">' + child += '<li class="song albumli" id="browselisttracks-' + resultArr[i].uri + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\', \'' + resultArr[i].uri + '\', \'' + index + '\');">' + '<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\', \'' + resultArr[i].uri + '\', \'' + index + '\');">' +
@ -132,16 +140,8 @@ function processBrowseDir(resultArr) {
$('#browselist').html(child); $('#browselist').html(child);
if (browseStack.length > 0 ) { if (browseStack.length > 0 ) {
/* child = ''; child = getMediaHuman(uri);
for (var i = 0; i < browseStack.length; i++) { iconClass = getMediaClass(uri);
child += browseStack[i] + ' / ';
}
child = getMediaHuman(browseStack[0]);
iconClass = getMediaClass(browseStack[0]);
*/
child = getMediaHuman(resultArr[0].uri);
iconClass = getMediaClass(resultArr[0].uri);
$('#browsepath').html('<i class="' + iconClass + '"></i> ' + child); $('#browsepath').html('<i class="' + iconClass + '"></i> ' + child);
} else { } else {
$('#browsepath').html(''); $('#browsepath').html('');
@ -192,7 +192,7 @@ function processPlaylistItems(resultDict) {
for (i = 0; i < resultDict.items.length; i++) { for (i = 0; i < resultDict.items.length; i++) {
trackUris.push(resultDict.items[i].uri); trackUris.push(resultDict.items[i].uri);
} }
return mopidy.library.lookup(null, trackUris).then(function(tracks) { return mopidy.library.lookup({'uris': trackUris}).then(function(tracks) {
// Transform from dict to list and cache result // Transform from dict to list and cache result
var newplaylisturi = resultDict.uri; var newplaylisturi = resultDict.uri;
playlists[newplaylisturi] = {'uri':newplaylisturi, 'tracks':[]}; playlists[newplaylisturi] = {'uri':newplaylisturi, 'tracks':[]};

View File

@ -1,17 +0,0 @@
/**
* Default streamuris which appear in the webinterface. Edit if you like.
* Take care when editting. Only edit the stuff between ''
* And don't use the default Windows Notepad for this (use Notepad++ on Windows)
*/
var streamUris = [];
//fill with defaults
streamUris.push(['NPR 24', 'http://nprdmp.ic.llnwd.net/stream/nprdmp_live01_mp3']);
streamUris.push(['3FM Dutch', 'http://icecast.omroep.nl/3fm-bb-mp3']);
streamUris.push(['BBC WorldService', 'http://vprbbc.streamguys.net:8000/vprbbc24.mp3']);
streamUris.push(['Arrow Jazz', 'http://81.173.3.132:8082']);
streamUris.push(['Queen Live Aid at Wembley (YouTube)', 'yt:http://www.youtube.com/watch?v=eQsM6u0a038']);
streamUris.push(['Groove Salad - Soma FM', 'http://somafm.com/groovesalad.pls']);
streamUris.push(['Kiss FM Berlin', 'http://stream.kissfm.de/kissfm/mp3-128/internetradio/']);
streamUris.push(['Muse - Newborn (SoundCloud)', 'sc:https://soundcloud.com/muse/01-new-born']);
streamUris.push(['Pinguin Radio', 'http://pr320.pinguinradio.com/listen.pls']);

View File

@ -1,6 +1,6 @@
CACHE MANIFEST CACHE MANIFEST
# 2016-01-26:v1 # 2016-02-04:v1
NETWORK: NETWORK:
* *
@ -74,6 +74,5 @@ js/lastfm.api.md5.js
js/lastfm.js js/lastfm.js
js/library.js js/library.js
js/process_ws.js js/process_ws.js
js/streamuris.js
mb.manifest mb.manifest
system.html system.html