mirror of
https://github.com/SuperBFG7/ympd
synced 2024-12-27 03:10:26 +00:00
Feat: Add playlist actions
This commit is contained in:
parent
c8895ebdd8
commit
c403202c7d
@ -213,3 +213,10 @@ div.alertBoxActive {
|
|||||||
.opacity05 {
|
.opacity05 {
|
||||||
opacity:0.5;
|
opacity:0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
caption {
|
||||||
|
caption-side: top;
|
||||||
|
font-size: 120%;
|
||||||
|
font-weight: bold;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
@ -195,6 +195,14 @@
|
|||||||
|
|
||||||
<div class="card-body hide" id="cardBrowsePlaylists">
|
<div class="card-body hide" id="cardBrowsePlaylists">
|
||||||
<div class="btn-toolbar card-toolbar" id="BrowsePlaylistsButtons" role="toolbar">
|
<div class="btn-toolbar card-toolbar" id="BrowsePlaylistsButtons" role="toolbar">
|
||||||
|
<div class="btn-group mr-2 hide">
|
||||||
|
<button data-href="{'cmd': 'appGoto', 'options': ['Browse','Playlists','All']}" id="btnBrowsePlaylistsAll" type="button" class="btn btn-secondary">« Playlists</button>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group mr-2 hide">
|
||||||
|
<button id="btnPlaylistClear" type="button" class="btn btn-secondary" data-href="{'cmd': 'playlistClear', 'options': []}" title="Clear playlist">
|
||||||
|
<span class="material-icons">clear_all</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div class="btn-group mr-2">
|
<div class="btn-group mr-2">
|
||||||
<button id="BrowsePlaylistsFilter" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Filter</button>
|
<button id="BrowsePlaylistsFilter" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Filter</button>
|
||||||
<div class="dropdown-menu bg-dark px-2 letters" id="BrowsePlaylistsFilterLetters">
|
<div class="dropdown-menu bg-dark px-2 letters" id="BrowsePlaylistsFilterLetters">
|
||||||
@ -210,9 +218,8 @@
|
|||||||
<button data-href="{'cmd': 'gotoPage', 'options': ['next']}" id="BrowsePlaylistsPaginationTopNext" title="Next Page" type="button" class="btn btn-secondary input-group-append">»</button>
|
<button data-href="{'cmd': 'gotoPage', 'options': ['next']}" id="BrowsePlaylistsPaginationTopNext" title="Next Page" type="button" class="btn btn-secondary input-group-append">»</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-responsive-md">
|
<div class="table-responsive-md">
|
||||||
<table id="BrowsePlaylistsList" class="table table-hover table-sm">
|
<table id="BrowsePlaylistsAllList" class="table table-hover table-sm">
|
||||||
<col class="tblnum"/>
|
<col class="tblnum"/>
|
||||||
<col class="tbltitle"/>
|
<col class="tbltitle"/>
|
||||||
<col class="tbllastmodified"/>
|
<col class="tbllastmodified"/>
|
||||||
@ -228,6 +235,27 @@
|
|||||||
<tbody class="clickable">
|
<tbody class="clickable">
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<table id="BrowsePlaylistsDetailList" class="table table-hover table-sm hide">
|
||||||
|
<caption>Playlist List</caption>
|
||||||
|
<col class="tblnum"/>
|
||||||
|
<col class="tbltitle"/>
|
||||||
|
<col class="tblartist"/>
|
||||||
|
<col class="tblalbum"/>
|
||||||
|
<col class="tbllength"/>
|
||||||
|
<col class="tblaction"/>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Artist</th>
|
||||||
|
<th>Album</th>
|
||||||
|
<th>Duration</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="clickable">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-toolbar" id="BrowsePlaylistsButtonsBottom" role="toolbar">
|
<div class="btn-toolbar" id="BrowsePlaylistsButtonsBottom" role="toolbar">
|
||||||
<div class="btn-group mr-2">
|
<div class="btn-group mr-2">
|
||||||
@ -248,10 +276,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body hide" id="cardBrowseDatabase">
|
<div class="card-body hide" id="cardBrowseDatabase">
|
||||||
|
|
||||||
<div class="btn-toolbar card-toolbar" id="BrowseDatabaseButtons" role="toolbar">
|
<div class="btn-toolbar card-toolbar" id="BrowseDatabaseButtons" role="toolbar">
|
||||||
<div class="btn-group mr-2">
|
<div class="btn-group mr-2 hide">
|
||||||
<button data-href="{'cmd': 'appGoto', 'options': ['Browse','Database','Artist']}" id="btnBrowseDatabaseArtist" type="button" class="btn btn-secondary hide">« Artists</button>
|
<button data-href="{'cmd': 'appGoto', 'options': ['Browse','Database','Artist']}" id="btnBrowseDatabaseArtist" type="button" class="btn btn-secondary">« Artists</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group mr-2">
|
<div class="btn-group mr-2">
|
||||||
<button id="BrowseDatabaseFilter" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Filter</button>
|
<button id="BrowseDatabaseFilter" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Filter</button>
|
||||||
@ -286,7 +313,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="BrowseDatabaseAlbumCards" class="row"></div>
|
<div id="BrowseDatabaseAlbumCards" class="row hide"></div>
|
||||||
|
|
||||||
<div class="btn-toolbar" id="BrowseDatabaseButtonsBottom" role="toolbar">
|
<div class="btn-toolbar" id="BrowseDatabaseButtonsBottom" role="toolbar">
|
||||||
<div class="btn-group mr-2">
|
<div class="btn-group mr-2">
|
||||||
@ -462,8 +489,8 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<!-- Modal -->
|
<!-- Modals -->
|
||||||
<div class="modal" id="modalConnectionError" role="dialog">
|
<div class="modal fade" id="modalConnectionError" role="dialog">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header bg-danger text-light">
|
<div class="modal-header bg-danger text-light">
|
||||||
@ -476,7 +503,59 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Modal -->
|
<div class="modal fade" id="modalAddToPlaylist" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title"><span class="material-icons title-icon">playlist_add</span> Add to playlist</h5>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form id="addToPlaylistFrm">
|
||||||
|
<input type="hidden" id="addToPlaylistUri"/>
|
||||||
|
<div class="form-group input-group col-md-6 border-secondary">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<div class="input-group-text bg-secondary text-light border-secondary">Playlist</div>
|
||||||
|
</div>
|
||||||
|
<select id="addToPlaylistPlaylist" class="form-control custom-select border-secondary">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-success" data-href="{'cmd': 'addToPlaylist', 'options': []}">Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="modalRenamePlaylist" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title"><span class="material-icons title-icon">playlist_add</span>Rename playlist</h5>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form class="needs-validation" id="renamePlaylistFrm" novalidate>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="fromInput">From</label>
|
||||||
|
<input type="text" class="form-control" id="renamePlaylistFrom" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="renamePlaylistTo">To</label>
|
||||||
|
<input type="text" class="form-control" id="renamePlaylistTo">
|
||||||
|
<div class="invalid-feedback">Invalid filename.</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-success" data-href="{'cmd': 'renamePlaylist', 'options': []}">Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="modal fade" id="modalSettings" tabindex="-1" role="dialog" aria-labelledby="settingsLabel" aria-hidden="true">
|
<div class="modal fade" id="modalSettings" tabindex="-1" role="dialog" aria-labelledby="settingsLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@ -570,7 +649,6 @@
|
|||||||
</div><!-- /.modal-dialog -->
|
</div><!-- /.modal-dialog -->
|
||||||
</div><!-- /.modal -->
|
</div><!-- /.modal -->
|
||||||
|
|
||||||
<!-- Modal -->
|
|
||||||
<div class="modal fade" id="modalAbout" tabindex="-1" role="dialog" aria-labelledby="settingsLabel" aria-hidden="true">
|
<div class="modal fade" id="modalAbout" tabindex="-1" role="dialog" aria-labelledby="settingsLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@ -608,7 +686,6 @@
|
|||||||
</div><!-- /.modal-dialog -->
|
</div><!-- /.modal-dialog -->
|
||||||
</div><!-- /.modal -->
|
</div><!-- /.modal -->
|
||||||
|
|
||||||
<!-- Modal -->
|
|
||||||
<div class="modal fade" id="modalAddstream" tabindex="-1" role="dialog" aria-labelledby="addstreamLabel" aria-hidden="true">
|
<div class="modal fade" id="modalAddstream" tabindex="-1" role="dialog" aria-labelledby="addstreamLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
215
htdocs/js/mpd.js
215
htdocs/js/mpd.js
@ -38,7 +38,12 @@ app.apps = { "Playback": { "state": "0/-/", "scrollPos": 0 },
|
|||||||
"Browse": {
|
"Browse": {
|
||||||
"active": "Database",
|
"active": "Database",
|
||||||
"tabs": { "Filesystem": { "state": "0/-/", "scrollPos": 0 },
|
"tabs": { "Filesystem": { "state": "0/-/", "scrollPos": 0 },
|
||||||
"Playlists": { "state": "0/-/", "scrollPos": 0 },
|
"Playlists": {
|
||||||
|
"active": "All",
|
||||||
|
"views": { "All": { "state": "0/-/", "scrollPos": 0 },
|
||||||
|
"Detail": { "state": "0/-/", "scrollPos": 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
"Database": {
|
"Database": {
|
||||||
"active": "Artist",
|
"active": "Artist",
|
||||||
"views": { "Artist": { "state": "0/-/", "scrollPos": 0 },
|
"views": { "Artist": { "state": "0/-/", "scrollPos": 0 },
|
||||||
@ -75,6 +80,8 @@ var modalSettings = new Modal(document.getElementById('modalSettings'));
|
|||||||
var modalAddstream = new Modal(document.getElementById('modalAddstream'));
|
var modalAddstream = new Modal(document.getElementById('modalAddstream'));
|
||||||
var modalSavequeue = new Modal(document.getElementById('modalSavequeue'));
|
var modalSavequeue = new Modal(document.getElementById('modalSavequeue'));
|
||||||
var modalSongDetails = new Modal(document.getElementById('modalSongDetails'));
|
var modalSongDetails = new Modal(document.getElementById('modalSongDetails'));
|
||||||
|
var modalAddToPlaylist = new Modal(document.getElementById('modalAddToPlaylist'));
|
||||||
|
var modalRenamePlaylist = new Modal(document.getElementById('modalRenamePlaylist'));
|
||||||
var mainMenu = new Dropdown(document.getElementById('mainMenu'));
|
var mainMenu = new Dropdown(document.getElementById('mainMenu'));
|
||||||
|
|
||||||
function appPrepare(scrollPos) {
|
function appPrepare(scrollPos) {
|
||||||
@ -102,6 +109,11 @@ function appPrepare(scrollPos) {
|
|||||||
}
|
}
|
||||||
scrollTo(scrollPos);
|
scrollTo(scrollPos);
|
||||||
}
|
}
|
||||||
|
var list = document.getElementById(app.current.app +
|
||||||
|
(app.current.tab == undefined ? '' : app.current.tab) +
|
||||||
|
(app.current.view == undefined ? '' : app.current.view) + 'List');
|
||||||
|
if (list)
|
||||||
|
list.classList.add('opacity05');
|
||||||
}
|
}
|
||||||
|
|
||||||
function appGoto(a,t,v,s) {
|
function appGoto(a,t,v,s) {
|
||||||
@ -171,13 +183,6 @@ function appRoute() {
|
|||||||
sendAPI({"cmd":"MPD_API_GET_CURRENT_SONG"}, songChange);
|
sendAPI({"cmd":"MPD_API_GET_CURRENT_SONG"}, songChange);
|
||||||
}
|
}
|
||||||
else if (app.current.app == 'Queue' ) {
|
else if (app.current.app == 'Queue' ) {
|
||||||
document.getElementById('QueueList').classList.add('opacity05');
|
|
||||||
/* if (app.last.app != app.current.app) {
|
|
||||||
if (app.current.search.length < 2) {
|
|
||||||
setPagination(app.current.page);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
var btns = document.getElementById('searchqueuetag').getElementsByTagName('button');
|
var btns = document.getElementById('searchqueuetag').getElementsByTagName('button');
|
||||||
for (var i = 0; i < btns.length; i++) {
|
for (var i = 0; i < btns.length; i++) {
|
||||||
btns[i].classList.remove('active');
|
btns[i].classList.remove('active');
|
||||||
@ -188,23 +193,23 @@ function appRoute() {
|
|||||||
}
|
}
|
||||||
getQueue();
|
getQueue();
|
||||||
}
|
}
|
||||||
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists') {
|
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'All') {
|
||||||
document.getElementById('BrowsePlaylistsList').classList.add('opacity05');
|
|
||||||
sendAPI({"cmd":"MPD_API_GET_PLAYLISTS","data": {"offset": app.current.page, "filter": app.current.filter}}, parsePlaylists);
|
sendAPI({"cmd":"MPD_API_GET_PLAYLISTS","data": {"offset": app.current.page, "filter": app.current.filter}}, parsePlaylists);
|
||||||
doSetFilterLetter('BrowsePlaylistsFilter');
|
doSetFilterLetter('BrowsePlaylistsFilter');
|
||||||
}
|
}
|
||||||
|
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'Detail') {
|
||||||
|
sendAPI({"cmd":"MPD_API_GET_PLAYLIST_LIST","data": {"offset": app.current.page, "filter": app.current.filter, "uri": app.current.search}}, parsePlaylists);
|
||||||
|
doSetFilterLetter('BrowsePlaylistsFilter');
|
||||||
|
}
|
||||||
else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.view == 'Artist') {
|
else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.view == 'Artist') {
|
||||||
document.getElementById('BrowseDatabaseArtistList').classList.add('opacity05');
|
|
||||||
sendAPI({"cmd":"MPD_API_GET_ARTISTS","data": {"offset": app.current.page, "filter": app.current.filter}}, parseListDBtags);
|
sendAPI({"cmd":"MPD_API_GET_ARTISTS","data": {"offset": app.current.page, "filter": app.current.filter}}, parseListDBtags);
|
||||||
doSetFilterLetter('BrowseDatabaseFilter');
|
doSetFilterLetter('BrowseDatabaseFilter');
|
||||||
}
|
}
|
||||||
else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.view == 'Album') {
|
else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.view == 'Album') {
|
||||||
document.getElementById('BrowseDatabaseAlbumCards').classList.add('opacity05');
|
|
||||||
sendAPI({"cmd":"MPD_API_GET_ARTISTALBUMS","data": {"offset": app.current.page, "filter": app.current.filter, "albumartist": app.current.search}}, parseListDBtags);
|
sendAPI({"cmd":"MPD_API_GET_ARTISTALBUMS","data": {"offset": app.current.page, "filter": app.current.filter, "albumartist": app.current.search}}, parseListDBtags);
|
||||||
doSetFilterLetter('BrowseDatabaseFilter');
|
doSetFilterLetter('BrowseDatabaseFilter');
|
||||||
}
|
}
|
||||||
else if (app.current.app == 'Browse' && app.current.tab == 'Filesystem') {
|
else if (app.current.app == 'Browse' && app.current.tab == 'Filesystem') {
|
||||||
document.getElementById('BrowseFilesystemList').classList.add('opacity05');
|
|
||||||
sendAPI({"cmd":"MPD_API_GET_FILESYSTEM","data": {"offset": app.current.page, "path": (app.current.search ? app.current.search : "/"), "filter": app.current.filter}}, parseFilesystem);
|
sendAPI({"cmd":"MPD_API_GET_FILESYSTEM","data": {"offset": app.current.page, "path": (app.current.search ? app.current.search : "/"), "filter": app.current.filter}}, parseFilesystem);
|
||||||
// Don't add all songs from root
|
// Don't add all songs from root
|
||||||
if (app.current.search)
|
if (app.current.search)
|
||||||
@ -238,15 +243,11 @@ function appRoute() {
|
|||||||
}
|
}
|
||||||
else if (app.current.app == 'Search') {
|
else if (app.current.app == 'Search') {
|
||||||
document.getElementById('searchstr').focus();
|
document.getElementById('searchstr').focus();
|
||||||
document.getElementById('SearchList').classList.add('opacity05');
|
|
||||||
if (app.last.app != app.current.app) {
|
if (app.last.app != app.current.app) {
|
||||||
if (app.current.search != '')
|
if (app.current.search != '')
|
||||||
document.getElementById('SearchList').getElementsByTagName('tbody')[0].innerHTML=
|
document.getElementById('SearchList').getElementsByTagName('tbody')[0].innerHTML=
|
||||||
'<tr><td><span class="material-icons">search</span></td>' +
|
'<tr><td><span class="material-icons">search</span></td>' +
|
||||||
'<td colspan="5">Searching...</td></tr>';
|
'<td colspan="5">Searching...</td></tr>';
|
||||||
// else
|
|
||||||
// setPagination(app.current.page);
|
|
||||||
// document.getElementById('searchstr').value = app.current.search;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app.current.search.length >= 2) {
|
if (app.current.search.length >= 2) {
|
||||||
@ -255,7 +256,6 @@ function appRoute() {
|
|||||||
document.getElementById('SearchList').getElementsByTagName('tbody')[0].innerHTML = '';
|
document.getElementById('SearchList').getElementsByTagName('tbody')[0].innerHTML = '';
|
||||||
document.getElementById('searchAddAllSongs').setAttribute('disabled', 'disabled');
|
document.getElementById('searchAddAllSongs').setAttribute('disabled', 'disabled');
|
||||||
document.getElementById('panel-heading-search').innerText = '';
|
document.getElementById('panel-heading-search').innerText = '';
|
||||||
// setPagination(app.current.page);
|
|
||||||
document.getElementById('SearchList').classList.remove('opacity05');
|
document.getElementById('SearchList').classList.remove('opacity05');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,10 +313,6 @@ function appInit() {
|
|||||||
document.getElementById('streamurl').focus();
|
document.getElementById('streamurl').focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('addstreamFrm').addEventListener('submit', function () {
|
|
||||||
addStream();
|
|
||||||
});
|
|
||||||
|
|
||||||
addFilterLetter('BrowseFilesystemFilterLetters');
|
addFilterLetter('BrowseFilesystemFilterLetters');
|
||||||
addFilterLetter('BrowseDatabaseFilterLetters');
|
addFilterLetter('BrowseDatabaseFilterLetters');
|
||||||
addFilterLetter('BrowsePlaylistsFilterLetters');
|
addFilterLetter('BrowsePlaylistsFilterLetters');
|
||||||
@ -386,7 +382,17 @@ function appInit() {
|
|||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
document.getElementById('BrowsePlaylistsList').addEventListener('click', function(event) {
|
document.getElementById('BrowsePlaylistsAllList').addEventListener('click', function(event) {
|
||||||
|
if (event.target.nodeName == 'TD') {
|
||||||
|
appendQueue('plist', decodeURI(event.target.parentNode.getAttribute("data-uri")), event.target.parentNode.getAttribute("data-name"));
|
||||||
|
}
|
||||||
|
else if (event.target.nodeName == 'A') {
|
||||||
|
event.preventDefault();
|
||||||
|
showMenu(event.target);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
document.getElementById('BrowsePlaylistsDetailList').addEventListener('click', function(event) {
|
||||||
if (event.target.nodeName == 'TD') {
|
if (event.target.nodeName == 'TD') {
|
||||||
appendQueue('plist', decodeURI(event.target.parentNode.getAttribute("data-uri")), event.target.parentNode.getAttribute("data-name"));
|
appendQueue('plist', decodeURI(event.target.parentNode.getAttribute("data-uri")), event.target.parentNode.getAttribute("data-name"));
|
||||||
}
|
}
|
||||||
@ -917,10 +923,31 @@ function parseFilesystem(obj) {
|
|||||||
function parsePlaylists(obj) {
|
function parsePlaylists(obj) {
|
||||||
if (app.current.app !== 'Browse' && app.current.tab !== 'Playlists')
|
if (app.current.app !== 'Browse' && app.current.tab !== 'Playlists')
|
||||||
return;
|
return;
|
||||||
|
if (app.current.view == 'All') {
|
||||||
|
document.getElementById('BrowsePlaylistsAllList').classList.remove('hide');
|
||||||
|
document.getElementById('BrowsePlaylistsDetailList').classList.add('hide');
|
||||||
|
document.getElementById('btnBrowsePlaylistsAll').parentNode.classList.add('hide');
|
||||||
|
document.getElementById('btnPlaylistClear').parentNode.classList.add('hide');
|
||||||
|
} else {
|
||||||
|
if (obj.uri.indexOf('.') > -1) {
|
||||||
|
document.getElementById('BrowsePlaylistsDetailList').setAttribute('data-ro', 'true')
|
||||||
|
document.getElementById('btnPlaylistClear').parentNode.classList.add('hide');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.getElementById('BrowsePlaylistsDetailList').setAttribute('data-ro', 'false');
|
||||||
|
document.getElementById('btnPlaylistClear').parentNode.classList.remove('hide');
|
||||||
|
}
|
||||||
|
document.getElementById('BrowsePlaylistsDetailList').setAttribute('data-uri', obj.uri);
|
||||||
|
document.getElementById('BrowsePlaylistsDetailList').getElementsByTagName('caption')[0].innerText = 'Playlist: ' + obj.uri;
|
||||||
|
document.getElementById('BrowsePlaylistsDetailList').classList.remove('hide');
|
||||||
|
document.getElementById('BrowsePlaylistsAllList').classList.add('hide');
|
||||||
|
document.getElementById('btnBrowsePlaylistsAll').parentNode.classList.remove('hide');
|
||||||
|
}
|
||||||
|
|
||||||
var nrItems = obj.data.length;
|
var nrItems = obj.data.length;
|
||||||
var tbody = document.getElementById(app.current.app + app.current.tab + 'List').getElementsByTagName('tbody')[0];
|
var tbody = document.getElementById(app.current.app + app.current.tab + app.current.view + 'List').getElementsByTagName('tbody')[0];
|
||||||
var tr = tbody.getElementsByTagName('tr');
|
var tr = tbody.getElementsByTagName('tr');
|
||||||
|
if (app.current.view == 'All') {
|
||||||
for (var i = 0; i < nrItems; i++) {
|
for (var i = 0; i < nrItems; i++) {
|
||||||
var uri = encodeURI(obj.data[i].uri);
|
var uri = encodeURI(obj.data[i].uri);
|
||||||
if (tr[i])
|
if (tr[i])
|
||||||
@ -940,6 +967,33 @@ function parsePlaylists(obj) {
|
|||||||
else
|
else
|
||||||
tbody.append(row);
|
tbody.append(row);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (app.current.view == 'Detail') {
|
||||||
|
for (var i = 0; i < nrItems; i++) {
|
||||||
|
var uri = encodeURI(obj.data[i].uri);
|
||||||
|
if (tr[i])
|
||||||
|
if (tr[i].getAttribute('data-uri') == uri)
|
||||||
|
continue;
|
||||||
|
var songpos = obj.offset + i;
|
||||||
|
var row = document.createElement('tr');
|
||||||
|
row.setAttribute('data-type', obj.data[i].type);
|
||||||
|
row.setAttribute('data-uri', uri);
|
||||||
|
row.setAttribute('data-name', obj.data[i].name);
|
||||||
|
row.setAttribute('data-songpos', songpos);
|
||||||
|
var minutes = Math.floor(obj.data[i].duration / 60);
|
||||||
|
var seconds = obj.data[i].duration - minutes * 60;
|
||||||
|
row.innerHTML = '<td>' + (songpos + 1) + '</td>' +
|
||||||
|
'<td>' + obj.data[i].title + '</td>' +
|
||||||
|
'<td>' + obj.data[i].artist + '</td>' +
|
||||||
|
'<td>' + obj.data[i].album + '</td>' +
|
||||||
|
'<td>' + minutes + ':' + (seconds < 10 ? '0' : '') + seconds +
|
||||||
|
'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';
|
||||||
|
if (i < tr.length)
|
||||||
|
tr[i].replaceWith(row);
|
||||||
|
else
|
||||||
|
tbody.append(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
var tr_length=tr.length - 1;
|
var tr_length=tr.length - 1;
|
||||||
for (var i = tr_length; i >= nrItems; i --) {
|
for (var i = tr_length; i >= nrItems; i --) {
|
||||||
tr[i].remove();
|
tr[i].remove();
|
||||||
@ -948,9 +1002,14 @@ function parsePlaylists(obj) {
|
|||||||
setPagination(obj.totalEntities);
|
setPagination(obj.totalEntities);
|
||||||
|
|
||||||
if (nrItems == 0)
|
if (nrItems == 0)
|
||||||
|
if (app.current.view == 'All')
|
||||||
tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' +
|
tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' +
|
||||||
'<td colspan="5">No playlists found.</td></tr>'
|
'<td colspan="5">No playlists found.</td></tr>';
|
||||||
document.getElementById(app.current.app + (app.current.tab==undefined ? '' : app.current.tab) + 'List').classList.remove('opacity05');
|
else
|
||||||
|
tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' +
|
||||||
|
'<td colspan="5">Empty playlist.</td></tr>';
|
||||||
|
|
||||||
|
document.getElementById(app.current.app + app.current.tab + app.current.view + 'List').classList.remove('opacity05');
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseListDBtags(obj) {
|
function parseListDBtags(obj) {
|
||||||
@ -959,7 +1018,7 @@ function parseListDBtags(obj) {
|
|||||||
if (obj.tagtype == 'AlbumArtist') {
|
if (obj.tagtype == 'AlbumArtist') {
|
||||||
document.getElementById('BrowseDatabaseAlbumCards').classList.add('hide');
|
document.getElementById('BrowseDatabaseAlbumCards').classList.add('hide');
|
||||||
document.getElementById('BrowseDatabaseArtistList').classList.remove('hide');
|
document.getElementById('BrowseDatabaseArtistList').classList.remove('hide');
|
||||||
document.getElementById('btnBrowseDatabaseArtist').classList.add('hide');
|
document.getElementById('btnBrowseDatabaseArtist').parentNode.classList.add('hide');
|
||||||
var nrItems = obj.data.length;
|
var nrItems = obj.data.length;
|
||||||
var tbody = document.getElementById(app.current.app + app.current.tab + app.current.view + 'List').getElementsByTagName('tbody')[0];
|
var tbody = document.getElementById(app.current.app + app.current.tab + app.current.view + 'List').getElementsByTagName('tbody')[0];
|
||||||
var tr = tbody.getElementsByTagName('tr');
|
var tr = tbody.getElementsByTagName('tr');
|
||||||
@ -994,7 +1053,7 @@ function parseListDBtags(obj) {
|
|||||||
} else if (obj.tagtype == 'Album') {
|
} else if (obj.tagtype == 'Album') {
|
||||||
document.getElementById('BrowseDatabaseAlbumCards').classList.remove('hide');
|
document.getElementById('BrowseDatabaseAlbumCards').classList.remove('hide');
|
||||||
document.getElementById('BrowseDatabaseArtistList').classList.add('hide');
|
document.getElementById('BrowseDatabaseArtistList').classList.add('hide');
|
||||||
document.getElementById('btnBrowseDatabaseArtist').classList.remove('hide');
|
document.getElementById('btnBrowseDatabaseArtist').parentNode.classList.remove('hide');
|
||||||
var nrItems = obj.data.length;
|
var nrItems = obj.data.length;
|
||||||
var cardContainer = document.getElementById('BrowseDatabaseAlbumCards');
|
var cardContainer = document.getElementById('BrowseDatabaseAlbumCards');
|
||||||
var cards = cardContainer.querySelectorAll('.col-md');
|
var cards = cardContainer.querySelectorAll('.col-md');
|
||||||
@ -1178,6 +1237,74 @@ function parseSongDetails(obj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function playlistDetails(uri) {
|
||||||
|
appGoto('Browse', 'Playlists', 'Detail', '0/-/' + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFromPlaylist(uri, pos) {
|
||||||
|
sendAPI({"cmd": "MPD_API_RM_PLAYLIST_TRACK", "data": {"uri": uri, "track": pos}});
|
||||||
|
document.getElementById('BrowsePlaylistsDetailList').classList.add('opacity05');
|
||||||
|
sendAPI({"cmd": "MPD_API_GET_PLAYLIST_LIST", "data": {"offset": app.current.page, "filter": app.current.filter, "uri": app.current.search}}, parsePlaylists);
|
||||||
|
}
|
||||||
|
|
||||||
|
function playlistClear() {
|
||||||
|
var uri = document.getElementById('BrowsePlaylistsDetailList').getAttribute('data-uri');
|
||||||
|
sendAPI({"cmd": "MPD_API_PLAYLIST_CLEAR", "data": {"uri": uri}});
|
||||||
|
document.getElementById('BrowsePlaylistsDetailList').classList.add('opacity05');
|
||||||
|
sendAPI({"cmd": "MPD_API_GET_PLAYLIST_LIST", "data": {"offset": app.current.page, "filter": app.current.filter, "uri": app.current.search}}, parsePlaylists);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAllPlaylists(obj) {
|
||||||
|
var nrItems = obj.data.length;
|
||||||
|
var playlists = '';
|
||||||
|
for (var i = 0; i < nrItems; i++) {
|
||||||
|
playlists += '<option>' + obj.data[i].uri + '</option>';
|
||||||
|
}
|
||||||
|
document.getElementById('addToPlaylistPlaylist').innerHTML += playlists;
|
||||||
|
if (obj.totalEntities > obj.returnedEntities) {
|
||||||
|
obj.offset += settings.max_elements_per_page;
|
||||||
|
sendAPI({"cmd":"MPD_API_GET_PLAYLISTS","data": {"offset": obj.offset, "filter": "-"}}, getAllPlaylists);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAddToPlaylist(uri) {
|
||||||
|
modalAddToPlaylist.show();
|
||||||
|
document.getElementById('addToPlaylistUri').value = uri;
|
||||||
|
document.getElementById('addToPlaylistPlaylist').innerHTML = '';
|
||||||
|
sendAPI({"cmd":"MPD_API_GET_PLAYLISTS","data": {"offset": 0, "filter": "-"}}, getAllPlaylists);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addToPlaylist() {
|
||||||
|
var uri = document.getElementById('addToPlaylistUri').value;
|
||||||
|
var plistEl = document.getElementById('addToPlaylistPlaylist');
|
||||||
|
var plist = plistEl.options[plistEl.selectedIndex].text;
|
||||||
|
sendAPI({"cmd": "MPD_API_ADD_TO_PLAYLIST", "data": {"uri": uri, "plist": plist}});
|
||||||
|
modalAddToPlaylist.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function showRenamePlaylist(from) {
|
||||||
|
document.getElementById('renamePlaylistFrm').classList.remove('was-validated');
|
||||||
|
document.getElementById('renamePlaylistTo').classList.remove('is-invalid');
|
||||||
|
modalRenamePlaylist.show();
|
||||||
|
document.getElementById('renamePlaylistFrom').value = from;
|
||||||
|
document.getElementById('renamePlaylistTo').value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function renamePlaylist() {
|
||||||
|
var from = document.getElementById('renamePlaylistFrom').value;
|
||||||
|
var to = document.getElementById('renamePlaylistTo').value;
|
||||||
|
var valid = to.replace(/\w/g,'');
|
||||||
|
if (to != '' && to != from && valid == '') {
|
||||||
|
sendAPI({"cmd": "MPD_API_PLAYLIST_RENAME", "data": {"from": from, "to": to}});
|
||||||
|
modalRenamePlaylist.hide();
|
||||||
|
sendAPI({"cmd":"MPD_API_GET_PLAYLISTS","data": {"offset": app.current.page, "filter": app.current.filter}}, parsePlaylists);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.getElementById('renamePlaylistTo').classList.add('is-invalid');
|
||||||
|
document.getElementById('renamePlaylistFrm').classList.add('was-validated');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showMenu(el) {
|
function showMenu(el) {
|
||||||
var type = el.getAttribute('data-type');
|
var type = el.getAttribute('data-type');
|
||||||
var uri = decodeURI(el.getAttribute('data-uri'));
|
var uri = decodeURI(el.getAttribute('data-uri'));
|
||||||
@ -1201,22 +1328,32 @@ function showMenu(el) {
|
|||||||
uri + '\',' + nextsongpos + ',\'' + name + '\']}">Add after current playing song</a>' : '') +
|
uri + '\',' + nextsongpos + ',\'' + name + '\']}">Add after current playing song</a>' : '') +
|
||||||
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +
|
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +
|
||||||
uri + '\',\'' + name + '\']}">Replace queue</a>' +
|
uri + '\',\'' + name + '\']}">Replace queue</a>' +
|
||||||
// ( type != 'plist' ? '<div class="dropdown-divider"></div><a class="dropdown-item" href="#">Add to playlist</a>' : '') +
|
( type != 'plist' ? '<div class="dropdown-divider"></div><a class="dropdown-item" href="#" data-href="{\'cmd\': \'showAddToPlaylist\', \'options\': [\'' + uri + '\']}">Add to playlist</a>' : '') +
|
||||||
( type != 'dir' ? '<div class="dropdown-divider"></div>' : '') +
|
( type != 'dir' ? '<div class="dropdown-divider"></div>' : '') +
|
||||||
( type == 'song' ? '<a class="dropdown-item" data-href="{\'cmd\': \'songDetails\', \'options\': [\'' + uri + '\']}" href="#">Songdetails</a>' : '');
|
( type == 'song' ? '<a class="dropdown-item" data-href="{\'cmd\': \'songDetails\', \'options\': [\'' + uri + '\']}" href="#">Songdetails</a>' : '') +
|
||||||
// ( type == 'plist' ? '<a class="dropdown-item" href="#">Show playlist</a>' : '');
|
( type == 'plist' ? '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'playlistDetails\', \'options\': [\'' + uri + '\']}">Show playlist</a>' : '');
|
||||||
}
|
}
|
||||||
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists') {
|
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'All') {
|
||||||
menu += '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'appendQueue\', \'options\': [\'' + type + '\',\'' +
|
menu += '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'appendQueue\', \'options\': [\'' + type + '\',\'' +
|
||||||
uri + '\',\'' + name + '\']}">Append to queue</a>' +
|
uri + '\',\'' + name + '\']}">Append to queue</a>' +
|
||||||
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +
|
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +
|
||||||
uri + '\',\'' + name + '\']}">Replace queue</a>' +
|
uri + '\',\'' + name + '\']}">Replace queue</a>' +
|
||||||
'<div class="dropdown-divider"></div>' +
|
'<div class="dropdown-divider"></div>' +
|
||||||
// '<a class="dropdown-item" href="#">Show playlist</a>' +
|
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'playlistDetails\', \'options\': [\'' + uri + '\']}">Edit playlist</a>' +
|
||||||
// '<a class="dropdown-item" href="#">Rename playlist</a>' +
|
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'showRenamePlaylist\', \'options\': [\'' + uri + '\']}">Rename playlist</a>' +
|
||||||
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delPlaylist\', \'options\': [\'' +
|
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delPlaylist\', \'options\': [\'' +
|
||||||
uri + '\',\'' + name + '\']}">Delete playlist</a>';
|
uri + '\',\'' + name + '\']}">Delete playlist</a>';
|
||||||
}
|
}
|
||||||
|
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'Detail') {
|
||||||
|
menu += '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'appendQueue\', \'options\': [\'' + type + '\',\'' +
|
||||||
|
uri + '\',\'' + name + '\']}">Append to queue</a>' +
|
||||||
|
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +
|
||||||
|
uri + '\',\'' + name + '\']}">Replace queue</a>' +
|
||||||
|
( document.getElementById('BrowsePlaylistsDetailList').getAttribute('data-ro') == 'false' ?
|
||||||
|
'<div class="dropdown-divider"></div>' +
|
||||||
|
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'removeFromPlaylist\', \'options\': [\'' + document.getElementById('BrowsePlaylistsDetailList').getAttribute('data-uri') + '\', \'' +
|
||||||
|
el.parentNode.parentNode.getAttribute('data-songpos') + '\']}">Remove</a>' : '');
|
||||||
|
}
|
||||||
else if (app.current.app == 'Queue') {
|
else if (app.current.app == 'Queue') {
|
||||||
menu += '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delQueueSong\', \'options\': [\'single\',' +
|
menu += '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delQueueSong\', \'options\': [\'single\',' +
|
||||||
el.parentNode.parentNode.getAttribute('data-trackid') + ']}">Remove</a>' +
|
el.parentNode.parentNode.getAttribute('data-trackid') + ']}">Remove</a>' +
|
||||||
@ -1262,7 +1399,7 @@ function sendAPI(request, callback) {
|
|||||||
if (ajaxRequest.responseText != '') {
|
if (ajaxRequest.responseText != '') {
|
||||||
var obj = JSON.parse(ajaxRequest.responseText);
|
var obj = JSON.parse(ajaxRequest.responseText);
|
||||||
if (obj.type == 'error') {
|
if (obj.type == 'error') {
|
||||||
showNotification('Error', obj.data, obj.data, 'error');
|
showNotification('Error', obj.data, obj.data, 'danger');
|
||||||
console.log('Error: ' + obj.data);
|
console.log('Error: ' + obj.data);
|
||||||
}
|
}
|
||||||
else if (obj.type == 'result' && obj.data != 'ok')
|
else if (obj.type == 'result' && obj.data != 'ok')
|
||||||
@ -1284,7 +1421,7 @@ function openLocalPlayer() {
|
|||||||
|
|
||||||
function updateDB() {
|
function updateDB() {
|
||||||
sendAPI({"cmd": "MPD_API_UPDATE_DB"});
|
sendAPI({"cmd": "MPD_API_UPDATE_DB"});
|
||||||
// showNotification('Updating MPD Database...', '', '', 'success');
|
showNotification('Updating MPD Database...', '', '', 'success');
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickPlay() {
|
function clickPlay() {
|
||||||
@ -1439,7 +1576,7 @@ function showNotification(notificationTitle,notificationText,notificationHtml,no
|
|||||||
else {
|
else {
|
||||||
alertBox = document.getElementById('alertBox');
|
alertBox = document.getElementById('alertBox');
|
||||||
}
|
}
|
||||||
alertBox.classList.remove('alert-success', 'alert-error');
|
alertBox.classList.remove('alert-success', 'alert-danger');
|
||||||
alertBox.classList.add('alert','alert-' + notificationType);
|
alertBox.classList.add('alert','alert-' + notificationType);
|
||||||
alertBox.innerHTML = '<div><strong>' + notificationTitle + '</strong><br/>' + notificationHtml + '</div>';
|
alertBox.innerHTML = '<div><strong>' + notificationTitle + '</strong><br/>' + notificationHtml + '</div>';
|
||||||
document.getElementsByTagName('main')[0].append(alertBox);
|
document.getElementsByTagName('main')[0].append(alertBox);
|
||||||
@ -1466,7 +1603,7 @@ function notificationsSupported() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function songChange(obj) {
|
function songChange(obj) {
|
||||||
if (obj.type == 'error')
|
if (obj.type == 'error' || obj.type == 'result')
|
||||||
return;
|
return;
|
||||||
var cur_song = obj.data.title + obj.data.artist + obj.data.album + obj.data.uri + obj.data.currentsongid;
|
var cur_song = obj.data.title + obj.data.artist + obj.data.album + obj.data.uri + obj.data.currentsongid;
|
||||||
if (last_song == cur_song)
|
if (last_song == cur_song)
|
||||||
@ -1479,7 +1616,7 @@ function songChange(obj) {
|
|||||||
|
|
||||||
if(typeof obj.data.artist != 'undefined' && obj.data.artist.length > 0 && obj.data.artist != '-') {
|
if(typeof obj.data.artist != 'undefined' && obj.data.artist.length > 0 && obj.data.artist != '-') {
|
||||||
textNotification += obj.data.artist;
|
textNotification += obj.data.artist;
|
||||||
htmlNotification += '<br/>' + obj.data.artist;
|
htmlNotification += obj.data.artist;
|
||||||
pageTitle += obj.data.artist + ' - ';
|
pageTitle += obj.data.artist + ' - ';
|
||||||
document.getElementById('artist').innerText = obj.data.artist;
|
document.getElementById('artist').innerText = obj.data.artist;
|
||||||
} else {
|
} else {
|
||||||
|
109
src/mpd_client.c
109
src/mpd_client.c
@ -78,7 +78,7 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg)
|
|||||||
|
|
||||||
switch(cmd_id) {
|
switch(cmd_id) {
|
||||||
case MPD_API_UNKNOWN:
|
case MPD_API_UNKNOWN:
|
||||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Unknown request: %.*s\"}", msg.len, msg.p );
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Unknown request\"}");
|
||||||
break;
|
break;
|
||||||
case MPD_API_SET_SETTINGS:
|
case MPD_API_SET_SETTINGS:
|
||||||
json_scanf(msg.p, msg.len, "{ data: { notificationWeb: %d, notificationPage: %d} }", &state.a, &state.b);
|
json_scanf(msg.p, msg.len, "{ data: { notificationWeb: %d, notificationPage: %d} }", &state.a, &state.b);
|
||||||
@ -140,7 +140,7 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg)
|
|||||||
case MPD_API_UPDATE_DB:
|
case MPD_API_UPDATE_DB:
|
||||||
uint_rc = mpd_run_update(mpd.conn, NULL);
|
uint_rc = mpd_run_update(mpd.conn, NULL);
|
||||||
if (uint_rc > 0)
|
if (uint_rc > 0)
|
||||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"Updating MPD Database...\"}");
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||||
break;
|
break;
|
||||||
case MPD_API_SET_PAUSE:
|
case MPD_API_SET_PAUSE:
|
||||||
mpd_run_toggle_pause(mpd.conn);
|
mpd_run_toggle_pause(mpd.conn);
|
||||||
@ -254,6 +254,15 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg)
|
|||||||
free(p_charbuf2);
|
free(p_charbuf2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MPD_API_PLAYLIST_RENAME:
|
||||||
|
je = json_scanf(msg.p, msg.len, "{ data: { from:%Q, to:%Q } }", &p_charbuf1, &p_charbuf2);
|
||||||
|
if (je == 2) {
|
||||||
|
mpd_run_rename(mpd.conn, p_charbuf1, p_charbuf2);
|
||||||
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"Renamed playlist %s to %s\"}", p_charbuf1, p_charbuf2);
|
||||||
|
free(p_charbuf1);
|
||||||
|
free(p_charbuf2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MPD_API_GET_PLAYLISTS:
|
case MPD_API_GET_PLAYLISTS:
|
||||||
je = json_scanf(msg.p, msg.len, "{ data: { offset:%u, filter:%Q } }", &uint_buf1, &p_charbuf1);
|
je = json_scanf(msg.p, msg.len, "{ data: { offset:%u, filter:%Q } }", &uint_buf1, &p_charbuf1);
|
||||||
if (je == 2) {
|
if (je == 2) {
|
||||||
@ -261,6 +270,39 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg)
|
|||||||
free(p_charbuf1);
|
free(p_charbuf1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MPD_API_GET_PLAYLIST_LIST:
|
||||||
|
je = json_scanf(msg.p, msg.len, "{ data: { uri: %Q, offset:%u, filter:%Q } }", &p_charbuf1, &uint_buf1, &p_charbuf2);
|
||||||
|
if (je == 3) {
|
||||||
|
n = mympd_put_playlist_list(mpd.buf, p_charbuf1, uint_buf1, p_charbuf2);
|
||||||
|
free(p_charbuf1);
|
||||||
|
free(p_charbuf2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MPD_API_ADD_TO_PLAYLIST:
|
||||||
|
je = json_scanf(msg.p, msg.len, "{ data: { plist:%Q, uri:%Q } }", &p_charbuf1, &p_charbuf2);
|
||||||
|
if (je == 2) {
|
||||||
|
mpd_run_playlist_add(mpd.conn, p_charbuf1, p_charbuf2);
|
||||||
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"Added %s to playlist %s\"}", p_charbuf2, p_charbuf1);
|
||||||
|
free(p_charbuf1);
|
||||||
|
free(p_charbuf2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MPD_API_PLAYLIST_CLEAR:
|
||||||
|
je = json_scanf(msg.p, msg.len, "{ data: { uri:%Q } }", &p_charbuf1);
|
||||||
|
if (je == 1) {
|
||||||
|
mpd_run_playlist_clear(mpd.conn, p_charbuf1);
|
||||||
|
free(p_charbuf1);
|
||||||
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MPD_API_RM_PLAYLIST_TRACK:
|
||||||
|
je = json_scanf(msg.p, msg.len, "{ data: { uri:%Q, track:%u } }", &p_charbuf1, &uint_buf1);
|
||||||
|
if (je == 2) {
|
||||||
|
mpd_run_playlist_delete(mpd.conn, p_charbuf1, uint_buf1);
|
||||||
|
free(p_charbuf1);
|
||||||
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MPD_API_GET_FILESYSTEM:
|
case MPD_API_GET_FILESYSTEM:
|
||||||
je = json_scanf(msg.p, msg.len, "{ data: { offset:%u, filter:%Q, path:%Q } }", &uint_buf1, &p_charbuf1, &p_charbuf2);
|
je = json_scanf(msg.p, msg.len, "{ data: { offset:%u, filter:%Q, path:%Q } }", &uint_buf1, &p_charbuf1, &p_charbuf2);
|
||||||
if (je == 3) {
|
if (je == 3) {
|
||||||
@ -737,8 +779,10 @@ int mympd_put_current_song(char *buffer) {
|
|||||||
char cover[500];
|
char cover[500];
|
||||||
|
|
||||||
song = mpd_run_current_song(mpd.conn);
|
song = mpd_run_current_song(mpd.conn);
|
||||||
if(song == NULL)
|
if (song == NULL) {
|
||||||
return 0;
|
len = json_printf(&out,"{type: result, data: ok}");
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
mympd_get_cover(mpd_song_get_uri(song),cover,500);
|
mympd_get_cover(mpd_song_get_uri(song),cover,500);
|
||||||
|
|
||||||
@ -1101,6 +1145,57 @@ int mympd_put_playlists(char *buffer, unsigned int offset, char *filter) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char *filter) {
|
||||||
|
struct mpd_entity *entity;
|
||||||
|
unsigned int entity_count = 0;
|
||||||
|
unsigned int entities_returned = 0;
|
||||||
|
const char *entityName;
|
||||||
|
int len;
|
||||||
|
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
||||||
|
|
||||||
|
if (!mpd_send_list_playlist_meta(mpd.conn, uri))
|
||||||
|
RETURN_ERROR_AND_RECOVER("mpd_send_list_meta");
|
||||||
|
|
||||||
|
len = json_printf(&out, "{ type: playlist_detail, data: [ ");
|
||||||
|
|
||||||
|
while((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
||||||
|
const struct mpd_song *song;
|
||||||
|
entity_count ++;
|
||||||
|
if (entity_count > offset && entity_count <= offset+MAX_ELEMENTS_PER_PAGE) {
|
||||||
|
song = mpd_entity_get_song(entity);
|
||||||
|
entityName = mympd_get_tag(song, MPD_TAG_TITLE);
|
||||||
|
if (strncmp(filter,"-",1) == 0 || strncasecmp(filter,entityName,1) == 0 ||
|
||||||
|
( strncmp(filter,"0",1) == 0 && isalpha(*entityName) == 0 )
|
||||||
|
) {
|
||||||
|
if (entities_returned ++) len += json_printf(&out,",");
|
||||||
|
len += json_printf(&out, "{type: song, uri: %Q, album: %Q, artist: %Q, duration: %d, title: %Q, name: %Q }",
|
||||||
|
mpd_song_get_uri(song),
|
||||||
|
mympd_get_tag(song, MPD_TAG_ALBUM),
|
||||||
|
mympd_get_tag(song, MPD_TAG_ARTIST),
|
||||||
|
mpd_song_get_duration(song),
|
||||||
|
entityName,
|
||||||
|
entityName
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
entity_count --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mpd_entity_free(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
len += json_printf(&out, "], totalEntities: %d, offset: %d, returnedEntities: %d, filter: %Q, uri: %Q }",
|
||||||
|
entity_count,
|
||||||
|
offset,
|
||||||
|
entities_returned,
|
||||||
|
filter,
|
||||||
|
uri
|
||||||
|
);
|
||||||
|
|
||||||
|
if (len > MAX_SIZE)
|
||||||
|
fprintf(stderr,"Buffer truncated\n");
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
int mympd_search(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr) {
|
int mympd_search(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr) {
|
||||||
struct mpd_song *song;
|
struct mpd_song *song;
|
||||||
unsigned long entity_count = 0;
|
unsigned long entity_count = 0;
|
||||||
@ -1150,7 +1245,8 @@ int mympd_search(char *buffer, char *mpdtagtype, unsigned int offset, char *sear
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > MAX_SIZE) fprintf(stderr,"Buffer truncated\n");
|
if (len > MAX_SIZE)
|
||||||
|
fprintf(stderr,"Buffer truncated\n");
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1180,7 +1276,8 @@ int mympd_search_add(char *buffer,char *mpdtagtype, char *searchstr) {
|
|||||||
mpd_song_free(song);
|
mpd_song_free(song);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > MAX_SIZE) fprintf(stderr,"Buffer truncated\n");
|
if (len > MAX_SIZE)
|
||||||
|
fprintf(stderr,"Buffer truncated\n");
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,10 @@
|
|||||||
X(MPD_API_REPLACE_TRACK) \
|
X(MPD_API_REPLACE_TRACK) \
|
||||||
X(MPD_API_ADD_PLAYLIST) \
|
X(MPD_API_ADD_PLAYLIST) \
|
||||||
X(MPD_API_REPLACE_PLAYLIST) \
|
X(MPD_API_REPLACE_PLAYLIST) \
|
||||||
|
X(MPD_API_RM_PLAYLIST_TRACK) \
|
||||||
|
X(MPD_API_PLAYLIST_CLEAR) \
|
||||||
|
X(MPD_API_PLAYLIST_RENAME) \
|
||||||
|
X(MPD_API_ADD_TO_PLAYLIST) \
|
||||||
X(MPD_API_PLAY_TRACK) \
|
X(MPD_API_PLAY_TRACK) \
|
||||||
X(MPD_API_SAVE_QUEUE) \
|
X(MPD_API_SAVE_QUEUE) \
|
||||||
X(MPD_API_RM_TRACK) \
|
X(MPD_API_RM_TRACK) \
|
||||||
@ -75,6 +79,7 @@
|
|||||||
X(MPD_API_SEND_SHUFFLE) \
|
X(MPD_API_SEND_SHUFFLE) \
|
||||||
X(MPD_API_GET_STATS) \
|
X(MPD_API_GET_STATS) \
|
||||||
X(MPD_API_GET_PLAYLISTS) \
|
X(MPD_API_GET_PLAYLISTS) \
|
||||||
|
X(MPD_API_GET_PLAYLIST_LIST) \
|
||||||
X(MPD_API_RM_PLAYLIST) \
|
X(MPD_API_RM_PLAYLIST) \
|
||||||
X(MPD_API_GET_ARTISTALBUMS) \
|
X(MPD_API_GET_ARTISTALBUMS) \
|
||||||
X(MPD_API_GET_ARTISTALBUMTITLES) \
|
X(MPD_API_GET_ARTISTALBUMTITLES) \
|
||||||
@ -146,6 +151,7 @@ int mympd_put_settings(char *buffer);
|
|||||||
int mympd_put_db_tag(char *buffer, unsigned int offset, char *mpdtagtype, char *mpdsearchtagtype, char *searchstr, char *filter);
|
int mympd_put_db_tag(char *buffer, unsigned int offset, char *mpdtagtype, char *mpdsearchtagtype, char *searchstr, char *filter);
|
||||||
int mympd_put_songs_in_album(char *buffer, char *albumartist, char *album);
|
int mympd_put_songs_in_album(char *buffer, char *albumartist, char *album);
|
||||||
int mympd_put_playlists(char *buffer, unsigned int offset, char *filter);
|
int mympd_put_playlists(char *buffer, unsigned int offset, char *filter);
|
||||||
|
int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char *filter);
|
||||||
int mympd_put_songdetails(char *buffer, char *uri);
|
int mympd_put_songdetails(char *buffer, char *uri);
|
||||||
void mympd_disconnect();
|
void mympd_disconnect();
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user