Merge branch 'develop'

Conflicts:
	README.rst
	mopidy_musicbox_webclient/static/css/webclient.css
	mopidy_musicbox_webclient/static/index.html
This commit is contained in:
woutervanwijk 2014-11-24 22:24:39 +01:00
parent aa867288d8
commit b82a956c52
18 changed files with 1242 additions and 429 deletions

View File

@ -1,7 +1,7 @@
Webclient
- Wouter van Wijk
- Flat Interface: Ulrich Lichtenegger
- Kingosticks
- Kingosticks (Nick Steel)
- Szymon Nowak
Mopidy:
@ -11,4 +11,5 @@ Icons:
https://github.com/hybridgroup/betterfrontend/blob/master/iconic/AUTHORS
Background:
Openclipart / Chrisdesign
Openclipart / Chrisdesign

View File

@ -39,8 +39,7 @@ Alternatively, clone the repository and run ``sudo python setup.py install`` fro
Usage
=====
Point your (modern) browser at Mopidy-MusicBox-Webclient running on your Mopidy server e.g. http://localhost:6680/musicbox.
Point your (modern) browser at Mopidy-MusicBox-Webclient running on your Mopidy server e.g. http://localhost:6680/musicbox_webclient.
Project resources
@ -59,10 +58,19 @@ v1.0.2 Dev
- A friendlier welcome with a home page with buttons to the most used functions
- Converted Radio Stations to Streams, so user can add streams for youtube, spotify, soundcloud, podcasts
<<<<<<< HEAD
- Enhanced radio/streams interface
- Search: select service to search
- Youtube icons added
- Fixed single quote bug #39, other bugs
=======
- Improved radio/streams interface
- Better handling of coverart
- Search: select service to search
- Youtube icons added
- Fixed single quote bug #39
- Bugfixes (search, popups, etc)
>>>>>>> develop
v1.0.1 (20-9-2014)
-------------------

View File

@ -5,7 +5,7 @@ import os
from mopidy import config, ext
__version__ = '1.0.2'
__version__ = '1.0.4'
class MusicBoxExtension(ext.Extension):

View File

@ -131,6 +131,11 @@
margin-top: 6px;
}
#contentHeadline a {
color:white;
margin-left: 20%;
}
#headermenubtn{
width: 50px;
}
@ -204,10 +209,23 @@
#artistviewimage, #albumviewcover {
float: right;
heigth: 90px;
max-width: 90%;
}
/*** home ***/
#homerows div {
text-align:center;
background-color: #2C3E50;
padding: 2px;
padding-top: 20px;
border: 2px solid white;
color: white;
}
<<<<<<< HEAD
/*** home ***/
#homerows div {
text-align:center;
background-color: #2C3E50;
@ -216,6 +234,8 @@
border: 3px solid white;
}
=======
>>>>>>> develop
#homerows div i {
font-size: 28px;
}
@ -332,18 +352,18 @@
/*******************
* Now Playing area
*******************/
.nowPlayingControls{
font-size: 1.2em;
line-height: 50px;
.nowPlayingControls {
font-size: 20px;
line-height: 45px;
padding-left: 10px;
}
.nowPlayingControls .fa{
vertical-align: -webkit-baseline-middle;
vertical-align: middle;
}
.nowPlayingControls #btplayNowPlaying{
font-size: 190%;
margin-left: 20px;
margin-right: 20px;
margin-left: 15px;
margin-right: 15px;
}
@ -360,7 +380,7 @@
}
#controlspopup, #artistpopup, #coverpopup {
max-width: 550px;
max-width: 90%;
background: white;
padding: 5px;
}
@ -374,7 +394,19 @@
display: block;
margin-left: auto;
margin-right: auto;
margin-bottom: 5px;
margin-bottom: 10px;
max-width:90%;
max-height:90%;
}
#buttons {
font-size: 24px;
padding-right: 15px;
margin-bottom: 15px;
}
#btplayNowPlaying {
padding-top: 15px;
}
#popupTracksLv li, #popupQueueLv li {
@ -543,7 +575,8 @@ a {
padding: 15px 25px 0px 25px;
}
#nowPlayingpane #controlspopupimage{
max-width: 100%;
max-width:90%;
max-height:90%;
}
.nowPlaying-artistInfo {
font-size: 12px;
@ -560,6 +593,8 @@ a {
}
#controlspopupimage{
max-width:90%;
max-height:90%;
margin-bottom: 3px;
}
#nowPlayingpane #slidercontainer {

View File

