mirror of
https://github.com/SuperBFG7/ympd
synced 2025-01-27 01:14:53 +00:00
Feat: Replaced mpd polling through mpd idle protocol
This commit is contained in:
parent
a6f63f6cb2
commit
19cc6bd053
34
dist/htdocs/js/mpd.min.js
vendored
34
dist/htdocs/js/mpd.min.js
vendored
@ -25,28 +25,28 @@ var c=app.current.search.split("/"),e=c.length,d="";for(a=0;a<e;a++){if(e-1==a){
|
||||
app.current.app)for(document.getElementById("searchstr").focus(),app.last.app!=app.current.app&&""!=app.current.search&&(document.getElementById("SearchList").getElementsByTagName("tbody")[0].innerHTML='<tr><td><span class="material-icons">search</span></td><td colspan="5">Searching...</td></tr>'),2<=app.current.search.length?sendAPI({cmd:"MPD_API_SEARCH",data:{mpdtag:app.current.filter,offset:app.current.page,searchstr:app.current.search}},parseSearch):(document.getElementById("SearchList").getElementsByTagName("tbody")[0].innerHTML=
|
||||
"",document.getElementById("searchAddAllSongs").setAttribute("disabled","disabled"),document.getElementById("searchAddAllSongsBtn").setAttribute("disabled","disabled"),document.getElementById("panel-heading-search").innerText="",document.getElementById("SearchList").classList.remove("opacity05"),setPagination(0)),b=document.getElementById("searchtags").getElementsByTagName("button"),c=b.length,a=0;a<c;a++)b[a].classList.remove("active"),b[a].innerText==app.current.filter&&(b[a].classList.add("active"),
|
||||
document.getElementById("searchtagsdesc").innerText=b[a].innerText);else appGoto("Playback");app.last.app=app.current.app;app.last.tab=app.current.tab;app.last.view=app.current.view}else appGoto("Playback")}
|
||||
function appInit(){getSettings();webSocketConnect();domCache.volumeBar.value=0;domCache.volumeBar.addEventListener("change",function(a){sendAPI({cmd:"MPD_API_SET_VOLUME",data:{volume:domCache.volumeBar.value}})},!1);domCache.progressBar.value=0;domCache.progressBar.addEventListener("change",function(a){current_song&&0<=current_song.currentSongId&&sendAPI({cmd:"MPD_API_SET_SEEK",data:{songid:current_song.currentSongId,seek:Math.ceil(domCache.progressBar.value/100*current_song.totalTime)}})},!1);document.getElementById("volumeIcon").parentNode.addEventListener("show.bs.dropdown",
|
||||
function(){sendAPI({cmd:"MPD_API_GET_OUTPUTS"},parseOutputnames)});document.getElementById("modalAbout").addEventListener("shown.bs.modal",function(){sendAPI({cmd:"MPD_API_GET_STATS"},parseStats)});document.getElementById("modalSaveQueue").addEventListener("shown.bs.modal",function(){var a=document.getElementById("saveQueueName");a.focus();a.value="";a.classList.remove("is-invalid");document.getElementById("saveQueueFrm").classList.remove("was-validated")});document.getElementById("modalSettings").addEventListener("shown.bs.modal",
|
||||
function(){getSettings();document.getElementById("settingsFrm").classList.remove("was-validated");document.getElementById("inputCrossfade").classList.remove("is-invalid");document.getElementById("inputMixrampdb").classList.remove("is-invalid");document.getElementById("inputMixrampdelay").classList.remove("is-invalid")});document.getElementById("addToPlaylistPlaylist").addEventListener("change",function(a){"New Playlist"==this.options[this.selectedIndex].text?(document.getElementById("addToPlaylistNewPlaylistDiv").classList.remove("hide"),
|
||||
document.getElementById("addToPlaylistNewPlaylist").focus()):document.getElementById("addToPlaylistNewPlaylistDiv").classList.add("hide")},!1);addFilterLetter("BrowseFilesystemFilterLetters");addFilterLetter("BrowseDatabaseFilterLetters");addFilterLetter("BrowsePlaylistsFilterLetters");for(var a=document.querySelectorAll("[data-href]"),b=a.length,c=0;c<b;c++)a[c].classList.add("clickable"),a[c].addEventListener("click",function(a){a.preventDefault();a.stopPropagation();a=JSON.parse(this.getAttribute("data-href").replace(/'/g,
|
||||
'"'));if("function"===typeof window[a.cmd])switch(a.cmd){case "sendAPI":sendAPI.apply(null,$jscomp.arrayFromIterable(a.options));break;default:window[a.cmd].apply(null,$jscomp.arrayFromIterable(a.options))}},!1);a=document.querySelectorAll(".pages");b=a.length;for(c=0;c<b;c++)a[c].addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&gotoPage(a.target.getAttribute("data-page"))},!1);document.getElementById("outputs").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&a.stopPropagation();
|
||||
sendAPI({cmd:"MPD_API_TOGGLE_OUTPUT",data:{output:a.target.getAttribute("data-output-id"),state:a.target.classList.contains("active")?0:1}});toggleBtn(a.target.id)},!1);document.getElementById("QueueList").addEventListener("click",function(a){"TD"==a.target.nodeName?sendAPI({cmd:"MPD_API_PLAY_TRACK",data:{track:a.target.parentNode.getAttribute("data-trackid")}}):"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowseFilesystemList").addEventListener("click",
|
||||
function(a){if("TD"==a.target.nodeName)switch(a.target.parentNode.getAttribute("data-type")){case "dir":appGoto("Browse","Filesystem",void 0,"0/"+app.current.filter+"/"+decodeURI(a.target.parentNode.getAttribute("data-uri")));break;case "song":appendQueue("song",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name"));break;case "plist":appendQueue("plist",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name"))}else"A"==
|
||||
a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowsePlaylistsAllList").addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("plist",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowsePlaylistsDetailList").addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("plist",
|
||||
decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowseDatabaseArtistList").addEventListener("click",function(a){"TD"==a.target.nodeName&&appGoto("Browse","Database","Album","0/-/"+a.target.parentNode.getAttribute("data-uri"))},!1);document.getElementById("SearchList").addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("song",decodeURI(a.target.parentNode.getAttribute("data-uri")),
|
||||
a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowseFilesystemAddAllSongsDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&("Add all to queue"==a.target.innerText?addAllFromBrowse():"Add all to playlist"==a.target.innerText&&showAddToPlaylist(app.current.search))},!1);document.getElementById("searchAddAllSongsDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&
|
||||
("Add all to queue"==a.target.innerText?addAllFromSearch():"Add all to playlist"==a.target.innerText&&showAddToPlaylist("SEARCH"))},!1);document.getElementById("searchtags").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,"0/"+a.target.innerText+"/"+app.current.search)},!1);document.getElementById("searchqueuestr").addEventListener("keyup",function(a){appGoto(app.current.app,app.current.tab,app.current.view,"0/"+app.current.filter+
|
||||
"/"+this.value)},!1);document.getElementById("searchqueuetag").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,app.current.page+"/"+a.target.innerText+"/"+app.current.search)},!1);document.getElementById("search").addEventListener("submit",function(){return!1},!1);document.getElementById("searchqueue").addEventListener("submit",function(){return!1},!1);document.getElementById("searchstr").addEventListener("keyup",function(a){appGoto("Search",
|
||||
void 0,void 0,"0/"+app.current.filter+"/"+this.value)},!1);dragAndDropTable("QueueList");dragAndDropTable("BrowsePlaylistsDetailList");window.addEventListener("hashchange",appRoute,!1);document.addEventListener("keydown",function(a){if("INPUT"!=a.target.tagName){switch(a.which){case 37:clickPrev();break;case 39:clickNext();break;case 32:clickPlay();break;default:return}a.preventDefault()}},!1);"serviceWorker"in navigator&&"https"==document.URL.substring(0,5)&&window.addEventListener("load",function(){navigator.serviceWorker.register("/sw.min.js",
|
||||
{scope:"/"}).then(function(a){console.log("ServiceWorker registration successful with scope: ",a.scope);a.update()},function(a){console.log("ServiceWorker registration failed: ",a)})});window.addEventListener("beforeinstallprompt",function(a){a.preventDefault();deferredPrompt=a});window.addEventListener("beforeinstallprompt",function(a){a.preventDefault();deferredPrompt=a;domCache.btnAdd.classList.remove("hide")});domCache.btnAdd.addEventListener("click",function(a){domCache.btnAdd.classList.add("hide");
|
||||
deferredPrompt.prompt();deferredPrompt.userChoice.then(function(a){"accepted"===a.outcome?console.log("User accepted the A2HS prompt"):console.log("User dismissed the A2HS prompt");deferredPrompt=null})});window.addEventListener("appinstalled",function(a){console.log("myMPD installed as app")})}
|
||||
function appInit(){getSettings();sendAPI({cmd:"MPD_API_GET_STATE"},parseState);webSocketConnect();domCache.volumeBar.value=0;domCache.volumeBar.addEventListener("change",function(a){sendAPI({cmd:"MPD_API_SET_VOLUME",data:{volume:domCache.volumeBar.value}})},!1);domCache.progressBar.value=0;domCache.progressBar.addEventListener("change",function(a){current_song&&0<=current_song.currentSongId&&sendAPI({cmd:"MPD_API_SET_SEEK",data:{songid:current_song.currentSongId,seek:Math.ceil(domCache.progressBar.value/
|
||||
100*current_song.totalTime)}})},!1);document.getElementById("volumeIcon").parentNode.addEventListener("show.bs.dropdown",function(){sendAPI({cmd:"MPD_API_GET_OUTPUTS"},parseOutputs)});document.getElementById("modalAbout").addEventListener("shown.bs.modal",function(){sendAPI({cmd:"MPD_API_GET_STATS"},parseStats)});document.getElementById("modalSaveQueue").addEventListener("shown.bs.modal",function(){var a=document.getElementById("saveQueueName");a.focus();a.value="";a.classList.remove("is-invalid");
|
||||
document.getElementById("saveQueueFrm").classList.remove("was-validated")});document.getElementById("modalSettings").addEventListener("shown.bs.modal",function(){getSettings();document.getElementById("settingsFrm").classList.remove("was-validated");document.getElementById("inputCrossfade").classList.remove("is-invalid");document.getElementById("inputMixrampdb").classList.remove("is-invalid");document.getElementById("inputMixrampdelay").classList.remove("is-invalid")});document.getElementById("addToPlaylistPlaylist").addEventListener("change",
|
||||
function(a){"New Playlist"==this.options[this.selectedIndex].text?(document.getElementById("addToPlaylistNewPlaylistDiv").classList.remove("hide"),document.getElementById("addToPlaylistNewPlaylist").focus()):document.getElementById("addToPlaylistNewPlaylistDiv").classList.add("hide")},!1);addFilterLetter("BrowseFilesystemFilterLetters");addFilterLetter("BrowseDatabaseFilterLetters");addFilterLetter("BrowsePlaylistsFilterLetters");for(var a=document.querySelectorAll("[data-href]"),b=a.length,c=0;c<
|
||||
b;c++)a[c].classList.add("clickable"),a[c].addEventListener("click",function(a){a.preventDefault();a.stopPropagation();a=JSON.parse(this.getAttribute("data-href").replace(/'/g,'"'));if("function"===typeof window[a.cmd])switch(a.cmd){case "sendAPI":sendAPI.apply(null,$jscomp.arrayFromIterable(a.options));break;default:window[a.cmd].apply(null,$jscomp.arrayFromIterable(a.options))}},!1);a=document.querySelectorAll(".pages");b=a.length;for(c=0;c<b;c++)a[c].addEventListener("click",function(a){"BUTTON"==
|
||||
a.target.nodeName&&gotoPage(a.target.getAttribute("data-page"))},!1);document.getElementById("outputs").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&a.stopPropagation();sendAPI({cmd:"MPD_API_TOGGLE_OUTPUT",data:{output:a.target.getAttribute("data-output-id"),state:a.target.classList.contains("active")?0:1}});toggleBtn(a.target.id)},!1);document.getElementById("QueueList").addEventListener("click",function(a){"TD"==a.target.nodeName?sendAPI({cmd:"MPD_API_PLAY_TRACK",data:{track:a.target.parentNode.getAttribute("data-trackid")}}):
|
||||
"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowseFilesystemList").addEventListener("click",function(a){if("TD"==a.target.nodeName)switch(a.target.parentNode.getAttribute("data-type")){case "dir":appGoto("Browse","Filesystem",void 0,"0/"+app.current.filter+"/"+decodeURI(a.target.parentNode.getAttribute("data-uri")));break;case "song":appendQueue("song",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name"));
|
||||
break;case "plist":appendQueue("plist",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name"))}else"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowsePlaylistsAllList").addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("plist",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},
|
||||
!1);document.getElementById("BrowsePlaylistsDetailList").addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("plist",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowseDatabaseArtistList").addEventListener("click",function(a){"TD"==a.target.nodeName&&appGoto("Browse","Database","Album","0/-/"+a.target.parentNode.getAttribute("data-uri"))},
|
||||
!1);document.getElementById("SearchList").addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("song",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowseFilesystemAddAllSongsDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&("Add all to queue"==a.target.innerText?addAllFromBrowse():"Add all to playlist"==
|
||||
a.target.innerText&&showAddToPlaylist(app.current.search))},!1);document.getElementById("searchAddAllSongsDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&("Add all to queue"==a.target.innerText?addAllFromSearch():"Add all to playlist"==a.target.innerText&&showAddToPlaylist("SEARCH"))},!1);document.getElementById("searchtags").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,"0/"+a.target.innerText+
|
||||
"/"+app.current.search)},!1);document.getElementById("searchqueuestr").addEventListener("keyup",function(a){appGoto(app.current.app,app.current.tab,app.current.view,"0/"+app.current.filter+"/"+this.value)},!1);document.getElementById("searchqueuetag").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,app.current.page+"/"+a.target.innerText+"/"+app.current.search)},!1);document.getElementById("search").addEventListener("submit",
|
||||
function(){return!1},!1);document.getElementById("searchqueue").addEventListener("submit",function(){return!1},!1);document.getElementById("searchstr").addEventListener("keyup",function(a){appGoto("Search",void 0,void 0,"0/"+app.current.filter+"/"+this.value)},!1);dragAndDropTable("QueueList");dragAndDropTable("BrowsePlaylistsDetailList");window.addEventListener("hashchange",appRoute,!1);document.addEventListener("keydown",function(a){if("INPUT"!=a.target.tagName){switch(a.which){case 37:clickPrev();
|
||||
break;case 39:clickNext();break;case 32:clickPlay();break;default:return}a.preventDefault()}},!1);"serviceWorker"in navigator&&"https"==document.URL.substring(0,5)&&window.addEventListener("load",function(){navigator.serviceWorker.register("/sw.min.js",{scope:"/"}).then(function(a){console.log("ServiceWorker registration successful with scope: ",a.scope);a.update()},function(a){console.log("ServiceWorker registration failed: ",a)})});window.addEventListener("beforeinstallprompt",function(a){a.preventDefault();
|
||||
deferredPrompt=a});window.addEventListener("beforeinstallprompt",function(a){a.preventDefault();deferredPrompt=a;domCache.btnAdd.classList.remove("hide")});domCache.btnAdd.addEventListener("click",function(a){domCache.btnAdd.classList.add("hide");deferredPrompt.prompt();deferredPrompt.userChoice.then(function(a){"accepted"===a.outcome?console.log("User accepted the A2HS prompt"):console.log("User dismissed the A2HS prompt");deferredPrompt=null})});window.addEventListener("appinstalled",function(a){console.log("myMPD installed as app")})}
|
||||
function dragAndDropTable(a){var b=document.getElementById(a).getElementsByTagName("tbody")[0];b.addEventListener("dragstart",function(a){"TR"==a.target.nodeName&&(a.target.classList.add("opacity05"),a.dataTransfer.setDragImage(a.target,0,0),a.dataTransfer.effectAllowed="move",a.dataTransfer.setData("Text",a.target.getAttribute("id")),dragEl=a.target.cloneNode(!0))},!1);b.addEventListener("dragleave",function(a){a.preventDefault();var b=a.target;"TD"==a.target.nodeName&&(b=a.target.parentNode);"TR"==
|
||||
b.nodeName&&b.classList.remove("dragover")},!1);b.addEventListener("dragover",function(a){a.preventDefault();for(var c=b.querySelectorAll(".dragover"),d=c.length,f=0;f<d;f++)c[f].classList.remove("dragover");c=a.target;"TD"==a.target.nodeName&&(c=a.target.parentNode);"TR"==c.nodeName&&c.classList.add("dragover");a.dataTransfer.dropEffect="move"},!1);b.addEventListener("dragend",function(a){for(var c=b.querySelectorAll(".dragover"),d=c.length,f=0;f<d;f++)c[f].classList.remove("dragover");document.getElementById(a.dataTransfer.getData("Text"))&&
|
||||
document.getElementById(a.dataTransfer.getData("Text")).classList.remove("opacity05")},!1);b.addEventListener("drop",function(c){c.stopPropagation();c.preventDefault();var e=c.target;"TD"==c.target.nodeName&&(e=c.target.parentNode);var d=document.getElementById(c.dataTransfer.getData("Text")).getAttribute("data-songpos"),f=e.getAttribute("data-songpos");document.getElementById(c.dataTransfer.getData("Text")).remove();dragEl.classList.remove("opacity05");b.insertBefore(dragEl,e);c=b.querySelectorAll(".dragover");
|
||||
e=c.length;for(var g=0;g<e;g++)c[g].classList.remove("dragover");document.getElementById(a).classList.add("opacity05");"Queue"==app.current.app?sendAPI({cmd:"MPD_API_MOVE_TRACK",data:{from:d,to:f}}):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view&&playlistMoveTrack(d,f)},!1)}
|
||||
function playlistMoveTrack(a,b){sendAPI({cmd:"MPD_API_PLAYLIST_MOVE_TRACK",data:{plist:app.current.search,from:a,to:b}});sendAPI({cmd:"MPD_API_GET_PLAYLIST_LIST",data:{offset:app.current.page,filter:app.current.filter,uri:app.current.search}},parsePlaylists)}
|
||||
function webSocketConnect(){socket=new WebSocket(getWsUrl());try{socket.onopen=function(){console.log("connected");showNotification("Connected to myMPD","","","success");modalConnectionError.hide();appRoute()},socket.onmessage=function(a){if(a.data!==last_state&&0!=a.data.length){try{var b=JSON.parse(a.data)}catch(c){console.log("Invalid JSON data received: "+a.data)}switch(b.type){case "state":parseState(b);break;case "disconnected":showNotification("myMPD lost connection to MPD","","","danger");
|
||||
break;case "update_queue":"Queue"===app.current.app&&getQueue();break;case "song_change":songChange(b);break;case "error":showNotification(b.data,"","","danger")}}},socket.onclose=function(){console.log("disconnected");modalConnectionError.show();setTimeout(function(){console.log("reconnect");webSocketConnect()},3E3)}}catch(a){alert("Error: "+a)}}
|
||||
break;case "update_queue":"Queue"===app.current.app&&getQueue();break;case "update_options":getSettings();break;case "update_outputs":sendAPI({cmd:"MPD_API_GET_OUTPUTS"},parseOutputs);break;case "song_change":songChange(b);break;case "error":showNotification(b.data,"","","danger")}}},socket.onclose=function(){console.log("disconnected");modalConnectionError.show();setTimeout(function(){console.log("reconnect");webSocketConnect()},3E3)}}catch(a){alert("Error: "+a)}}
|
||||
function getWsUrl(){var a=document.URL;if("https"==a.substring(0,5)){var b="wss://";a=a.substr(8)}else b="ws://","http"==a.substring(0,4)&&(a=a.substr(7));a=a.split("#");var c=/\/$/.test(a[0])?"":"/";return b+a[0]+c+"ws"}
|
||||
function parseStats(a){document.getElementById("mpdstats_artists").innerText=a.data.artists;document.getElementById("mpdstats_albums").innerText=a.data.albums;document.getElementById("mpdstats_songs").innerText=a.data.songs;document.getElementById("mpdstats_dbplaytime").innerText=beautifyDuration(a.data.dbplaytime);document.getElementById("mpdstats_playtime").innerText=beautifyDuration(a.data.playtime);document.getElementById("mpdstats_uptime").innerText=beautifyDuration(a.data.uptime);var b=new Date(1E3*
|
||||
a.data.dbupdated);document.getElementById("mpdstats_dbupdated").innerText=b.toUTCString();document.getElementById("mympdVersion").innerText=a.data.mympd_version;document.getElementById("mpdVersion").innerText=a.data.mpd_version}function toggleBtn(a,b){if(a=document.getElementById(a))void 0==b&&(b=a.classList.contains("active")?0:1),1==b?(a.classList.add("active"),a.setAttribute("aria-pressed","true")):(a.classList.remove("active"),a.setAttribute("aria-pressed","false"))}
|
||||
@ -54,7 +54,7 @@ function parseSettings(a){toggleBtn("btnRandom",a.data.random);toggleBtn("btnCon
|
||||
document.getElementById("inputMixrampdb").value=a.data.mixrampdb):document.getElementById("inputMixrampdb").setAttribute("disabled","disabled");void 0!=a.data.mixrampdelay?(document.getElementById("inputMixrampdelay").removeAttribute("disabled"),document.getElementById("inputMixrampdelay").value=a.data.mixrampdelay):document.getElementById("inputMixrampdelay").setAttribute("disabled","disabled");document.getElementById("selectReplaygain").value=a.data.replaygain;var b=document.getElementById("btnnotifyWeb");
|
||||
notificationsSupported()?a.data.notificationWeb?(toggleBtn("btnnotifyWeb",a.data.notificationWeb),Notification.requestPermission(function(b){"permission"in Notification||(Notification.permission=b);"granted"===b?toggleBtn("btnnotifyWeb",1):(toggleBtn("btnnotifyWeb",0),a.data.notificationWeb=0)})):toggleBtn("btnnotifyWeb",0):(b.setAttribute("disabled","disabled"),toggleBtn("btnnotifyWeb",0));toggleBtn("btnnotifyPage",a.data.notificationPage);settings=a.data;settings.mpdstream="http://";settings.mpdstream=
|
||||
"127.0.0.1"==settings.mpdhost||"localhost"==settings.mpdhost?settings.mpdstream+window.location.hostname:settings.mpdstream+settings.mpdhost;settings.mpdstream+=":"+settings.streamport+"/"}function getSettings(){sendAPI({cmd:"MPD_API_GET_SETTINGS"},parseSettings)}
|
||||
function parseOutputnames(a){for(var b="",c=a.data.outputs.length,e=0;e<c;e++)b+='<button data-output-id="'+a.data.outputs[e].id+'" class="btn btn-secondary btn-block',1==a.data.outputs[e].state&&(b+=" active"),b+='"><span class="material-icons float-left">volume_up</span> '+a.data.outputs[e].name+"</button>";domCache.outputs.innerHTML=b}
|
||||
function parseOutputs(a){for(var b="",c=a.data.outputs.length,e=0;e<c;e++)b+='<button data-output-id="'+a.data.outputs[e].id+'" class="btn btn-secondary btn-block',1==a.data.outputs[e].state&&(b+=" active"),b+='"><span class="material-icons float-left">volume_up</span> '+a.data.outputs[e].name+"</button>";domCache.outputs.innerHTML=b}
|
||||
function parseState(a){if(JSON.stringify(a)!==JSON.stringify(last_state)){1==a.data.state?(domCache.btnPlay.innerText="play_arrow",playstate="stop"):2==a.data.state?(domCache.btnPlay.innerText="pause",playstate="play"):(domCache.btnPlay.innerText="play_arrow",playstate="pause");-1==a.data.nextsongpos?domCache.btnNext.setAttribute("disabled","disabled"):domCache.btnNext.removeAttribute("disabled");0>=a.data.songpos?domCache.btnPrev.setAttribute("disabled","disabled"):domCache.btnPrev.removeAttribute("disabled");
|
||||
0==a.data.queue_length?domCache.btnPlay.setAttribute("disabled","disabled"):domCache.btnPlay.removeAttribute("disabled");-1==a.data.volume?(domCache.volumePrct.innerText="Volumecontrol disabled",domCache.volumeControl.classList.add("hide")):(domCache.volumeControl.classList.remove("hide"),domCache.volumePrct.innerText=a.data.volume+" %",domCache.volumeIcon.innerText=0==a.data.volume?"volume_off":50>a.data.volume?"volume_down":"volume_up");domCache.volumeBar.value=a.data.volume;current_song.totalTime=
|
||||
a.data.totalTime;current_song.currentSongId=a.data.currentsongid;var b=Math.floor(a.data.totalTime/60),c=a.data.totalTime-60*b,e=Math.floor(a.data.elapsedTime/60),d=a.data.elapsedTime-60*e;domCache.progressBar.value=Math.floor(100*a.data.elapsedTime/a.data.totalTime);b=e+":"+(10>d?"0":"")+d+" / "+b+":"+(10>c?"0":"")+c;domCache.counter.innerText=b;last_state&&(c=document.getElementById("queueTrackId"+last_state.data.currentsongid))&&(e=c.getElementsByTagName("td"),e[4].innerText=c.getAttribute("data-duration"),
|
||||
|
@ -288,7 +288,7 @@ function appRoute() {
|
||||
|
||||
function appInit() {
|
||||
getSettings();
|
||||
// sendAPI({"cmd":"MPD_API_GET_OUTPUTS"}, parseOutputnames);
|
||||
sendAPI({"cmd":"MPD_API_GET_STATE"}, parseState);
|
||||
|
||||
webSocketConnect();
|
||||
|
||||
@ -306,7 +306,7 @@ function appInit() {
|
||||
}, false);
|
||||
|
||||
document.getElementById('volumeIcon').parentNode.addEventListener('show.bs.dropdown', function () {
|
||||
sendAPI({"cmd":"MPD_API_GET_OUTPUTS"}, parseOutputnames);
|
||||
sendAPI({"cmd":"MPD_API_GET_OUTPUTS"}, parseOutputs);
|
||||
});
|
||||
|
||||
document.getElementById('modalAbout').addEventListener('shown.bs.modal', function () {
|
||||
@ -668,6 +668,12 @@ function webSocketConnect() {
|
||||
if (app.current.app === 'Queue')
|
||||
getQueue();
|
||||
break;
|
||||
case 'update_options':
|
||||
getSettings();
|
||||
break;
|
||||
case 'update_outputs':
|
||||
sendAPI({"cmd":"MPD_API_GET_OUTPUTS"}, parseOutputs);
|
||||
break;
|
||||
case 'song_change':
|
||||
songChange(obj);
|
||||
break;
|
||||
@ -807,7 +813,7 @@ function getSettings() {
|
||||
sendAPI({"cmd": "MPD_API_GET_SETTINGS"}, parseSettings);
|
||||
}
|
||||
|
||||
function parseOutputnames(obj) {
|
||||
function parseOutputs(obj) {
|
||||
var btns = '';
|
||||
var outputsLen = obj.data.outputs.length;
|
||||
for (var i = 0; i < outputsLen; i++) {
|
||||
|
113
src/mpd_client.c
113
src/mpd_client.c
@ -38,7 +38,7 @@
|
||||
#include "../dist/src/frozen/frozen.h"
|
||||
|
||||
/* forward declaration */
|
||||
static int mympd_notify_callback(struct mg_connection *c, const char *param);
|
||||
void mympd_notify(struct mg_mgr *s);
|
||||
|
||||
const char * mpd_cmd_strs[] = {
|
||||
MPD_CMDS(GEN_STR)
|
||||
@ -88,6 +88,9 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
case MPD_API_UNKNOWN:
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Unknown request\"}");
|
||||
break;
|
||||
case MPD_API_GET_STATE:
|
||||
n = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.queue_version);
|
||||
break;
|
||||
case MPD_API_SET_SETTINGS:
|
||||
json_scanf(msg.p, msg.len, "{data: { notificationWeb: %d, notificationPage: %d}}", &state.a, &state.b);
|
||||
char tmpfile[200];
|
||||
@ -505,60 +508,6 @@ int mympd_close_handler(struct mg_connection *c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mympd_notify_callback(struct mg_connection *c, const char *param) {
|
||||
size_t n;
|
||||
if (!is_websocket(c))
|
||||
return 0;
|
||||
|
||||
if (param) {
|
||||
/* error message? */
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"%s\"}",param);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Error in mpd_notify_callback: %s\n",param);
|
||||
#endif
|
||||
mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, mpd.buf, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!c->user_data)
|
||||
c->user_data = calloc(1, sizeof(struct t_mpd_client_session));
|
||||
|
||||
struct t_mpd_client_session *s = (struct t_mpd_client_session *)c->user_data;
|
||||
|
||||
if (mpd.conn_state != MPD_CONNECTED) {
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"disconnected\"}");
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "Notify: disconnected\n");
|
||||
#endif
|
||||
mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, mpd.buf, n);
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "Notify: %s\n",mpd.buf);
|
||||
#endif
|
||||
mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, mpd.buf, strlen(mpd.buf));
|
||||
|
||||
if (s->song_id != mpd.song_id) {
|
||||
n = mympd_put_current_song(mpd.buf);
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "Notify: %s\n",mpd.buf);
|
||||
#endif
|
||||
mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, mpd.buf, n);
|
||||
s->song_id = mpd.song_id;
|
||||
}
|
||||
|
||||
if (s->queue_version != mpd.queue_version) {
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_queue\"}");
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "Notify: update_queue\n");
|
||||
#endif
|
||||
mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, mpd.buf, n);
|
||||
s->queue_version = mpd.queue_version;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mympd_poll(struct mg_mgr *s, int timeout) {
|
||||
struct pollfd fds[1];
|
||||
int pollrc;
|
||||
@ -570,24 +519,24 @@ void mympd_poll(struct mg_mgr *s, int timeout) {
|
||||
mpd.conn = mpd_connection_new(config.mpdhost, config.mpdport, mpd.timeout);
|
||||
if (mpd.conn == NULL) {
|
||||
fprintf(stderr, "Out of memory.");
|
||||
snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"disconnected\"}");
|
||||
mympd_notify(s);
|
||||
mpd.conn_state = MPD_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS) {
|
||||
fprintf(stderr, "MPD connection: %s\n", mpd_connection_get_error_message(mpd.conn));
|
||||
for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c)) {
|
||||
mympd_notify_callback(c, mpd_connection_get_error_message(mpd.conn));
|
||||
}
|
||||
snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"%s\"}", mpd_connection_get_error_message(mpd.conn));
|
||||
mympd_notify(s);
|
||||
mpd.conn_state = MPD_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.mpdpass && !mpd_run_password(mpd.conn, config.mpdpass)) {
|
||||
fprintf(stderr, "MPD connection: %s\n", mpd_connection_get_error_message(mpd.conn));
|
||||
for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c)) {
|
||||
mympd_notify_callback(c, mpd_connection_get_error_message(mpd.conn));
|
||||
}
|
||||
snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"%s\"}", mpd_connection_get_error_message(mpd.conn));
|
||||
mympd_notify(s);
|
||||
mpd.conn_state = MPD_FAILURE;
|
||||
return;
|
||||
}
|
||||
@ -600,6 +549,8 @@ void mympd_poll(struct mg_mgr *s, int timeout) {
|
||||
|
||||
case MPD_FAILURE:
|
||||
fprintf(stderr, "MPD connection failed.\n");
|
||||
snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"disconnected\"}");
|
||||
mympd_notify(s);
|
||||
|
||||
case MPD_DISCONNECT:
|
||||
case MPD_RECONNECT:
|
||||
@ -622,9 +573,22 @@ void mympd_poll(struct mg_mgr *s, int timeout) {
|
||||
}
|
||||
}
|
||||
|
||||
void mympd_notify(struct mg_mgr *s) {
|
||||
for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c)) {
|
||||
if (!is_websocket(c))
|
||||
continue;
|
||||
mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, mpd.buf, strlen(mpd.buf));
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"NOTIFY: %s\n", mpd.buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mympd_parse_idle(struct mg_mgr *s) {
|
||||
mpd_connection_set_timeout(mpd.conn, 100);
|
||||
mpd_connection_set_timeout(mpd.conn, 60);
|
||||
enum mpd_idle idle_bitmask = mpd_recv_idle(mpd.conn, false);
|
||||
mpd_connection_set_timeout(mpd.conn, mpd.timeout);
|
||||
int len;
|
||||
|
||||
for (unsigned j = 0;; ++j) {
|
||||
enum mpd_idle idle_event = 1 << j;
|
||||
@ -637,39 +601,42 @@ void mympd_parse_idle(struct mg_mgr *s) {
|
||||
#endif
|
||||
switch(idle_event) {
|
||||
case MPD_IDLE_DATABASE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_database\"}");
|
||||
break;
|
||||
case MPD_IDLE_STORED_PLAYLIST:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_stored_playlist\"}");
|
||||
break;
|
||||
case MPD_IDLE_QUEUE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_queue\"}");
|
||||
break;
|
||||
case MPD_IDLE_PLAYER:
|
||||
break;
|
||||
case MPD_IDLE_MIXER:
|
||||
len = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.queue_version);
|
||||
break;
|
||||
case MPD_IDLE_OUTPUT:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_outputs\"}");
|
||||
break;
|
||||
case MPD_IDLE_OPTIONS:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_options\"}");
|
||||
break;
|
||||
case MPD_IDLE_UPDATE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_update\"}");
|
||||
break;
|
||||
case MPD_IDLE_STICKER:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_sticker\"}");
|
||||
break;
|
||||
case MPD_IDLE_SUBSCRIPTION:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_subscription\"}");
|
||||
break;
|
||||
case MPD_IDLE_MESSAGE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_message\"}");
|
||||
break;
|
||||
}
|
||||
if (len > 0)
|
||||
mympd_notify(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//old behaviour
|
||||
if (idle_bitmask > 0) {
|
||||
mpd_connection_set_timeout(mpd.conn, mpd.timeout);
|
||||
mpd.buf_size = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.queue_version);
|
||||
for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c))
|
||||
mympd_notify_callback(c, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
char* mympd_get_tag(struct mpd_song const *song, enum mpd_tag_type tag) {
|
||||
@ -684,7 +651,7 @@ char* mympd_get_tag(struct mpd_song const *song, enum mpd_tag_type tag) {
|
||||
return str;
|
||||
}
|
||||
|
||||
int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsigned *queue_version) {
|
||||
int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsigned *queue_version) {
|
||||
struct mpd_status *status;
|
||||
const struct mpd_audio_format *audioformat;
|
||||
int len;
|
||||
@ -697,7 +664,7 @@ int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsi
|
||||
return 0;
|
||||
}
|
||||
if (status) {
|
||||
audioformat = mpd_status_get_audio_format(status);
|
||||
audioformat = mpd_status_get_audio_format(status);
|
||||
}
|
||||
|
||||
len = json_printf(&out,"{type:state, data:{"
|
||||
|
@ -92,6 +92,7 @@
|
||||
X(MPD_API_WELCOME) \
|
||||
X(MPD_API_GET_SETTINGS) \
|
||||
X(MPD_API_SET_SETTINGS) \
|
||||
X(MPD_API_GET_STATE) \
|
||||
X(MPD_API_UNKNOWN)
|
||||
|
||||
enum mpd_cmd_ids {
|
||||
@ -141,12 +142,6 @@ static int is_websocket(const struct mg_connection *nc) {
|
||||
return nc->flags & MG_F_IS_WEBSOCKET;
|
||||
}
|
||||
|
||||
struct t_mpd_client_session {
|
||||
int song_id;
|
||||
int next_song_id;
|
||||
unsigned queue_version;
|
||||
};
|
||||
|
||||
void mympd_poll(struct mg_mgr *sm, int timeout);
|
||||
void mympd_parse_idle(struct mg_mgr *s);
|
||||
void callback_mympd(struct mg_connection *nc, const struct mg_str msg);
|
||||
|
@ -256,8 +256,8 @@ int main(int argc, char **argv) {
|
||||
printf("myMPD started on ssl port %s\n", config.sslport);
|
||||
|
||||
while (s_signal_received == 0) {
|
||||
mympd_poll(&mgr, 100);
|
||||
mg_mgr_poll(&mgr, 100);
|
||||
mympd_poll(&mgr, 60);
|
||||
mg_mgr_poll(&mgr, 60);
|
||||
}
|
||||
mg_mgr_free(&mgr);
|
||||
mympd_disconnect();
|
||||
|
Loading…
Reference in New Issue
Block a user