1
0
mirror of https://github.com/SuperBFG7/ympd synced 2024-06-25 22:23:16 +00:00

Search, Queueview and BrowseFilesystem enhancements

This commit is contained in:
jcorporation 2018-05-29 22:12:11 +02:00
parent 26b4f66fab
commit f122355c38
5 changed files with 292 additions and 292 deletions

View File

@ -85,14 +85,6 @@ tbody {
background-color:#eee;
}
#filter > a.active {
font-weight: bold;
pointer-events: none;
cursor: default;
text-decoration: none;
color: black;
}
.hide {
display: none !important;
}
@ -101,7 +93,7 @@ tbody {
float: right !important;
}
#queue-buttons, #browsePlaylistsButtons {
#queue-buttons, #browsePlaylistsButtons, #searchButtons, #browseFilesystemButtons, #browseDatabaseButtons {
margin-bottom:20px;
}

View File

@ -264,11 +264,24 @@
<ol id="browseBreadcrumb" class="breadcrumb">
</ol>
<div class="btn-toolbar" id="filter-toolbar">
<div class="btn-group mr-2 flex-wrap" data-toggle="radio" id="filter"></div>
<div class="btn-toolbar collapse show" id="browseFilesystemButtons" role="toolbar">
<div class="btn-group mr-2 pull-right">
<button id="add-all-songs" class="btn btn-secondary">Add all</button>
</div>
<div class="btn-group mr-2">
<button id="browseFilesystemGoto" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Goto</button>
<div class="dropdown-menu bg-dark px-2" id="browseFilesystemGotoLetters">
</div>
</div>
<div id="browseFilesystemPaginationTop" class="btn-group mr-2">
<button onclick="gotoPage('prev',this,event)" id="browseFilesystemPaginationTopPrev" title="Previous Page" type="button" class="btn btn-secondary">&laquo;</button>
<div class="input-group-append">
<button id="browseFilesystemPaginationTopPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Page 1 / 1</button>
<div class="dropdown-menu bg-dark px-2" id="browseFilesystemPaginationTopPages">
</div>
</div>
<button onclick="gotoPage('next',this,event)" id="browseFilesystemPaginationTopNext" title="Next Page" type="button" class="btn btn-secondary input-group-append">&raquo;</button>
</div>
</div>
<div class="table-responsive-md">
@ -293,16 +306,56 @@
</tbody>
</table>
</div>
<ul id="browsePagination" class="pagination justify-content-center hide">
<li id="browsePrev" class="page-item disabled"><a class="page-link text-secondary" href="">Previous</a></li>
<li id="browseNext" class="page-item disabled"><a class="page-link text-secondary" href="">Next</a></li>
</ul>
<div class="btn-toolbar" id="browseFilesystemButtonsBottom" role="toolbar">
<div class="btn-group mr-2">
<button type="button" class="btn btn-secondary" onclick="scrollToTop()" title="To top">
<span class="material-icons">keyboard_arrow_up</span>
</button>
</div>
<div id="browseFilesystemPaginationBottom" class="btn-group mr-2 dropup">
<button onclick="gotoPage('prev',this,event)" id="browseFilesystemPaginationBottomPrev" title="Previous Page" type="button" class="btn btn-secondary">&laquo;</button>
<div class="input-group-append">
<button id="browseFilesystemPaginationBottomPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Page 1 / 1</button>
<div class="dropdown-menu bg-dark px-2" id="browseFilesystemPaginationBottomPages">
</div>
</div>
<button onclick="gotoPage('next',this,event)" id="browseFilesystemPaginationBottomNext" title="Next Page" type="button" class="btn btn-secondary input-group-append">&raquo;</button>
</div>
</div>
</div>
</div>
<div class="card hide" id="cardSearch">
<div class="card-header" id="panel-heading-search">Search</div>
<div class="card-header">Search
<span id="panel-heading-search" class="text pull-right"></span>
</div>
<div class="card-body">
<div class="btn-toolbar collapse show" id="searchButtons" role="toolbar">
<form id="search2" role="search">
<div class="input-group mr-2">
<input type="text" class="form-control" placeholder="Search" id="searchstr2"/>
<div class="input-group-append">
<button title="Select tags to search" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown"><span class="material-icons">search</span></button>
<div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchtags2">
<h6 class="dropdown-header text-light">Search in Tag</h6>
<button type="button" class="btn btn-success btn-block">Any Tag</button>
<button type="button" class="btn btn-secondary btn-block">Title</button>
<button type="button" class="btn btn-secondary btn-block">Artist</button>
<button type="button" class="btn btn-secondary btn-block">Album</button>
</div>
</div>
</div>
</form>
<div id="searchPaginationTop" class="btn-group mr-2">
<button onclick="gotoPage('prev',this,event)" id="searchPaginationTopPrev" title="Previous Page" type="button" class="btn btn-secondary">&laquo;</button>
<div class="input-group-append">
<button id="searchPaginationTopPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Page 1 / 1</button>
<div class="dropdown-menu bg-dark px-2" id="searchPaginationTopPages">
</div>
</div>
<button onclick="gotoPage('next',this,event)" id="searchPaginationTopNext" title="Next Page" type="button" class="btn btn-secondary input-group-append">&raquo;</button>
</div>
</div>
<div class="table-responsive-md">
<table id="searchList" class="table table-hover table-sm">
<col class="tblnum"/>
@ -325,6 +378,22 @@
</tbody>
</table>
</div>
<div class="btn-toolbar" id="searchButtonsBottom" role="toolbar">
<div class="btn-group mr-2">
<button type="button" class="btn btn-secondary" onclick="scrollToTop()" title="To top">
<span class="material-icons">keyboard_arrow_up</span>
</button>
</div>
<div id="searchPaginationBottom" class="btn-group mr-2 dropup">
<button onclick="gotoPage('prev',this,event)" id="searchPaginationBottomPrev" title="Previous Page" type="button" class="btn btn-secondary">&laquo;</button>
<div class="input-group-append">
<button id="searchPaginationBottomPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Page 1 / 1</button>
<div class="dropdown-menu bg-dark px-2" id="searchPaginationBottomPages">
</div>
</div>
<button onclick="gotoPage('next',this,event)" id="searchPaginationBottomNext" title="Next Page" type="button" class="btn btn-secondary input-group-append">&raquo;</button>
</div>
</div>
</div>
</div>
@ -332,8 +401,9 @@
<nav class="navbar navbar-expand navbar-dark fixed-bottom bg-dark">
<div class="d-flex flex-fill navbar-nav" id="navbar-bottom">
<div class="nav-item flex-fill text-center" id="navPlayback"><a class="nav-link" href="#/playing/">Playback</a></div>
<div class="nav-item flex-fill text-center" id="navQueue"><a class="nav-link" href="#/queue/0">Queue</a></div>
<div class="nav-item flex-fill text-center" id="navQueue"><a class="nav-link" href="#/queue/0/Any Tag/">Queue</a></div>
<div class="nav-item flex-fill text-center" id="navBrowse"><a class="nav-link" href="#/browse/filesystem/0/">Browse</a></div>
<div class="nav-item flex-fill text-center" id="navSearch"><a class="nav-link" href="#/search/0/Any Tag/">Search</a></div>
</div>
</nav>
</footer>

