better pla handling, queue

This commit is contained in:
Wouter van Wijk 2013-09-07 20:07:25 +02:00
parent df211e5bce
commit 7950bf1d57
6 changed files with 178 additions and 160 deletions

View File

@ -1,6 +1,6 @@
/*****
/*
* Mopidy Webclient CSS
* (c)
* (c) Wouter van Wijk 2012-2013
*/
/****************************
@ -80,7 +80,7 @@
}
}
/* phone */
/* phone landscape */
@media all and (max-width: 30em) {
/*header*/
.header-breakpoint.ui-grid-b .ui-block-a {
@ -110,8 +110,8 @@
}
/* phone portrait */
@media all and (max-width: 20em) {
.header-breakpoint.ui-grid-b .ui-block-c {
@media all and (max-width: 25em) {
.navtxt, .header-breakpoint.ui-grid-b .ui-block-c {
display: none;
}
#playlistspane, .scroll {
@ -402,13 +402,15 @@
text-decoration: none;
}
#popupArtistName, #popupTrackName, #popupAlbumName, .popupArtistName {
.popupArtistName, .popupTrackName, .popupAlbumName, .popupArtistName {
font-style: oblique;
}
#controlsmodal, #artistpopup, #coverpopup {
max-width: 500px;
min-width: 300px;
background: white;
padding: 5px;
}
#h_artistname {

View File

@ -42,7 +42,7 @@
<meta name="description" content="MusicBox">
<meta name="author" content="Wouter van Wijk">
<meta name="copyright" content="(c) 2012-2013 Wouter van Wijk" />
<link href="css/ws.css" rel="stylesheet">
<link href="css/webclient.css" rel="stylesheet">
<link href="css/jquery.mobile.iscrollview.css" rel="stylesheet">
<!-- <link rel="stylesheet" href="css/add2home.css"> -->
@ -102,15 +102,15 @@
<a href="#" onclick="return playTrack(ADD_ALL_BOTTOM);" id="liaddtobottom">Add all to Bottom of Queue</a>
</li>
<li>
<a href="#" onclick="showAlbumPopup()">Show Album <span id="popupAlbumName"></span></a>
<a href="#" onclick="showAlbumPopup()">Show Album <span class="popupAlbumName"></span></a>
</li>
<li id="popupArtistsLi">
<a href="#" onclick="showArtist()" id="popupArtistHref">Show Artist <span id="popupArtistName"></span>
<a href="#" onclick="showArtist()" class="popupArtistHref">Show Artist <span class="popupArtistName"></span>
</a>
</li>
<div data-role="collapsible" data-icon="false" data-inset="false" id="popupArtistsDiv">
<div data-role="collapsible" data-icon="false" data-inset="false" class="popupArtistsDiv">
<h2>Artists</h2>
<ul data-icon="false" data-inset="false" data-role="listview" id="popupArtistsLv"></ul>
<ul data-icon="false" data-inset="false" data-role="listview" class="popupArtistsLv"></ul>
</div>
</ul>
</div>
@ -120,21 +120,21 @@
<div data-role="collapsible-set">
<ul data-role="listview" data-icon="false" id="popupQueueLv">
<li>
<a href="#" onclick="return playTrack();">Play <span class="popupTrackName"></span></a>
<a href="#" onclick="return playTrackQueue();">Play <span class="popupTrackName"></span></a>
</li>
<li>
<a href="#" onclick="return removeTrack();">Remove from Queue</a>
</li>
<li>
<a href="#" onclick="showAlbumPopup()">Show Album <span id="popupAlbumName"></span></a>
<a href="#" onclick="showAlbumPopup()">Show Album <span class="popupAlbumName"></span></a>
</li>
<li id="popupArtistsLi">
<a href="#" onclick="showArtist()" id="popupArtistHref">Show Artist <span id="popupArtistName"></span>
<a href="#" onclick="showArtist()" class="popupArtistHref">Show Artist <span class="popupArtistName"></span>
</a>
</li>
<div data-role="collapsible" data-icon="false" data-inset="false" id="popupArtistsDiv">
<div data-role="collapsible" data-icon="false" data-inset="false" class="popupArtistsDiv">
<h2>Artists</h2>
<ul data-icon="false" data-inset="false" data-role="listview" id="popupArtistsLv"></ul>
<ul data-icon="false" data-inset="false" data-role="listview" class="popupArtistsLv"></ul>
</div>
</ul>
</div>
@ -239,7 +239,8 @@
<ul id="radiostationstable" class="table"></ul>
<p>Add an url of a radio station stream that you want to listen to. The last 25 stations are saved locally (not on the server yet).
You cannot use container files like M3U, ASPX or PLS (yet), you have to add the real stream
(open the container file in a text-editor to find streams).</p>
(open the container file in a text-editor to find streams).
To find stations, use e.g. <a href="http://www.listenlive.eu/" target="_blank">Listenlive</a> or <a href="http://www.dirble.com/" target="_blank">Dirble</a>.</p>
<form>
<input id="radiouriinput" placeholder="Playlist URI" class="span2" data-clear-btn="true" onkeypress="return radioPressed(event.keyCode);" id="appendedInputButton" type="text" />
<input id="radionameinput" placeholder="Name" class="span2" data-clear-btn="true" onkeypress="return radioPressed(event.keyCode);" id="appendedInputButton" type="text" />
@ -255,16 +256,16 @@
<div data-role="navbar" data-iconpos="left">
<ul>
<li id="navplaylists">
<a href="#playlists" onclick="switchContent('playlists' ); return false;"><img src="images/icons/list_nested_24x21.png" /> Playlists </a>
<a href="#playlists" onclick="switchContent('playlists' ); return false;"><img src="images/icons/list_nested_24x21.png" /> <span class="navtxt">Playlists </span></a>
</li>
<li id="navcurrent">
<a href="#current" onclick="switchContent('current' ); return false;"><img src="images/icons/list_24x21.png" /> Queue </a>
<a href="#current" onclick="switchContent('current' ); return false;"><img src="images/icons/list_24x21.png" /> <span class="navtxt">Queue </span></a>
</li>
<li id="navsearch">
<a href="#search" onclick="switchContent('search' ); return false;" ><img src="images/icons/magnifying_glass_24x24.png" /> Search </a>
<a href="#search" onclick="switchContent('search' ); return false;" ><img src="images/icons/magnifying_glass_24x24.png" /> <span class="navtxt">Search </span></a>
</li>
<li id="navradio">
<a href="#radio" onclick="switchContent('radio' ); return false;" ><img src="images/icons/mic_18x24.png" /> Radio </a>
<a href="#radio" onclick="switchContent('radio' ); return false;" ><img src="images/icons/mic_18x24.png" /> <span class="navtxt">Radio </span></a>
</li>
</ul>
</div><!-- /navbar -->

View File

@ -1,41 +1,22 @@
/********************************************************
* play an uri from a trackslist or the current playlist
* play an uri from a tracklist
*********************************************************/
function playTrack(addtoqueue) {
//stop directly, for user feedback
if (!addtoqueue) {
mopidy.playback.stop(true);
mopidy.tracklist.clear();
}
$('#popupTracks').popup('close');
$('#controlsmodal').popup('close');
toast('Loading...');
//function playtrack(uri, playlisturi) {
playlisturi = $('#popupTracks').data("list");
uri = $('#popupTracks').data("track");
var trackslist = new Array();
var track, tracksbefore, tracksafter;
var tracks = getTracksFromUri(playlisturi);
if (tracks) {
if (!addtoqueue) {
clearQueue();
}
$(CURRENT_PLAYLIST_TABLE).empty();
} else {
tracks = currentplaylist;
for (var i = 0; i < tracks.length; i++) {
if (tracks[i].uri == uri) {
track = i + 1;
break;
}
}
for (var i = 0; i < track; i++) {
mopidy.playback.next();
}
mopidy.playback.play();
return false;
}
//find track that was selected
for (var selected = 0; selected < tracks.length; selected++) {
@ -50,6 +31,7 @@ function playTrack(addtoqueue) {
break;
}
}
console.log(selected, playing, tracks);
//switch popup options
switch (addtoqueue) {
@ -65,18 +47,77 @@ function playTrack(addtoqueue) {
}
// first add track to be played, then the other tracks
mopidy.tracklist.add(tracks.slice(selected, selected + 1) );
// mopidy.tracklist.add(null, 0, playlisturi);
mopidy.tracklist.add( tracks ); //.slice(selected, selected + 1) );
//wait 1.5 second before adding the rest to give server the time to start playing
setTimeout(function() {
/* setTimeout(function() {
mopidy.tracklist.add(tracks.slice(0, selected), 0);
if (selected < tracks.length) {
mopidy.tracklist.add(tracks.slice(selected + 1) );
}
}, (1500));
mopidy.playback.play();
}, 1500);
*/
// mopidy.playback.changeTrack(tracks[selected]);
for (var i = 0; i <= selected; i++) {
mopidy.playback.next();
}
mopidy.playback.play(); //tracks[selected]);
console.log(selected);
return false;
}
/********************************************************
* play an uri from the queue
*********************************************************/
function playTrackQueue() {
//stop directly, for user feedback
mopidy.playback.stop(true);
$('#popupQueue').popup('close');
toast('Loading...');
playlisturi = $('#popupQueue').data("list");
uri = $('#popupQueue').data("track");
var track;
for (var i = 0; i < currentplaylist.length; i++) {
if (currentplaylist[i].uri == uri) {
track = i + 1;
break;
}
}
for (var i = 0; i < track; i++) {
mopidy.playback.next();
}
mopidy.playback.play(); //currentplaylist[track]);
console.log(track, currentplaylist[track]);
return false;
}
/********************************************************
* remove a track from the queue
*********************************************************/
function removeTrack() {
$('#popupQueue').popup('close');
toast('Deleting...');
uri = $('#popupQueue').data("track");
console.log(uri);
for (var i = 0; i < currentplaylist.length; i++) {
if (currentplaylist[i].uri == uri) {
break;
}
}
var track = {};
track.uri = currentplaylist[i].uri;
mopidy.tracklist.remove(track);
console.log(currentplaylist[i].uri);
}
function clearQueue () {
mopidy.tracklist.clear();
return false;
@ -306,16 +347,16 @@ function addRadioUri(name, uri) {
$('#radionameinput').val('');
}
uri = uri || $('#radiouriinput').val();
// console.log( name , uri);
if (validUri(uri)) {
showLoading(true);
toast('Selecting radiostation...');
//stop directly, for user feedback
mopidy.playback.stop(true);
//hide ios/android keyboard
document.activeElement.blur();
$("input").blur();
clearQueue();
mopidy.tracklist.add(null,null, uri );
mopidy.tracklist.add(null,0, uri );
mopidy.playback.play();
var tmpname = name || '';
var i = 0;
//add station to list and check for doubles and add no more than 25
@ -335,9 +376,7 @@ function addRadioUri(name, uri) {
$('#radiouriinput').val(uri);
radioStations.unshift([tmpname, uri]);
saveRadioStations();
mopidy.playback.play();
updateRadioStations();
showLoading(false);
} else {
toast ('No valid url!');
}

View File

@ -138,32 +138,13 @@ function albumTracksToTable(pl, target, uri) {
};
$(target).html(tmp);
$(target).attr('data', uri);
//set click handlers
/* $(table + ' .name').click(function() {
return playtrack(this.id, uri)
});*/
//create (for new tables)
// $(target).listview().trigger("create");
//refresh
// $(target).listview('refresh');
}
function resultsToTables(results, target, uri) {
var newalbum = [];
var nexturi = '';
var count = 0;
//check if there are too many different albums in the list
/* for (var i = 1; i < results.length; i++) {
if (results[i].album.uri != results[i - 1].album.uri)
count++;
}
console.log(count);
//don't do the fancy rendering if there are more than X albums in the list
if (count > 8) {
playlisttotable(results, target, uri);
return;
}
*/
// var popupMenu = (target == CURRENT_PLAYLIST_TABLE) ? 'popupQueue' : 'popupTracks';
newalbum = [];
$(target).html('');
@ -172,19 +153,19 @@ function resultsToTables(results, target, uri) {
var tableid, j, artistname, alburi;
var targetmin = target.substr(1);
$(target).attr('data', uri);
for ( i = 0; i < results.length; i++) {
var length = 0 || results.length;
for ( i = 0; i < length; i++) {
newalbum.push(results[i]);
nexturi = '';
if (i < results.length - 1) {
if (i < length - 1) {
nexturi = results[i + 1].album.uri;
}
if (results[i].album.uri != nexturi) {
tableid = 'art' + i;
//render differently if only one track in the album
if ( newalbum.length == 1 ) {
// html += '<li data-role="list-divider" data-theme="d" class="smalldivider"></li>';
if (i != 0) { html += '<li class="smalldivider"> &nbsp;</li>'; }
// html += '<li id="' + targetmin + '-' + newalbum[0].uri + '"><a href="#" onclick="return ' + popupMenu + '(event, \'' + uri + '\',\'' + newalbum[0].uri + '\');">';
html += '<li id="' + targetmin + '-' + newalbum[0].uri + '"><a href="#" onclick="return popupTracks(event, \'' + uri + '\',\'' + newalbum[0].uri + '\');">';
html += '<h1>' + newalbum[0].name + "</h1>";
html += '<p>';
@ -205,7 +186,6 @@ function resultsToTables(results, target, uri) {
} else {
html += '<li class="albumdivider">';
// html += '<a href="#coverpopup" onclick="return coverPopup();" data-position-to="window" data-rel="popup"><img id="' + targetmin + '-cover-' + i + '" class="artistcover" width="30" height="30" /></a>';
html += '<a href="#" onclick="return showAlbum(\'' + results[i].album.uri + '\');"><img id="' + targetmin + '-cover-' + i + '" class="artistcover" width="30" height="30" /><h1>' + results[i].album.name + '</h1><p>';
for ( j = 0; j < results[i].album.artists.length; j++) {
html += results[i].album.artists[j].name;
@ -217,9 +197,9 @@ function resultsToTables(results, target, uri) {
}
}
html += '</p></a></li>';
// html += '<ul data-role="listview" data-inset="true" data-icon="false" class="" id="' + tableid + '"></ul>';
for ( j = 0; j < newalbum.length; 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 + '\');">';
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>';
};
@ -232,7 +212,6 @@ function resultsToTables(results, target, uri) {
}
tableid = "#" + tableid;
$(target).html(html);
$(target).attr('data', uri);
// $(target).listview('refresh');
}
@ -270,9 +249,6 @@ function playlisttotable(pl, target, uri) {
$(target).html(tmp);
$(target).attr('data', uri);
//refresh
// $(target).listview('refresh');
}
function getPlaylistFromUri(uri) {
@ -304,17 +280,53 @@ function timeFromSeconds(length) {
/******* Toast ***/
function toast (message, delay) {
function toast (message, delay, textOnly) {
textOnl = textOnly || false;
message = message || "Loading...";
delay = delay || 1000;
$.mobile.showPageLoadingMsg("a", message);
$.mobile.loading( 'show', {
text: message,
textVisible: true,
theme: 'a',
textonly: textOnl
});
if(delay > 0) {
setTimeout(function(){
$.mobile.hidePageLoadingMsg();
$.mobile.loading('hide');
}, delay);
}
}
/*****************
* Modal dialogs
*****************/
function showLoading(on) {
if (on) {
$("body").css("cursor", "progress");
$.mobile.loading('show', {
text : 'Loading data from ' + PROGRAM_NAME + '. Please wait...',
textVisible : true,
theme : 'a'
});
} else {
$("body").css("cursor", "default");
$.mobile.loading('hide');
}
}
function showOffline(on) {
if (on) {
$.mobile.loading('show', {
text : 'Trying to reach ' + PROGRAM_NAME + '. Please wait...',
textVisible : true,
theme : 'a'
});
} else {
$.mobile.loading('hide');
}
}
// from http://dzone.com/snippets/validate-url-regexp
function validUri(str) {
var regexp = /(mms|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/

View File

@ -89,6 +89,7 @@ function setSongInfo(data) {
$(this).addClass('currenttrack');
}
});
$('#playlisttracks li').each(function() {
$(this).removeClass("currenttrack2");
if (this.id == 'playlisttracks-' + data.uri) {
@ -114,8 +115,9 @@ function setSongInfo(data) {
$(this).addClass('currenttrack2');
}
});
if (songdata.name == data.name) {
if (data.name && (songdata.name == data.name)) {
return;
}
if (data) {
@ -130,18 +132,11 @@ function setSongInfo(data) {
for (var key in radioStations) {
rs = radioStations[key];
if (rs && rs[1] == data.name) {
data.name = (rs[0] || rs[1]) + ' [Stream]';
data.name = (rs[0] || rs[1]);
}
};
}
if (data.album) {
$("#modalalbum").html('Album: <a href="#" onclick="return showAlbum(\'' + data.album.uri + '\');">' + data.album.name + '</a>');
getCover(artiststext, data.album.name, '#infocover, #controlspopupimage', 'extralarge');
} else {
$("#modalalbum").html('');
}
$("#modalname").html(data.name);
if (!data.length || data.length == 0) {
@ -173,7 +168,15 @@ function setSongInfo(data) {
arttmp += ': ' + artistshtml;
}
$("#modalartist").html(arttmp);
if (data.album) {
$("#modalalbum").html('Album: <a href="#" onclick="return showAlbum(\'' + data.album.uri + '\');">' + data.album.name + '</a>');
getCover(artiststext, data.album.name, '#infocover, #controlspopupimage', 'extralarge');
} else {
$("#modalalbum").html('');
$("#infocover").attr('src', '../images/icons/cd_32x32.png');
}
$("#modalartist").html(arttmp);
$("#trackslider").attr("min", 0);
$("#trackslider").attr("max", data.length);
@ -191,48 +194,37 @@ function coverPopup() {
function popupTracks(e, listuri, trackuri) {
if (!e)
var e = window.event;
$('#popupTrackName').html(popupData[trackuri].name);
$('#popupAlbumName').html(popupData[trackuri].album.name);
$('.popupTrackName').html(popupData[trackuri].name);
$('.popupAlbumName').html(popupData[trackuri].album.name);
var child = "";
// $('#popupArtistsLi').remove();
if (popupData[trackuri].artists.length == 1) {
//this doesnt work
// child += '<a href="#" onclick="showArtist(\'' +popupData[trackuri].artists[0].uri + '\');">Show Artist <span class="popupArtistName">' + popupData[trackuri].artists[0].name + '</span></a>';
/* $('#popupTracksLv').append($('<li/>', {
'id' : "popupArtistsLi"
}).append($('<a/>', {
'href' : '#',
'onclick' : 'showArtist(\'' + popupData[trackuri].artists[0].uri + '\');',
'text' : 'Show Artist '
}).append($('<span/>', {
'class' : 'popupArtistName',
'text' : popupData[trackuri].artists[0].name
}))));
*/ child = '<a href="#" onclick="showArtist(\'' + popupData[trackuri].artists[0].uri + '\');">Show Artist</a>';
$('#popupArtistName').html(popupData[trackuri].artists[0].name);
$('#popupArtistHref').attr('onclick', 'showArtist("' + popupData[trackuri].artists[0].uri + '");' );
$('#popupArtistsDiv').hide();
$('#popupArtistsLi').show();
child = '<a href="#" onclick="showArtist(\'' + popupData[trackuri].artists[0].uri + '\');">Show Artist</a>';
$('.popupArtistName').html(popupData[trackuri].artists[0].name);
$('.popupArtistHref').attr('onclick', 'showArtist("' + popupData[trackuri].artists[0].uri + '");' );
$('.popupArtistsDiv').hide();
$('.popupArtistsLi').show();
} else {
for (var j = 0; j < popupData[trackuri].artists.length; j++) {
child += '<li><a href="#" onclick="showArtist(\'' + popupData[trackuri].artists[j].uri + '\');"><span class="popupArtistName">' + popupData[trackuri].artists[j].name + '</span></a></li>';
}
$('#popupArtistsLi').hide();
$('#popupArtistsLv').html(child).show();
$('#popupArtistsDiv').show();
$('.popupArtistsLi').hide();
$('.popupArtistsLv').html(child).show();
$('.popupArtistsDiv').show();
// this makes the viewport of the window resize somehow
$('#popupArtistsLv').listview("refresh");
$('.popupArtistsLv').listview("refresh");
}
var hash = document.location.hash.split('?');
var divid = hash[0].substr(1);
if (divid == 'current') {
$(".addqueue").hide();
var popupName = '#popupQueue';
} else {
$(".addqueue").show();
var popupName = '#popupTracks';
}
$('#popupTracks').data("list", listuri).data("track", trackuri).popup("open", {
$(popupName).data("list", listuri).data("track", trackuri).popup("open", {
x : e.pageX,
y : e.pageY
});
@ -244,35 +236,6 @@ function showAlbumPopup() {
showAlbum(popupData[uri].album.uri);
}
/*****************
* Modal dialogs
*****************/
function showLoading(on) {
if (on) {
$("body").css("cursor", "progress");
$.mobile.loading('show', {
text : 'Loading data from ' + PROGRAM_NAME + '. Please wait...',
textVisible : true,
theme : 'a'
});
} else {
$("body").css("cursor", "default");
$.mobile.loading('hide');
}
}
function showOffline(on) {
if (on) {
$.mobile.loading('show', {
text : 'Trying to reach ' + PROGRAM_NAME + '. Please wait...',
textVisible : true,
theme : 'a'
});
} else {
$.mobile.loading('hide');
}
}
/*********************
* initialize sockets
*********************/
@ -280,11 +243,10 @@ function showOffline(on) {
function initSocketevents() {
mopidy.on("state:online", function() {
showOffline(false);
showLoading(true);
getCurrentPlaylist();
updateStatusOfAll();
getPlaylists();
showLoading(true);
showLoading(false);
$(window).hashchange();
});
@ -381,24 +343,27 @@ $(document).ready(function() {
$(window).resize(function() {
resizeMb();
});
initRadio();
/* $(document).keypress( function (event) {
$(document).keypress( function (event) {
// console.log('kp');
if (event.target.tagName != 'INPUT') {
event.preventDefault();
switch(event.which) {
case 'p':
case 32:
doPlay();
break;
case ']':
case '>':
doNext();
break;
case '[':
case '<':
doPrevious();
break;
}
return true;
}
});
*/
initRadio();
});
$(document).bind("pageinit", function() {

View File

@ -66,8 +66,7 @@ function processSearchResults(resultArr) {
var artists = (results.artists) ? results.artists : '';
var albums = (results.albums) ? results.albums : '';
if ((tracks == '') && (artists == '') && (albums == '')) {
alert('No results');
showLoading(false);
toast('No results', 1500, true);
return false;
}
$("#searchresults").show();