X-Git-Url: https://git.rvb.name/mpd-lua.git/blobdiff_plain/55262d4cf0ac84eb33fafca62bdcae22a4d478b3..refs/heads/master:/mpd.js diff --git a/mpd.js b/mpd.js new file mode 100644 index 0000000..b5ff513 --- /dev/null +++ b/mpd.js @@ -0,0 +1,496 @@ +urlbase="/cgi-bin/mpd.cgi?" +minScrollHeight=200 + +currentState="" + +function GetFilename(url) +{ + if (url) + return url.split('/').pop().split('#')[0].split('?')[0]; +} + +function EscapeStr(str) { + res = str.replace(/'/g,"\\'"); + return res; +} + +function SetSize() { + var w = window, + d = document, + e = d.documentElement, + g = d.getElementsByTagName('body')[0], + body_h = g.clientHeight, + window_h = w.innerHeight|| e.clientHeight|| g.clientHeight, + items = d.getElementById('items'), + current_h = items.clientHeight, + new_h=(window_h-body_h)+current_h; + if (new_h>minScrollHeight) { + items.style.height=new_h+"px"; + } +} + +function toHHMMSS(seconds) { + var hours = Math.floor(seconds / 3600); + seconds -= hours*3600; + var minutes = Math.floor(seconds / 60); + seconds -= minutes*60; + + if (hours < 10) {hours = "0"+hours;} + if (minutes < 10) {minutes = "0"+minutes;} + if (seconds < 10) {seconds = "0"+seconds;} + if (hours == 0) { + return minutes+':'+seconds; + } else { + return hours+':'+minutes+':'+seconds; + } +} + +function RefreshTime() { + if (currentSeconds) { + currentTime = toHHMMSS(currentSeconds) + if (trackSeconds) { + trackTime = toHHMMSS(trackSeconds) + nowPlayingTime = currentTime+"/"+trackTime + } else { + nowPlayingTime = currentTime + } + } else { + nowPlayingTime = "-:--/-:--" + } + document.getElementById('nowplaying_tracklen').innerHTML=nowPlayingTime; +} + +function PeriodicRefreshTime() { + if (currentState == "play") { + nowTime = Date.now() + delta = (nowTime - updateTime)/1000 + currentSeconds = updateSeconds + Math.round(delta) + if (trackSeconds && (currentSeconds > trackSeconds)) { + currentSeconds = trackSeconds + } + RefreshTime() + } +} + +function RefreshPageStatus() { + + var req = new XMLHttpRequest(); + + req.onreadystatechange = function () { + if (this.readyState != 4 || this.status != 200) return; + var returnedData = JSON.parse(this.responseText); + trackName = GetFilename(returnedData['current_playing']); + try { + var trackName=decodeURI(trackName).replace(/%2C/g,",") + } + catch(e) { + console.log(trackName) + } + trackNo = returnedData['song']; + trackId = returnedData['songid'] + currentState = returnedData['state']; + document.title='MPD Player: '+trackName; + if (trackNo) { + var nowPlayingTrackNo=String(1+Number(trackNo)) + } else { + var nowPlayingTrackNo="--" + } + nowPlayingTrack = nowPlayingTrackNo + '/' + returnedData['playlistlength']; + nowPlayingName = trackName; + playingTime = returnedData['time'] + if (playingTime) { + var splits = playingTime.split(":") + updateTime = Date.now() + currentSeconds = Number(splits[0]) + updateSeconds = currentSeconds + trackSeconds = Number(splits[1]) + } else { + currentSeconds = null + } + if (currentState=='stop') { + nowPlayingName = '<font color="gray">' + nowPlayingName+ '</font>' + } + document.getElementById('nowplaying_trackno').innerHTML=nowPlayingTrack; + document.getElementById('nowplaying_trackname').innerHTML=nowPlayingName; + RefreshTime() + if (currentState=="play") { + document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('pause')\"><img class=\"button\" title=\"Pause\" src=\"images/pause.svg\"></span>"; + } else { + document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('play')\"><img class=\"button\" title=\"Play\" src=\"images/play-button.svg\"></span>"; + } + if (currentState=="stop") { + document.getElementById('stopbutton').innerHTML="<span><img class=\"button\" src=\"images/stopoff.svg\"></span>"; + } else { + document.getElementById('stopbutton').innerHTML="<span onclick=\"Command('stop')\"><img class=\"button\" title=\"Stop\" src=\"images/stop.svg\"></span>"; + } + if (returnedData["repeat"]=="1") { + document.getElementById('repeatstate').innerHTML="<img class=\"button\" title=\"Replay is on\" src=\"images/replay.svg\"></a>"; + } else { + document.getElementById('repeatstate').innerHTML="<img class=\"button\" title=\"Replay is off\" src=\"images/replayoff.svg\"></a>"; + } + document.getElementById('volume_total').innerHTML="<div id=\"volume_actual\" style=\"width:"+returnedData["volume"]+"%\">"; + + var items = document.getElementById('items'); + var table = items.getElementsByClassName('track'); + var current_track="track_"+trackId; + for (var i = 0; i < table.length; i++) { + if (table[i].id==current_track) { + table[i].classList.add("itemActive"); + } else { + table[i].classList.remove("itemActive") + } + } + + }; + + req.open("GET", urlbase+"status", true); + req.send(); + +} + +function RefreshPlaylist() { + +var req = new XMLHttpRequest(); + +req.onreadystatechange = function () { + if (this.readyState != 4 || this.status != 200) return; + var returnedData = JSON.parse(this.responseText); + + var playlistMenuText = "<table>\ + <tr>\ + <td><span onclick=\"EditPlayList()\"><img class=\"medium-button\" title=\"Files\" src=\"images/folder.svg\"></span><td>\ + <td><span onclick=\"LoadPlayList()\"><img class=\"medium-button\" title=\"Lists\" src=\"images/list.svg\"></span><td>\ + <td><span onclick=\"SavePlayList()\"><img class=\"medium-button\" title=\"Save current list\" src=\"images/download.svg\"></span><td>\ + <td><span onclick=\"return confirm('Clear current playlist, are you sure?') ? PlaylistCommand('clear') : false;\" ><img class=\"medium-button\" title=\"Clear current list\" src=\"images/cancel.svg\"></span><td>\ + </tr>\ + </table>"; + + var itemsText="<table>\ + <tr id=\"items_heading\">\ + <td></td class=\"track_number\"><td class=\"file\">Title</td><td class=\"medium-button\" colspan=\"3\">Controls</td>\ + </tr>"; + + var even = 0; + for (var key in returnedData) { + var rec=returnedData[key]; + var name=GetFilename(rec["title"]); + try { + var name=decodeURI(name).replace(/%2C/g,",") + } + catch(e) { + console.log(name) + } + var id=rec["id"]; + + if (even) { + evText="itemEven"; + } else { + evText="itemOdd"; + }; + + even = ! even; + + itemsText = itemsText + "<tr id=\"track_"+id+"\" class=\"track "+evText+"\">\ + <td class=\"track_number\">\ + <a name=\""+id+"\">"+(Number(key)+1)+"</a></td>\ + </td>\ + <td class=\"file\">\ + <span class=\"link\" onclick=\"PlaylistCommand('playitem',"+id+")\">"+name+"</span>\ + </td>\ + <td class=\"move\">\ + <span onclick=\"PlaylistCommand('moveup',"+id+")\"><img class=\"small-button\" title=\"Move up\" src=\"images/up-arrow.svg\"></span>\ + </td>\ + <td class=\"move\">\ + <span onclick=\"PlaylistCommand('movedown',"+id+")\"><img class=\"small-button\" title=\"Move down\" src=\"images/down-arrow.svg\"></span>\ + </td>\ + <td class=\"remove\">\ + <span onclick=\"PlaylistCommand('remove',"+id+")\"><img class=\"small-button\" title=\"Remove\" src=\"images/cancel.svg\"></span>\ + </td>\ + </tr>"; + } + + itemsText = itemsText + "</table>"; + + document.getElementById('items').innerHTML=itemsText; + document.getElementById('playlist_menu_top').innerHTML=playlistMenuText; + document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText; +}; + +req.open("GET", urlbase+"playlist", true); +req.send(); + +} + +function EditPlayList(dir) { + +var req = new XMLHttpRequest(); + +req.onreadystatechange = function () { + if (this.readyState != 4 || this.status != 200) return; + var returnedData = JSON.parse(this.responseText); + + var playlistMenuText = "<table>\ + <tr>\ + <td><span onclick=\"RefreshPageContent()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\ + <td><span onclick=\"return confirm('Add all to the list, are you sure?') ? PlaylistEditCommand('add','"+EscapeStr(dir)+"') : false;\" ><img class=\"medium-button\" title=\"Add all\" src=\"images/plus.svg\"></span><td>\ + </tr>\ + </table>"; + + var itemsText= "<table>\ + <tr id=\"items_heading\">\ + <td></td class=\"track_number\"><td class=\"file\">Title</td><td colspan=\"2\">Controls</td>\ + </tr>"; + + var even = 0; + if (dir) { + var lastSlash=dir.lastIndexOf("/"); + if (lastSlash>0) { + var upperLevel=dir.slice(0,lastSlash); + } else { + var upperLevel=""; + } + even = ! even; + var itemsText = itemsText + "<tr class=\"itemOdd\">\ + <td class=\"track_number\"></td>\ + <td class=\"file\"><span class=\"link\" onclick=\"EditPlayList('"+upperLevel+"')\">..</span></td>\ + <td></td><td></td>"; + } + + var i = 0; + for (var key in returnedData) { + var rec=returnedData[key]; + var type=rec["type"]; + var name=rec["name"]; + var lastSlash=name.lastIndexOf("/"); + if (lastSlash>0) { + var tailName=name.slice(lastSlash+1); + } else { + var tailName=name + }; + try { + var tailName=decodeURI(tailName).replace(/%2C/g,",") + } + catch(e) { + console.log(tailName) + } + + if (type == "directory" || type == "file") { + if (even) { + evText="itemEven"; + } else { + evText="itemOdd"; + }; + + i = i + 1; + even = ! even; + + itemsText = itemsText + "<tr class=\""+evText+"\">\ + <td class=\"track_number\">\ + <a name=\""+i+"\"></a></td>\ + </td>"; + + if (type == "directory") { + itemsText = itemsText + "<td class=\"file\">\ + <span class=\"link\" onclick=\"EditPlayList('"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\ + <span onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img class=\"small-button\" title=\"Add\" src=\"images/plus.svg\"></span></td>"; + }; + + if (type == "file") { + itemsText = itemsText + "<td class=\"file\">\ + <span class=\"link\" onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\ + <span onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img class=\"small-button\" title=\"Add\" src=\"images/plus.svg\"></span></td>"; + }; + + itemsText = itemsText + "</tr>"; + + } + + } + + var itemsText = itemsText+"</table>"; + document.getElementById('items').innerHTML=itemsText; + document.getElementById('playlist_menu_top').innerHTML=playlistMenuText; + document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText; +}; + +if (!dir) { dir = ''; }; + +req.open("GET", urlbase+"lists|edit|"+dir, true); +req.send(); + +} + +function LoadPlayList() { + +var req = new XMLHttpRequest(); + +req.onreadystatechange = function () { + if (this.readyState != 4 || this.status != 200) return; + var returnedData = JSON.parse(this.responseText); + playlistMenuText="<table>\ + <tr>\ + <td><span onclick=\"RefreshPageContent()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\ + <td><span onclick=\"confirm('Clear current playlist, are you sure?') ? PlaylistCommandRefStatus('clear') : false;\" ><img class=\"medium-button\" title=\"Clear all\" src=\"images/cancel.svg\"></span><td>\ + </tr>\ + </table>"; + itemsText="<table>\ + <tr id=\"items_heading\">\ + <td class=\"track_number\"></td><td class=\"file\">Name</td><td>Controls</td>\ + </tr>"; + + var even = 0; + for (var key in returnedData) { + var name=returnedData[key]; + + if (even) { + evText="itemEven"; + } else { + evText="itemOdd"; + }; + + even = ! even; + + itemsText = itemsText + "<tr class=\""+evText+"\">\ + <td class=\"track_number\"><a name=\"0\"></a></td>\ + <td class=\"file\"><span class=\"link\" onclick=\"PlaylistEditCommandRefFull('load','"+EscapeStr(name)+"')\">"+name+"</td>\ + <td class=\"controls\"><span onclick=\"confirm('Delete playlist "+name+", are you sure?') ? DelPlayList('"+EscapeStr(name)+"') : false;\"><img class=\"small-button\" title=\"Delete\" src=\"images/minus.svg\"></span></td>\ + </tr>"; + } + + itemsText=itemsText+"</table>"; + document.getElementById('items').innerHTML=itemsText; + document.getElementById('playlist_menu_top').innerHTML=playlistMenuText; + document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText; +}; + +req.open("GET", urlbase+"lists|load", true); +req.send(); + +} + +function SavePlayList() { + +var name=window.prompt('List name',''); + +var req = new XMLHttpRequest(); + +req.onreadystatechange = function () { + if (this.readyState != 4 || this.status != 200) return; + if (this.responseText != 'OK') { + window.alert(this.responseText); + } +}; + +req.open("GET", urlbase+"lists|save|"+name, true); +req.send(); + +} + +function DelPlayList(item) { + +var req = new XMLHttpRequest(); + +req.onreadystatechange = function () { + if (this.readyState != 4 || this.status != 200) return; + LoadPlayList(); + RefreshPageStatus(); +}; + +req.open("GET", urlbase+"lists|delete|"+item, true); +req.send(); + +} + +function RefreshPageContent() { + RefreshPlaylist(); + RefreshPageStatus(); +} + +function Command(cmd) { + +var req = new XMLHttpRequest(); + +req.onreadystatechange = function () { + if (this.readyState != 4 || this.status != 200) return; + RefreshPageStatus(); +}; + +req.open("GET", urlbase+cmd, true); +req.send(); + +} + +function PlaylistCommand(cmd,item) { + +var req = new XMLHttpRequest(); + +req.onreadystatechange = function () { + if (this.readyState != 4 || this.status != 200) return; + RefreshPageContent(); +}; + +req.open("GET", urlbase+"cpl|"+cmd+"|"+item, true); +req.send(); + +} + +function PlaylistCommandRefStatus(cmd,item) { + +var req = new XMLHttpRequest(); + +req.onreadystatechange = function () { + if (this.readyState != 4 || this.status != 200) return; + RefreshPageStatus(); +}; + +req.open("GET", urlbase+"cpl|"+cmd+"|"+item, true); +req.send(); + +} + +function PlaylistEditCommand(cmd,item) { + +var req = new XMLHttpRequest(); + +req.onreadystatechange = function () { + if (this.readyState != 4 || this.status != 200) return; + RefreshPageStatus(); +}; + +req.open("GET", urlbase+"lists|"+cmd+"|"+item, true); +req.send(); + +} + +function PlaylistEditCommandRefFull(cmd,item) { + +var req = new XMLHttpRequest(); + +req.onreadystatechange = function () { + if (this.readyState != 4 || this.status != 200) return; + RefreshPageContent(); +}; + +req.open("GET", urlbase+"lists|"+cmd+"|"+item, true); +req.send(); + +} + +function subscribe_status() { + var xhr = new XMLHttpRequest(); + + xhr.onreadystatechange = function() { + if (this.readyState != 4) return; + if (this.status == 200) { + RefreshPageStatus() + setTimeout(subscribe_status,1000) + } else { + setTimeout(subscribe_status,15000) + } + } + xhr.open("GET", urlbase+"idle", true); + xhr.send(); +} + +setTimeout(subscribe_status,5000) +setInterval(PeriodicRefreshTime, 1000);