1 urlbase="/cgi-bin/mpd.lua?"
6 function GetFilename(url)
9 return url.split('/').pop().split('#')[0].split('?')[0];
12 function EscapeStr(str) {
13 res = str.replace(/'/g,"\\'");
20 e = d.documentElement,
21 g = d.getElementsByTagName('body')[0],
22 body_h = g.clientHeight,
23 window_h = w.innerHeight|| e.clientHeight|| g.clientHeight,
24 items = d.getElementById('items'),
25 current_h = items.clientHeight,
26 new_h=(window_h-body_h)+current_h;
27 if (new_h>minScrollHeight) {
28 items.style.height=new_h+"px";
32 function toHHMMSS(seconds) {
33 var hours = Math.floor(seconds / 3600);
34 seconds -= hours*3600;
35 var minutes = Math.floor(seconds / 60);
36 seconds -= minutes*60;
38 if (hours < 10) {hours = "0"+hours;}
39 if (minutes < 10) {minutes = "0"+minutes;}
40 if (seconds < 10) {seconds = "0"+seconds;}
42 return minutes+':'+seconds;
44 return hours+':'+minutes+':'+seconds;
48 function RefreshTime() {
50 currentTime = toHHMMSS(currentSeconds)
51 trackTime = toHHMMSS(trackSeconds)
52 nowPlayingTime = currentTime+"/"+trackTime
54 nowPlayingTime = "-:--/-:--"
56 document.getElementById('nowplaying_tracklen').innerHTML=nowPlayingTime;
59 function PeriodicRefreshTime() {
60 if (currentState == "play") {
62 delta = (nowTime - updateTime)/1000
63 currentSeconds = updateSeconds + Math.round(delta)
64 if (currentSeconds > trackSeconds) {
65 currentSeconds = trackSeconds
71 function RefreshPageStatus() {
73 var req = new XMLHttpRequest();
75 req.onreadystatechange = function () {
76 if (this.readyState != 4 || this.status != 200) return;
77 var returnedData = JSON.parse(this.responseText);
78 trackName = GetFilename(returnedData['current_playing']);
79 trackNo = returnedData['song'];
80 currentState = returnedData['state'];
81 document.title='MPD Player: '+trackName;
82 nowPlayingTrack = (1+Number(trackNo)) + '/' + returnedData['playlistlength'];
83 nowPlayingName = trackName;
84 playingTime = returnedData['time']
86 var splits = playingTime.split(":")
87 updateTime = Date.now()
88 currentSeconds = Number(splits[0])
89 updateSeconds = currentSeconds
90 trackSeconds = Number(splits[1])
94 if (currentState=='stop') {
95 nowPlayingName = '<font color="gray">' + nowPlayingName+ '</font>'
97 document.getElementById('nowplaying_trackno').innerHTML=nowPlayingTrack;
98 document.getElementById('nowplaying_trackname').innerHTML=nowPlayingName;
100 if (currentState=="play") {
101 document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('pause')\"><img class=\"button\" width=\"30\" src=\"images/pause.svg\"></span>";
103 document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('play')\"><img class=\"button\" width=\"30\" src=\"images/play-button.svg\"></span>";
105 if (currentState=="stop") {
106 document.getElementById('stopbutton').innerHTML="<span><img class=\"button\" width=\"30\" src=\"images/stopoff.svg\"></span>";
108 document.getElementById('stopbutton').innerHTML="<span onclick=\"Command('stop')\"><img class=\"button\" width=\"30\" src=\"images/stop.svg\"></span>";
110 if (returnedData["repeat"]=="1") {
111 document.getElementById('repeatstate').innerHTML="<img width=\"30\" src=\"images/replay.svg\"></a>";
113 document.getElementById('repeatstate').innerHTML="<img width=\"30\" src=\"images/replayoff.svg\"></a>";
115 document.getElementById('volume_total').innerHTML="<div id=\"volume_actual\" style=\"width:"+returnedData["volume"]+"%\">";
117 var items = document.getElementById('items');
118 var table = items.getElementsByClassName('track');
119 var current_track="track_"+trackNo;
120 for (var i = 0; i < table.length; i++) {
121 if (table[i].id==current_track) {
122 table[i].classList.add("itemActive");
124 table[i].classList.remove("itemActive")
130 req.open("GET", urlbase+"status", true);
135 function RefreshPlaylist() {
137 var req = new XMLHttpRequest();
139 req.onreadystatechange = function () {
140 if (this.readyState != 4 || this.status != 200) return;
141 var returnedData = JSON.parse(this.responseText);
143 var playlistMenuText = "<table>\
145 <td><span class=\"button\" onclick=\"EditPlayList()\"><img width=\"20\" src=\"images/folder.svg\"></span><td>\
146 <td><span class=\"button\" onclick=\"LoadPlayList()\"><img width=\"20\" src=\"images/list.svg\"></span><td>\
147 <td><span class=\"button\" onclick=\"SavePlayList()\"><img width=\"20\" src=\"images/download.svg\"></span><td>\
148 <td><span class=\"button\" onclick=\"return confirm('Clear current playlist, are you sure?') ? PlaylistCommand('clear') : false;\" ><img width=\"20\" src=\"images/cancel.svg\"></span><td>\
152 var itemsText="<table>\
153 <tr id=\"items_heading\">\
154 <td></td class=\"track_number\"><td class=\"file\">Title</td><td class=\"button\" colspan=\"3\">Controls</td>\
158 for (var key in returnedData) {
159 var rec=returnedData[key];
160 var name=GetFilename(rec["name"]);
171 itemsText = itemsText + "<tr id=\"track_"+id+"\" class=\"track "+evText+"\">\
172 <td class=\"track_number\">\
173 <a name=\""+id+"\">"+(Number(id)+1)+"</a></td>\
176 <span class=\"button\" onclick=\"PlaylistCommand('playitem',"+id+")\">"+name+"</span>\
179 <span class=\"button\" onclick=\"PlaylistCommand('moveup',"+id+")\"><img width=\"15\" src=\"images/up-arrow.svg\"></span>\
182 <span class=\"button\" onclick=\"PlaylistCommand('movedown',"+id+")\"><img width=\"15\" src=\"images/down-arrow.svg\"></span>\
184 <td class=\"remove\">\
185 <span class=\"button\" onclick=\"PlaylistCommand('remove',"+id+")\"><img width=\"15\" src=\"images/cancel.svg\"></span>\
190 itemsText = itemsText + "</table>";
192 document.getElementById('items').innerHTML=itemsText;
193 document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
194 document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
197 req.open("GET", urlbase+"playlist", true);
202 function EditPlayList(dir) {
204 var req = new XMLHttpRequest();
206 req.onreadystatechange = function () {
207 if (this.readyState != 4 || this.status != 200) return;
208 var returnedData = JSON.parse(this.responseText);
210 var playlistMenuText = "<table>\
212 <td><span class=\"button\" onclick=\"RefreshPlaylist()\"><img width=\"20\" src=\"images/list.svg\"></span><td>\
213 <td><span class=\"button\" onclick=\"return confirm('Add all to the list, are you sure?') ? PlaylistEditCommand('add','"+EscapeStr(dir)+"') : false;\" ><img width=\"20\" src=\"images/plus.svg\"></span><td>\
217 var itemsText= "<table>\
218 <tr id=\"items_heading\">\
219 <td></td class=\"track_number\"><td class=\"file\">Title</td><td class=\"button\" colspan=\"2\">Controls</td>\
224 var lastSlash=dir.lastIndexOf("/");
226 var upperLevel=dir.slice(0,lastSlash);
231 var itemsText = itemsText + "<tr class=\"itemOdd\">\
232 <td class=\"track_number\"></td>\
233 <td class=\"file\"><span class=\"button\" onclick=\"EditPlayList('"+upperLevel+"')\">..</span></td>\
238 for (var key in returnedData) {
239 var rec=returnedData[key];
240 var type=rec["type"];
241 var name=rec["name"];
242 var lastSlash=name.lastIndexOf("/");
244 var tailName=name.slice(lastSlash+1);
249 if (type == "directory" || type == "file") {
259 itemsText = itemsText + "<tr class=\""+evText+"\">\
260 <td class=\"track_number\">\
261 <a name=\""+i+"\"></a></td>\
264 if (type == "directory") {
265 itemsText = itemsText + "<td class=\"file\">\
266 <span class=\"button\" onclick=\"EditPlayList('"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\
267 <span class=\"button\" onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img width=\"15\" src=\"images/plus.svg\"></span></td>";
270 if (type == "file") {
271 itemsText = itemsText + "<td class=\"file\">\
272 <span class=\"button\" onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\
273 <span class=\"button\" onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img width=\"15\" src=\"images/plus.svg\"></span></td>";
276 itemsText = itemsText + "</tr>";
282 var itemsText = itemsText+"</table>";
283 document.getElementById('items').innerHTML=itemsText;
284 document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
285 document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
288 if (!dir) { dir = ''; };
290 req.open("GET", urlbase+"lists|edit|"+dir, true);
295 function LoadPlayList() {
297 var req = new XMLHttpRequest();
299 req.onreadystatechange = function () {
300 if (this.readyState != 4 || this.status != 200) return;
301 var returnedData = JSON.parse(this.responseText);
302 playlistMenuText="<table>\
304 <td><span class=\"button\" onclick=\"RefreshPlaylist()\"><img width=\"20\" src=\"images/list.svg\"></span><td>\
305 <td><span class=\"button\" onclick=\"confirm('Clear current playlist, are you sure?') ? PlaylistCommandRefStatus('clear') : false;\" ><img width=\"20\" src=\"images/cancel.svg\"></span><td>\
309 <tr id=\"items_heading\">\
310 <td class=\"track_number\"></td><td class=\"file\">Name</td><td class=\"button\">Controls</td>\
314 for (var key in returnedData) {
315 var name=returnedData[key];
325 itemsText = itemsText + "<tr class=\""+evText+"\">\
326 <td class=\"track_number\"><a name=\"0\"></a></td>\
327 <td class=\"file\"><span class=\"button\" onclick=\"PlaylistEditCommandRefFull('load','"+EscapeStr(name)+"')\">"+name+"</td>\
328 <td class=\"controls\"><span class=\"button\" onclick=\"confirm('Delete playlist "+name+", are you sure?') ? DelPlayList('"+EscapeStr(name)+"') : false;\"><img width=\"20\" src=\"images/minus.svg\"></span></td>\
332 itemsText=itemsText+"</table>";
333 document.getElementById('items').innerHTML=itemsText;
334 document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
335 document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
338 req.open("GET", urlbase+"lists|load", true);
343 function SavePlayList() {
345 var name=window.prompt('List name','');
347 var req = new XMLHttpRequest();
349 req.onreadystatechange = function () {
350 if (this.readyState != 4 || this.status != 200) return;
351 if (this.responseText != 'OK') {
352 window.alert(this.responseText);
356 req.open("GET", urlbase+"lists|save|"+name, true);
361 function DelPlayList(item) {
363 var req = new XMLHttpRequest();
365 req.onreadystatechange = function () {
366 if (this.readyState != 4 || this.status != 200) return;
371 req.open("GET", urlbase+"lists|delete|"+item, true);
376 function RefreshPageContent() {
381 function Command(cmd) {
383 var req = new XMLHttpRequest();
385 req.onreadystatechange = function () {
386 if (this.readyState != 4 || this.status != 200) return;
390 req.open("GET", urlbase+cmd, true);
395 function PlaylistCommand(cmd,item) {
397 var req = new XMLHttpRequest();
399 req.onreadystatechange = function () {
400 if (this.readyState != 4 || this.status != 200) return;
401 RefreshPageContent();
404 req.open("GET", urlbase+"cpl|"+cmd+"|"+item, true);
409 function PlaylistCommandRefStatus(cmd,item) {
411 var req = new XMLHttpRequest();
413 req.onreadystatechange = function () {
414 if (this.readyState != 4 || this.status != 200) return;
418 req.open("GET", urlbase+"cpl|"+cmd+"|"+item, true);
423 function PlaylistEditCommand(cmd,item) {
425 var req = new XMLHttpRequest();
427 req.onreadystatechange = function () {
428 if (this.readyState != 4 || this.status != 200) return;
432 req.open("GET", urlbase+"lists|"+cmd+"|"+item, true);
437 function PlaylistEditCommandRefFull(cmd,item) {
439 var req = new XMLHttpRequest();
441 req.onreadystatechange = function () {
442 if (this.readyState != 4 || this.status != 200) return;
443 RefreshPageContent();
446 req.open("GET", urlbase+"lists|"+cmd+"|"+item, true);
451 function subscribe_status() {
452 var xhr = new XMLHttpRequest();
454 xhr.onreadystatechange = function() {
455 if (this.readyState != 4) return;
456 if (this.status == 200) {
458 setTimeout(subscribe_status,1000)
460 setTimeout(subscribe_status,15000)
463 xhr.open("GET", urlbase+"idle", true);
467 setTimeout(subscribe_status,5000)
468 setInterval(PeriodicRefreshTime, 1000);