User's favourite streams now saved as an m3u playlist.
This commit is contained in:
parent
d211b92447
commit
0090699818
@ -411,33 +411,22 @@
|
||||
<form>
|
||||
<div class="ui-grid-a pl-breakpoint">
|
||||
<div class="ui-block-a" style="padding: 5px">
|
||||
<p>Select a service and add the URL of the stream you want to listen to.
|
||||
<select id="selectstreamservice" data-native-menu="true">
|
||||
<option value="">Internet Radio (mp3, m3u, asx, etc)</option>
|
||||
<option value="yt">YouTube</option>
|
||||
<option value="">Spotify Uri</option>
|
||||
<option value="sc">SoundCloud</option>
|
||||
<option value="podcast">Podcast</option>
|
||||
</select>
|
||||
<p>Play a specific stream/track and optionally save it to your favourites.
|
||||
<button class="btn" type="button" onclick="return getCurrentlyPlaying();">
|
||||
Get currently playing
|
||||
</button>
|
||||
<input id="streamuriinput" placeholder="URI" class="span2" data-clear-btn="true"
|
||||
onkeypress="return streamPressed(event.keyCode);" id="appendedInputButton" type="text"/>
|
||||
<button class="btn" type="button" onclick="return playStreamUri();">
|
||||
Play
|
||||
</button>
|
||||
|
||||
<input id="streamuriinput" placeholder="URI" class="span2" data-clear-btn="true"
|
||||
onkeypress="return streamPressed(event.keyCode);" id="appendedInputButton" type="text"/>
|
||||
<button class="btn" type="button" onclick="return playStreamUri();">
|
||||
Play
|
||||
</button>
|
||||
|
||||
<p>Put in a name and hit the Save button to save the stream in your browser (not on the server yet). <!-- To find stations, use the Browse function with extensions like Dirble or TuneIn, the right values will appear in these boxes automatically. Or use websites like <a href="http://www.listenlive.eu/" target="_blank">Listenlive</a> or <a
|
||||
href="http://www.dirble.com/" target="_blank">Dirble</a>.</p> -->
|
||||
|
||||
<input id="streamnameinput" placeholder="Name" class="span2" data-clear-btn="true"
|
||||
onkeypress="return streamPressed(event.keyCode);" id="appendedInputButton" type="text"/>
|
||||
<button class="btn" type="button" onclick="return saveStreamUri();">
|
||||
Save
|
||||
</button>
|
||||
<input id="streamnameinput" placeholder="Name" class="span2" data-clear-btn="true"
|
||||
onkeypress="return streamPressed(event.keyCode);" id="appendedInputButton" type="text"/>
|
||||
<button class="btn" type="button" onclick="return addFavourite();">
|
||||
Save
|
||||
</button>
|
||||
<br/>
|
||||
<button class="btn" type="button" onclick="$('#streamuriinput').val(songdata.track.uri); return true;">
|
||||
Add currently playing url
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="ui-block-b" style="padding: 5px">
|
||||
|
||||
153
mopidy_musicbox_webclient/static/js/controls.js
vendored
153
mopidy_musicbox_webclient/static/js/controls.js
vendored
@ -286,7 +286,7 @@ function doPlay() {
|
||||
if(isStreamUri(songdata.track.uri)) {
|
||||
mopidy.playback.stop();
|
||||
} else {
|
||||
mopidy.playback.pause();
|
||||
mopidy.playback.pause();
|
||||
}
|
||||
}
|
||||
setPlayState(!play);
|
||||
@ -497,8 +497,8 @@ function playStreamUri(uri) {
|
||||
mopidy.playback.stop();
|
||||
//hide ios/android keyboard
|
||||
document.activeElement.blur();
|
||||
$("input").blur();
|
||||
clearQueue();
|
||||
$("input").blur();
|
||||
mopidy.tracklist.add(null, null, nwuri);
|
||||
mopidy.playback.play();
|
||||
} else {
|
||||
@ -507,71 +507,108 @@ function playStreamUri(uri) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function saveStreamUri(nwuri) {
|
||||
var i = 0;
|
||||
var name = $('#streamnameinput').val().trim();
|
||||
var uri = nwuri || $('#streamuriinput').val().trim();
|
||||
var service = $('#selectstreamservice').val();
|
||||
if (service) {
|
||||
uri = serviceupdateStreamUris + ':' + uri;
|
||||
}
|
||||
toast('Adding stream ' + uri, 500);
|
||||
//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;
|
||||
function getCurrentlyPlaying() {
|
||||
$('#streamuriinput').val(songdata.track.uri);
|
||||
var name = songdata.track.name;
|
||||
if (songdata.track.artists) {
|
||||
var artistStr = artistsToString(songdata.track.artists);
|
||||
if (artistStr) {
|
||||
name = artistStr + ' - ' + name;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
streamUris.unshift([name, uri]);
|
||||
$.cookie.json = true;
|
||||
$.cookie('streamUris', streamUris);
|
||||
updateStreamUris();
|
||||
return false;
|
||||
$('#streamnameinput').val(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
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];
|
||||
function getPlaylistByName(name, scheme, create) {
|
||||
return mopidy.playlists.filter({"name": name}).then(function(plists) {
|
||||
for (var i = 0; i < plists.length; i++) {
|
||||
if (!scheme || getScheme(plists[i].uri) == scheme) {
|
||||
return plists[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
$.cookie.json = true;
|
||||
$.cookie('streamUris', streamUris);
|
||||
updateStreamUris();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateStreamUris() {
|
||||
var tmp = '';
|
||||
$('#streamuristable').empty();
|
||||
var child = '';
|
||||
for (var key in streamUris) {
|
||||
var rs = streamUris[key];
|
||||
if (rs) {
|
||||
name = 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] + '\');"> </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;
|
||||
if (create) {
|
||||
return mopidy.playlists.create(name, scheme).done(function(plist) {
|
||||
console.log("Created playlist '%s'", plist.name);
|
||||
return plist;
|
||||
});
|
||||
}
|
||||
}
|
||||
$('#streamuristable').html(tmp);
|
||||
console.log("Can't find playist '%s", name);
|
||||
});
|
||||
}
|
||||
|
||||
function initStreams() {
|
||||
$.cookie.json = true;
|
||||
tmpRS = $.cookie('streamUris');
|
||||
streamUris = tmpRS || streamUris;
|
||||
updateStreamUris();
|
||||
function getFavourites() {
|
||||
return getPlaylistByName(STREAMS_PLAYLIST_NAME,
|
||||
STREAMS_PLAYLIST_SCHEME,
|
||||
true).then(function(playlist) {
|
||||
return playlist;
|
||||
});
|
||||
}
|
||||
|
||||
function addFavourite(uri, name) {
|
||||
var uri = uri || $('#streamuriinput').val().trim();
|
||||
var name = name || $('#streamnameinput').val().trim();
|
||||
mopidy.library.lookup(null, [uri]).then(function(results) {
|
||||
var newTracks = results[uri];
|
||||
if (newTracks.length == 1) {
|
||||
// TODO: Supporting adding an entire playlist?
|
||||
if (name) {
|
||||
newTracks[0].name = name; // User overrides name.
|
||||
}
|
||||
getFavourites().then(function(favourites) {
|
||||
if (favourites) {
|
||||
if (favourites.tracks) {
|
||||
//Array.prototype.push.apply(favourites.tracks, newTracks)
|
||||
favourites.tracks.push(newTracks[0]);
|
||||
} else {
|
||||
favourites.tracks = [newTracks[0]];
|
||||
}
|
||||
mopidy.playlists.save(favourites).then(function(s) {
|
||||
showFavourites();
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (newTracks.length == 0) {
|
||||
console.log('No tracks to add');
|
||||
} else {
|
||||
console.log('Too many tracks (%d) to add', tracks.length);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deleteFavourite(index) {
|
||||
getFavourites().then(function(favourites) {
|
||||
if (favourites && favourites.tracks && index < favourites.tracks.length) {
|
||||
var name = favourites.tracks[index].name;
|
||||
if (confirm("Are you sure you want to remove '" + name + "'?")) {
|
||||
favourites.tracks.splice(index, 1);
|
||||
mopidy.playlists.save(favourites).then(function(s) {
|
||||
showFavourites();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showFavourites() {
|
||||
$('#streamuristable').empty();
|
||||
getFavourites().then(function(favourites) {
|
||||
if (favourites && favourites.tracks) {
|
||||
tracks = favourites.tracks;
|
||||
var tmp = '';
|
||||
var child = '';
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
child = '<li><span class="ui-icon ui-icon-delete ui-icon-shadow" style="float:right; margin: .5em; margin-top: .8em;"><a href="#" onclick="return deleteFavourite(\'' + i + '\');"> </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(\'' + tracks[i].uri + '\');">';
|
||||
child += '<h1>' + tracks[i].name + '</h1></a></li>';
|
||||
tmp += child;
|
||||
}
|
||||
$('#streamuristable').html(tmp);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function haltSystem() {
|
||||
|
||||
@ -34,6 +34,9 @@ var newposition = 0;
|
||||
var playlisttracksScroll;
|
||||
var playlistslistScroll;
|
||||
|
||||
var STREAMS_PLAYLIST_NAME = '[Radio Streams]';
|
||||
var STREAMS_PLAYLIST_SCHEME = 'm3u';
|
||||
|
||||
//array of cached playlists (not only user-playlists, also search, artist, album-playlists)
|
||||
var playlists = {};
|
||||
var currentplaylist;
|
||||
@ -152,6 +155,20 @@ function getAlbum(pl) {
|
||||
};
|
||||
}
|
||||
|
||||
function artistsToString(artists, max) {
|
||||
var result = '';
|
||||
max = max || 3;
|
||||
for (var i = 0; i < artists.length && i < max; i++) {
|
||||
if (artists[i].name) {
|
||||
if (i > 0) {
|
||||
result += ', ';
|
||||
}
|
||||
result += artists[i].name;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* break up results and put them in album tables
|
||||
*********************************************************/
|
||||
@ -488,17 +505,20 @@ function validServiceUri(str) {
|
||||
return validUri(str) || isServiceUri(str);
|
||||
}
|
||||
|
||||
function getScheme(uri) {
|
||||
return uri.split(':')[0].toLowerCase();
|
||||
}
|
||||
|
||||
function isStreamUri(uri) {
|
||||
var uriSplit = uri.split(":");
|
||||
var a = validUri(uri);
|
||||
var b = radioExtensionsList.indexOf(uriSplit[0].toLowerCase()) >= 0;
|
||||
var b = radioExtensionsList.indexOf(getScheme(uri)) >= 0;
|
||||
return a || b;
|
||||
}
|
||||
|
||||
function getMediaClass(uri) {
|
||||
var uriSplit = uri.split(":")[0].toLowerCase();
|
||||
var scheme = getScheme(uri);
|
||||
for (var i = 0; i < uriClassList.length; i++) {
|
||||
if (uriSplit == uriClassList[i][0]) {
|
||||
if (scheme == uriClassList[i][0]) {
|
||||
return "fa " + uriClassList[i][1];
|
||||
}
|
||||
}
|
||||
@ -506,9 +526,9 @@ function getMediaClass(uri) {
|
||||
}
|
||||
|
||||
function getMediaHuman(uri) {
|
||||
var uriSplit = uri.split(":")[0].toLowerCase();
|
||||
var scheme = getScheme(uri);
|
||||
for (var i = 0; i < uriHumanList.length; i++) {
|
||||
if (uriSplit == uriHumanList[i][0]) {
|
||||
if (scheme == uriHumanList[i][0]) {
|
||||
return uriHumanList[i][1];
|
||||
}
|
||||
}
|
||||
@ -516,19 +536,26 @@ function getMediaHuman(uri) {
|
||||
}
|
||||
|
||||
function isServiceUri(uri) {
|
||||
var uriSplit = uri.split(":")[0].toLowerCase();
|
||||
var retVal = false;
|
||||
|
||||
var scheme = getScheme(uri);
|
||||
for (var i = 0; i < uriClassList.length; i++) {
|
||||
if (uriSplit == uriClassList[i][0]) {
|
||||
retVal = true;
|
||||
if (scheme == uriClassList[i][0]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < radioExtensionsList.length; i++) {
|
||||
if (uriSplit == radioExtensionsList[i]) {
|
||||
retVal = true;
|
||||
if (scheme == radioExtensionsList[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
return false;
|
||||
}
|
||||
|
||||
function isFavouritesPlaylist(playlist) {
|
||||
return (playlist.name == STREAMS_PLAYLIST_NAME &&
|
||||
getScheme(playlist.uri) == STREAMS_PLAYLIST_SCHEME);
|
||||
}
|
||||
|
||||
function isSpotifyStarredPlaylist(playlist) {
|
||||
var starredRegex = /spotify:user:.*:starred/g;
|
||||
return (starredRegex.test(playlist.uri) && playlist.name == 'Starred');
|
||||
}
|
||||
|
||||
@ -114,11 +114,11 @@ function setSongInfo(data) {
|
||||
|
||||
if(data.track.artists) {
|
||||
for (var j = 0; j < data.track.artists.length; j++) {
|
||||
artistshtml += '<a href="#" onclick="return showArtist(\'' + data.track.artists[j].uri + '\');">' + data.track.artists[j].name + '</a>';
|
||||
artiststext += data.track.artists[j].name;
|
||||
if (j != data.track.artists.length - 1) {
|
||||
artistshtml += ', ';
|
||||
artiststext += ', ';
|
||||
artistshtml += '<a href="#" onclick="return showArtist(\'' + data.track.artists[j].uri + '\');">' + data.track.artists[j].name + '</a>';
|
||||
artiststext += data.track.artists[j].name;
|
||||
if (j != data.track.artists.length - 1) {
|
||||
artistshtml += ', ';
|
||||
artiststext += ', ';
|
||||
}
|
||||
}
|
||||
arttmp = artistshtml;
|
||||
@ -224,6 +224,7 @@ function initSocketevents() {
|
||||
getCurrentPlaylist();
|
||||
updateStatusOfAll();
|
||||
getPlaylists();
|
||||
showFavourites();
|
||||
getBrowseDir();
|
||||
getSearchSchemes();
|
||||
showLoading(false);
|
||||
@ -552,7 +553,7 @@ $(document).ready(function(event) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
initStreams();
|
||||
|
||||
|
||||
if ($(window).width() < 980) {
|
||||
$("#panel").panel("close");
|
||||
|
||||
@ -159,19 +159,20 @@ function processGetPlaylists(resultArr) {
|
||||
if ((!resultArr) || (resultArr == '')) {
|
||||
return;
|
||||
}
|
||||
var tmp = '',
|
||||
starredRegex = /spotify:user:.*:starred/g;
|
||||
var tmp = '', favourites = '', starred = '';
|
||||
|
||||
for (var i = 0; i < resultArr.length; i++) {
|
||||
var li_html = '<li><a href="#" onclick="return showTracklist(this.id);" id="' + resultArr[i].uri + '">';
|
||||
if(starredRegex.test(resultArr[i].uri) && resultArr[i].name == "Starred") {
|
||||
// Prepend the user's Spotify "Starred" playlist to the results (like Spotify official client).
|
||||
tmp = li_html + '★ Spotify Starred Tracks</a></li>' + tmp;
|
||||
if(isSpotifyStarredPlaylist(resultArr[i])) {
|
||||
starred = li_html + '★ Spotify Starred Tracks</a></li>' + tmp;
|
||||
} else if (isFavouritesPlaylist(resultArr[i])) {
|
||||
favourites = li_html + '♥ Musicbox Favourites</a></li>';
|
||||
} else {
|
||||
// Append everything else.
|
||||
tmp = tmp + li_html + '<i class="' + getMediaClass(resultArr[i].uri) + '"></i> ' + resultArr[i].name + '</a></li>';
|
||||
}
|
||||
};
|
||||
// Prepend the user's Spotify "Starred" playlist and favourites to the results. (like Spotify official client).
|
||||
tmp = favourites + starred + tmp;
|
||||
$('#playlistslist').html(tmp);
|
||||
scrollToTracklist();
|
||||
showLoading(false);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user