View File

@ -32,7 +32,6 @@ var lastSongTitle = "";
var current_song = new Object();
var MAX_ELEMENTS_PER_PAGE = 100;
var isTouch = Modernizr.touch ? 1 : 0;
var filter = "";
var playstate = "";
var progressBar;
var volumeBar;
@ -65,15 +64,30 @@ var app = $.sammy(function() {
$('#navPlayback').addClass('active');
});
this.get(/\#\/queue\/(\d+)/, function() {
prepare();
this.get(/\#\/queue\/(\d+)\/([^\/]+)\/(.*)/, function() {
current_app = 'queue';
$('#navQueue').addClass('active');
$('#cardQueue').removeClass('hide');
$('#panel-heading-queue').empty();
pagination = parseInt(this.params['splat'][0]);
$('#queueList').find("tr:gt(0)").remove();
socket.send('MPD_API_GET_QUEUE,'+pagination);
var mpdtag = this.params['splat'][1];
var searchstr = this.params['splat'][2];
if ($('#cardQueue').hasClass('hide')) {
prepare();
if (searchstr == '') {
setPagination(pagination);
}
$('#searchtags2 > button').each(function() {
if ($(this).text == mpdtag) { $(this).removeClass('btn-secondary').addClass('btn-success'); }
});
$('#cardQueue').removeClass('hide');
$('#navQueue').addClass('active');
}
$('#queueList > tbody').empty();
if (searchstr.length >= 3) {
socket.send('MPD_API_SEARCH_QUEUE,' + mpdtag + ','+pagination+',' + searchstr);
}
else {
socket.send('MPD_API_GET_QUEUE,'+pagination);
}
});
this.get(/\#\/browse\/playlists\/(\d+)/, function() {
@ -109,8 +123,8 @@ var app = $.sammy(function() {
$('#cardBrowse').removeClass('hide');
$('#cardBrowseFilesystem').removeClass('hide');
$('#cardBrowseNavFilesystem').addClass('active');
$('#browseFilesystemList').find("tr:gt(0)").remove();
$('#browseBreadcrumb').empty().append("<li class=\"breadcrumb-item\"><a uri=\"\" onclick=\"set_filter('')\">root</a></li>");
$('#browseFilesystemList > tbody').empty();
$('#browseBreadcrumb').empty().append("<li class=\"breadcrumb-item\"><a uri=\"\">root</a></li>");
socket.send('MPD_API_GET_BROWSE,'+pagination+','+(browsepath ? browsepath : "/"));
// Don't add all songs from root
var add_all_songs = $('#add-all-songs');
@ -123,7 +137,6 @@ var app = $.sammy(function() {
} else {
add_all_songs.addClass('hide');
}
//$('#panel-heading-browse').text("Browse database: /"+browsepath);
var path_array = browsepath.split('/');
var full_path = "";
@ -139,21 +152,35 @@ var app = $.sammy(function() {
});
});
this.get(/\#\/search\/(.*)/, function() {
prepare();
this.get(/\#\/search\/(\d+)\/([^\/]+)\/(.*)/, function() {
current_app = 'search';
$('#cardSearch').removeClass('hide');
var searchstr = this.params['splat'][0];
$('#search > input').val(searchstr);
socket.send('MPD_API_SEARCH,' + searchstr);
$('#searchList').find("tr:gt(0)").remove();
$('#searchList > tbody').append(
"<tr><td><span class=\"material-icons\">search</span></td>" +
"<td colspan=\"3\">Searching</td>" +
"<td></td><td></td></tr>");
$('#panel-heading-search').text("Search: "+searchstr);
pagination = parseInt(this.params['splat'][0]);
var mpdtag = this.params['splat'][1];
var searchstr = this.params['splat'][2];
if ($('#cardSearch').hasClass('hide')) {
prepare();
if (searchstr != '') {
$('#searchList > tbody').append(
"<tr><td><span class=\"material-icons\">search</span></td>" +
"<td colspan=\"3\">Searching</td>" +
"<td></td><td></td></tr>");
}
else {
setPagination(pagination);
}
$('#search > input').val(searchstr);
$('#searchstr2').val(searchstr);
$('#searchtags2 > button').each(function() {
if ($(this).text == mpdtag) { $(this).removeClass('btn-secondary').addClass('btn-success'); }
});
$('#cardSearch').removeClass('hide');
$('#navSearch').addClass('active');
}
$('#searchList > tbody').empty();
if (searchstr.length >= 3) {
socket.send('MPD_API_SEARCH,' + mpdtag + ','+pagination+',' + searchstr);
}
});
this.get("/", function(context) {
@ -259,7 +286,7 @@ function webSocketConnect() {
nrItems++;
var minutes = Math.floor(obj.data[song].duration / 60);
var seconds = obj.data[song].duration - minutes * 60;
$('#queueList > tbody').append(
"<tr trackid=\"" + obj.data[song].id + "\"><td>" + (obj.data[song].pos + 1) + "</td>" +
"<td>"+ obj.data[song].title +"</td>" +
@ -280,7 +307,7 @@ function webSocketConnect() {
if ( isTouch ) {
$('#queueList > tbody > tr > td:last-child').append(
'<a class="pull-right btn-group-hover color-darkgrey" href="#/queue/' + pagination + '" '+
'onclick="trash($(this).parents(\'tr\'));">' +
'onclick="delQueueSong($(this).parents(\'tr\'));">' +
'<span class="material-icons">delete</span></a>');
} else {
$('#queueList > tbody > tr').on({
@ -294,7 +321,7 @@ function webSocketConnect() {
if($(this).children().last().has("a").length == 0)
$(this).children().last().append(
'<a class="pull-right btn-group-hover color-darkgrey" href="#/queue/' + pagination + '" ' +
'onclick="trash($(this).parents(\'tr\'));">' +
'onclick="delQueueSong($(this).parents(\'tr\'));">' +
'<span class="material-icons">delete</span></a>')
.find('a').fadeTo('fast',1);
});
@ -335,17 +362,17 @@ function webSocketConnect() {
setPagination(obj.totalEntities);
if ( isTouch ) {
$('#'+current_app+'List > tbody > tr > td:last-child').append(
"<a class=\"pull-right btn-group-hover color-darkgrey\" href=\"#/\" " +
"onclick=\"delPlaylist($(this).parents('tr'));\">" +
"<span class=\"material-icons\">delete</span></a>");
'<a class="pull-right btn-group-hover color-darkgrey" href="#/browse/playlists/' + pagination + '" '+
'onclick="delPlaylist($(this).parents(\'tr\'));">' +
'<span class="material-icons">delete</span></a>');
} else {
$('#'+current_app+'List > tbody > tr').on({
mouseover: function(){
if($(this).children().last().has("a").length == 0)
if($(this).children().last().has('a').length == 0)
$(this).children().last().append(
"<a class=\"pull-right btn-group-hover color-darkgrey\" href=\"#/\" " +
"onclick=\"delPlaylist($(this).parents('tr'));\">" +
"<span class=\"material-icons\">delete</span></a>");
'<a class="pull-right btn-group-hover color-darkgrey" href="#/browse/playlists/' + pagination + '" '+
'onclick="delPlaylist($(this).parents(\'tr\'));">' +
'<span class="material-icons">delete</span></a>');
},
mouseleave: function(){
var doomed = $(this);
@ -368,7 +395,8 @@ function webSocketConnect() {
}
break;
case 'search':
$('#searchList').find("tr:gt(0)").remove();
$('#searchList > tbody').empty();
$('#panel-heading-search').text(obj.totalEntities + ' Songs found');
case 'browse':
if(current_app !== 'browseFilesystem' && current_app !== 'search')
break;
@ -382,78 +410,32 @@ function webSocketConnect() {
nrItems++;
switch(obj.data[item].type) {
case 'directory':
var clazz = 'dir';
if (filter !== "") {
var first = obj.data[item].dir[0];
if (filter === "num" && isNaN(first)) {
clazz += ' hide';
} else if (filter >= "A" && filter <= "Z" && first.toUpperCase() !== filter) {
clazz += ' hide';
} else if (filter === "plist") {
clazz += ' hide';
}
}
$('#'+current_app+'List > tbody').append(
"<tr uri=\"" + encodeURI(obj.data[item].dir) + "\" class=\"" + clazz + "\">" +
"<td><span class=\"material-icons\">folder_open</span></td>" +
"<td colspan=\"3\"><a>" + basename(obj.data[item].dir) + "</a></td>" +
"<td></td><td></td></tr>"
);
break;
case 'playlist':
var clazz = 'plist';
if ( (filter !== "") && (filter !== "plist") ) {
clazz += ' hide';
}
$('#'+current_app+'List > tbody').append(
"<tr uri=\"" + encodeURI(obj.data[item].plist) + "\" class=\"" + clazz + "\">" +
"<td><span class=\"material-icons\">list</span></td>" +
"<td colspan=\"3\"><a>" + basename(obj.data[item].plist) + "</a></td>" +
"<td></td><td></td></tr>"
'<tr uri="' + encodeURI(obj.data[item].dir) + '" class="dir">' +
'<td><span class="material-icons">folder_open</span></td>' +
'<td colspan="3"><a>' + basename(obj.data[item].dir) + '</a></td>' +
'<td></td><td></td></tr>'
);
break;
case 'song':
var minutes = Math.floor(obj.data[item].duration / 60);
var seconds = obj.data[item].duration - minutes * 60;
if (obj.data[item].artist == null) {
var artist = "<td colspan=\"2\">";
} else {
var artist = "<td>" + obj.data[item].artist +
"<span>" + obj.data[item].album + "</span></td><td>";
}
$('#'+current_app+'List > tbody').append(
"<tr uri=\"" + encodeURI(obj.data[item].uri) + "\" class=\"song\">" +
"<td><span class=\"material-icons\">music_note</span></td>" +
"<td>" + obj.data[item].title + "</td>" +
"<td>" + obj.data[item].artist + "</td>" +
"<td>" + obj.data[item].album + "</td>" +
"<td>" + minutes + ":" + (seconds < 10 ? '0' : '') + seconds +
"</td><td></td></tr>"
'<tr uri="' + encodeURI(obj.data[item].uri) + '" class="song">' +
'<td><span class="material-icons">music_note</span></td>' +
'<td>' + obj.data[item].title + '</td>' +
'<td>' + obj.data[item].artist + '</td>' +
'<td>' + obj.data[item].album + '</td>' +
'<td>' + minutes + ':' + (seconds < 10 ? '0' : '') + seconds +
'</td><td></td></tr>'
);
break;
case 'wrap':
if(current_app == 'browseFilesystem') {
$('#browseNext').removeClass('disabled');
$('#browsePagination').removeClass('hide');
} else {
$('#'+current_app+'List > tbody').append(
"<tr><td><span class=\"material-icons\">error_outline</span></td>" +
"<td colspan=\"3\">Too many results, please refine your search!</td>" +
"<td></td><td></td></tr>"
);
}
break;
}
if(pagination > 0) {
$('#browsePrev').removeClass('disabled');
$('#browsePagination').removeClass('hide');
}
}
setPagination(obj.totalEntities);
if (current_app == 'search')
if (nrItems == 0) {
$('#'+current_app+'List > tbody').append(
@ -497,18 +479,12 @@ function webSocketConnect() {
pagination = 0;
browsepath = $(this).attr("uri");
$("#browseFilesystemList > a").attr("href", '#/browse/filesystem/'+pagination+'/'+browsepath);
$('#filter > a').attr("href", '#/browse/filesystem/'+pagination+'/'+browsepath);
app.setLocation('#/browse/filesystem/'+pagination+'/'+browsepath);
set_filter('');
break;
case 'song':
socket.send("MPD_API_ADD_TRACK," + decodeURI($(this).attr("uri")));
showNotification('"' + $('td:nth-last-child(3)', this).text() + '" added','','','success');
break;
case 'plist':
socket.send("MPD_API_ADD_PLAYLIST," + decodeURI($(this).attr("uri")));
showNotification('"' + $('td:nth-last-child(3)', this).text() + '" added','','','success');
break;
}
}
});
@ -518,9 +494,7 @@ function webSocketConnect() {
pagination = 0;
browsepath = $(this).attr("uri");
$("#browseFilesystemList > a").attr("href", '#/browse/filesystem/'+pagination+'/'+browsepath);
$('#filter > a').attr("href", '#/browse/filesystem/'+pagination+'/'+browsepath);
app.setLocation('#/browse/filesystem/'+pagination+'/'+browsepath);
set_filter('');
}
});
@ -814,7 +788,7 @@ function setLocalStream(mpdhost,streamport) {
Cookies.set('mpdstream', mpdstream, { expires: 424242 });
}
function trash(tr) {
function delQueueSong(tr) {
if ( $('#btntrashmodeup').hasClass('btn-success') ) {
socket.send('MPD_API_RM_RANGE,0,' + (tr.index() + 1));
tr.remove();
@ -827,6 +801,11 @@ function trash(tr) {
};
}
function delPlaylist(tr) {
socket.send("MPD_API_RM_PLAYLIST," + decodeURI(tr.attr("uri")));
tr.remove();
}
function basename(path) {
return path.split('/').reverse()[0];
}
@ -925,10 +904,29 @@ $('#search > input').keypress(function (event) {
});
$('#search').submit(function () {
app.setLocation("#/search/"+$('#search > input').val());
doSearch($('#search > input').val());
return false;
});
function doSearch(searchstr) {
var mpdtag='Any Tag';
$('#searchtags2 > button').each(function() {
if ($(this).hasClass('btn-success')) { mpdtag=$(this).text(); }
});
app.setLocation('#/search/' + pagination + '/' + mpdtag + '/' + searchstr);
}
$('#searchstr2').keyup(function (event) {
pagination=0;
doSearch($(this).val());
});
$('#searchtags2 > button').on('click',function (e) {
$('#searchtags2 > button').removeClass('btn-success').addClass('btn-secondary');
$(this).removeClass('btn-secondary').addClass('btn-success');
doSearch($('#searchstr2').val());
});
$('#searchqueuestr').keyup(function (event) {
pagination=0;
doQueueSearch();
@ -946,40 +944,13 @@ function doQueueSearch() {
$('#searchqueuetag > button').each(function() {
if ($(this).hasClass('btn-success')) { mpdtag=$(this).text(); }
});
if (searchstr.length >= 3) {
socket.send('MPD_API_SEARCH_QUEUE,' + mpdtag + ','+pagination+',' + searchstr);
}
if (searchstr.length == 0) {
socket.send('MPD_API_GET_QUEUE,0');
}
app.setLocation('#/queue/' + pagination + '/' + mpdtag + '/' + searchstr);
}
$('#searchqueue').submit(function () {
return false;
});
$('.page-link').on('click', function (e) {
switch ($(this).text()) {
case "Next":
pagination += MAX_ELEMENTS_PER_PAGE;
break;
case "Previous":
pagination -= MAX_ELEMENTS_PER_PAGE;
if(pagination <= 0)
pagination = 0;
break;
}
switch(current_app) {
case "browseFilesystem":
app.setLocation('#/browse/filesystem/'+pagination+'/'+browsepath);
break;
}
e.preventDefault();
});
function scrollToTop() {
document.body.scrollTop = 0; // For Safari
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
@ -1011,6 +982,9 @@ function gotoPage(x,element,event) {
app.setLocation('#/queue/'+pagination);
}
break;
case "search":
doSearch($('#searchstr2').val());
break;
case "browseFilesystem":
app.setLocation('#/browse/filesystem/'+pagination+'/'+browsepath);
break;
@ -1127,51 +1101,11 @@ $(document).keydown(function(e){
e.preventDefault();
});
function set_filter (c) {
filter = c;
$('#filter > a').removeClass('btn-success');
$('#f' + c).addClass('btn-success');
if (filter === "") {
$('#'+current_app+'List > tbody > tr').removeClass('hide');
} else if (filter === "plist") {
$('#'+current_app+'List > tbody > tr.dir').addClass('hide');
$('#'+current_app+'List > tbody > tr.song').addClass('hide');
$('#'+current_app+'List > tbody > tr.plist').removeClass('hide');
} else {
$.each($('#'+current_app+'List > tbody > tr'), function(i, line) {
var first = basename($(line).attr('uri'))[0];
if ( $(line).hasClass('song') ) {
first = $(line).children().eq(3).text()[0];
}
if (filter === "num") {
if (!isNaN(first)) {
$(line).removeClass('hide');
} else {
$(line).addClass('hide');
}
} else if (filter >= "A" && filter <= "Z") {
if (first.toUpperCase() === filter) {
$(line).removeClass('hide');
} else {
$(line).addClass('hide');
}
}
});
}
}
function add_filter () {
$('#filter').append('<a class="btn btn-secondary" onclick="set_filter(\'\')" href="#/browse/filesystem/'+pagination+'/'+browsepath+'">All</a>');
$('#filter').append('<a class="btn btn-secondary" id="fnum" onclick="set_filter(\'num\')" href="#/browse/filesystem/'+pagination+'/'+browsepath+'">#</a>');
for (i = 65; i <= 90; i++) {
var c = String.fromCharCode(i);
$('#filter').append('<a class="btn btn-secondary" id="f' + c + '" onclick="set_filter(\'' + c + '\');" href="#/browse/filesystem/' + pagination + '/' + browsepath + '">' + c + '</a>');
$('#browseFilesystemGotoLetters').append('<a class="btn btn-secondary" onclick="gotoLetter(\'' + c + '\');" href="#/browse/filesystem/' + pagination + '/' + browsepath + '">' + c + '</a>');
}
$('#filter').append('<a class="btn btn-secondary material-icons" id="fplist" onclick="set_filter(\'plist\')" href="#/browse/filesystem/'+pagination+'/'+browsepath+'">list</a>');
}
function chVolume (increment) {

View File

@ -183,11 +183,11 @@ int callback_mpd(struct mg_connection *c)
if((token = strtok(NULL, ",")) == NULL)
goto out_browse;
free(p_charbuf);
free(p_charbuf);
p_charbuf = strdup(c->content);
n = mpd_put_browse(mpd.buf, get_arg2(p_charbuf), uint_buf);
out_browse:
free(p_charbuf);
free(p_charbuf);
break;
case MPD_API_ADD_TRACK:
p_charbuf = strdup(c->content);
@ -248,10 +248,32 @@ out_save_queue:
free(p_charbuf);
break;
case MPD_API_SEARCH_QUEUE:
p_charbuf = strdup(c->content);
if(strcmp(strtok(p_charbuf, ","), "MPD_API_SEARCH_QUEUE"))
goto out_search_queue;
goto out_search_queue;
if((token = strtok(NULL, ",")) == NULL) {
goto out_search_queue;
} else {
mpdtagtype = strdup(token);
}
uint_buf = strtoul(strtok(NULL, ","), NULL, 10);
if((token = strtok(NULL, ",")) == NULL) {
free(mpdtagtype);
goto out_search_queue;
} else {
searchstr = strdup(token);
}
n = mpd_search_queue(mpd.buf, mpdtagtype, uint_buf, searchstr);
free(searchstr);
out_search_queue:
free(p_charbuf);
break;
case MPD_API_SEARCH:
p_charbuf = strdup(c->content);
if(strcmp(strtok(p_charbuf, ","), "MPD_API_SEARCH"))
goto out_search;
if((token = strtok(NULL, ",")) == NULL) {
goto out_search_queue;
} else {
@ -266,25 +288,8 @@ out_save_queue:
} else {
searchstr = strdup(token);
}
//free(p_charbuf);
//p_charbuf = strdup(c->content);
n = mpd_search_queue(mpd.buf, mpdtagtype, uint_buf, searchstr);
n = mpd_search(mpd.buf, mpdtagtype, uint_buf, searchstr);
free(searchstr);
out_search_queue:
free(p_charbuf);
break;
case MPD_API_SEARCH:
p_charbuf = strdup(c->content);
if(strcmp(strtok(p_charbuf, ","), "MPD_API_SEARCH"))
goto out_search;
if((token = strtok(NULL, ",")) == NULL)
goto out_search;
free(p_charbuf);
p_charbuf = strdup(c->content);
n = mpd_search(mpd.buf, get_arg1(p_charbuf));
out_search:
free(p_charbuf);
break;
@ -312,6 +317,20 @@ out_search:
out_send_message:
free(p_charbuf);
break;
case MPD_API_RM_PLAYLIST:
p_charbuf = strdup(c->content);
if(strcmp(strtok(p_charbuf, ","), "MPD_API_RM_PLAYLIST"))
goto out_rm_playlist;
if((token = strtok(NULL, ",")) == NULL)
goto out_rm_playlist;
free(p_charbuf);
p_charbuf = strdup(c->content);
mpd_run_rm(mpd.conn, get_arg1(p_charbuf));
out_rm_playlist:
free(p_charbuf);
break;
case MPD_API_GET_OPTIONS:
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"mpdoptions\", \"data\": "
"{\"mpdhost\" : \"%s\", \"mpdport\": \"%d\", \"passwort_set\": %s, "
@ -713,58 +732,38 @@ int mpd_put_browse(char *buffer, char *path, unsigned int offset)
while((entity = mpd_recv_entity(mpd.conn)) != NULL) {
const struct mpd_song *song;
const struct mpd_directory *dir;
const struct mpd_playlist *pl;
entity_count++;
if(offset > entity_count)
{
mpd_entity_free(entity);
entity_count++;
continue;
}
else if(offset + MAX_ELEMENTS_PER_PAGE - 1 < entity_count)
{
mpd_entity_free(entity);
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\",\"count\":");
cur += json_emit_int(cur, end - cur, entity_count);
cur += json_emit_raw_str(cur, end - cur, "} ");
break;
}
if(entity_count > offset && entity_count <= offset+MAX_ELEMENTS_PER_PAGE) {
switch (mpd_entity_get_type(entity)) {
case MPD_ENTITY_TYPE_UNKNOWN:
break;
switch (mpd_entity_get_type(entity)) {
case MPD_ENTITY_TYPE_UNKNOWN:
break;
case MPD_ENTITY_TYPE_SONG:
song = mpd_entity_get_song(entity);
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song));
cur += json_emit_raw_str(cur, end - cur, ",\"album\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_get_album(song));
cur += json_emit_raw_str(cur, end - cur, ",\"artist\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_get_artist(song));
cur += json_emit_raw_str(cur, end - cur, ",\"duration\":");
cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song));
cur += json_emit_raw_str(cur, end - cur, ",\"title\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song));
cur += json_emit_raw_str(cur, end - cur, "},");
break;
case MPD_ENTITY_TYPE_SONG:
song = mpd_entity_get_song(entity);
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song));
cur += json_emit_raw_str(cur, end - cur, ",\"album\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_get_album(song));
cur += json_emit_raw_str(cur, end - cur, ",\"artist\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_get_artist(song));
// cur += json_emit_raw_str(cur, end - cur, ",\"album_artist\":");
// cur += json_emit_quoted_str(cur, end - cur, mpd_get_album_artist(song));
cur += json_emit_raw_str(cur, end - cur, ",\"duration\":");
cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song));
cur += json_emit_raw_str(cur, end - cur, ",\"title\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song));
cur += json_emit_raw_str(cur, end - cur, "},");
break;
case MPD_ENTITY_TYPE_DIRECTORY:
dir = mpd_entity_get_directory(entity);
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"directory\",\"dir\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_directory_get_path(dir));
cur += json_emit_raw_str(cur, end - cur, "},");
break;
case MPD_ENTITY_TYPE_DIRECTORY:
dir = mpd_entity_get_directory(entity);
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"directory\",\"dir\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_directory_get_path(dir));
cur += json_emit_raw_str(cur, end - cur, "},");
break;
case MPD_ENTITY_TYPE_PLAYLIST:
pl = mpd_entity_get_playlist(entity);
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"playlist\",\"plist\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_playlist_get_path(pl));
cur += json_emit_raw_str(cur, end - cur, "},");
break;
case MPD_ENTITY_TYPE_PLAYLIST:
break;
}
}
mpd_entity_free(entity);
entity_count++;
@ -778,8 +777,9 @@ int mpd_put_browse(char *buffer, char *path, unsigned int offset)
/* remove last ',' */
cur--;
cur += json_emit_raw_str(cur, end - cur, "]}");
cur += json_emit_raw_str(cur, end - cur, "],\"totalEntities\":");
cur += json_emit_int(cur, end - cur, entity_count);
cur += json_emit_raw_str(cur, end - cur, "}");
return cur - buffer;
}
@ -822,25 +822,36 @@ int mpd_put_playlists(char *buffer, unsigned int offset)
return cur - buffer;
}
int mpd_search(char *buffer, char *searchstr)
int mpd_search(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr)
{
char *cur = buffer;
const char *end = buffer + MAX_SIZE;
struct mpd_song *song;
unsigned long totalSongs = 0;
unsigned long entity_count = 0;
unsigned long entities_returned = 0;
if(mpd_search_db_songs(mpd.conn, false) == false)
RETURN_ERROR_AND_RECOVER("mpd_search_db_songs");
else if(mpd_search_add_any_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, searchstr) == false)
RETURN_ERROR_AND_RECOVER("mpd_search_add_any_tag_constraint");
else if(mpd_search_commit(mpd.conn) == false)
if(mpd_search_db_songs(mpd.conn, false) == false) {
RETURN_ERROR_AND_RECOVER("mpd_search_queue_songs");
}
if (mpd_tag_name_parse(mpdtagtype) != MPD_TAG_UNKNOWN) {
if (mpd_search_add_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, mpd_tag_name_parse(mpdtagtype), searchstr) == false)
RETURN_ERROR_AND_RECOVER("mpd_search_add_tag_constraint");
}
else {
if (mpd_search_add_any_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, searchstr) == false)
RETURN_ERROR_AND_RECOVER("mpd_search_add_any_tag_constraint");
}
if(mpd_search_commit(mpd.conn) == false)
RETURN_ERROR_AND_RECOVER("mpd_search_commit");
else {
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"search\",\"data\":[ ");
while((song = mpd_recv_song(mpd.conn)) != NULL) {
totalSongs ++;
if (totalSongs <=300) {
entity_count ++;
if(entity_count > offset && entity_count <= offset+MAX_ELEMENTS_PER_PAGE) {
entities_returned ++;
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\"");
cur += json_emit_raw_str(cur, end - cur, ",\"uri\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song));
@ -848,8 +859,6 @@ int mpd_search(char *buffer, char *searchstr)
cur += json_emit_quoted_str(cur, end - cur, mpd_get_album(song));
cur += json_emit_raw_str(cur, end - cur, ",\"artist\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_get_artist(song));
// cur += json_emit_raw_str(cur, end - cur, ",\"album_artist\":");
// cur += json_emit_quoted_str(cur, end - cur, mpd_get_album_artist(song));
cur += json_emit_raw_str(cur, end - cur, ",\"duration\":");
cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song));
cur += json_emit_raw_str(cur, end - cur, ",\"title\":");
@ -859,18 +868,18 @@ int mpd_search(char *buffer, char *searchstr)
mpd_song_free(song);
}
/* Maximum results */
if(totalSongs++ > 300)
{
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\"},");
}
/* remove last ',' */
cur--;
cur += json_emit_raw_str(cur, end - cur, "]");
cur += json_emit_raw_str(cur, end - cur, ",\"totalSongs\":");
cur += json_emit_int(cur, end - cur, totalSongs);
cur += json_emit_raw_str(cur, end - cur, ",\"totalEntities\":");
cur += json_emit_int(cur, end - cur, entity_count);
cur += json_emit_raw_str(cur, end - cur, ",\"offset\":");
cur += json_emit_int(cur, end - cur, offset);
cur += json_emit_raw_str(cur, end - cur, ",\"returnedEntities\":");
cur += json_emit_int(cur, end - cur, entities_returned);
cur += json_emit_raw_str(cur, end - cur, ",\"mpdtagtype\":");
cur += json_emit_quoted_str(cur, end - cur, mpdtagtype);
cur += json_emit_raw_str(cur, end - cur, "}");
}
return cur - buffer;
@ -905,8 +914,6 @@ int mpd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char *
totalSongs ++;
if(totalSongs > offset && totalSongs <= offset+MAX_ELEMENTS_PER_PAGE) {
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\"");
// cur += json_emit_raw_str(cur, end - cur, ",\"uri\":");
// cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song));
cur += json_emit_raw_str(cur, end - cur, ",\"id\":");
cur += json_emit_int(cur, end - cur, mpd_song_get_id(song));
cur += json_emit_raw_str(cur, end - cur, ",\"pos\":");
@ -915,8 +922,6 @@ int mpd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char *
cur += json_emit_quoted_str(cur, end - cur, mpd_get_album(song));
cur += json_emit_raw_str(cur, end - cur, ",\"artist\":");
cur += json_emit_quoted_str(cur, end - cur, mpd_get_artist(song));
// cur += json_emit_raw_str(cur, end - cur, ",\"album_artist\":");
// cur += json_emit_quoted_str(cur, end - cur, mpd_get_album_artist(song));
cur += json_emit_raw_str(cur, end - cur, ",\"duration\":");
cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song));
cur += json_emit_raw_str(cur, end - cur, ",\"title\":");
@ -926,15 +931,13 @@ int mpd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char *
}
}
/* if (totalSongs > 100) {
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\"},");
}
*/
cur--;
cur += json_emit_raw_str(cur, end - cur, "]");
cur += json_emit_raw_str(cur, end - cur, ",\"totalSongs\":");
cur += json_emit_int(cur, end - cur, totalSongs);
cur += json_emit_raw_str(cur, end - cur, ",\"mpdtagtype\":");
cur += json_emit_quoted_str(cur, end - cur, mpdtagtype);
cur += json_emit_raw_str(cur, end - cur, "}");
}
return cur - buffer;

View File

@ -77,7 +77,8 @@
X(MPD_API_GET_STATS) \
X(MPD_API_SET_MIXRAMPDB) \
X(MPD_API_SET_MIXRAMPDELAY) \
X(MPD_API_GET_PLAYLISTS)
X(MPD_API_GET_PLAYLISTS) \
X(MPD_API_RM_PLAYLIST)
enum mpd_cmd_ids {
MPD_CMDS(GEN_ENUM)
@ -128,7 +129,7 @@ int mpd_put_current_song(char *buffer);
int mpd_put_queue(char *buffer, unsigned int offset);
int mpd_put_playlists(char *buffer, unsigned int offset);
int mpd_put_browse(char *buffer, char *path, unsigned int offset);
int mpd_search(char *buffer, char *searchstr);
int mpd_search(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr);
int mpd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr);
int mympd_get_stats();
void mpd_disconnect();