@ -3,13 +3,16 @@
<html>
<head>
<meta charset="utf-8">
<script src="js/jquery-1.10.2.min.js"></script>
<script src="js/jquery-1.11.1.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/jquery.mobile.flatui.css"/>
<script type='application/javascript' src='js/fastclick.js'></script>
<!-- <script type='application/javascript' src='js/fastclick.js'></script> -->
<script>
//configuration
// var wsLocation = location.host + ':6680'; //for musicbox configuration and normal operation of mopidy http
// var wsLocation = location.host + ':6680'; //for normal operation of mopidy http
var wsLocation = location.host; //for running on port 80
if (wsLocation == location.hostname) {
wsLocation = location.hostname + ':6680';
}
var isMusicBox = true; //set to true to remove buttons only for musicbox
$(document).bind("mobileinit", function () {
@ -21,9 +24,10 @@
// buttonMarkup.corners: false
});
});
window.addEventListener('load', function () {
/* window.addEventListener('load', function () {
new FastClick(document.body);
}, false);
*/
</script>
<link rel="icon" type="image/gif" href="images/icons/musicbox32.gif" />
<link rel="apple-touch-icon" href="images/icons/musicbox57.png" />
@ -75,6 +79,13 @@
<li id="navnowPlaying" data-icon="false">
<a href="#nowPlaying" onclick="switchContent('nowPlaying' ); return false;">
<span class="navtxt"> Now Playing </span><i class="fa fa-music"></i></a>
<<<<<<< HEAD
=======
</li>
<li id="navcurrent" data-icon="false">
<a href="#current" onclick="switchContent('current' ); return false;">
<span class="navtxt">Queue </span><i class="fa fa-bars"></i></a>
>>>>>>> develop
</li>
<li id="navplaylists" data-icon="false">
<a href="#playlists" onclick="switchContent('playlists' ); return false;">
@ -84,18 +95,27 @@
<a href="#browse" onclick="switchContent('browse' ); return false;">
<span class="navtxt"> Browse </span><i class="fa fa-folder"></i></a>
</li>
<<<<<<< HEAD
<li id="navcurrent" data-icon="false">
<a href="#current" onclick="switchContent('current' ); return false;">
<span class="navtxt">Queue </span><i class="fa fa-bars"></i></a>
=======
<li id="navstream" data-icon="false">
<a href="#stream" onclick="switchContent('stream' ); return false;">
<span class="navtxt">Streams </span><i class="fa fa-rss"></i></a>
>>>>>>> develop
</li>
<li id="navsearch" data-icon="false">
<a href="#search" onclick="switchContent('search' ); return false;">
<span class="navtxt">Search </span><i class="fa fa-search"></i></a>
</li>
<<<<<<< HEAD
<li id="navstream" data-icon="false">
<a href="#stream" onclick="switchContent('stream' ); return false;">
<span class="navtxt">Streams </span><i class="fa fa-rss"></i></a>
</li>
=======
>>>>>>> develop
<li id="navEnterFullscreen" data-icon="false">
<a href="#">
<span class="navtxt"> Fullscreen </span><i class="fa fa-desktop"></i></a>
@ -158,7 +178,7 @@
Queue</a>
</li>
<li>
<a href="#" onclick="showAlbumPopup()">Show Album <span class="popupAlbumName"></span></a>
<a href="#" onclick="showAlbumPopup('#popupTracks')">Show Album <span class="popupAlbumName"></span></a>
</li>
<li id="popupArtistsLi">
<a href="#" onclick="showArtist()" class="popupArtistHref">Show Artist <span
@ -183,7 +203,7 @@
<a href="#" onclick="return removeTrack();">Remove from Queue</a>
</li>
<li>
<a href="#" onclick="showAlbumPopup()">Show Album <span class="popupAlbumName"></span></a>
<a href="#" onclick="showAlbumPopup('#popupQueue')">Show Album <span class="popupAlbumName"></span></a>
</li>
<li id="popupArtistsLi">
<a href="#" onclick="showArtist()" class="popupArtistHref">Show Artist <span
@ -202,23 +222,36 @@
<div data-role="header" data-tap-toggle="false" id="header" data-position="fixed" class="ui-grid-b header-breakpoint headerbtn">
<a href="#panel" style="margin-left: -12px; padding-top: 2px;" id="headermenubtn"><i class="fa fa-align-justify"></i></a>
<<<<<<< HEAD
<h1 id="contentHeadline" >Musicbox</h1>
=======
<h1 id="contentHeadline">Musicbox</h1>
>>>>>>> develop
<a id="headersearchbtn" href="#" class="ui-btn-icon-right headerbtn" onclick="switchContent('search' ); return false;">
<i class="fa fa-search"></i></a>
</div>
<!-- /header -->
<div data-role="content" id="homepane" class="pane">
<<<<<<< HEAD
<div id="homerows" class="ui-grid-c ui-responsive">
<a href="#nowPlaying" onclick="switchContent('nowPlaying' ); return false;">
<div class="ui-block-a">
<i class="fa fa-music"></i>
<h5>Now Playing</h5>
=======
<div id="homerows" class="ui-grid-a ui-responsive">
<a href="#nowPlaying" onclick="switchContent('nowPlaying' ); return false;">
<div class="ui-block-a">
<i class="fa fa-music"></i>
<h4>Now Playing</h4>
>>>>>>> develop
</div>
</a>
<a href="#current" onclick="switchContent('current' ); return false;">
<div class="ui-block-b">
<i class="fa fa-bars"></i>
<<<<<<< HEAD
<h5>Queue</h5>
</div>
</a>
@ -256,6 +289,45 @@
<div class="ui-block-d">
<i class="fa fa-power-off"></i>
<h5>System</h5>
=======
<h4>Queue</h4>
</div>
</a>
<a href="#playlists" onclick="switchContent('playlists' ); return false;">
<div class="ui-block-a">
<i class="fa fa-star"></i>
<h4>Playlists</h4>
</div>
</a>
<a href="#browse" onclick="switchContent('browse' ); return false;">
<div class="ui-block-b">
<i class="fa fa-folder"></i>
<h4>Browse</h4>
</div>
</a>
<a href="#stream" onclick="switchContent('stream' ); return false;">
<div class="ui-block-a">
<i class="fa fa-rss"></i>
<h4>Streams</h4>
</div>
</a>
<a href="#search" onclick="switchContent('search' ); return false;">
<div class="ui-block-b">
<i class="fa fa-search"></i>
<h4>Search</h4>
</div>
</a>
<a id="homesettings" href="/settings/">
<div class="ui-block-a">
<i class="fa fa-gear"></i>
<h4>Settings</h4>
</div>
</a>
<a id="homeshutdown" href="system.html">
<div class="ui-block-b">
<i class="fa fa-power-off"></i>
<h4>System</h4>
>>>>>>> develop
</div>
</a>
@ -429,26 +501,13 @@
</div>
</div>
<div data-role="footer" data-tap-toggle="false" data-position="fixed" id="nowPlayingFooter">
<!-- <p id="buttons">
<select name="flip-random" id="flip-random" data-role="slider" data-mini="true" >
<option value="off">Shuffle</option>
<option value="on">Shuffle</option>
</select>
<select name="flip-repeat" id="flip-repeat" data-role="slider" data-mini="true">
<option value="off">Repeat</option>
<option value="on">Repeat</option>
</select>
</p> -->
<!--&nbsp; <a href="#" onclick="doShuffle(); return false" title="Shuffle"><img src="images/icons/fork_21x24.png"-->
<!--id="shufflebt" alt=""/></a>-->
<p id="buttons"' style="float:right; margin-top: 20px; margin-right: 5px;">
<a href="#" onclick="doRandom(); return false"><i class="fa fa-random" id="randombt"></i></a>
&nbsp; <a href="#" onclick="doRepeat(); return false"><i class="fa fa-repeat" id="repeatbt"></i></a>
&nbsp; <a href="#" onclick="doShuffle(); return false" title="Shuffle"><i class="fa fa-code-fork" id="shufflebt"></i></a>
&nbsp; <a href="#" onclick="doShuffle(); return false"><i class="fa fa-arrows-v" id="shufflebt"></i></a>
</p>
<div class="nowPlayingControls" style="float:left; margin-left: 5px;">
@ -479,7 +538,7 @@
<script type="text/javascript" src="js/lastfm.api.js"></script>
<script type="text/javascript" src="js/lastfm.api.cache.js"></script>
<script src="js/lastfm.js"></script>
<script src="js/images.js"></script>
<script src="js/gui.js"></script>
</body>

View File

@ -2,7 +2,8 @@
* play tracks from a browse list
*********************************************************/
function playBrowsedTracks(addtoqueue, trackid) {
//stop directly, for user feedback
//stop directly, for user feedback.
if (!addtoqueue) {
mopidy.playback.stop(true);
mopidy.tracklist.clear();
@ -11,41 +12,42 @@ function playBrowsedTracks(addtoqueue, trackid) {
var selected = 0, counter = 0;
var isRadio = isRadioUri(trackid);
//only add one station for dirble, otherwise add all tracks
if (isRadio) {
mopidy.tracklist.add(null, null, trackid);
var isStream = isStreamUri(trackid);
//only add one uri for dirble, tunein; otherwise add all tracks
if (isStream) {
mopidy.tracklist.add(null, null, trackid);
} else {
//add selected item to the playlist
$('.browsetrack').each(function() {
if (this.id == trackid) {
selected = counter;
//add selected item to the playlist
$('.browsetrack').each(function() {
if (this.id == trackid) {
selected = counter;
}
mopidy.tracklist.add(null, null, this.id);
counter++;
} );
mopidy.tracklist.add(null, null, this.id);
counter++;
});
}
//play selected item
if (!addtoqueue) {
for (var i = 0; i <= selected; i++) {
mopidy.playback.next();
}
//play selected item
if (!addtoqueue) {
mopidy.playback.stop();
for (var i = 0; i <= selected; i++) {
mopidy.playback.next();
}
mopidy.playback.play(); //tracks[selected]);
}
//add all items, but selected to the playlist
selected = 0;
counter = 0
/* if(!isRadio) {
$('.browsetrack').each(function() {
//do not add selected song again
if (this.id == trackid) {
selected = counter;
} else {
mopidy.tracklist.add(null, counter, this.id);
}
counter++;
/* if(!isStream) {
$('.browsetrack').each(function() {
//do not add selected song again
if (this.id == trackid) {
selected = counter;
} else {
mopidy.tracklist.add(null, counter, this.id);
}
counter++;
} );
}
*/
@ -57,8 +59,17 @@ function playBrowsedTracks(addtoqueue, trackid) {
* play an uri from a tracklist
*********************************************************/
function playTrack(addtoqueue) {
//stop directly, for user feedback
var hash = document.location.hash.split('?');
var divid = hash[0].substr(1);
if (!addtoqueue) {
addtoqueue = PLAY_NOW;
}
// console.log(addtoqueue, divid);
//stop directly, for user feedback. If searchresults, also clear queue
if (!addtoqueue || ((addtoqueue == PLAY_NOW) && (divid == 'search'))) {
mopidy.playback.stop(true);
mopidy.tracklist.clear();
}
@ -74,22 +85,28 @@ function playTrack(addtoqueue) {
var track, tracksbefore, tracksafter;
var tracks = getTracksFromUri(playlisturi);
//find track that was selected
//find track that was selected
for (var selected = 0; selected < tracks.length; selected++) {
if (tracks[selected].uri == uri) {
break;
}
}
//find track that is playing
//find track that is playing
for (var playing = 0; playing < currentplaylist.length; playing++) {
if (currentplaylist[playing].uri == songdata.uri) {
break;
}
}
//switch popup options
//switch popup options
switch (addtoqueue) {
case PLAY_NOW:
if (divid == 'search') {
mopidy.tracklist.add(tracks.slice(selected, selected + 1));
mopidy.playback.play();
return false;
}
case ADD_THIS_BOTTOM:
mopidy.tracklist.add(tracks.slice(selected, selected + 1));
return false;
@ -100,49 +117,41 @@ function playTrack(addtoqueue) {
mopidy.tracklist.add(tracks);
return false;
}
// PLAY_NOW, play the selected track
// mopidy.tracklist.add(null, null, uri); //tracks);
mopidy.tracklist.add(tracks);
//normal
// mopidy.tracklist.add(tracks);
//test mopidy.tracklist.add(null, 0, playlisturi);
// first add track to be played, then the other tracks
mopidy.tracklist.add(tracks.slice(selected, selected + 1) );
// // mopidy.playback.changeTrack(tracks[selected]);
// mopidy.tracklist.add(tracks.slice(selected, selected + 1) );
// //wait 2.5 seconds before adding the rest to give server the time to start playing
// setTimeout(function() {
// mopidy.tracklist.add(tracks.slice(0, selected), 0);
// if (selected < tracks.length) {
// mopidy.tracklist.add(tracks.slice(selected + 1) );
// }
// }, 2500);
if (!addtoqueue) {
for (var i = 0; i <= selected; i++) {
mopidy.playback.next();
}
mopidy.playback.play(); //tracks[selected]);
if (!addtoqueue) {
mopidy.playback.stop();
for (var i = 0; i <= selected; i++) {
mopidy.playback.next();
}
mopidy.playback.play();
}
mopidy.tracklist.add(tracks.slice(0, selected), 0);
if (selected < tracks.length) {
mopidy.tracklist.add(tracks.slice(selected + 1) );
}
//console.log(selected);
return false;
}
/***
* Plays a Track given by an URI
* @param uri
* Plays a Track given by an URI from the given playlist URI.
* @param track_uri, playlist_uri
* @returns {boolean}
*/
function playTrackByUri(uri, playlisturi){
//console.log('playuri');
//stop directly, for user feedback
function playTrackByUri(track_uri, playlist_uri) {
function findAndPlayTrack(tltracks) {
// console.log('fa', tltracks, track_uri);
if (tltracks == []) { return;}
// Find track that was selected
for (var selected = 0; selected < tltracks.length; selected++) {
if (tltracks[selected].track.uri == track_uri) {
mopidy.playback.play(tltracks[selected]);
return;
}
}
console.log('Failed to play selected track ', track_uri);
}
// Stop directly, for user feedback
mopidy.playback.stop(true);
mopidy.tracklist.clear();
@ -153,32 +162,18 @@ function playTrackByUri(uri, playlisturi){
toast('Loading...');
var trackslist = new Array();
var track, tracksbefore, tracksafter;
var tracks = getTracksFromUri(playlisturi);
//find track that was selected
for (var selected = 0; selected < tracks.length; selected++) {
if (tracks[selected].uri == uri) {
break;
var func;
func = mopidy.tracklist.add(null, null, playlist_uri);
func.then(
function(tltracks) {
//check if tltracks is filled, some backends (gmusic) do not support adding by uri, it seems
if (tltracks.length == 0) {
var tracks = getTracksFromUri(playlist_uri);
mopidy.tracklist.add(tracks).then(findAndPlayTrack);
}
findAndPlayTrack(tltracks);
}
}
//find track that is playing
for (var playing = 0; playing < currentplaylist.length; playing++) {
if (currentplaylist[playing].uri == songdata.uri) {
break;
}
}
mopidy.tracklist.add(tracks);
for (var i = 0; i <= selected; i++) {
mopidy.playback.next();
}
mopidy.playback.play(); //tracks[selected]);
// console.log(selected);
).then(getCurrentPlaylist()); // Updates some state
return false;
}
@ -192,27 +187,24 @@ function playTrackByUri(uri, playlisturi){
* @param playlisturi
* @returns {boolean}
*/
function playTrackQueueByUri(uri, playlisturi){
//console.log('playqu');
function playTrackQueueByUri(uri, playlisturi) {
// console.log('playquuri');
//stop directly, for user feedback
//console.log('qu');
mopidy.playback.stop(true);
$('#popupQueue').popup('close');
toast('Loading...');
var track;
for (var i = 0; i < currentplaylist.length; i++) {
if (currentplaylist[i].uri == uri) {
track = i + 1;
break;
mopidy.tracklist.filter({
'uri': [uri]
}).then(
function(tltracks) {
if (tltracks.length > 0) {
mopidy.playback.play(tltracks[0]);
return;
}
console.log('Failed to play selected track ', uri);
}
}
for (var i = 0; i < track; i++) {
mopidy.playback.next();
}
mopidy.playback.play(); //currentplaylist[track]);
//console.log(track, currentplaylist[track]);
);
return false;
}
@ -221,9 +213,10 @@ function playTrackQueueByUri(uri, playlisturi){
* @returns {boolean}
*/
function playTrackQueue() {
// console.log('playqu');
playlisturi = $('#popupQueue').data("list");
uri = $('#popupQueue').data("track");
return playTrackByUri(uri, playlisturi);
return playTrackQueueByUri(uri, playlisturi);
}
/********************************************************
@ -242,9 +235,9 @@ function removeTrack() {
}
}
var track = {};
track.uri = currentplaylist[i].uri;
track.uri = [currentplaylist[i].uri];
mopidy.tracklist.remove(track);
console.log(currentplaylist[i].uri);
// console.log(currentplaylist[i].uri);
}
function clearQueue() {
@ -312,9 +305,9 @@ function setRepeat(nwrepeat) {
return
}
if (!nwrepeat) {
$("#repeatbt").attr('style', 'color:#7cc4e7');
$("#repeatbt").attr('style', 'color:#2489ce');
} else {
$("#repeatbt").attr('style', 'color:#66FF33');
$("#repeatbt").attr('style', 'color:#66DD33');
}
repeat = nwrepeat;
}
@ -324,26 +317,26 @@ function setRandom(nwrandom) {
return
}
if (!nwrandom) {
$("#randombt").attr('style', 'color:#7cc4e7');
$("#randombt").attr('style', 'color:#2489ce');
} else {
$("#randombt").attr('style', 'color:#66FF33');
$("#randombt").attr('style', 'color:#66DD33');
}
random = nwrandom;
}
function doRandom() {
if (random == false) {
//check for mopidy 0.16.x or higher
if (mopidy.tracklist.setRandom) {
mopidy.tracklist.setRandom(true).then();
} else {
//check for mopidy 0.16.x or higher
if (mopidy.tracklist.setRandom) {
mopidy.tracklist.setRandom(true).then();
} else {
mopidy.playback.setRandom(true).then();
}
} else {
//check for mopidy 0.16.x or higher
if (mopidy.tracklist.setRandom) {
mopidy.tracklist.setRandom(false).then();
} else {
//check for mopidy 0.16.x or higher
if (mopidy.tracklist.setRandom) {
mopidy.tracklist.setRandom(false).then();
} else {
mopidy.playback.setRandom(false).then();
}
}
@ -352,19 +345,19 @@ function doRandom() {
function doRepeat() {
if (repeat == false) {
//check for mopidy 0.16.x or higher
if (mopidy.tracklist.setRepeat) {
//check for mopidy 0.16.x or higher
if (mopidy.tracklist.setRepeat) {
mopidy.tracklist.setRepeat(true).then();
} else {
mopidy.playback.setRepeat(true).then();
}
mopidy.playback.setRepeat(true).then();
}
} else {
//check for mopidy 0.16.x or higher
if (mopidy.tracklist.setRepeat) {
//check for mopidy 0.16.x or higher
if (mopidy.tracklist.setRepeat) {
mopidy.tracklist.setRepeat(false).then();
} else {
mopidy.playback.setRepeat(false).then();
}
mopidy.playback.setRepeat(false).then();
}
}
setRepeat(!repeat);
}
@ -433,10 +426,10 @@ function doSeekPos(value) {
function triggerPos() {
if (mopidy) {
posChanging = true;
// mopidy.playback.pause();
// console.log(newposition);
// mopidy.playback.pause();
// console.log(newposition);
mopidy.playback.seek(newposition);
// mopidy.playback.resume();
// mopidy.playback.resume();
resumePosTimer();
posChanging = false;
}
@ -526,99 +519,117 @@ function pausePosTimer() {
}
/*********************************
* Radio
* Stream
*********************************/
function radioPressed(key) {
function streamPressed(key) {
if (key == 13) {
addRadioUri();
playStreamUri();
return false;
}
return true;
}
function addRadioUri(name, uri) {
function playStreamUri(uri) {
//value of name is based on the passing of an uri as a parameter or not
var name = '';
if (!uri) {
name = $('#radionameinput').val();
} else {
$('#radionameinput').val('');
var nwuri = uri || $('#streamuriinput').val().trim();
var service = $('#selectstreamservice').val();
if (!uri && service) {
nwuri = service + ':' + nwuri;
}
uri = uri || $('#radiouriinput').val();
if (isRadioUri(uri)) {
toast('Selecting radiostation...');
if (isServiceUri(nwuri) || isStreamUri(nwuri) || validUri(nwuri)) {
toast('Playing...');
//stop directly, for user feedback
mopidy.playback.stop(true);
//hide ios/android keyboard
document.activeElement.blur();
$("input").blur();
clearQueue();
mopidy.tracklist.add(null, 0, uri);
mopidy.tracklist.add(null, null, nwuri);
mopidy.playback.play();
var tmpname = name || '';
var i = 0;
//add station to list and check for doubles and add no more than 25
for (var key in radioStations) {
rs = radioStations[key];
if (i > 25) {
delete radioStations[key];
continue;
}
i++;
if (rs && rs[1] == uri) {
tmpname = name || radioStations[key][0];
delete radioStations[key];
}
}
;
$('#radionameinput').val(tmpname);
$('#radiouriinput').val(uri);
radioStations.unshift([tmpname, uri]);
saveRadioStations();
updateRadioStations();
} else {
toast('No valid url!');
}
return false;
}
function updateRadioStations() {
function saveStreamUri() {
var i = 0;
var name = $('#streamnameinput').val().trim();
var uri = $('#streamuriinput').val().trim();
var service = $('#selectstreamservice').val();
if (service) {
uri = service + ':' + uri;
}
//add stream to list and check for doubles and add no more than 100
for (var key in streamUris) {
rs = streamUris[key];
if (i > 100) {
delete streamUris[key];
continue;
}
i++;
}
streamUris.unshift([name, uri]);
$.cookie.json = true;
$.cookie('streamUris', streamUris);
updateStreamUris();
return false;
}
function deleteStreamUri(uri) {
var i = 0;
for (var key in streamUris) {
rs = streamUris[key];
if (rs && rs[1] == uri) {
if (confirm("About to remove " + rs[0] + ". Sure?")) {
delete streamUris[key];
}
}
}
$.cookie.json = true;
$.cookie('streamUris', streamUris);
updateStreamUris();
return false;
}
function updateStreamUris() {
var tmp = '';
$('#radiostationstable').empty();
$('#streamuristable').empty();
var child = '';
for (var key in radioStations) {
var rs = radioStations[key];
for (var key in streamUris) {
var rs = streamUris[key];
if (rs) {
name = rs[0] || rs[1];
child = '<li data-icon="delete"> <a href="#" onclick="return addRadioUri(\'' + rs[0] + '\', \'' + rs[1] + '\');">';
child = '<li><span class="ui-icon ui-icon-delete ui-icon-shadow" style="float:right; margin: .5em; margin-top: .8em;"><a href="#" onclick="return deleteStreamUri(\'' + rs[1] + '\');">&nbsp;</a></span>' +
'<i class="fa fa-rss" style="float: left; padding: .5em; padding-top: 1em;"></i>' +
' <a style="margin-left: 20px" href="#" onclick="return playStreamUri(\'' + rs[1] + '\');">';
child += '<h1>' + name + '</h1></a></li>';
tmp += child;
}
}
;
$('#radiostationstable').html(tmp);
$('#streamuristable').html(tmp);
}
function initRadio() {
function initStreams() {
$.cookie.json = true;
tmpRS = $.cookie('radioStations');
radioStations = tmpRS || radioStations;
updateRadioStations();
}
function saveRadioStations() {
$.cookie.json = true;
$.cookie('radioStations', radioStations);
tmpRS = $.cookie('streamUris');
streamUris = tmpRS || streamUris;
updateStreamUris();
}
function haltSystem() {
$.post("/settings/shutdown");
toast('Stopping system...', 10000);
setTimeout(function(){window.history.back();}, 10000);
setTimeout(function() {
window.history.back();
}, 10000);
}
function rebootSystem() {
$.post("/settings/reboot");
toast('Rebooting...', 10000);
setTimeout(function(){window.history.back();}, 10000);
setTimeout(function() {
window.history.back();
}, 10000);
}

View File

@ -0,0 +1,502 @@
/**
* @author Wouter van Wijk
*
* all kinds functions and vars
*/
var baseurl = '/mopidy';
var host = window.location.hostname;
var port = window.location.port;
var wsurl = host + ':' + port + baseurl
var intv;
var socket;
var mopidy;
//values for controls
var play = false;
var random;
var repeat;
var currentVolume = -1;
var muteVolume = -1;
var volumeChanging = false;
var posChanging = false;
var posTimer;
var volumeTimer;
var seekTimer;
var initgui = true;
var currentpos = 0;
var popupData = {};
var songlength = 0;
var artistshtml = '';
var artiststext = '';
var songname = '';
var songdata = '';
var newposition = 0;
var playlisttracksScroll;
var playlistslistScroll;
//array of cached playlists (not only user-playlists, also search, artist, album-playlists)
var playlists = {};
var currentplaylist;
var customPlaylists = [];
var customTracklists = [];
var browseStack = [];
var ua = navigator.userAgent,
isMobileSafari = /Mac/.test(ua) && /Mobile/.test(ua), isMobileWebkit = /WebKit/.test(ua) && /Mobile/.test(ua), isMobile = /Mobile/.test(ua), isWebkit = /WebKit/.test(ua);
//constants
PROGRAM_NAME = 'MusicBox';
//PROGRAM_NAME = 'Mopidy';
ARTIST_TABLE = '#artiststable';
ALBUM_TABLE = '#albumstable';
PLAYLIST_TABLE = '#playlisttracks';
CURRENT_PLAYLIST_TABLE = '#currenttable';
SEARCH_ALL_TABLE = '#allresulttable';
SEARCH_ALBUM_TABLE = '#albumresulttable';
SEARCH_ARTIST_TABLE = '#artistresulttable';
SEARCH_TRACK_TABLE = '#trackresulttable';
PLAY_NOW = 0;
PLAY_NEXT = 1;
ADD_THIS_BOTTOM = 2;
ADD_ALL_BOTTOM = 3;
MAX_TABLEROWS = 50;
//update track slider timer, milliseconds
TRACK_TIMER = 1000;
//check status timer, every 5 or 10 sec
STATUS_TIMER = 10000;
// the first part of Mopidy extensions which serve radio streams
var radioExtensionsList = ['somafm', 'tunein', 'dirble'];
var uriClassList = [ ['spotify', 'fa-spotify'], ['local', 'fa-file-sound-o'], ['podcast', 'fa-rss-square'], ['dirble', 'fa-microphone'],
['tunein', 'fa-headphones'], ['soundcloud', 'fa-soundcloud'], ['sc', 'fa-soundcloud'], ['gmusic', 'fa-google'], ['internetarchive', 'fa-university'], ['somafm', 'fa-flask'], ['youtube', 'fa-youtube'], ['yt', 'fa-youtube'], ['subsonic', 'fa-folder-open'] ];
var uriHumanList = [ ['spotify', 'Spotify'], ['local', 'Local Files'], ['podcast', 'Podcasts'], ['dirble', 'Dirble'],
['tunein', 'TuneIn'], ['soundcloud', 'SoundCloud'], ['gmusic', 'Google Music'], ['internetarchive', 'Internet Archive'], ['somafm', 'Soma FM'], ['youtube', 'YouTube'], ['subsonic', 'Subsonic'] ];
var uriServiceDetectList = [['youtube.com', 'yt'], ['soundcloud.com', 'sc']];
function scrollToTop() {
var divtop = 0;
$('body,html').animate({
scrollTop : divtop
}, 250);
}
function scrollToTracklist() {
/* if (isMobileWebkit) {
playlistslistScroll.refresh();
}
*/
var divtop = $("#playlisttracksdiv").offset().top - 50;
$('body,html').animate({
scrollTop : divtop
}, 250);
}
//A hack to find the name of the first artist of a playlist. this is not yet returned by mopidy
//does not work wel with multiple artists of course
function getArtist(pl) {
for (var i = 0; i < pl.length; i++) {
for (var j = 0; j < pl[i].artists.length; j++) {
if (pl[i].artists[j].name != '') {
return pl[i].artists[j].name;
}
}
};
}
//A hack to find the first album of a playlist. this is not yet returned by mopidy
function getAlbum(pl) {
for (var i = 0; i < pl.length; i++) {
if (pl[i].album.name != '') {
return pl[i].album.name;
}
};
}
/********************************************************
* break up results and put them in album tables
*********************************************************/
function albumTracksToTable(pl, target, uri) {
var tmp = '<ul class="songsOfAlbum table" >';
var liId = '';
var targetmin = target.substr(1);
$(target).empty();
for (var i = 0; i < pl.length; i++) {
popupData[pl[i].uri] = pl[i];
liID = targetmin + '-' + pl[i].uri;
tmp += renderSongLi(pl[i], liID, uri, 'playTrackByUri');
};
tmp += '</ul>';
$(target).html(tmp);
$(target).attr('data', uri);
}
function renderSongLi(song, liID, uri, playlistType){
var name;
if (!song.name || song.name == '') {
name = uri.split('/');
name = decodeURI(name[name.length - 1]);
} else {
name = song.name;
}
// var iconClass = getMediaClass(liID.split('-')[1]);
songLi = '<li class="song albumli" id="' + liID + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\',\'' + song.uri + '\');">' +
'<i class="fa fa-ellipsis-v"></i>' +
'</a>' +'<a href="#" onclick="return ' + playlistType + '(\'' + song.uri + '\',\'' + uri + '\');">' +
// '<h1 class="trackname"><i class="' + iconClass + '"></i> ' + name + '</h1>' +
'<h1 class="trackname">' + name + '</h1>' +
'</a>' +
'</li>';
return songLi;
}
function resultsToTables(results, target, uri) {
if (!results) { return }
if (target == '#currenttable') {
playlistType = 'playTrackQueueByUri';
} else {
playlistType = 'playTrackByUri';
}
var newalbum = [];
//keep a list of albums for retreiving of covers
var coversList = [];
var nextname = '';
var count = 0;
$(target).html('');
//break into albums and put in tables
var html = '';
var tableid, j, artistname, alburi, name, iconClass;
var targetmin = target.substr(1);
$(target).attr('data', uri);
var length = 0 || results.length;
for ( i = 0; i < length; i++) {
//create album if none extists
if (!results[i].album) { results[i].album={}; }
//create album uri if there is none
if (!results[i].album.uri) { results[i].album.uri = 'x'; }
if (!results[i].album.name) { results[i].album.name = ''; }
//create name if there is no one
if (!results[i].name || results[i].name == '') {
name = results[i].uri.split('/');
results[i].name = decodeURI(name[name.length - 1]) || 'Track ' + String(i);
}
//leave out unplayable items
if (results[i].name.substring(0,12) == '[unplayable]') continue;
newalbum.push(results[i]);
nextname = '';
if ((i < length - 1) && results[i+1].album && results[i+1].album.name ) {
nextname = results[i + 1].album.name;
}
if (results[i].length == -1) {
html += '<li class="albumli"><a href="#"><h1><i class="' + iconClass + '"></i> ' + results[i].name + ' [Stream]</h1></a></li>';
newalbum = [];
nextname = '';
} else {
if ( (results[i].album.name != nextname) || (nextname == '') ) {
tableid = 'art' + i;
//render differently if only one track in the album
if ( newalbum.length == 1 ) {
if (i != 0) { html += '<li class="smalldivider"> &nbsp;</li>'; }
iconClass = getMediaClass(newalbum[0].uri);
html += '<li class="song albumli" id="' + targetmin + '-' + newalbum[0].uri + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\',\'' + newalbum[0].uri + '\');">' +
'<i class="fa fa-ellipsis-v"></i></a>' +
'<a href="#" onclick="return ' + playlistType + '(\'' + newalbum[0].uri + '\',\'' + uri + '\');">' +
'<h1><i class="' + iconClass + '"></i> ' + newalbum[0].name + "</h1><p>";
/* '<span style="float: right;">' + timeFromSeconds(newalbum[0].length / 1000) + '</span>'; */
if (newalbum[0].artists) {
for ( j = 0; j < newalbum[0].artists.length; j++) {
html += newalbum[0].artists[j].name;
html += (j == newalbum[0].artists.length - 1) ? '' : ' / ';
//stop after 3
if (j > 2) {
html += '...';
break;
}
}
}
if ( newalbum[0].album.name != '') { html += ' / ';}
html += '<em>' + newalbum[0].album.name + '</em></p>';
html += '</a></li>';
popupData[newalbum[0].uri] = newalbum[0];
newalbum = [];
} else { //newalbum length
if ( results[i].album.uri && results[i].album.name ) {
// iconClass = getMediaClass(results[i].album.uri);
iconClass = getMediaClass(newalbum[0].uri);
html += '<li class="albumdivider">';
html += '<a href="#" onclick="return showAlbum(\'' + results[i].album.uri + '\');"><img id="' +
targetmin + '-cover-' + i + '" class="artistcover" width="30" height="30" /><h1><i class="' + iconClass + '"></i> ' + results[i].album.name + '</h1><p>';
}
if (results[i].album.artists) {
for (j = 0; j < results[i].album.artists.length; j++) {
html += results[i].album.artists[j].name;
html += (j == results[i].album.artists.length - 1) ? '' : ' / ';
//stop after 3
if (j > 2) {
child += '...';
break;
}
}
}
html += '</p></a></li>';
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 + '\');">';
//hERE!
var liID = targetmin + '-' + newalbum[j].uri;
html+= renderSongLi(newalbum[j], liID, uri, playlistType);
//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 = [];
if (results[i].album) {
coversList.push([results[i].album, i]);
}
} //newalbum length
if (results[i].album) {
coversList.push([results[i].album, i]);
}
} //albums name
}
}
tableid = "#" + tableid;
$(target).html(html);
$(target).attr('data', uri);
//retreive albumcovers
for (i = 0; i < coversList.length; i++){
// console.log(coversList[i]);
getCover(coversList[i][0], target + '-cover-' + coversList[i][1], 'small');
}
}
//process updated playlist to gui
function playlisttotable(pl, target, uri) {
var tmp = '';
$(target).html('');
var targetmin = target.substr(1);
var child = '';
for (var i = 0; i < pl.length; i++) {
if (pl[i]) {
popupData[pl[i].uri] = pl[i];
child = '<li id="' + targetmin + '-' + pl[i].uri + '"><a href="#" onclick="return popupTracks(event, \'' + uri + '\',\'' + pl[i].uri + '\');">';
child += '<h1>' + pl[i].name + "</h1>";
child += '<p>';
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++) {
if (pl[i].artists[j]) {
child += pl[i].artists[j].name;
child += (j == pl[i].artists.length - 1) ? '' : ' / ';
//stop after 3
if (j > 2) {
child += '...';
break;
}
}
}
child += ' / <em>' + pl[i].album.name + '</em></p>';
child += '</a></li>';
tmp += child;
}
};
$(target).html(tmp);
$(target).attr('data', uri);
}
function getPlaylistFromUri(uri) {
if (playlists[uri]) {
return playlists[uri];
}
if (customPlaylists[uri]) {
return customPlaylists[uri];
}
}
function getTracksFromUri(uri) {
var pl = getPlaylistFromUri(uri);
if (pl) {
return pl.tracks;
} else if (customTracklists[uri]) {
return customTracklists[uri];
}
return [];
}
//convert time to human readable format
function timeFromSeconds(length) {
var d = Number(length);
var h = Math.floor(d / 3600);
var m = Math.floor(d % 3600 / 60);
var s = Math.floor(d % 3600 % 60);
return ((h > 0 ? h + ":" : "") + (m > 0 ? (h > 0 && m < 10 ? "0" : "") + m + ":" : "0:") + (s < 10 ? "0" : "") + s);
}
/******* Toast ***/
function toast (message, delay, textOnly) {
textOnl = textOnly || false;
message = message || "Loading...";
delay = delay || 1000;
$.mobile.loading( 'show', {
text: message,
textVisible: true,
theme: 'a',
textonly: textOnl
});
if(delay > 0) {
setTimeout(function(){
$.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#!:.?+=&%@!\-\/]))?/
// return regexp.test(str) || isServiceUri(str);
return regexp.test(str);
}
function validServiceUri(str) {
return validUri(str) || isServiceUri(str);
}
/*
$.event.special.swipe = $.extend($.event.special.swipe, {
start: function( event ) {
var data = event.originalEvent.touches ?
event.originalEvent.touches[ 0 ] : event;
return {
time: ( new Date() ).getTime(),
coords: [ data.pageX, data.pageY ],
origin: $( event.target ),
offset: $('body').scrollTop()
};
},
stop: function( event ) {
var data = event.originalEvent.touches ?
event.originalEvent.touches[ 0 ] : event;
return {
time: ( new Date() ).getTime(),
coords: [ data.pageX, data.pageY ],
offset: $('body').scrollTop()
};
alert.log('stop');
},
handleSwipe: function( start, stop ) {
var swipe = $.event.special.swipe,
x = Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ),
y = Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ),
offset = Math.abs( start.offset - stop.offset ),
time = stop.time - start.time;
if ( time < swipe.durationThreshold && x > swipe.horizontalDistanceThreshold && ( y + offset )
< swipe.verticalDistanceThreshold ) {
start.origin.trigger( "swipe" ).trigger( ( start.coords[ 0 ] - stop.coords[ 0 ] ) ? "swipeleft" : "swiperight" );
// alert(x + ' ' + y + ' ' + time + ' ' + offset + ' ' + swipe.verticalDistanceThreshold);
}
}
});
*/
function isStreamUri (uri) {
var uriSplit = uri.split(":");
var a = validUri(uri);
var b = radioExtensionsList.indexOf(uriSplit[0].toLowerCase()) >= 0;
return a || b;
}
function getMediaClass(uri) {
var uriSplit = uri.split(":")[0].toLowerCase();
for (var i = 0; i < uriClassList.length; i++) {
if (uriSplit == uriClassList[i][0]) {
return "fa " + uriClassList[i][1];
}
}
return '';
}
function getMediaHuman(uri) {
var uriSplit = uri.split(":")[0].toLowerCase();
for (var i = 0; i < uriHumanList.length; i++) {
if (uriSplit == uriHumanList[i][0]) {
return uriHumanList[i][1];
}
}
return '';
}
function isServiceUri(uri) {
var uriSplit = uri.split(":")[0].toLowerCase();
var retVal = false;
for (var i = 0; i < uriClassList.length; i++) {
if (uriSplit == uriClassList[i][0]) {
retVal = true;
}
}
for (var i = 0; i < radioExtensionsList.length; i++) {
if (uriSplit == radioExtensionsList[i]) {
retVal = true;
}
}
return retVal;
}

View File

@ -47,10 +47,10 @@ var customTracklists = [];
var browseStack = [];
var ua = navigator.userAgent,
isMobileSafari = /Mac/.test(ua) && /Mobile/.test(ua), isMobileWebkit = /WebKit/.test(ua) && /Mobile/.test(ua), isMobile = /Mobile/.test(ua), isWebkit = /WebKit/.test(ua);
// the first part of Mopidy extensions which serve radiostations (streams)
var radioExtensionsUris = ['somafm', 'tunein', 'dirble'];
isMobileSafari = /Mac/.test(ua) && /Mobile/.test(ua),
isMobileWebkit = /WebKit/.test(ua) && /Mobile/.test(ua),
isMobile = /Mobile/.test(ua),
isWebkit = /WebKit/.test(ua);
//constants
PROGRAM_NAME = 'MusicBox';
@ -77,30 +77,63 @@ TRACK_TIMER = 1000;
//check status timer, every 5 or 10 sec
STATUS_TIMER = 10000;
//var uriHumanList = [ ['spotify', 'Spotify'], ['local', 'Local Files'], ['podcast', 'Podcasts'], ['dirble', 'Dirble'],
// ['tunein', 'TuneIn'], ['soundcloud', 'SoundCloud'], ['sc', 'SoundCloud'], ['gmusic', 'Google Music'], ['internetarchive', 'Internet Archive'], ['somafm', 'Soma FM'], ['yt', 'YouTube'], ['youtube', 'YouTube'], ['subsonic', 'Subsonic'] ];
// the first part of Mopidy extensions which serve radio streams
var radioExtensionsList = ['somafm', 'tunein', 'dirble', 'audioaddict'];
var uriClassList = [ ['spotify', 'fa-spotify'], ['local', 'fa-file-sound-o'], ['podcast', 'fa-rss-square'], ['dirble', 'fa-microphone'],
['tunein', 'fa-headphones'], ['soundcloud', 'fa-soundcloud'], ['sc', 'fa-soundcloud'], ['gmusic', 'fa-google'], ['internetarchive', 'fa-university'], ['somafm', 'fa-flask'], ['youtube', 'fa-youtube'], ['yt', 'fa-youtube'], ['subsonic', 'fa-folder-open'] ];
var uriClassList = [
['spotify', 'fa-spotify'],
['spotifytunigo', 'fa-spotify'],
['local', 'fa-file-sound-o'],
['podcast', 'fa-rss-square'],
['dirble', 'fa-microphone'],
['tunein', 'fa-headphones'],
['soundcloud', 'fa-soundcloud'],
['sc', 'fa-soundcloud'],
['gmusic', 'fa-google'],
['internetarchive', 'fa-university'],
['somafm', 'fa-flask'],
['youtube', 'fa-youtube'],
['yt', 'fa-youtube'],
['audioaddict', 'fa-bullhorn'],
['subsonic', 'fa-folder-open']
];
var uriHumanList = [ ['spotify', 'Spotify'], ['local', 'Local Files'], ['podcast', 'Podcasts'], ['dirble', 'Dirble'],
['tunein', 'TuneIn'], ['soundcloud', 'SoundCloud'], ['gmusic', 'Google Music'], ['internetarchive', 'Internet Archive'], ['somafm', 'Soma FM'], ['youtube', 'YouTube'], ['subsonic', 'Subsonic'] ];
var uriHumanList = [
['spotify', 'Spotify'],
['spotifytunigo', 'Spotify Browse'],
['local', 'Local Files'],
['podcast', 'Podcasts'],
['dirble', 'Dirble'],
['tunein', 'TuneIn'],
['soundcloud', 'SoundCloud'],
['gmusic', 'Google Music'],
['internetarchive', 'Internet Archive'],
['somafm', 'Soma FM'],
['youtube', 'YouTube'],
['audioaddict', 'AudioAddict'],
['subsonic', 'Subsonic']
];
var uriServiceDetectList = [
['youtube.com', 'yt'],
['soundcloud.com', 'sc']
];
function scrollToTop() {
var divtop = 0;
$('body,html').animate({
scrollTop : divtop
scrollTop: divtop
}, 250);
}
function scrollToTracklist() {
/* if (isMobileWebkit) {
/* if (isMobileWebkit) {
playlistslistScroll.refresh();
}
*/
var divtop = $("#playlisttracksdiv").offset().top - 50;
$('body,html').animate({
scrollTop : divtop
scrollTop: divtop
}, 250);
}
@ -137,46 +170,48 @@ function albumTracksToTable(pl, target, uri) {
popupData[pl[i].uri] = pl[i];
liID = targetmin + '-' + pl[i].uri;
tmp += renderSongLi(pl[i], liID, uri, 'playTrackByUri');
//child = '<li id="' + targetmin + '-' + pl[i].uri + '"><a href="#" onclick="return popupTracks(event, \'' + uri + '\',\'' + pl[i].uri + '\');">';
// child += '<p style="float:right; display: inline;">' + timeFromSeconds(pl[i].length / 1000) + '</p><h1>' + pl[i].name + '</h1></a></li>';
};
tmp += '</ul>';
$(target).html(tmp);
$(target).attr('data', uri);
}
function renderSongLi(song, liID, uri, playlistType){
function renderSongLi(song, liID, uri, playlistType) {
var name;
if (!song.name || song.name == '') {
name = uri.split('/');
name = decodeURI(name[name.length - 1]);
name = uri.split('/');
name = decodeURI(name[name.length - 1]);
} else {
name = song.name;
name = song.name;
}
// var iconClass = getMediaClass(liID.split('-')[1]);
// var iconClass = getMediaClass(liID.split('-')[1]);
songLi = '<li class="song albumli" id="' + liID + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\',\'' + song.uri + '\');">' +
'<i class="fa fa-ellipsis-v"></i>' +
'</a>' +'<a href="#" onclick="return ' + playlistType + '(\'' + song.uri + '\',\'' + uri + '\');">' +
// '<h1 class="trackname"><i class="' + iconClass + '"></i> ' + name + '</h1>' +
'<h1 class="trackname">' + name + '</h1>' +
'</a>' + '<a href="#" onclick="return ' + playlistType + '(\'' + song.uri + '\',\'' + uri + '\');">' +
// '<h1 class="trackname"><i class="' + iconClass + '"></i> ' + name + '</h1>' +
'<h1 class="trackname">' + name + '</h1>' +
'</a>' +
'</li>';
'</li>';
return songLi;
}
function resultsToTables(results, target, uri) {
if (!results) { return }
if (!results) {
return
}
if (target == '#currenttable') {
playlistType = 'playTrackQueueByUri';
} else if (target == SEARCH_TRACK_TABLE) {
playlistType = 'playTrackByUri';
} else {
playlistType = 'playTrackByUri';
}
var newalbum = [];
//keep a list of albums for retreiving of covers
var coversList = [];
var nextname = '';
var count = 0;
$(target).html('');
@ -187,103 +222,120 @@ function resultsToTables(results, target, uri) {
var targetmin = target.substr(1);
$(target).attr('data', uri);
var length = 0 || results.length;
for ( i = 0; i < length; i++) {
//create album if none extists
if (!results[i].album) { results[i].album={}; }
//create album uri if there is none
if (!results[i].album.uri) { results[i].album.uri = 'x'; }
if (!results[i].album.name) { results[i].album.name = ''; }
//create name if there is no one
for (i = 0; i < length; i++) {
//create album if none extists
if (!results[i].album) {
results[i].album = {};
}
//create album uri if there is none
if (!results[i].album.uri) {
results[i].album.uri = 'x';
}
if (!results[i].album.name) {
results[i].album.name = '';
}
//create name if there is no one
if (!results[i].name || results[i].name == '') {
name = results[i].uri.split('/');
results[i].name = decodeURI(name[name.length - 1]) || 'Track ' + String(i);
name = results[i].uri.split('/');
results[i].name = decodeURI(name[name.length - 1]) || 'Track ' + String(i);
}
//leave out unplayable items
if (results[i].name.substring(0,12) == '[unplayable]') continue;
if (results[i].name.substring(0, 12) == '[unplayable]') continue;
newalbum.push(results[i]);
nextname = '';
if ((i < length - 1) && results[i+1].album && results[i+1].album.name ) {
nextname = '';
if ((i < length - 1) && results[i + 1].album && results[i + 1].album.name) {
nextname = results[i + 1].album.name;
}
if (results[i].length == -1) {
html += '<li class="albumli"><a href="#"><h1><i class="' + iconClass + '"></i> ' + results[i].name + ' [Stream]</h1></a></li>';
newalbum = [];
nextname = '';
} else {
if ( (results[i].album.name != nextname) || (nextname == '') ) {
tableid = 'art' + i;
//render differently if only one track in the album
if ( newalbum.length == 1 ) {
if (i != 0) { html += '<li class="smalldivider"> &nbsp;</li>'; }
iconClass = getMediaClass(newalbum[0].uri);
html += '<li class="song albumli" id="' + targetmin + '-' + newalbum[0].uri + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\',\'' + newalbum[0].uri + '\');">' +
'<i class="fa fa-ellipsis-v"></i></a>' +
'<a href="#" onclick="return ' + playlistType + '(\'' + newalbum[0].uri + '\',\'' + uri + '\');">' +
'<h1><i class="' + iconClass + '"></i> ' + newalbum[0].name + "</h1><p>";
/* '<span style="float: right;">' + timeFromSeconds(newalbum[0].length / 1000) + '</span>'; */
if (newalbum[0].artists) {
for ( j = 0; j < newalbum[0].artists.length; j++) {
html += newalbum[0].artists[j].name;
html += (j == newalbum[0].artists.length - 1) ? '' : ' / ';
//stop after 3
if (j > 2) {
html += '...';
break;
}
}
}
if ( newalbum[0].album.name != '') { html += ' / ';}
html += '<em>' + newalbum[0].album.name + '</em></p>';
html += '</a></li>';
popupData[newalbum[0].uri] = newalbum[0];
newalbum = [];
} else { //newalbum length
if ( results[i].album.uri && results[i].album.name ) {
// iconClass = getMediaClass(results[i].album.uri);
nextname = '';
} else {
if ((results[i].album.name != nextname) || (nextname == '')) {
tableid = 'art' + i;
//render differently if only one track in the album
if (newalbum.length == 1) {
if (i != 0) {
html += '<li class="smalldivider"> &nbsp;</li>';
}
iconClass = getMediaClass(newalbum[0].uri);
html += '<li class="albumdivider">';
html += '<a href="#" onclick="return showAlbum(\'' + results[i].album.uri + '\');"><img id="' +
targetmin + '-cover-' + i + '" class="artistcover" width="30" height="30" /><h1><i class="' + iconClass + '"></i> ' + results[i].album.name + '</h1><p>';
}
if (results[i].album.artists) {
for (j = 0; j < results[i].album.artists.length; j++) {
html += results[i].album.artists[j].name;
html += (j == results[i].album.artists.length - 1) ? '' : ' / ';
//stop after 3
if (j > 2) {
child += '...';
break;
html += '<li class="song albumli" id="' + targetmin + '-' + newalbum[0].uri + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\',\'' + newalbum[0].uri + '\');">' +
'<i class="fa fa-ellipsis-v"></i></a>' +
'<a href="#" onclick="return ' + playlistType + '(\'' + newalbum[0].uri + '\',\'' + uri + '\');">' +
'<h1><i class="' + iconClass + '"></i> ' + newalbum[0].name + "</h1><p>";
/* '<span style="float: right;">' + timeFromSeconds(newalbum[0].length / 1000) + '</span>'; */
if (newalbum[0].artists) {
for (j = 0; j < newalbum[0].artists.length; j++) {
html += newalbum[0].artists[j].name;
html += (j == newalbum[0].artists.length - 1) ? '' : ' / ';
//stop after 3
if (j > 2) {
html += '...';
break;
}
}
}
}
html += '</p></a></li>';
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 + '\');">';
}
if (newalbum[0].album.name != '') {
html += ' / ';
}
html += '<em>' + newalbum[0].album.name + '</em></p>';
html += '</a></li>';
//hERE!
var liID = targetmin + '-' + newalbum[j].uri;
html+= renderSongLi(newalbum[j], liID, uri, playlistType);
popupData[newalbum[0].uri] = newalbum[0];
newalbum = [];
} else { //newalbum length
if (results[i].album.uri && results[i].album.name) {
// iconClass = getMediaClass(results[i].album.uri);
iconClass = getMediaClass(newalbum[0].uri);
html += '<li class="albumdivider">';
html += '<a href="#" onclick="return showAlbum(\'' + results[i].album.uri + '\');"><img id="' +
targetmin + '-cover-' + i + '" class="artistcover" width="30" height="30" /><h1><i class="' + iconClass + '"></i> ' + results[i].album.name + '</h1><p>';
}
if (results[i].album.artists) {
for (j = 0; j < results[i].album.artists.length; j++) {
html += results[i].album.artists[j].name;
html += (j == results[i].album.artists.length - 1) ? '' : ' / ';
//stop after 3
if (j > 2) {
child += '...';
break;
}
}
}
html += '</p></a></li>';
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>';
//hERE!
var liID = targetmin + '-' + newalbum[j].uri;
html += renderSongLi(newalbum[j], liID, uri, playlistType);
//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 = [];
if (results[i].album) {
coversList.push([results[i].album, i]);
}
} //newalbum length
if (results[i].album) {
coversList.push([results[i].album, i]);
}
;
artistname = results[i].artists[0].name;
getCover(artistname, results[i].album.name, target + '-cover-' + i, 'small');
// customTracklists[results[i].album.uri] = newalbum;
newalbum = [];
} //newalbum length
} //albums name
} //albums name
}
}
tableid = "#" + tableid;
$(target).html(html);
$(target).attr('data', uri);
//retreive albumcovers
for (i = 0; i < coversList.length; i++) {
// console.log(coversList[i]);
getCover(coversList[i][0], target + '-cover-' + coversList[i][1], 'small');
}
}
//process updated playlist to gui
@ -293,28 +345,28 @@ function playlisttotable(pl, target, uri) {
var targetmin = target.substr(1);
var child = '';
for (var i = 0; i < pl.length; i++) {
if (pl[i]) {
if (pl[i]) {
popupData[pl[i].uri] = pl[i];
child = '<li id="' + targetmin + '-' + pl[i].uri + '"><a href="#" onclick="return popupTracks(event, \'' + uri + '\',\'' + pl[i].uri + '\');">';
child += '<h1>' + pl[i].name + "</h1>";
child = '<li id="' + targetmin + '-' + pl[i].uri + '"><a href="#" onclick="return popupTracks(event, \'' + uri + '\',\'' + pl[i].uri + '\');">';
child += '<h1>' + pl[i].name + "</h1>";
child += '<p>';
child += '<span style="float: right;">' + timeFromSeconds(pl[i].length / 1000) + '</span>';
// <span class="ui-icon ui-icon-arrow-r ui-icon-shadow">&nbsp;</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++) {
if (pl[i].artists[j]) {
if (pl[i].artists[j]) {
child += pl[i].artists[j].name;
child += (j == pl[i].artists.length - 1) ? '' : ' / ';
//stop after 3
if (j > 2) {
child += '...';
break;
}
}
child += (j == pl[i].artists.length - 1) ? '' : ' / ';
//stop after 3
if (j > 2) {
child += '...';
break;
}
}
}
child += ' / <em>' + pl[i].album.name + '</em></p>';
child += ' / <em>' + pl[i].album.name + '</em></p>';
child += '</a></li>';
tmp += child;
}
tmp += child;
}
};
$(target).html(tmp);
@ -351,18 +403,18 @@ function timeFromSeconds(length) {
/******* Toast ***/
function toast (message, delay, textOnly) {
function toast(message, delay, textOnly) {
textOnl = textOnly || false;
message = message || "Loading...";
delay = delay || 1000;
$.mobile.loading( 'show', {
text: message,
textVisible: true,
theme: 'a',
textonly: textOnl
$.mobile.loading('show', {
text: message,
textVisible: true,
theme: 'a',
textonly: textOnl
});
if(delay > 0) {
setTimeout(function(){
if (delay > 0) {
setTimeout(function() {
$.mobile.loading('hide');
}, delay);
}
@ -375,9 +427,9 @@ function showLoading(on) {
if (on) {
$("body").css("cursor", "progress");
$.mobile.loading('show', {
text : 'Loading data from ' + PROGRAM_NAME + '. Please wait...',
textVisible : true,
theme : 'a'
text: 'Loading data from ' + PROGRAM_NAME + '. Please wait...',
textVisible: true,
theme: 'a'
});
} else {
$("body").css("cursor", "default");
@ -388,9 +440,9 @@ function showLoading(on) {
function showOffline(on) {
if (on) {
$.mobile.loading('show', {
text : 'Trying to reach ' + PROGRAM_NAME + '. Please wait...',
textVisible : true,
theme : 'a'
text: 'Trying to reach ' + PROGRAM_NAME + '. Please wait...',
textVisible: true,
theme: 'a'
});
} else {
$.mobile.loading('hide');
@ -401,9 +453,14 @@ function showOffline(on) {
// from http://dzone.com/snippets/validate-url-regexp
function validUri(str) {
var regexp = /^(mms|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
// return regexp.test(str) || isServiceUri(str);
return regexp.test(str);
}
function validServiceUri(str) {
return validUri(str) || isServiceUri(str);
}
/*
$.event.special.swipe = $.extend($.event.special.swipe, {
start: function( event ) {
@ -425,7 +482,7 @@ $.event.special.swipe = $.extend($.event.special.swipe, {
coords: [ data.pageX, data.pageY ],
offset: $('body').scrollTop()
};
alert.log('stop');
alert.log('stop');
},
handleSwipe: function( start, stop ) {
@ -439,16 +496,16 @@ $.event.special.swipe = $.extend($.event.special.swipe, {
start.origin.trigger( "swipe" ).trigger( ( start.coords[ 0 ] - stop.coords[ 0 ] ) ? "swipeleft" : "swiperight" );
// alert(x + ' ' + y + ' ' + time + ' ' + offset + ' ' + swipe.verticalDistanceThreshold);
// alert(x + ' ' + y + ' ' + time + ' ' + offset + ' ' + swipe.verticalDistanceThreshold);
}
}
});
*/
function isRadioUri (uri) {
function isStreamUri(uri) {
var uriSplit = uri.split(":");
var a = validUri(uri);
var b = radioExtensionsUris.indexOf(uriSplit[0].toLowerCase()) >= 0;
var b = radioExtensionsList.indexOf(uriSplit[0].toLowerCase()) >= 0;
return a || b;
}
@ -472,3 +529,21 @@ function getMediaHuman(uri) {
return '';
}
function isServiceUri(uri) {
var uriSplit = uri.split(":")[0].toLowerCase();
var retVal = false;
for (var i = 0; i < uriClassList.length; i++) {
if (uriSplit == uriClassList[i][0]) {
retVal = true;
}
}
for (var i = 0; i < radioExtensionsList.length; i++) {
if (uriSplit == radioExtensionsList[i]) {
retVal = true;
}
}
return retVal;
}

View File

@ -24,6 +24,13 @@ function resizeMb() {
$("#infoname").html(songdata.name);
$("#infoartist").html(artiststext);
if ($(window).width() <= 960) {
// $('#playlisttracksdiv').hide();
// $('#playlistslistdiv').show();
} else {
$('#playlisttracksdiv').show();
$('#playlistslistdiv').show();
}
// //set height of playlist scrollers
/* if ($(window).width() > 960) {
$('#playlisttracksdiv').show();
@ -76,8 +83,8 @@ function setSongInfo(data) {
artiststext = '';
if (validUri(data.name)) {
for (var key in radioStations) {
rs = radioStations[key];
for (var key in streamUris) {
rs = streamUris[key];
if (rs && rs[1] == data.name) {
data.name = (rs[0] || rs[1]);
}
@ -93,8 +100,8 @@ function setSongInfo(data) {
$("#songlength").html('');
pausePosTimer();
$('#trackslider').slider('disable');
$('#radionameinput').val(data.name);
$('#radiouriinput').val(data.uri);
// $('#streamnameinput').val(data.name);
// $('#streamuriinput').val(data.uri);
} else {
songlength = data.length;
$("#songlength").html(timeFromSeconds(data.length / 1000));
@ -114,10 +121,9 @@ function setSongInfo(data) {
}
arttmp = artistshtml;
}
if (data.album && data.album.name) {
$("#modalalbum").html('<a href="#" onclick="return showAlbum(\'' + data.album.uri + '\');">' + data.album.name + '</a>');
getCover(artiststext, data.album.name, '#infocover, #controlspopupimage', 'extralarge');
getCover(data.album, '#infocover, #controlspopupimage', 'extralarge');
} else {
$("#modalalbum").html('');
$("#infocover").attr('src', 'images/default_cover.png');
@ -190,8 +196,8 @@ function popupTracks(e, listuri, trackuri) {
return false;
}
function showAlbumPopup() {
uri = $('#popupTracks').data("track");
function showAlbumPopup(popupId) {
uri = $(popupId).data("track");
showAlbum(popupData[uri].album.uri);
}
@ -205,7 +211,8 @@ function initSocketevents() {
getCurrentPlaylist();
updateStatusOfAll();
getPlaylists();
getBrowseDir();
getBrowseDir();
getSearchSchemes();
showLoading(false);
$(window).hashchange();
});
@ -284,14 +291,11 @@ function enterFullscreen() {
elem.requestFullscreen();
}
}
}
function exitFullscreen() {
document.webkitExitFullscreen();
document.mozCancelFullscreen();
document.exitFullscreen();
}
function onFullScreenEnter() {
@ -323,11 +327,12 @@ function setHeadline(site){
if(str==""){
str=site;
}
$('#contentHeadline').text(str);
$('#contentHeadline').html('<a href="#home" onclick="switchContent(\'home\'); return false;">' + str + '</a>');
}
//update timer
function updateStatusTimer() {
// console.log('statustimer');
mopidy.playback.getCurrentTrack().then(processCurrenttrack, console.error);
mopidy.playback.getTimePosition().then(processCurrentposition, console.error);
//TODO check offline?
@ -370,11 +375,15 @@ function locationHashChanged() {
$('#' + divid + 'pane').show();
switch(divid) {
case 'home':
$('#navhome a').addClass('ui-state-active ui-state-persist ui-btn-active');
break;
case 'nowPlaying':
$('#navnowPlaying a').addClass('ui-state-active ui-state-persist ui-btn-active');
break;
case 'current':
$('#navcurrent a').addClass('ui-state-active ui-state-persist ui-btn-active');
getCurrentPlaylist();
break;
case 'playlists':
$('#navplaylists a').addClass('ui-state-active ui-state-persist ui-btn-active');
@ -389,8 +398,8 @@ function locationHashChanged() {
initSearch($('#searchinput').val());
}
break;
case 'radio':
$('#navradio a').addClass('ui-state-active ui-state-persist ui-btn-active');
case 'stream':
$('#navstream a').addClass('ui-state-active ui-state-persist ui-btn-active');
break;
case 'artists':
if (uri != '') {
@ -452,7 +461,7 @@ $(document).ready(function(event) {
resetSong();
if (location.hash.length < 2) {
switchContent("playlists");
switchContent("home");
}
@ -491,6 +500,8 @@ $(document).ready(function(event) {
if (!isMusicBox) {
$('#navSettings').hide();
$('#navshutdown').hide();
$('#homesettings').hide();
$('#homeshutdown').hide();
}
//navigation stuff
@ -513,7 +524,7 @@ $(document).ready(function(event) {
return true;
}
});
initRadio();
initStreams();
if ($(window).width() < 980) {
$("#panel").panel("close");
@ -544,7 +555,6 @@ $(document).ready(function(event) {
$("#panel").panel("close");
event.stopImmediatePropagation(); }
} );
});
function updatePlayIcons (uri) {

View File

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -57,6 +57,18 @@ function initSearch() {
/********************************************************
* process results of a search
*********************************************************/
//# speed clone http://jsperf.com/cloning-an-object/2
function clone(obj) {
var target = {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
target[i] = obj[i];
}
}
return target;
}
function processSearchResults(resultArr) {
$(SEARCH_TRACK_TABLE).empty();
$(SEARCH_ARTIST_TABLE).empty();
@ -65,10 +77,9 @@ function processSearchResults(resultArr) {
// Merge results from different backends.
// TODO should of coures have multiple tables
var results = {'tracks': [], 'artists': [], 'albums': []};
var emptyResult = true;
for (var i = 0; i < resultArr.length; ++i) {
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]);
@ -76,6 +87,31 @@ function processSearchResults(resultArr) {
}
}
}
*/
for (var i = 0; i < resultArr.length; i++) {
if (resultArr[i].tracks) {
for (j = 0; j < resultArr[i].tracks.length; j++) {
results.tracks.push(resultArr[i].tracks[j]);
emptyResult = false;
}
}
if (resultArr[i].artists) {
for (j = 0; j < resultArr[i].artists.length; j++) {
results.artists.push(resultArr[i].artists[j]);
emptyResult = false;
}
}
if (resultArr[i].albums) {
for (j = 0; j < resultArr[i].albums.length; j++) {
results.albums.push(resultArr[i].albums[j]);
emptyResult = false;
}
}
}
// console.log(resultArr, results);
customTracklists['trackresultscache'] = results.tracks;
@ -203,7 +239,11 @@ function getCurrentPlaylist() {
function togglePlaylists() {
if ($(window).width() <= 960) {
$('#playlisttracksdiv').toggle();
$('#playlistslistdiv').toggle();
//Hide other div
($('#playlisttracksdiv').is(":visible")) ? $('#playlistslistdiv').hide() : $('#playlistslistdiv').show();
} else {
$('#playlisttracksdiv').show();
$('#playlistslistdiv').show();
}
return true;
}
@ -218,7 +258,7 @@ function showTracklist(uri) {
} else {
showLoading(true);
}
updatePlayIcons(uri);
$('#playlistslist li a').each(function() {
$(this).removeClass("playlistactive");
if (this.id == uri) {
@ -227,6 +267,7 @@ function showTracklist(uri) {
});
// scrollToTracklist();
//lookup recent tracklist
mopidy.playlists.lookup(uri).then(processGetTracklist, console.error);
return false;
}
@ -236,6 +277,7 @@ function showTracklist(uri) {
*/
function showArtist(nwuri) {
$('#popupQueue').popup('close');
$('#popupTracks').popup('close');
$('#controlsmodal').popup('close');
$(ARTIST_TABLE).empty();
@ -244,7 +286,10 @@ function showArtist(nwuri) {
//TODO cache
$('#h_artistname').html('');
showLoading(true);
mopidy.library.lookup(nwuri).then(processArtistResults, console.error);
mopidy.library.lookup(nwuri).then(function(resultArr) {
resultArr.uri = nwuri;
processArtistResults(resultArr);
}, console.error);
switchContent('artists', nwuri);
scrollToTop();
setSongInfo();
@ -252,12 +297,13 @@ function showArtist(nwuri) {
}
function showAlbum(uri) {
$('#popupQueue').popup('close');
$('#popupTracks').popup('close');
$('#controlsmodal').popup('close');
$(ALBUM_TABLE).empty();
//fill from cache
var pl = getTracksFromUri(uri);
if (pl) {
if (pl.length>0) {
albumTracksToTable(pl, ALBUM_TABLE, uri);
var albumname = getAlbum(pl);
var artistname = getArtist(pl);
@ -266,13 +312,19 @@ function showAlbum(uri) {
$('#coverpopupalbumname').html(albumname);
$('#coverpopupartist').html(artistname);
showLoading(false);
getCover(artistname, albumname, '#albumviewcover, #coverpopupimage', 'extralarge');
mopidy.library.lookup(uri).then(processAlbumResults, console.error);
mopidy.library.lookup(uri).then(function(resultArr) {
resultArr.uri = uri;
processAlbumResults(resultArr);
}, console.error);
// getCover(pl, '#albumviewcover, #coverpopupimage', 'extralarge');
} else {
showLoading(true);
$('#h_albumname').html('');
$('#h_albumartist').html('');
mopidy.library.lookup(uri).then(processAlbumResults, console.error);
mopidy.library.lookup(uri).then(function(resultArr) {
resultArr.uri = uri;
processAlbumResults(resultArr);
}, console.error);
}
//show page
switchContent('albums', uri);
@ -297,4 +349,4 @@ function getSearchSchemes() {
$("#selectSearchService").selectmenu( "refresh", true );
}, console.error
);
}
}

View File

@ -9,7 +9,6 @@
* process results of a (new) currently playing track
*********************************************************/
function processCurrenttrack(data) {
// console.log(data);
setSongInfo(data);
}
@ -60,18 +59,13 @@ function processPlaystate(data) {
* process results of a browse list
*********************************************************/
function processBrowseDir(resultArr) {
/*<p><ul><li>Donec id elit non mi porta</li><li>Gravida at eget metus. Fusce dapibus.</li><li>Tellus ac cursus commodo</li></p>
<p><a class="btn" href="#">More &raquo;</a></p>
*/
if ((!resultArr) || (resultArr == '')) {
var backHtml = '<li style="background-color:#ccc"><a href="#" onclick="return getBrowseDir();"><h1 class="trackname"><i class="fa fa-arrow-circle-left"></i> Back</h1></a></li>'
if ( (!resultArr) || (resultArr == '') || (resultArr.length == 0) ) {
$('#browsepath').html('No tracks found...');
$('#browselist').html(backHtml);
showLoading(false);
return;
}
// console.log(resultArr);
if (resultArr.length == 0) {
return;
}
$('#browselist').empty();
@ -88,8 +82,6 @@ function processBrowseDir(resultArr) {
if (resultArr[0].type == 'track' ) {
rooturi = rooturi.replace(":track:", ":directory:");
}
colonindex = rooturi.lastIndexOf(':');
slashindex = rooturi.lastIndexOf('/');
@ -97,8 +89,7 @@ function processBrowseDir(resultArr) {
rooturi = rooturi.slice(0, lastindex);
if (browseStack.length > 0) {
// child += '<li><a href="#" onclick="return getBrowseDir();"><h1 class="trackname">..</h1></a></li>';
child += '<li style="background-color:#ccc"><a href="#" onclick="return getBrowseDir();"><h1 class="trackname"><i class="fa fa-arrow-circle-left"></i> Back</h1></a></li>';
child += backHtml;
}
for (var i = 0; i < resultArr.length; i++) {
@ -132,7 +123,7 @@ function processBrowseDir(resultArr) {
} else {
$('#browsepath').html('');
}
updatePlayIcons(songdata.uri);
showLoading(false);
@ -186,10 +177,6 @@ function processGetTracklist(resultArr) {
setSongInfo();
resultsToTables(playlists[newplaylisturi].tracks, PLAYLIST_TABLE, newplaylisturi);
showLoading(false);
// scrollToTracklist();
// if (isMobileWebkit) {
// playlisttracksScroll.refresh();
// }
}
/********************************************************
@ -206,6 +193,12 @@ function processCurrentPlaylist(resultArr) {
* process results of an artist lookup
*********************************************************/
function processArtistResults(resultArr) {
if (!resultArr || (resultArr.length == 0)) {
$('#h_artistname').text('Artist not found...');
getCover('', '#artistviewimage, #artistpopupimage', 'extralarge');
showLoading(false);
return;
}
customTracklists[resultArr.uri] = resultArr;
resultsToTables(resultArr, ARTIST_TABLE, resultArr.uri);
@ -220,6 +213,13 @@ function processArtistResults(resultArr) {
* process results of an album lookup
*********************************************************/
function processAlbumResults(resultArr) {
// console.log(resultArr);
if (!resultArr || (resultArr.length == 0)) {
$('#h_albumname').text('Album not found...');
getCover('', '#albumviewcover, #coverpopupimage', 'extralarge');
showLoading(false);
return;
}
customTracklists[resultArr.uri] = resultArr;
albumTracksToTable(resultArr, ALBUM_TABLE, resultArr.uri);
var albumname = getAlbum(resultArr);
@ -228,7 +228,7 @@ function processAlbumResults(resultArr) {
$('#h_albumartist').html(artistname);
$('#coverpopupalbumname').html(albumname);
$('#coverpopupartist').html(artistname);
getCover(artistname, albumname, '#albumviewcover, #coverpopupimage', 'extralarge');
setSongInfo();
getCover(resultArr[0].album, '#albumviewcover, #coverpopupimage', 'extralarge');
showLoading(false);
}

View File

@ -1,16 +0,0 @@
/**
* Default Radiostations 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 radioStations = [];
//fill with defaults
radioStations.push(['NPR 24', 'http://nprdmp.ic.llnwd.net/stream/nprdmp_live01_mp3']);
radioStations.push(['3FM Dutch', 'http://icecast.omroep.nl/3fm-bb-mp3']);
radioStations.push(['BBC WorldService', 'http://vprbbc.streamguys.net:8000/vprbbc24.mp3']);
radioStations.push(['Arrow Jazz', 'http://81.173.3.132:8082']);
radioStations.push(['PBS Australia', 'http://eno.emit.com:8000/pbsfm_live_64.mp3']);
radioStations.push(['Groove Salad - Soma FM', 'http://somafm.com/groovesalad.pls']);
radioStations.push(['Kiss FM Berlin', 'http://stream.kissfm.de/kissfm/mp3-128/internetradio/']);
radioStations.push(['Pinguin Radio', 'http://pr320.pinguinradio.com/listen.pls']);

View File

@ -0,0 +1,17 @@
/**
* 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']);