mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-31 05:43:01 +00:00 
			
		
		
		
	| @@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.6) | ||||
| project (mympd C) | ||||
| set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/") | ||||
| set(CPACK_PACKAGE_VERSION_MAJOR "3") | ||||
| set(CPACK_PACKAGE_VERSION_MINOR "3") | ||||
| set(CPACK_PACKAGE_VERSION_PATCH "1") | ||||
| set(CPACK_PACKAGE_VERSION_MINOR "4") | ||||
| set(CPACK_PACKAGE_VERSION_PATCH "0") | ||||
|  | ||||
| if(CMAKE_BUILD_TYPE MATCHES RELEASE) | ||||
|     set(ASSETS_PATH "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/htdocs") | ||||
|   | ||||
							
								
								
									
										4
									
								
								dist/htdocs/css/bootstrap.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								dist/htdocs/css/bootstrap.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/htdocs/index.html
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/htdocs/index.html
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										71
									
								
								dist/htdocs/js/mpd.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										71
									
								
								dist/htdocs/js/mpd.min.js
									
									
									
									
										vendored
									
									
								
							| @@ -8,9 +8,8 @@ $jscomp.polyfill("String.prototype.repeat",function(a){return a?a:function(a){va | ||||
| var socket,last_song="",last_state,current_song={},playstate="",settings={},alertTimeout,deferredPrompt,dragEl,app={apps:{Playback:{state:"0/-/",scrollPos:0},Queue:{state:"0/Any Tag/",scrollPos:0},Browse:{active:"Database",tabs:{Filesystem:{state:"0/-/",scrollPos:0},Playlists:{active:"All",views:{All:{state:"0/-/",scrollPos:0},Detail:{state:"0/-/",scrollPos:0}}},Database:{active:"Artist",views:{Artist:{state:"0/-/",scrollPos:0},Album:{state:"0/-/",scrollPos:0}}}}},Search:{state:"0/Any Tag/",scrollPos:0}}, | ||||
| current:{app:"Playback",tab:void 0,view:void 0,page:0,filter:"",search:"",scrollPos:0},last:{app:void 0,tab:void 0,view:void 0,filter:"",search:"",scrollPos:0}},domCache={};domCache.navbarBottomBtns=document.getElementById("navbar-bottom").getElementsByTagName("div");domCache.navbarBottomBtnsLen=domCache.navbarBottomBtns.length;domCache.panelHeadingBrowse=document.getElementById("panel-heading-browse").getElementsByTagName("a");domCache.panelHeadingBrowseLen=domCache.panelHeadingBrowse.length; | ||||
| domCache.counter=document.getElementById("counter");domCache.volumePrct=document.getElementById("volumePrct");domCache.volumeControl=document.getElementById("volumeControl");domCache.volumeIcon=document.getElementById("volumeIcon");domCache.btnPlay=document.getElementById("btnPlay");domCache.btnPrev=document.getElementById("btnPrev");domCache.btnNext=document.getElementById("btnNext");domCache.progressBar=document.getElementById("progressBar");domCache.volumeBar=document.getElementById("volumeBar"); | ||||
| domCache.outputs=document.getElementById("outputs");domCache.btnAdd=document.getElementById("btnAdd"); | ||||
| var modalConnectionError=new Modal(document.getElementById("modalConnectionError")),modalSettings=new Modal(document.getElementById("modalSettings")),modalAddstream=new Modal(document.getElementById("modalAddstream")),modalSavequeue=new Modal(document.getElementById("modalSaveQueue")),modalSongDetails=new Modal(document.getElementById("modalSongDetails")),modalAddToPlaylist=new Modal(document.getElementById("modalAddToPlaylist")),modalRenamePlaylist=new Modal(document.getElementById("modalRenamePlaylist")), | ||||
| mainMenu=new Dropdown(document.getElementById("mainMenu")); | ||||
| domCache.outputs=document.getElementById("outputs");domCache.btnAdd=document.getElementById("nav-add2homescreen"); | ||||
| var modalConnectionError=new Modal(document.getElementById("modalConnectionError")),modalSettings=new Modal(document.getElementById("modalSettings")),modalSavequeue=new Modal(document.getElementById("modalSaveQueue")),modalSongDetails=new Modal(document.getElementById("modalSongDetails")),modalAddToPlaylist=new Modal(document.getElementById("modalAddToPlaylist")),modalRenamePlaylist=new Modal(document.getElementById("modalRenamePlaylist")),mainMenu=new Dropdown(document.getElementById("mainMenu")); | ||||
| function appPrepare(a){if(app.current.app!=app.last.app||app.current.tab!=app.last.tab||app.current.view!=app.last.view){for(var b=0;b<domCache.navbarBottomBtnsLen;b++)domCache.navbarBottomBtns[b].classList.remove("active");document.getElementById("cardPlayback").classList.add("hide");document.getElementById("cardQueue").classList.add("hide");document.getElementById("cardBrowse").classList.add("hide");document.getElementById("cardSearch").classList.add("hide");for(b=0;b<domCache.panelHeadingBrowseLen;b++)domCache.panelHeadingBrowse[b].classList.remove("active"); | ||||
| document.getElementById("cardBrowsePlaylists").classList.add("hide");document.getElementById("cardBrowseDatabase").classList.add("hide");document.getElementById("cardBrowseFilesystem").classList.add("hide");document.getElementById("card"+app.current.app).classList.remove("hide");document.getElementById("nav"+app.current.app).classList.add("active");void 0!=app.current.tab&&(document.getElementById("card"+app.current.app+app.current.tab).classList.remove("hide"),document.getElementById("card"+app.current.app+ | ||||
| "Nav"+app.current.tab).classList.add("active"));scrollTo(a)}(a=document.getElementById(app.current.app+(void 0==app.current.tab?"":app.current.tab)+(void 0==app.current.view?"":app.current.view)+"List"))&&a.classList.add("opacity05")} | ||||
| @@ -21,24 +20,26 @@ app.apps[app.current.app].tabs[app.current.tab].views[app.current.view].state&&( | ||||
| if("Playback"==app.current.app)sendAPI({cmd:"MPD_API_GET_CURRENT_SONG"},songChange);else if("Queue"==app.current.app){var b=document.getElementById("searchqueuetag").getElementsByTagName("button");for(a=0;a<b.length;a++)b[a].classList.remove("active"),b[a].innerText==app.current.filter&&(b[a].classList.add("active"),document.getElementById("searchqueuetagdesc").innerText=b[a].innerText);getQueue()}else if("Browse"==app.current.app&&"Playlists"==app.current.tab&&"All"==app.current.view)sendAPI({cmd:"MPD_API_GET_PLAYLISTS", | ||||
| data:{offset:app.current.page,filter:app.current.filter}},parsePlaylists),doSetFilterLetter("BrowsePlaylistsFilter");else if("Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view)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("Browse"==app.current.app&&"Database"==app.current.tab&&"Artist"==app.current.view)sendAPI({cmd:"MPD_API_GET_ARTISTS", | ||||
| data:{offset:app.current.page,filter:app.current.filter}},parseListDBtags),doSetFilterLetter("BrowseDatabaseFilter");else if("Browse"==app.current.app&&"Database"==app.current.tab&&"Album"==app.current.view)sendAPI({cmd:"MPD_API_GET_ARTISTALBUMS",data:{offset:app.current.page,filter:app.current.filter,albumartist:app.current.search}},parseListDBtags),doSetFilterLetter("BrowseDatabaseFilter");else if("Browse"==app.current.app&&"Filesystem"==app.current.tab){sendAPI({cmd:"MPD_API_GET_FILESYSTEM",data:{offset:app.current.page, | ||||
| path:app.current.search?app.current.search:"/",filter:app.current.filter}},parseFilesystem);app.current.search?document.getElementById("BrowseFilesystemAddAllSongs").removeAttribute("disabled"):document.getElementById("BrowseFilesystemAddAllSongs").setAttribute("disabled","disabled");b='<li class="breadcrumb-item"><a data-uri="">root</a></li>';var c=app.current.search.split("/"),e=c.length,d="";for(a=0;a<e;a++){if(e-1==a){b+='<li class="breadcrumb-item active">'+c[a]+"</li>";break}d+=c[a];b+='<li class="breadcrumb-item"><a data-uri="'+ | ||||
| d+'">'+c[a]+"</a></li>";d+="/"}a=document.getElementById("BrowseBreadcrumb");a.innerHTML=b;b=a.getElementsByTagName("a");c=b.length;for(a=0;a<c;a++)b[a].addEventListener("click",function(){appGoto("Browse","Filesystem",void 0,"0/"+app.current.filter+"/"+this.getAttribute("data-uri"))},!1);doSetFilterLetter("BrowseFilesystemFilter")}else if("Search"==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("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")} | ||||
| path:app.current.search?app.current.search:"/",filter:app.current.filter}},parseFilesystem);app.current.search?(document.getElementById("BrowseFilesystemAddAllSongs").removeAttribute("disabled"),document.getElementById("BrowseFilesystemAddAllSongsBtn").removeAttribute("disabled")):(document.getElementById("BrowseFilesystemAddAllSongs").setAttribute("disabled","disabled"),document.getElementById("BrowseFilesystemAddAllSongsBtn").setAttribute("disabled","disabled"));b='<li class="breadcrumb-item"><a data-uri="">root</a></li>'; | ||||
| var c=app.current.search.split("/"),e=c.length,d="";for(a=0;a<e;a++){if(e-1==a){b+='<li class="breadcrumb-item active">'+c[a]+"</li>";break}d+=c[a];b+='<li class="breadcrumb-item"><a data-uri="'+d+'">'+c[a]+"</a></li>";d+="/"}a=document.getElementById("BrowseBreadcrumb");a.innerHTML=b;b=a.getElementsByTagName("a");c=b.length;for(a=0;a<c;a++)b[a].addEventListener("click",function(){appGoto("Browse","Filesystem",void 0,"0/"+app.current.filter+"/"+this.getAttribute("data-uri"))},!1);doSetFilterLetter("BrowseFilesystemFilter")}else if("Search"== | ||||
| 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();sendAPI({cmd:"MPD_API_GET_OUTPUTNAMES"},parseOutputnames);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("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("modalAddstream").addEventListener("shown.bs.modal",function(){var a=document.getElementById("streamUrl");a.focus();a.value="";a.classList.remove("is-invalid"); | ||||
| document.getElementById("addStreamFrm").classList.remove("was-validated")});addFilterLetter("BrowseFilesystemFilterLetters");addFilterLetter("BrowseDatabaseFilterLetters");addFilterLetter("BrowsePlaylistsFilterLetters");for(var a=document.querySelectorAll("button[data-href], a[data-href]"),b=a.length,c=0;c<b;c++)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("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(){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("button[data-href], a[data-href]"),b=a.length,c=0;c<b;c++)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"); | ||||
| @@ -63,7 +64,7 @@ function parseQueue(a){if("Queue"===app.current.app){0<a.totalTime?document.getE | ||||
| for(var e=c.getElementsByTagName("tr"),d=0;d<b;d++)if(!e[d]||e[d].getAttribute("data-trackid")!=a.data[d].id||e[d].getAttribute("data-songpos")!=a.data[d].pos+1){var f=Math.floor(a.data[d].duration/60),g=a.data[d].duration-60*f;f=f+":"+(10>g?"0":"")+g;g=document.createElement("tr");g.setAttribute("draggable","true");g.setAttribute("data-trackid",a.data[d].id);g.setAttribute("id","queueTrackId"+a.data[d].id);g.setAttribute("data-songpos",a.data[d].pos+1);g.setAttribute("data-duration",f);g.setAttribute("data-uri", | ||||
| a.data[d].uri);g.innerHTML="<td>"+(a.data[d].pos+1)+"</td><td>"+a.data[d].title+"</td><td>"+a.data[d].artist+"</td><td>"+a.data[d].album+"</td><td>"+f+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';d<e.length?e[d].replaceWith(g):c.append(g)}for(d=e.length-1;d>=b;d--)e[d].remove();"queuesearch"==a.type&&0==b?c.innerHTML='<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">No results, please refine your search!</td></tr>':"queue"==a.type&& | ||||
| 0==b&&(c.innerHTML='<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">Empty queue</td></tr>');setPagination(a.totalEntities);document.getElementById("QueueList").classList.remove("opacity05")}} | ||||
| function parseSearch(a){"Search"===app.current.app&&(document.getElementById("panel-heading-search").innerHTML=a.totalEntities+" Songs found",0<a.totalEntities?document.getElementById("searchAddAllSongs").removeAttribute("disabled"):document.getElementById("searchAddAllSongs").setAttribute("disabled","disabled"),parseFilesystem(a))} | ||||
| function parseSearch(a){"Search"===app.current.app&&(document.getElementById("panel-heading-search").innerHTML=a.totalEntities+" Songs found",0<a.totalEntities?(document.getElementById("searchAddAllSongs").removeAttribute("disabled"),document.getElementById("searchAddAllSongsBtn").removeAttribute("disabled")):(document.getElementById("searchAddAllSongs").setAttribute("disabled","disabled"),document.getElementById("searchAddAllSongsBtn").setAttribute("disabled","disabled")),parseFilesystem(a))} | ||||
| function parseFilesystem(a){if("Browse"===app.current.app||"Filesystem"===app.current.tab||"Search"===app.current.app){for(var b=a.data.length,c=document.getElementById(app.current.app+(void 0==app.current.tab?"":app.current.tab)+"List").getElementsByTagName("tbody")[0],e=c.getElementsByTagName("tr"),d=0;d<b;d++){var f=encodeURI(a.data[d].uri);if(!e[d]||e[d].getAttribute("data-uri")!=f){var g=document.createElement("tr");g.setAttribute("data-type",a.data[d].type);g.setAttribute("data-uri",f);g.setAttribute("data-name", | ||||
| a.data[d].name);switch(a.data[d].type){case "dir":g.innerHTML='<td><span class="material-icons">folder_open</span></td><td colspan="4">'+a.data[d].name+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';break;case "song":f=Math.floor(a.data[d].duration/60);var h=a.data[d].duration-60*f;g.innerHTML='<td><span class="material-icons">music_note</span></td><td>'+a.data[d].title+"</td><td>"+a.data[d].artist+"</td><td>"+a.data[d].album+"</td><td>"+f+":"+(10>h?"0":"")+h+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>'; | ||||
| break;case "plist":g.innerHTML='<td><span class="material-icons">list</span></td><td colspan="4">'+a.data[d].name+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>'}d<e.length?e[d].replaceWith(g):c.append(g)}}for(d=e.length-1;d>=b;d--)e[d].remove();setPagination(a.totalEntities);0==b&&(c.innerHTML='<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">No results</td></tr>');document.getElementById(app.current.app+(void 0==app.current.tab?"": | ||||
| @@ -83,18 +84,23 @@ function parseListTitles(a){if("Browse"===app.current.app||"Database"===app.curr | ||||
| a.data[f].title+'" data-uri="'+encodeURI(a.data[f].uri)+'"><td>'+a.data[f].track+"</td><td>"+a.data[f].title+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td></tr>';b.innerHTML=e;c.addEventListener("click",function(a){a.preventDefault();showMenu(this)},!1);b.parentNode.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)}} | ||||
| function setPagination(a){var b=Math.ceil(a/settings.max_elements_per_page),c=app.current.app+(void 0==app.current.tab?"":app.current.tab);0==b&&(b=1);for(var e=["PaginationTop","PaginationBottom"],d=0;2>d;d++){document.getElementById(c+e[d]+"Page").innerText=app.current.page/settings.max_elements_per_page+1+" / "+b;if(1<b){document.getElementById(c+e[d]+"Page").removeAttribute("disabled");for(var f="",g=0;g<b;g++)f+='<button data-page="'+g*settings.max_elements_per_page+'" type="button" class="mr-1 mb-1 btn-sm btn btn-secondary">'+ | ||||
| (g+1)+"</button>";document.getElementById(c+e[d]+"Pages").innerHTML=f}else document.getElementById(c+e[d]+"Page").setAttribute("disabled","disabled");a>app.current.page+settings.max_elements_per_page?(document.getElementById(c+e[d]+"Next").removeAttribute("disabled"),document.getElementById(c+"ButtonsBottom").classList.remove("hide")):(document.getElementById(c+e[d]+"Next").setAttribute("disabled","disabled"),document.getElementById(c+"ButtonsBottom").classList.add("hide"));0<app.current.page?(document.getElementById(c+ | ||||
| e[d]+"Prev").removeAttribute("disabled"),document.getElementById(c+"ButtonsBottom").classList.remove("hide")):document.getElementById(c+e[d]+"Prev").setAttribute("disabled","disabled")}} | ||||
| (g+1)+"</button>";document.getElementById(c+e[d]+"Pages").innerHTML=f}else document.getElementById(c+e[d]+"Page").setAttribute("disabled","disabled");a>app.current.page+settings.max_elements_per_page?(document.getElementById(c+e[d]+"Next").removeAttribute("disabled"),document.getElementById(c+e[d]).classList.remove("hide"),document.getElementById(c+"ButtonsBottom").classList.remove("hide")):(document.getElementById(c+e[d]+"Next").setAttribute("disabled","disabled"),document.getElementById(c+e[d]).classList.add("hide"), | ||||
| document.getElementById(c+"ButtonsBottom").classList.add("hide"));0<app.current.page?(document.getElementById(c+e[d]+"Prev").removeAttribute("disabled"),document.getElementById(c+e[d]).classList.remove("hide"),document.getElementById(c+"ButtonsBottom").classList.remove("hide")):document.getElementById(c+e[d]+"Prev").setAttribute("disabled","disabled")}} | ||||
| function appendQueue(a,b,c){switch(a){case "song":sendAPI({cmd:"MPD_API_ADD_TRACK",data:{uri:b}});showNotification('"'+c+'" added',"","","success");break;case "dir":sendAPI({cmd:"MPD_API_ADD_TRACK",data:{uri:b}});showNotification('"'+c+'" added',"","","success");break;case "plist":sendAPI({cmd:"MPD_API_ADD_PLAYLIST",data:{plist:b}}),showNotification('"'+c+'" added',"","","success")}} | ||||
| function appendAfterQueue(a,b,c,e){switch(a){case "song":sendAPI({cmd:"MPD_API_ADD_TRACK_AFTER",data:{uri:b,to:c}}),showNotification('"'+e+'" added to pos '+c,"","","success")}} | ||||
| function replaceQueue(a,b,c){switch(a){case "song":sendAPI({cmd:"MPD_API_REPLACE_TRACK",data:{uri:b}});showNotification('"'+c+'" replaced',"","","success");break;case "dir":sendAPI({cmd:"MPD_API_REPLACE_TRACK",data:{uri:b}});showNotification('"'+c+'" replaced',"","","success");break;case "plist":sendAPI({cmd:"MPD_API_REPLACE_PLAYLIST",data:{plist:b}}),showNotification('"'+c+'" replaced',"","","success")}} | ||||
| function songDetails(a){sendAPI({cmd:"MPD_API_GET_SONGDETAILS",data:{uri:a}},parseSongDetails);modalSongDetails.show()} | ||||
| function parseSongDetails(a){var b=document.getElementById("modalSongDetails");b.querySelector(".album-cover").style.backgroundImage='url("'+a.data.cover+'")';b.getElementsByTagName("h1")[0].innerText=a.data.title;b=b.getElementsByTagName("tr");for(var c=b.length,e=0;e<c;e++){var d=b[e].getAttribute("data-name"),f=a.data[d];"duration"==d?(d=Math.floor(f/60),f-=60*d,f=d+":"+(10>f?"0":"")+f):"uri"==d&&(f='<a class="text-success" href="/library/'+f+'">'+f+"</a>");b[e].getElementsByTagName("td")[1].innerHTML= | ||||
| f}}function playlistDetails(a){appGoto("Browse","Playlists","Detail","0/-/"+a)}function removeFromPlaylist(a,b){sendAPI({cmd:"MPD_API_RM_PLAYLIST_TRACK",data:{uri:a,track:b}});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)} | ||||
| f}}function playlistDetails(a){appGoto("Browse","Playlists","Detail","0/-/"+a)}function removeFromPlaylist(a,b){b--;sendAPI({cmd:"MPD_API_RM_PLAYLIST_TRACK",data:{uri:a,track:b}});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 a=document.getElementById("BrowsePlaylistsDetailList").getAttribute("data-uri");sendAPI({cmd:"MPD_API_PLAYLIST_CLEAR",data:{uri:a}});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(a){for(var b=a.data.length,c="",e=0;e<b;e++)c+="<option>"+a.data[e].uri+"</option>";document.getElementById("addToPlaylistPlaylist").innerHTML+=c;a.totalEntities>a.returnedEntities&&(a.offset+=settings.max_elements_per_page,sendAPI({cmd:"MPD_API_GET_PLAYLISTS",data:{offset:a.offset,filter:"-"}},getAllPlaylists))} | ||||
| function showAddToPlaylist(a){modalAddToPlaylist.show();document.getElementById("addToPlaylistUri").value=a;document.getElementById("addToPlaylistPlaylist").innerHTML="";sendAPI({cmd:"MPD_API_GET_PLAYLISTS",data:{offset:0,filter:"-"}},getAllPlaylists)} | ||||
| function addToPlaylist(){var a=document.getElementById("addToPlaylistUri").value,b=document.getElementById("addToPlaylistPlaylist");sendAPI({cmd:"MPD_API_ADD_TO_PLAYLIST",data:{uri:a,plist:b.options[b.selectedIndex].text}});modalAddToPlaylist.hide()} | ||||
| function getAllPlaylists(a){for(var b=a.data.length,c="<option></option><option>New Playlist</option>",e=0;e<b;e++)c+="<option>"+a.data[e].uri+"</option>";document.getElementById("addToPlaylistPlaylist").innerHTML+=c;a.totalEntities>a.returnedEntities&&(a.offset+=settings.max_elements_per_page,sendAPI({cmd:"MPD_API_GET_PLAYLISTS",data:{offset:a.offset,filter:"-"}},getAllPlaylists))} | ||||
| function toggleAddToPlaylistFrm(){var a=document.getElementById("toggleAddToPlaylistBtn");toggleBtn("toggleAddToPlaylistBtn");a.classList.contains("active")?(document.getElementById("addToPlaylistFrm").classList.remove("hide"),document.getElementById("addStreamFooter").classList.add("hide"),document.getElementById("addToPlaylistFooter").classList.remove("hide")):(document.getElementById("addToPlaylistFrm").classList.add("hide"),document.getElementById("addStreamFooter").classList.remove("hide"),document.getElementById("addToPlaylistFooter").classList.add("hide"))} | ||||
| function showAddToPlaylist(a){document.getElementById("addToPlaylistUri").value=a;document.getElementById("addToPlaylistPlaylist").innerHTML="";document.getElementById("addToPlaylistNewPlaylistDiv").classList.add("hide");document.getElementById("addToPlaylistFrm").classList.remove("was-validated");document.getElementById("addToPlaylistNewPlaylist").classList.remove("is-invalid");toggleBtn("toggleAddToPlaylistBtn",0);var b=document.getElementById("streamUrl");b.focus();b.value="";b.classList.remove("is-invalid"); | ||||
| document.getElementById("addStreamFrm").classList.remove("was-validated");"stream"!=a?(document.getElementById("addStreamFooter").classList.add("hide"),document.getElementById("addStreamFrm").classList.add("hide"),document.getElementById("addToPlaylistFooter").classList.remove("hide"),document.getElementById("addToPlaylistFrm").classList.remove("hide"),document.getElementById("addToPlaylistLabel").innerText="Add to playlist"):(document.getElementById("addStreamFooter").classList.remove("hide"),document.getElementById("addStreamFrm").classList.remove("hide"), | ||||
| document.getElementById("addToPlaylistFooter").classList.add("hide"),document.getElementById("addToPlaylistFrm").classList.add("hide"),document.getElementById("addToPlaylistLabel").innerText="Add Stream");modalAddToPlaylist.show();sendAPI({cmd:"MPD_API_GET_PLAYLISTS",data:{offset:0,filter:"-"}},getAllPlaylists)} | ||||
| function addToPlaylist(){var a=document.getElementById("addToPlaylistUri").value;if("stream"==a&&(a=document.getElementById("streamUrl").value,""==a||-1==a.indexOf("http"))){document.getElementById("streamUrl").classList.add("is-invalid");document.getElementById("addStreamFrm").classList.add("was-validated");return}var b=document.getElementById("addToPlaylistPlaylist");b=b.options[b.selectedIndex].text;if("New Playlist"==b){b=document.getElementById("addToPlaylistNewPlaylist").value;var c=b.replace(/\w/g, | ||||
| "");if(""==b||""!=c){document.getElementById("addToPlaylistNewPlaylist").classList.add("is-invalid");document.getElementById("addToPlaylistFrm").classList.add("was-validated");return}}""!=b?("SEARCH"!=a?sendAPI({cmd:"MPD_API_ADD_TO_PLAYLIST",data:{uri:a,plist:b}}):addAllFromSearchPlist(b),modalAddToPlaylist.hide()):(document.getElementById("addToPlaylistPlaylist").classList.add("is-invalid"),document.getElementById("addToPlaylistFrm").classList.add("was-validated"))} | ||||
| function addStream(){var a=document.getElementById("streamUrl").value;""!=a&&0==a.indexOf("http")?(sendAPI({cmd:"MPD_API_ADD_TRACK",data:{uri:a}}),modalAddToPlaylist.hide(),showNotification("Added stream "+a+"to queue","","","success")):(document.getElementById("streamUrl").classList.add("is-invalid"),document.getElementById("addStreamFrm").classList.add("was-validated"))} | ||||
| function showRenamePlaylist(a){document.getElementById("renamePlaylistFrm").classList.remove("was-validated");document.getElementById("renamePlaylistTo").classList.remove("is-invalid");modalRenamePlaylist.show();document.getElementById("renamePlaylistFrom").value=a;document.getElementById("renamePlaylistTo").value=""} | ||||
| function renamePlaylist(){var a=document.getElementById("renamePlaylistFrom").value,b=document.getElementById("renamePlaylistTo").value,c=b.replace(/\w/g,"");""!=b&&b!=a&&""==c?(sendAPI({cmd:"MPD_API_PLAYLIST_RENAME",data:{from:a,to:b}}),modalRenamePlaylist.hide(),sendAPI({cmd:"MPD_API_GET_PLAYLISTS",data:{offset:app.current.page,filter:app.current.filter}},parsePlaylists)):(document.getElementById("renamePlaylistTo").classList.add("is-invalid"),document.getElementById("renamePlaylistFrm").classList.add("was-validated"))} | ||||
| function showMenu(a){var b=a.getAttribute("data-type"),c=decodeURI(a.getAttribute("data-uri")),e=a.getAttribute("data-name"),d=0;if(null==b||null==c)b=a.parentNode.parentNode.getAttribute("data-type"),c=decodeURI(a.parentNode.parentNode.getAttribute("data-uri")),e=a.parentNode.parentNode.getAttribute("data-name");last_state&&(d=last_state.data.nextsongpos);var f="";"Browse"==app.current.app&&"Filesystem"==app.current.tab||"Search"==app.current.app||"Browse"==app.current.app&&"Database"==app.current.tab&& | ||||
| @@ -102,18 +108,19 @@ function showMenu(a){var b=a.getAttribute("data-type"),c=decodeURI(a.getAttribut | ||||
| c+"']}\">Add to playlist</a>":"")+("dir"!=b?'<div class="dropdown-divider"></div>':"")+("song"==b?"<a class=\"dropdown-item\" data-href=\"{'cmd': 'songDetails', 'options': ['"+c+'\']}" href="#">Songdetails</a>':"")+("plist"==b?"<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'playlistDetails', 'options': ['"+c+"']}\">Show playlist</a>":""):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"All"==app.current.view?f+="<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendQueue', 'options': ['"+ | ||||
| b+"','"+c+"','"+e+"']}\">Append to queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['"+b+"','"+c+"','"+e+"']}\">Replace queue</a><div class=\"dropdown-divider\"></div><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'playlistDetails', 'options': ['"+c+"']}\">Edit playlist</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'showRenamePlaylist', 'options': ['"+c+"']}\">Rename playlist</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delPlaylist', 'options': ['"+ | ||||
| c+"']}\">Delete playlist</a>":"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view?f+="<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendQueue', 'options': ['"+b+"','"+c+"','"+e+"']}\">Append to queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['"+b+"','"+c+"','"+e+"']}\">Replace queue</a>"+("false"==document.getElementById("BrowsePlaylistsDetailList").getAttribute("data-ro")?"<div class=\"dropdown-divider\"></div><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'removeFromPlaylist', 'options': ['"+ | ||||
| document.getElementById("BrowsePlaylistsDetailList").getAttribute("data-uri")+"', '"+a.parentNode.parentNode.getAttribute("data-songpos")+"']}\">Remove</a>":""):"Queue"==app.current.app&&(f+="<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['single',"+a.parentNode.parentNode.getAttribute("data-trackid")+"]}\">Remove</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['range',0,"+a.parentNode.parentNode.getAttribute("data-songpos")+ | ||||
| "]}\">Remove all upwards</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['range',"+(parseInt(a.parentNode.parentNode.getAttribute("data-songpos"))-1)+',-1]}">Remove all downwards</a><div class="dropdown-divider"></div>'+(-1==c.indexOf("http")?"<a class=\"dropdown-item\" data-href=\"{'cmd': 'songDetails', 'options': ['"+c+'\']}" href="#">Songdetails</a>':""));void 0==a.Popover&&(new Popover(a,{trigger:"click",template:'<div class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content">'+ | ||||
| f+"</div></div>"}),b=a.Popover,a.addEventListener("shown.bs.popover",function(a){document.querySelector(".popover-content").addEventListener("click",function(a){a.preventDefault();a.stopPropagation();a=JSON.parse(a.target.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)},!1),b.show())} | ||||
| document.getElementById("BrowsePlaylistsDetailList").getAttribute("data-uri")+"', '"+a.parentNode.parentNode.getAttribute("data-songpos")+"']}\">Remove</a>":"")+("plist"!=b?"<div class=\"dropdown-divider\"></div><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'showAddToPlaylist', 'options': ['"+c+"']}\">Add to playlist</a>":""):"Queue"==app.current.app&&(f+="<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['single',"+a.parentNode.parentNode.getAttribute("data-trackid")+ | ||||
| "]}\">Remove</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['range',0,"+a.parentNode.parentNode.getAttribute("data-songpos")+"]}\">Remove all upwards</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['range',"+(parseInt(a.parentNode.parentNode.getAttribute("data-songpos"))-1)+',-1]}">Remove all downwards</a><div class="dropdown-divider"></div>'+(-1==c.indexOf("http")?"<a class=\"dropdown-item\" data-href=\"{'cmd': 'songDetails', 'options': ['"+ | ||||
| c+'\']}" href="#">Songdetails</a>':""));void 0==a.Popover&&(new Popover(a,{trigger:"click",template:'<div class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content">'+f+"</div></div>"}),b=a.Popover,a.addEventListener("shown.bs.popover",function(a){document.querySelector(".popover-content").addEventListener("click",function(a){a.preventDefault();a.stopPropagation();a=JSON.parse(a.target.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)},!1),b.show())} | ||||
| function sendAPI(a,b){var c=new XMLHttpRequest;c.open("POST","/api",!0);c.setRequestHeader("Content-type","application/json");c.onreadystatechange=function(){if(4==c.readyState)if(""!=c.responseText){var e=JSON.parse(c.responseText);"error"==e.type?(showNotification("Error",e.data,e.data,"danger"),console.log("Error: "+e.data)):"result"==e.type&&"ok"!=e.data?showNotification(e.data,"","","success"):void 0!=b&&"function"==typeof b&&b(e)}else console.log("Empty response for request: "+JSON.stringify(a))}; | ||||
| c.send(JSON.stringify(a))}function openLocalPlayer(){window.open("/player.html#"+settings.mpdstream,"LocalPlayer")}function updateDB(){sendAPI({cmd:"MPD_API_UPDATE_DB"});showNotification("Updating MPD Database...","","","success")}function clickPlay(){"play"!=playstate?sendAPI({cmd:"MPD_API_SET_PLAY"}):sendAPI({cmd:"MPD_API_SET_PAUSE"})}function clickStop(){sendAPI({cmd:"MPD_API_SET_STOP"})}function clickPrev(){sendAPI({cmd:"MPD_API_SET_PREV"})} | ||||
| function clickNext(){sendAPI({cmd:"MPD_API_SET_NEXT"})}function delQueueSong(a,b,c){"range"==a?sendAPI({cmd:"MPD_API_RM_RANGE",data:{start:b,end:c}}):"single"==a&&sendAPI({cmd:"MPD_API_RM_TRACK",data:{track:b}})}function delPlaylist(a){sendAPI({cmd:"MPD_API_RM_PLAYLIST",data:{uri:a}});document.getElementById("BrowsePlaylistsAllList").querySelector("tr[data-uri="+encodeURI(a)+"]").remove()} | ||||
| function clickNext(){sendAPI({cmd:"MPD_API_SET_NEXT"})}function delQueueSong(a,b,c){"range"==a?sendAPI({cmd:"MPD_API_RM_RANGE",data:{start:b,end:c}}):"single"==a&&sendAPI({cmd:"MPD_API_RM_TRACK",data:{track:b}})}function delPlaylist(a){sendAPI({cmd:"MPD_API_RM_PLAYLIST",data:{uri:a}});sendAPI({cmd:"MPD_API_GET_PLAYLISTS",data:{offset:app.current.page,filter:app.current.filter}},parsePlaylists)} | ||||
| function confirmSettings(){var a=!0,b=document.getElementById("inputCrossfade");if(!b.getAttribute("disabled")){var c=parseInt(b.value);isNaN(c)?(b.classList.add("is-invalid"),a=!1):b.value=c}b=document.getElementById("inputMixrampdb");b.getAttribute("disabled")||(c=parseFloat(b.value),isNaN(c)?(b.classList.add("is-invalid"),a=!1):b.value=c);b=document.getElementById("inputMixrampdelay");b.getAttribute("disabled")||("nan"==b.value&&(b.value="-1"),c=parseFloat(b.value),isNaN(c)?(b.classList.add("is-invalid"), | ||||
| a=!1):b.value=c);1==a?(a=document.getElementById("selectReplaygain"),sendAPI({cmd:"MPD_API_SET_SETTINGS",data:{consume:document.getElementById("btnConsume").classList.contains("active")?1:0,random:document.getElementById("btnRandom").classList.contains("active")?1:0,single:document.getElementById("btnSingle").classList.contains("active")?1:0,repeat:document.getElementById("btnRepeat").classList.contains("active")?1:0,replaygain:a.options[a.selectedIndex].value,crossfade:document.getElementById("inputCrossfade").value, | ||||
| mixrampdb:document.getElementById("inputMixrampdb").value,mixrampdelay:document.getElementById("inputMixrampdelay").vaue,notificationWeb:document.getElementById("btnnotifyWeb").classList.contains("active")?1:0,notificationPage:document.getElementById("btnnotifyPage").classList.contains("active")?1:0}},getSettings),modalSettings.hide()):document.getElementById("settingsFrm").classList.add("was-validated")} | ||||
| function addAllFromBrowse(){sendAPI({cmd:"MPD_API_ADD_TRACK",data:{uri:app.current.search}});showNotification("Added all songs","","","success")}function addAllFromSearch(){2<=app.current.search.length&&(sendAPI({cmd:"MPD_API_SEARCH_ADD",data:{filter:app.current.filter,searchstr:app.current.search}}),showNotification("Added "+parseInt(document.getElementById("panel-heading-search").innerText)+" songs from search","","","success"))} | ||||
| function scrollTo(a){document.body.scrollTop=a;document.documentElement.scrollTop=a}function gotoPage(a){switch(a){case "next":app.current.page+=settings.max_elements_per_page;break;case "prev":app.current.page-=settings.max_elements_per_page;0>=app.current.page&&(app.current.page=0);break;default:app.current.page=a}appGoto(app.current.app,app.current.tab,app.current.view,app.current.page+"/"+app.current.filter+"/"+app.current.search)} | ||||
| function addStream(){var a=document.getElementById("streamUrl").value;""!=a&&0==a.indexOf("http")?(sendAPI({cmd:"MPD_API_ADD_TRACK",data:{uri:a}}),modalAddstream.hide()):(document.getElementById("streamUrl").classList.add("is-invalid"),document.getElementById("addStreamFrm").classList.add("was-validated"))} | ||||
| function addAllFromSearchPlist(a){if(2<=app.current.search.length){var b=app.current.filter;"Any Tag"==b&&(b="any");sendAPI({cmd:"MPD_API_SEARCH_ADD_PLIST",data:{plist:a,filter:b,searchstr:app.current.search}});showNotification("Added "+parseInt(document.getElementById("panel-heading-search").innerText)+" songs from search to "+a,"","","success")}}function scrollTo(a){document.body.scrollTop=a;document.documentElement.scrollTop=a} | ||||
| function gotoPage(a){switch(a){case "next":app.current.page+=settings.max_elements_per_page;break;case "prev":app.current.page-=settings.max_elements_per_page;0>=app.current.page&&(app.current.page=0);break;default:app.current.page=a}appGoto(app.current.app,app.current.tab,app.current.view,app.current.page+"/"+app.current.filter+"/"+app.current.search)} | ||||
| function saveQueue(){var a=document.getElementById("saveQueueName").value,b=a.replace(/\w/g,"");""!=a&&""==b?(sendAPI({cmd:"MPD_API_SAVE_QUEUE",data:{plist:a}}),modalSavequeue.hide()):(document.getElementById("saveQueueName").classList.add("is-invalid"),document.getElementById("saveQueueFrm").classList.add("was-validated"))} | ||||
| function showNotification(a,b,c,e){1==settings.notificationWeb&&(b=new Notification(a,{icon:"assets/favicon.ico",body:b}),setTimeout(function(a){a.close()},3E3,b));1==settings.notificationPage&&(document.getElementById("alertBox")?b=document.getElementById("alertBox"):(b=document.createElement("div"),b.setAttribute("id","alertBox"),b.addEventListener("click",function(){hideNotification()},!1)),b.classList.remove("alert-success","alert-danger"),b.classList.add("alert","alert-"+e),b.innerHTML="<div><strong>"+ | ||||
| a+"</strong><br/>"+c+"</div>",document.getElementsByTagName("main")[0].append(b),document.getElementById("alertBox").classList.add("alertBoxActive"),alertTimeout&&clearTimeout(alertTimeout),alertTimeout=setTimeout(function(){hideNotification()},3E3))}function hideNotification(){document.getElementById("alertBox")&&(document.getElementById("alertBox").classList.remove("alertBoxActive"),setTimeout(function(){document.getElementById("alertBox").remove()},600))} | ||||
|   | ||||
							
								
								
									
										2
									
								
								dist/htdocs/sw.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/htdocs/sw.min.js
									
									
									
									
										vendored
									
									
								
							| @@ -10,5 +10,5 @@ function(){function a(a){return function(d){c||(c=!0,a.call(b,d))}}var b=this,c= | ||||
| void 0;try{d=a.then}catch(h){this.reject_(h);return}"function"==typeof d?this.settleSameAsThenable_(d,a):this.fulfill_(a)};c.prototype.reject_=function(a){this.settle_(2,a)};c.prototype.fulfill_=function(a){this.settle_(1,a)};c.prototype.settle_=function(a,b){if(0!=this.state_)throw Error("Cannot settle("+a+", "+b+"): Promise already settled in state"+this.state_);this.state_=a;this.result_=b;this.executeOnSettledCallbacks_()};c.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var a= | ||||
| 0;a<this.onSettledCallbacks_.length;++a)l.asyncExecute(this.onSettledCallbacks_[a]);this.onSettledCallbacks_=null}};var l=new b;c.prototype.settleSameAsPromise_=function(a){var b=this.createResolveAndReject_();a.callWhenSettled_(b.resolve,b.reject)};c.prototype.settleSameAsThenable_=function(a,b){var c=this.createResolveAndReject_();try{a.call(b,c.resolve,c.reject)}catch(k){c.reject(k)}};c.prototype.then=function(a,b){function d(a,b){return"function"==typeof a?function(b){try{f(a(b))}catch(m){e(m)}}: | ||||
| b}var f,e,g=new c(function(a,b){f=a;e=b});this.callWhenSettled_(d(a,f),d(b,e));return g};c.prototype.catch=function(a){return this.then(void 0,a)};c.prototype.callWhenSettled_=function(a,b){function c(){switch(d.state_){case 1:a(d.result_);break;case 2:b(d.result_);break;default:throw Error("Unexpected state: "+d.state_);}}var d=this;null==this.onSettledCallbacks_?l.asyncExecute(c):this.onSettledCallbacks_.push(c)};c.resolve=f;c.reject=function(a){return new c(function(b,c){c(a)})};c.race=function(a){return new c(function(b, | ||||
| c){for(var d=$jscomp.makeIterator(a),e=d.next();!e.done;e=d.next())f(e.value).callWhenSettled_(b,c)})};c.all=function(a){var b=$jscomp.makeIterator(a),d=b.next();return d.done?f([]):new c(function(a,c){function e(b){return function(c){g[b]=c;h--;0==h&&a(g)}}var g=[],h=0;do g.push(void 0),h++,f(d.value).callWhenSettled_(e(g.length-1),c),d=b.next();while(!d.done)})};return c},"es6","es3");var CACHE="myMPD-cache-v3.3.0",urlsToCache="/ /player.html /css/bootstrap.min.css /css/mpd.min.css /js/bootstrap-native-v4.min.js /js/mpd.min.js /js/player.min.js /assets/appicon-167.png /assets/appicon-192.png /assets/appicon-512.png /assets/coverimage-httpstream.png /assets/coverimage-notavailable.png /assets/favicon.ico /assets/MaterialIcons-Regular.eot /assets/MaterialIcons-Regular.ttf /assets/MaterialIcons-Regular.woff /assets/MaterialIcons-Regular.woff2".split(" "); | ||||
| c){for(var d=$jscomp.makeIterator(a),e=d.next();!e.done;e=d.next())f(e.value).callWhenSettled_(b,c)})};c.all=function(a){var b=$jscomp.makeIterator(a),d=b.next();return d.done?f([]):new c(function(a,c){function e(b){return function(c){g[b]=c;h--;0==h&&a(g)}}var g=[],h=0;do g.push(void 0),h++,f(d.value).callWhenSettled_(e(g.length-1),c),d=b.next();while(!d.done)})};return c},"es6","es3");var CACHE="myMPD-cache-v3.4.0",urlsToCache="/ /player.html /css/bootstrap.min.css /css/mpd.min.css /js/bootstrap-native-v4.min.js /js/mpd.min.js /js/player.min.js /assets/appicon-167.png /assets/appicon-192.png /assets/appicon-512.png /assets/coverimage-httpstream.png /assets/coverimage-notavailable.png /assets/favicon.ico /assets/MaterialIcons-Regular.eot /assets/MaterialIcons-Regular.ttf /assets/MaterialIcons-Regular.woff /assets/MaterialIcons-Regular.woff2".split(" "); | ||||
| self.addEventListener("install",function(a){a.waitUntil(caches.open(CACHE).then(function(a){return a.addAll(urlsToCache)}))});self.addEventListener("fetch",function(a){a.respondWith(caches.match(a.request).then(function(b){return b?b:fetch(a.request)}))});self.addEventListener("activate",function(a){a.waitUntil(caches.keys().then(function(a){return Promise.all(a.map(function(a){if(a!=CACHE)return caches.delete(a)}))}))}); | ||||
|   | ||||
| @@ -176,7 +176,6 @@ main { | ||||
| } | ||||
|  | ||||
| a.card-img-top { | ||||
|  height:250px; | ||||
|  overflow:hidden; | ||||
|  display:block; | ||||
| } | ||||
|   | ||||
| @@ -23,12 +23,12 @@ | ||||
|             <span class="material-icons header-logo">play_circle_outline</span>myMPD | ||||
|           </a> | ||||
|           <div class="dropdown-menu bg-dark"> | ||||
|             <a id="nav-addstream" class="dropdown-item text-light bg-dark" href="#" data-toggle="modal" data-target="#modalAddstream">Add Stream</a> | ||||
|             <a id="nav-addstream" class="dropdown-item text-light bg-dark" href="#" data-href="{'cmd':'showAddToPlaylist','options':['stream']}">Add Stream</a> | ||||
|             <a id="nav-updatedb" class="dropdown-item text-light bg-dark" href="#" data-href="{'cmd':'updateDB','options':[]}">Update Database</a> | ||||
|             <a id="nav-localplayer" class="dropdown-item text-light bg-dark" href="#" data-href="{'cmd':'openLocalPlayer','options':[]}">Local Player</a> | ||||
|             <a id="nav-settings" class="dropdown-item text-light bg-dark" href="#" data-toggle="modal" data-target="#modalSettings">Settings</a> | ||||
|             <a id="nav-about" class="dropdown-item text-light bg-dark" href="#" data-toggle="modal" data-target="#modalAbout">About</a> | ||||
|             <a id="btnAdd" class="dropdown-item text-light bg-dark hide" href="#">Add2HomeScreen</a> | ||||
|             <a id="nav-add2homescreen" class="dropdown-item text-light bg-dark hide" href="#">Add2HomeScreen</a> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="btn-toolbar col-auto pl-0 pr-0" role="toolbar"> | ||||
| @@ -76,9 +76,9 @@ | ||||
|       <div class="card-header">Playback</div> | ||||
|       <div class="card-body"> | ||||
|         <div class="album-cover" id="album-cover"></div> | ||||
|         <h1 id="currenttrack"></h1> | ||||
|         <h3 id="artist"></h3> | ||||
|         <h4 id="album"></h4> | ||||
|         <h1 id="currentTrack" data-href="{'cmd': 'songClick', 'options': []}"></h1> | ||||
|         <h3 id="currentArtist" data-href="{'cmd': 'artistClick', 'options': []}"></h3> | ||||
|         <h4 id="currentAlbum"></h4> | ||||
|         <div class="row"> | ||||
|           <div class="col-8"> | ||||
|             <input type="range" min="0" max="100" step="1" class="form-control-range" id="progressBar"> | ||||
| @@ -97,17 +97,26 @@ | ||||
|       </div> | ||||
|       <div class="card-body"> | ||||
|         <div class="btn-toolbar card-toolbar" id="queue-buttons" role="toolbar"> | ||||
|           <div id="queue-actions" class="btn-group mr-2"> | ||||
|             <button type="button" class="btn btn-secondary" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_SEND_SHUFFLE'}]}" title="Shuffle queue"> | ||||
|               <span class="material-icons">shuffle</span> | ||||
|             </button> | ||||
|             <button type="button" class="btn btn-secondary" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_RM_ALL'}]}" title="Clear queue"> | ||||
|               <span class="material-icons">clear_all</span> | ||||
|             </button> | ||||
|           <div class="btn-group mr-2"> | ||||
|             <button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#modalSaveQueue" title="Save queue"> | ||||
|               <span class="material-icons">save</span> | ||||
|             </button> | ||||
|           </div> | ||||
|           <div class="btn-group mr-2"> | ||||
|             <button type="button" class="btn btn-secondary" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_SEND_SHUFFLE'}]}" title="Shuffle queue"> | ||||
|               <span class="material-icons">shuffle</span> | ||||
|             </button> | ||||
|           </div> | ||||
|           <div class="input-group mr-2"> | ||||
|             <div class="input-group-prepend"> | ||||
|               <button type="button" class="btn btn-secondary material-icons" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_QUEUE_CLEAR'}]}" title="Clear queue">clear_all</button> | ||||
|               <button id="clearQueueBtn" class="btn btn-secondary dropdown-toggle dropdown-toggle-split rounded-right" type="button" data-toggle="dropdown"></button> | ||||
|               <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="clearQueueDropdown"> | ||||
|                   <button type="button" class="btn btn-secondary btn-block" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_QUEUE_CLEAR'}]}" >Clear queue</button> | ||||
|                   <button type="button" class="btn btn-secondary btn-block" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_QUEUE_CROP'}]}" >Crop queue</button> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|           <form id="searchqueue" role="search"> | ||||
|             <div class="input-group mr-2"> | ||||
|               <input type="text" class="form-control" placeholder="Search Queue" id="searchqueuestr"/> | ||||
| @@ -126,7 +135,7 @@ | ||||
|               </div> | ||||
|             </div> | ||||
|           </form> | ||||
|           <div id="QueuePaginationTop" class="btn-group mr-2"> | ||||
|           <div id="QueuePaginationTop" class="btn-group mr-2 hide"> | ||||
|             <button data-href="{'cmd': 'gotoPage', 'options': ['prev']}" id="QueuePaginationTopPrev" title="Previous Page" type="button" class="btn btn-secondary">«</button> | ||||
|               <div class="input-group-append"> | ||||
|                 <button id="QueuePaginationTopPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">1 / 1</button> | ||||
| @@ -159,7 +168,7 @@ | ||||
|             </tbody> | ||||
|           </table> | ||||
|         </div> | ||||
|         <div class="btn-toolbar" id="QueueButtonsBottom" role="toolbar"> | ||||
|         <div class="btn-toolbar hide" id="QueueButtonsBottom" role="toolbar"> | ||||
|           <div class="btn-group mr-2"> | ||||
|             <button type="button" class="btn btn-secondary" data-href="{'cmd':'scrollTo','options':[0]}" title="To top"> | ||||
|               <span class="material-icons">keyboard_arrow_up</span> | ||||
| @@ -208,7 +217,7 @@ | ||||
|             <div class="dropdown-menu bg-dark px-2 letters" id="BrowsePlaylistsFilterLetters"> | ||||
|             </div> | ||||
|           </div>         | ||||
|           <div id="BrowsePlaylistsPaginationTop" class="btn-group mr-2"> | ||||
|           <div id="BrowsePlaylistsPaginationTop" class="btn-group mr-2 hide"> | ||||
|             <button data-href="{'cmd': 'gotoPage', 'options': ['prev']}" id="BrowsePlaylistsPaginationTopPrev" title="Previous Page" type="button" class="btn btn-secondary">«</button> | ||||
|               <div class="input-group-append"> | ||||
|                 <button id="BrowsePlaylistsPaginationTopPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">1 / 1</button> | ||||
| @@ -257,7 +266,7 @@ | ||||
|             </tbody> | ||||
|           </table>           | ||||
|         </div> | ||||
|         <div class="btn-toolbar" id="BrowsePlaylistsButtonsBottom" role="toolbar"> | ||||
|         <div class="btn-toolbar hide" id="BrowsePlaylistsButtonsBottom" role="toolbar"> | ||||
|           <div class="btn-group mr-2"> | ||||
|             <button type="button" class="btn btn-secondary" data-href="{'cmd': 'scrollTo', 'options': [0]}" title="To top"> | ||||
|               <span class="material-icons">keyboard_arrow_up</span> | ||||
| @@ -285,7 +294,7 @@ | ||||
|             <div class="dropdown-menu bg-dark px-2 letters" id="BrowseDatabaseFilterLetters"> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div id="BrowseDatabasePaginationTop" class="btn-group mr-2"> | ||||
|           <div id="BrowseDatabasePaginationTop" class="btn-group mr-2 hide"> | ||||
|             <button data-href="{'cmd': 'gotoPage', 'options': ['prev']}" id="BrowseDatabasePaginationTopPrev" title="Previous Page" type="button" class="btn btn-secondary">«</button> | ||||
|               <div class="input-group-append"> | ||||
|                 <button id="BrowseDatabasePaginationTopPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">1 / 1</button> | ||||
| @@ -313,9 +322,9 @@ | ||||
|           </table> | ||||
|         </div> | ||||
|          | ||||
|         <div id="BrowseDatabaseAlbumCards" class="row hide"></div> | ||||
|         <div id="BrowseDatabaseAlbumList" class="row hide"></div> | ||||
|          | ||||
|         <div class="btn-toolbar" id="BrowseDatabaseButtonsBottom" role="toolbar"> | ||||
|         <div class="btn-toolbar hide" id="BrowseDatabaseButtonsBottom" role="toolbar"> | ||||
|           <div class="btn-group mr-2"> | ||||
|             <button type="button" class="btn btn-secondary" data-href="{'cmd': 'scrollTo', 'options': [0]}" title="To top"> | ||||
|               <span class="material-icons">keyboard_arrow_up</span> | ||||
| @@ -336,15 +345,22 @@ | ||||
|  | ||||
|       <div class="card-body hide" id="cardBrowseFilesystem"> | ||||
|         <div class="btn-toolbar card-toolbar" id="BrowseFilesystemButtons" role="toolbar"> | ||||
|           <div class="btn-group mr-2 pull-right"> | ||||
|             <button data-href="{'cmd': 'addAllFromBrowse', 'options': []}" id="BrowseFilesystemAddAllSongs" class="btn btn-secondary">Add all</button> | ||||
|           </div> | ||||
|           <div class="btn-group mr-2"> | ||||
|             <button id="BrowseFilesystemFilter" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Filter</button> | ||||
|             <div class="dropdown-menu bg-dark px-2 letters" id="BrowseFilesystemFilterLetters"> | ||||
|             </div> | ||||
|           </div>           | ||||
|           <div id="BrowseFilesystemPaginationTop" class="btn-group mr-2"> | ||||
|           <div class="input-group mr-2"> | ||||
|             <div class="input-group-prepend"> | ||||
|               <button data-href="{'cmd': 'addAllFromBrowse', 'options': []}" id="BrowseFilesystemAddAllSongs" class="btn btn-secondary">Add all</button> | ||||
|               <button id="BrowseFilesystemAddAllSongsBtn" class="btn btn-secondary dropdown-toggle dropdown-toggle-split rounded-right" type="button" data-toggle="dropdown"></button> | ||||
|               <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="BrowseFilesystemAddAllSongsDropdown"> | ||||
|                 <button type="button" class="btn btn-secondary btn-block">Add all to queue</button> | ||||
|                 <button type="button" class="btn btn-secondary btn-block">Add all to playlist</button> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div id="BrowseFilesystemPaginationTop" class="btn-group mr-2 hide"> | ||||
|             <button data-href="{'cmd': 'gotoPage', 'options': ['prev']}" id="BrowseFilesystemPaginationTopPrev" title="Previous Page" type="button" class="btn btn-secondary">«</button> | ||||
|               <div class="input-group-append"> | ||||
|                 <button id="BrowseFilesystemPaginationTopPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">1 / 1</button> | ||||
| @@ -380,7 +396,7 @@ | ||||
|             </tbody> | ||||
|           </table> | ||||
|         </div> | ||||
|         <div class="btn-toolbar" id="BrowseFilesystemButtonsBottom" role="toolbar"> | ||||
|         <div class="btn-toolbar hide" id="BrowseFilesystemButtonsBottom" role="toolbar"> | ||||
|           <div class="btn-group mr-2"> | ||||
|             <button type="button" class="btn btn-secondary" data-href="{'cmd': 'scrollTo', 'options': [0]}" title="To top"> | ||||
|               <span class="material-icons">keyboard_arrow_up</span> | ||||
| @@ -423,10 +439,17 @@ | ||||
|               </div> | ||||
|             </div> | ||||
|           </form> | ||||
|           <div class="btn-group mr-2 pull-right"> | ||||
|           <div class="input-group mr-2"> | ||||
|             <div class="input-group-prepend"> | ||||
|               <button id="searchAddAllSongs" class="btn btn-secondary" data-href="{'cmd': 'addAllFromSearch', 'options': []}">Add all</button> | ||||
|               <button id="searchAddAllSongsBtn" class="btn btn-secondary dropdown-toggle dropdown-toggle-split rounded-right" type="button" data-toggle="dropdown"></button> | ||||
|               <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchAddAllSongsDropdown"> | ||||
|                   <button type="button" class="btn btn-secondary btn-block">Add all to queue</button> | ||||
|                   <button type="button" class="btn btn-secondary btn-block">Add all to playlist</button> | ||||
|               </div> | ||||
|           <div id="AearchPaginationTop" class="btn-group mr-2"> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div id="SearchPaginationTop" class="btn-group mr-2 hide"> | ||||
|             <button data-href="{'cmd': 'gotoPage', 'options': ['prev']}" id="SearchPaginationTopPrev" title="Previous Page" type="button" class="btn btn-secondary">«</button> | ||||
|               <div class="input-group-append"> | ||||
|                 <button id="SearchPaginationTopPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">1 / 1</button> | ||||
| @@ -458,7 +481,7 @@ | ||||
|             </tbody> | ||||
|           </table> | ||||
|         </div> | ||||
|         <div class="btn-toolbar" id="SearchButtonsBottom" role="toolbar"> | ||||
|         <div class="btn-toolbar hide" id="SearchButtonsBottom" role="toolbar"> | ||||
|           <div class="btn-group mr-2"> | ||||
|             <button type="button" class="btn btn-secondary" data-href="{'cmd': 'scrollTo', 'options': [0]}" title="To top"> | ||||
|               <span class="material-icons">keyboard_arrow_up</span> | ||||
| @@ -490,7 +513,7 @@ | ||||
|   </footer> | ||||
|  | ||||
|   <!-- Modals --> | ||||
|   <div class="modal fade" id="modalConnectionError" role="dialog"> | ||||
|   <div class="modal fade" id="modalConnectionError" tabindex="-1" role="dialog"> | ||||
|     <div class="modal-dialog" role="document"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header bg-danger text-light"> | ||||
| @@ -503,37 +526,65 @@ | ||||
|       </div> | ||||
|   </div> | ||||
|  | ||||
|   <div class="modal fade" id="modalAddToPlaylist" role="dialog"> | ||||
|   <div class="modal fade" id="modalAddToPlaylist" tabindex="-1" 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> | ||||
|           <h5 class="modal-title"><span class="material-icons title-icon">playlist_add</span> <span id="addToPlaylistLabel">Add to playlist</span></h5> | ||||
|           <button type="button" class="close" data-dismiss="modal"> | ||||
|             <span>×</span> | ||||
|           </button> | ||||
|         </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> | ||||
|           <form id="addStreamFrm" class="needs-validation hide" novalidate> | ||||
|             <div class="row"> | ||||
|               <div class="form-group col-md-12"> | ||||
|                 <label class="control-label" for="streamUrl">Stream URL</label> | ||||
|                 <input type="text" class="form-control" id="streamUrl" placeholder="http://uri.to/stream.mp3"/> | ||||
|                 <div class="invalid-feedback">Invalid uri</div> | ||||
|               </div> | ||||
|               <select id="addToPlaylistPlaylist" class="form-control custom-select border-secondary"> | ||||
|               </select> | ||||
|             </div> | ||||
|             <div class="row"> | ||||
|               <div class="form-group col-md-12"> | ||||
|                 <button id="toggleAddToPlaylistBtn" class="btn btn-secondary" data-href="{'cmd': 'toggleAddToPlaylistFrm', 'options':[]}">Add to playlist</button> | ||||
|               </div> | ||||
|             </div> | ||||
|           </form>         | ||||
|  | ||||
|           <form class="needs-validation hide" id="addToPlaylistFrm" novalidate> | ||||
|             <input type="hidden" id="addToPlaylistUri"/> | ||||
|             <div class="form-group"> | ||||
|               <label for="addToPlaylistPlaylist">Playlist</label> | ||||
|               <select id="addToPlaylistPlaylist" class="form-control custom-select"></select> | ||||
|               <div class="invalid-feedback">Please choose playlist.</div> | ||||
|             </div> | ||||
|             <div class="form-group hide" id="addToPlaylistNewPlaylistDiv"> | ||||
|               <label for="addToPlaylistNewPlaylist">Create Playlist</label> | ||||
|               <input id="addToPlaylistNewPlaylist" class="form-control"/> | ||||
|               <div class="invalid-feedback">Invalid filename.</div> | ||||
|             </div> | ||||
|           </form> | ||||
|         </div> | ||||
|         <div class="modal-footer"> | ||||
|         <div class="modal-footer" id="addToPlaylistFooter"> | ||||
|           <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> | ||||
|           <button type="button" class="btn btn-success" data-href="{'cmd': 'addToPlaylist', 'options': []}">Add</button> | ||||
|         </div> | ||||
|         <div class="modal-footer hide" id="addStreamFooter"> | ||||
|           <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> | ||||
|           <button type="button" class="btn btn-success" data-href="{'cmd': 'addStream', 'options': []}">Add</button> | ||||
|         </div>                 | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <div class="modal fade" id="modalRenamePlaylist" role="dialog"> | ||||
|   <div class="modal fade" id="modalRenamePlaylist" tabindex="-1" 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> | ||||
|           <button type="button" class="close" data-dismiss="modal"> | ||||
|             <span>×</span> | ||||
|           </button> | ||||
|         </div> | ||||
|         <div class="modal-body"> | ||||
|           <form class="needs-validation" id="renamePlaylistFrm" novalidate> | ||||
| @@ -543,7 +594,7 @@ | ||||
|             </div> | ||||
|             <div class="form-group"> | ||||
|               <label for="renamePlaylistTo">To</label> | ||||
|               <input type="text" class="form-control" id="renamePlaylistTo"> | ||||
|               <input type="text" class="form-control" id="renamePlaylistTo"/> | ||||
|               <div class="invalid-feedback">Invalid filename.</div> | ||||
|             </div> | ||||
|           </form> | ||||
| @@ -556,13 +607,13 @@ | ||||
|       </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"> | ||||
|     <div class="modal-dialog"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header"> | ||||
|           <h5 class="modal-title" id="settingsLabel"><span class="material-icons title-icon">settings</span> Settings</h5> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||
|             <span aria-hidden="true">×</span> | ||||
|           <button type="button" class="close" data-dismiss="modal"> | ||||
|             <span>×</span> | ||||
|           </button> | ||||
|         </div> | ||||
|         <div class="modal-body"> | ||||
| @@ -645,17 +696,17 @@ | ||||
|           <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> | ||||
|           <button type="button" class="btn btn-success" data-href="{'cmd': 'confirmSettings', 'options': []}">Save</button> | ||||
|         </div> | ||||
|       </div><!-- /.modal-content --> | ||||
|     </div><!-- /.modal-dialog --> | ||||
|   </div><!-- /.modal --> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|    | ||||
|   <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"> | ||||
|     <div class="modal-dialog"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header"> | ||||
|           <h5 class="modal-title" id="aboutLabel"><span class="material-icons title-icon">play_circle_outline</span> About</h5> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||
|             <span aria-hidden="true">×</span> | ||||
|           <button type="button" class="close" data-dismiss="modal"> | ||||
|             <span>×</span> | ||||
|           </button> | ||||
|         </div> | ||||
|         <div class="modal-body"> | ||||
| @@ -682,45 +733,17 @@ | ||||
|             </tbody> | ||||
|           </table>           | ||||
|         </div> | ||||
|       </div><!-- /.modal-content --> | ||||
|     </div><!-- /.modal-dialog --> | ||||
|   </div><!-- /.modal --> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <div class="modal fade" id="modalAddstream" tabindex="-1" role="dialog" aria-labelledby="addstreamLabel" aria-hidden="true"> | ||||
|     <div class="modal-dialog"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header"> | ||||
|           <h5 class="modal-title" id="addstreamLabel"><span class="material-icons title-icon">view_stream</span> Add Stream</h5> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||
|             <span aria-hidden="true">×</span> | ||||
|           </button> | ||||
|         </div> | ||||
|         <div class="modal-body"> | ||||
|           <form id="addStreamFrm" class="needs-validation" novalidate> | ||||
|             <div class="row"> | ||||
|               <div class="form-group col-md-12"> | ||||
|                 <label class="control-label" for="streamUrl">Stream URL</label> | ||||
|                 <input type="text" class="form-control" id="streamUrl" placeholder="http://uri.to/stream.mp3"/> | ||||
|                 <div class="invalid-feedback">Invalid uri</div> | ||||
|               </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': 'addStream', 'options': []}">Add Stream</button> | ||||
|         </div> | ||||
|       </div><!-- /.modal-content --> | ||||
|     </div><!-- /.modal-dialog --> | ||||
|   </div><!-- /.modal --> | ||||
|  | ||||
|   <div class="modal fade" id="modalSaveQueue" tabindex="-1" role="dialog" aria-hidden="true"> | ||||
|   <div class="modal fade" id="modalSaveQueue" tabindex="-1" role="dialog"> | ||||
|     <div class="modal-dialog"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header"> | ||||
|           <h5 class="modal-title"><span class="material-icons title-icon">save</span> Save Queue</h5> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||
|             <span aria-hidden="true">×</span> | ||||
|           <button type="button" class="close" data-dismiss="modal"> | ||||
|             <span>×</span> | ||||
|           </button>           | ||||
|         </div> | ||||
|         <div class="modal-body"> | ||||
| @@ -738,17 +761,17 @@ | ||||
|           <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> | ||||
|           <button type="button" class="btn btn-success" data-href="{'cmd': 'saveQueue', 'options': []}">Save Queue</button> | ||||
|         </div> | ||||
|       </div><!-- /.modal-content --> | ||||
|     </div><!-- /.modal-dialog --> | ||||
|   </div><!-- /.modal --> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <div class="modal fade" id="modalSongDetails" tabindex="-1" role="dialog" aria-hidden="true"> | ||||
|   <div class="modal fade" id="modalSongDetails" tabindex="-1" role="dialog"> | ||||
|     <div class="modal-dialog"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header"> | ||||
|           <h5 class="modal-title"><span class="material-icons title-icon">music_note</span> Song Details</h5> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||
|             <span aria-hidden="true">×</span> | ||||
|           <button type="button" class="close" data-dismiss="modal"> | ||||
|             <span>×</span> | ||||
|           </button>           | ||||
|         </div> | ||||
|         <div class="modal-body"> | ||||
| @@ -769,9 +792,9 @@ | ||||
|         <div class="modal-footer"> | ||||
|           <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> | ||||
|         </div> | ||||
|       </div><!-- /.modal-content --> | ||||
|     </div><!-- /.modal-dialog --> | ||||
|   </div><!-- /.modal --> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <script src="js/bootstrap-native-v4.min.js"></script> | ||||
|   <script src="js/mpd.js"></script> | ||||
|   | ||||
							
								
								
									
										209
									
								
								htdocs/js/mpd.js
									
									
									
									
									
								
							
							
						
						
									
										209
									
								
								htdocs/js/mpd.js
									
									
									
									
									
								
							| @@ -74,11 +74,11 @@ domCache.btnNext = document.getElementById('btnNext'); | ||||
| domCache.progressBar = document.getElementById('progressBar'); | ||||
| domCache.volumeBar = document.getElementById('volumeBar'); | ||||
| domCache.outputs = document.getElementById('outputs'); | ||||
| domCache.btnAdd = document.getElementById('btnAdd'); | ||||
| domCache.btnAdd = document.getElementById('nav-add2homescreen'); | ||||
| domCache.currentTrack = document.getElementById('currentTrack'); | ||||
|  | ||||
| var modalConnectionError = new Modal(document.getElementById('modalConnectionError')); | ||||
| var modalSettings = new Modal(document.getElementById('modalSettings')); | ||||
| var modalAddstream = new Modal(document.getElementById('modalAddstream')); | ||||
| var modalSavequeue = new Modal(document.getElementById('modalSaveQueue')); | ||||
| var modalSongDetails = new Modal(document.getElementById('modalSongDetails')); | ||||
| var modalAddToPlaylist = new Modal(document.getElementById('modalAddToPlaylist')); | ||||
| @@ -213,10 +213,14 @@ function appRoute() { | ||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Filesystem') { | ||||
|         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 | ||||
|         if (app.current.search) | ||||
|         if (app.current.search) { | ||||
|             document.getElementById('BrowseFilesystemAddAllSongs').removeAttribute('disabled'); | ||||
|         else | ||||
|             document.getElementById('BrowseFilesystemAddAllSongs').setAttribute('disabled', 'disabled') | ||||
|             document.getElementById('BrowseFilesystemAddAllSongsBtn').removeAttribute('disabled'); | ||||
|         } | ||||
|         else { | ||||
|             document.getElementById('BrowseFilesystemAddAllSongs').setAttribute('disabled', 'disabled'); | ||||
|             document.getElementById('BrowseFilesystemAddAllSongsBtn').setAttribute('disabled', 'disabled'); | ||||
|         } | ||||
|         // Create breadcrumb | ||||
|         var breadcrumbs='<li class="breadcrumb-item"><a data-uri="">root</a></li>'; | ||||
|         var pathArray = app.current.search.split('/'); | ||||
| @@ -256,6 +260,7 @@ function appRoute() { | ||||
|         } else { | ||||
|             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); | ||||
| @@ -319,21 +324,25 @@ function appInit() { | ||||
|         document.getElementById('inputMixrampdelay').classList.remove('is-invalid'); | ||||
|     }); | ||||
|  | ||||
|     document.getElementById('modalAddstream').addEventListener('shown.bs.modal', function () { | ||||
|         var streamUrl = document.getElementById('streamUrl') | ||||
|         streamUrl.focus(); | ||||
|         streamUrl.value = ''; | ||||
|         streamUrl.classList.remove('is-invalid'); | ||||
|         document.getElementById('addStreamFrm').classList.remove('was-validated'); | ||||
|     }); | ||||
|  | ||||
|     document.getElementById('addToPlaylistPlaylist').addEventListener('change',function(event) { | ||||
|         if (this.options[this.selectedIndex].text == 'New Playlist') { | ||||
|             document.getElementById('addToPlaylistNewPlaylistDiv').classList.remove('hide'); | ||||
|             document.getElementById('addToPlaylistNewPlaylist').focus(); | ||||
|         } | ||||
|         else { | ||||
|             document.getElementById('addToPlaylistNewPlaylistDiv').classList.add('hide'); | ||||
|         } | ||||
|     }, false); | ||||
|      | ||||
|     addFilterLetter('BrowseFilesystemFilterLetters'); | ||||
|     addFilterLetter('BrowseDatabaseFilterLetters'); | ||||
|     addFilterLetter('BrowsePlaylistsFilterLetters'); | ||||
|  | ||||
|     var hrefs = document.querySelectorAll('button[data-href], a[data-href]'); | ||||
|     var hrefs = document.querySelectorAll('[data-href]'); | ||||
|     var hrefsLen = hrefs.length; | ||||
|     for (var i = 0; i < hrefsLen; i++) { | ||||
|         hrefs[i].classList.add('clickable'); | ||||
|         hrefs[i].addEventListener('click', function(event) { | ||||
|             event.preventDefault(); | ||||
|             event.stopPropagation(); | ||||
| @@ -432,6 +441,28 @@ function appInit() { | ||||
|         } | ||||
|     }, false); | ||||
|  | ||||
|     document.getElementById('BrowseFilesystemAddAllSongsDropdown').addEventListener('click', function(event) { | ||||
|         if (event.target.nodeName == 'BUTTON') { | ||||
|             if (event.target.innerText == 'Add all to queue') { | ||||
|                 addAllFromBrowse(); | ||||
|             } | ||||
|             else if (event.target.innerText == 'Add all to playlist') { | ||||
|                 showAddToPlaylist(app.current.search);                 | ||||
|             } | ||||
|         } | ||||
|     }, false); | ||||
|  | ||||
|     document.getElementById('searchAddAllSongsDropdown').addEventListener('click', function(event) { | ||||
|         if (event.target.nodeName == 'BUTTON') { | ||||
|             if (event.target.innerText == 'Add all to queue') { | ||||
|                 addAllFromSearch(); | ||||
|             } | ||||
|             else if (event.target.innerText == 'Add all to playlist') { | ||||
|                 showAddToPlaylist('SEARCH');                 | ||||
|             } | ||||
|         } | ||||
|     }, false); | ||||
|  | ||||
|     document.getElementById('searchtags').addEventListener('click', function(event) { | ||||
|         if (event.target.nodeName == 'BUTTON') | ||||
|             appGoto(app.current.app, app.current.tab, app.current.view, '0/' + event.target.innerText + '/' + app.current.search);             | ||||
| @@ -947,10 +978,14 @@ function parseSearch(obj) { | ||||
|     if (app.current.app !== 'Search') | ||||
|         return; | ||||
|     document.getElementById('panel-heading-search').innerHTML = obj.totalEntities + ' Songs found'; | ||||
|     if (obj.totalEntities > 0) | ||||
|     if (obj.totalEntities > 0) { | ||||
|         document.getElementById('searchAddAllSongs').removeAttribute('disabled'); | ||||
|     else | ||||
|         document.getElementById('searchAddAllSongsBtn').removeAttribute('disabled'); | ||||
|     }  | ||||
|     else { | ||||
|         document.getElementById('searchAddAllSongs').setAttribute('disabled','disabled'); | ||||
|         document.getElementById('searchAddAllSongsBtn').setAttribute('disabled','disabled'); | ||||
|     } | ||||
|     parseFilesystem(obj); | ||||
| } | ||||
|  | ||||
| @@ -1108,7 +1143,7 @@ function parseListDBtags(obj) { | ||||
|     if (app.current.app !== 'Browse' && app.current.tab !== 'Database' && app.current.view !== 'Artist') return; | ||||
|    | ||||
|     if (obj.tagtype == 'AlbumArtist') { | ||||
|         document.getElementById('BrowseDatabaseAlbumCards').classList.add('hide'); | ||||
|         document.getElementById('BrowseDatabaseAlbumList').classList.add('hide'); | ||||
|         document.getElementById('BrowseDatabaseArtistList').classList.remove('hide'); | ||||
|         document.getElementById('btnBrowseDatabaseArtist').parentNode.classList.add('hide'); | ||||
|         var nrItems = obj.data.length; | ||||
| @@ -1143,11 +1178,11 @@ function parseListDBtags(obj) { | ||||
|         document.getElementById('BrowseDatabaseArtistList').classList.remove('opacity05');                               | ||||
|                                 | ||||
|     } else if (obj.tagtype == 'Album') { | ||||
|         document.getElementById('BrowseDatabaseAlbumCards').classList.remove('hide'); | ||||
|         document.getElementById('BrowseDatabaseAlbumList').classList.remove('hide'); | ||||
|         document.getElementById('BrowseDatabaseArtistList').classList.add('hide'); | ||||
|         document.getElementById('btnBrowseDatabaseArtist').parentNode.classList.remove('hide');     | ||||
|         var nrItems = obj.data.length; | ||||
|         var cardContainer = document.getElementById('BrowseDatabaseAlbumCards'); | ||||
|         var cardContainer = document.getElementById('BrowseDatabaseAlbumList'); | ||||
|         var cards = cardContainer.querySelectorAll('.col-md'); | ||||
|         for (var i = 0; i < nrItems; i++) { | ||||
|             var id=genId(obj.data[i].value); | ||||
| @@ -1179,7 +1214,7 @@ function parseListDBtags(obj) { | ||||
|             cards[i].remove(); | ||||
|         } | ||||
|         setPagination(obj.totalEntities); | ||||
|         document.getElementById('BrowseDatabaseAlbumCards').classList.remove('opacity05');         | ||||
|         document.getElementById('BrowseDatabaseAlbumList').classList.remove('opacity05');         | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -1245,14 +1280,17 @@ function setPagination(number) { | ||||
|      | ||||
|         if (number > app.current.page + settings.max_elements_per_page) { | ||||
|             document.getElementById(cat + p[i] + 'Next').removeAttribute('disabled'); | ||||
|             document.getElementById(cat + p[i]).classList.remove('hide'); | ||||
|             document.getElementById(cat + 'ButtonsBottom').classList.remove('hide'); | ||||
|         } else { | ||||
|             document.getElementById(cat + p[i] + 'Next').setAttribute('disabled', 'disabled'); | ||||
|             document.getElementById(cat + p[i]).classList.add('hide'); | ||||
|             document.getElementById(cat + 'ButtonsBottom').classList.add('hide'); | ||||
|         } | ||||
|      | ||||
|         if (app.current.page > 0) { | ||||
|             document.getElementById(cat + p[i] + 'Prev').removeAttribute('disabled'); | ||||
|             document.getElementById(cat + p[i]).classList.remove('hide'); | ||||
|             document.getElementById(cat + 'ButtonsBottom').classList.remove('hide'); | ||||
|         } else { | ||||
|             document.getElementById(cat + p[i] + 'Prev').setAttribute('disabled', 'disabled'); | ||||
| @@ -1303,6 +1341,14 @@ function replaceQueue(type, uri, name) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| function songClick() { | ||||
|     songDetails(domCache.currentTrack.getAttribute('data-uri')); | ||||
| } | ||||
|  | ||||
| function artistClick() { | ||||
|     appGoto('Browse', 'Database', 'Album', '0/-/' + document.getElementById('currentArtist').innerText); | ||||
| } | ||||
|  | ||||
| function songDetails(uri) { | ||||
|     sendAPI({"cmd": "MPD_API_GET_SONGDETAILS", "data": {"uri": uri}}, parseSongDetails); | ||||
|     modalSongDetails.show(); | ||||
| @@ -1334,6 +1380,7 @@ function playlistDetails(uri) { | ||||
| } | ||||
|  | ||||
| function removeFromPlaylist(uri, pos) { | ||||
|     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); | ||||
| @@ -1348,7 +1395,7 @@ function playlistClear() { | ||||
|  | ||||
| function getAllPlaylists(obj) { | ||||
|     var nrItems = obj.data.length; | ||||
|     var playlists = ''; | ||||
|     var playlists = '<option></option><option>New Playlist</option>'; | ||||
|     for (var i = 0; i < nrItems; i++) { | ||||
|         playlists += '<option>' + obj.data[i].uri + '</option>'; | ||||
|     } | ||||
| @@ -1359,20 +1406,98 @@ function getAllPlaylists(obj) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| function toggleAddToPlaylistFrm() { | ||||
|     var btn = document.getElementById('toggleAddToPlaylistBtn'); | ||||
|     toggleBtn('toggleAddToPlaylistBtn'); | ||||
|     if (btn.classList.contains('active')) { | ||||
|         document.getElementById('addToPlaylistFrm').classList.remove('hide'); | ||||
|         document.getElementById('addStreamFooter').classList.add('hide'); | ||||
|         document.getElementById('addToPlaylistFooter').classList.remove('hide'); | ||||
|     }     | ||||
|     else { | ||||
|         document.getElementById('addToPlaylistFrm').classList.add('hide'); | ||||
|         document.getElementById('addStreamFooter').classList.remove('hide'); | ||||
|         document.getElementById('addToPlaylistFooter').classList.add('hide'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function showAddToPlaylist(uri) { | ||||
|     modalAddToPlaylist.show(); | ||||
|     document.getElementById('addToPlaylistUri').value = uri; | ||||
|     document.getElementById('addToPlaylistPlaylist').innerHTML = ''; | ||||
|     document.getElementById('addToPlaylistNewPlaylistDiv').classList.add('hide'); | ||||
|     document.getElementById('addToPlaylistFrm').classList.remove('was-validated'); | ||||
|     document.getElementById('addToPlaylistNewPlaylist').classList.remove('is-invalid'); | ||||
|     toggleBtn('toggleAddToPlaylistBtn',0); | ||||
|     var streamUrl = document.getElementById('streamUrl') | ||||
|     streamUrl.focus(); | ||||
|     streamUrl.value = ''; | ||||
|     streamUrl.classList.remove('is-invalid'); | ||||
|     document.getElementById('addStreamFrm').classList.remove('was-validated'); | ||||
|     if (uri != 'stream') { | ||||
|         document.getElementById('addStreamFooter').classList.add('hide'); | ||||
|         document.getElementById('addStreamFrm').classList.add('hide'); | ||||
|         document.getElementById('addToPlaylistFooter').classList.remove('hide'); | ||||
|         document.getElementById('addToPlaylistFrm').classList.remove('hide'); | ||||
|         document.getElementById('addToPlaylistLabel').innerText = 'Add to playlist'; | ||||
|     } else { | ||||
|         document.getElementById('addStreamFooter').classList.remove('hide'); | ||||
|         document.getElementById('addStreamFrm').classList.remove('hide'); | ||||
|         document.getElementById('addToPlaylistFooter').classList.add('hide'); | ||||
|         document.getElementById('addToPlaylistFrm').classList.add('hide'); | ||||
|         document.getElementById('addToPlaylistLabel').innerText = 'Add Stream'; | ||||
|     } | ||||
|     modalAddToPlaylist.show();     | ||||
|     sendAPI({"cmd":"MPD_API_GET_PLAYLISTS","data": {"offset": 0, "filter": "-"}}, getAllPlaylists); | ||||
| } | ||||
|  | ||||
| function addToPlaylist() { | ||||
|     var uri = document.getElementById('addToPlaylistUri').value; | ||||
|     if (uri == 'stream') { | ||||
|         uri = document.getElementById('streamUrl').value; | ||||
|         if (uri == '' || uri.indexOf('http') == -1) { | ||||
|             document.getElementById('streamUrl').classList.add('is-invalid'); | ||||
|             document.getElementById('addStreamFrm').classList.add('was-validated'); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     var plistEl = document.getElementById('addToPlaylistPlaylist'); | ||||
|     var plist = plistEl.options[plistEl.selectedIndex].text; | ||||
|     if (plist == 'New Playlist') { | ||||
|         var newPl = document.getElementById('addToPlaylistNewPlaylist').value; | ||||
|         var valid = newPl.replace(/\w/g,''); | ||||
|         if (newPl != '' && valid == '') { | ||||
|             plist = newPl; | ||||
|         } else { | ||||
|             document.getElementById('addToPlaylistNewPlaylist').classList.add('is-invalid'); | ||||
|             document.getElementById('addToPlaylistFrm').classList.add('was-validated'); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     if (plist != '') { | ||||
|         if (uri != 'SEARCH')  | ||||
|             sendAPI({"cmd": "MPD_API_ADD_TO_PLAYLIST", "data": {"uri": uri, "plist": plist}}); | ||||
|         else | ||||
|             addAllFromSearchPlist(plist);             | ||||
|         modalAddToPlaylist.hide(); | ||||
|     } | ||||
|     else { | ||||
|         document.getElementById('addToPlaylistPlaylist').classList.add('is-invalid'); | ||||
|         document.getElementById('addToPlaylistFrm').classList.add('was-validated'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function addStream() { | ||||
|     var streamUrl = document.getElementById('streamUrl').value; | ||||
|     if (streamUrl != '' && streamUrl.indexOf('http') == 0) { | ||||
|         sendAPI({"cmd": "MPD_API_ADD_TRACK", "data": {"uri": streamUrl}}); | ||||
|         modalAddToPlaylist.hide(); | ||||
|         showNotification('Added stream ' + streamUrl + 'to queue', '', '', 'success'); | ||||
|     } | ||||
|     else { | ||||
|         document.getElementById('streamUrl').classList.add('is-invalid'); | ||||
|         document.getElementById('addStreamFrm').classList.add('was-validated'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function showRenamePlaylist(from) { | ||||
|     document.getElementById('renamePlaylistFrm').classList.remove('was-validated'); | ||||
| @@ -1444,7 +1569,8 @@ function showMenu(el) { | ||||
|             ( 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>' : ''); | ||||
|             el.parentNode.parentNode.getAttribute('data-songpos') + '\']}">Remove</a>' : '') + | ||||
|             ( type != 'plist' ? '<div class="dropdown-divider"></div><a class="dropdown-item" href="#" data-href="{\'cmd\': \'showAddToPlaylist\', \'options\': [\'' + uri + '\']}">Add to playlist</a>' : ''); | ||||
|     } | ||||
|     else if (app.current.app == 'Queue') { | ||||
|         menu += '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delQueueSong\', \'options\': [\'single\',' +  | ||||
| @@ -1544,7 +1670,7 @@ function delQueueSong(mode, start, end) { | ||||
|  | ||||
| function delPlaylist(uri) { | ||||
|     sendAPI({"cmd": "MPD_API_RM_PLAYLIST", "data": {"uri": uri}}); | ||||
|     document.getElementById('BrowsePlaylistsAllList').querySelector('tr[data-uri=' + encodeURI(uri) + ']').remove(); | ||||
|     sendAPI({"cmd":"MPD_API_GET_PLAYLISTS","data": {"offset": app.current.page, "filter": app.current.filter}}, parsePlaylists);     | ||||
| } | ||||
|  | ||||
| function confirmSettings() { | ||||
| @@ -1612,6 +1738,17 @@ function addAllFromSearch() { | ||||
|     } | ||||
| } | ||||
|  | ||||
| function addAllFromSearchPlist(plist) { | ||||
|     if (app.current.search.length >= 2) { | ||||
|         var filter = app.current.filter; | ||||
|         if (filter == 'Any Tag') | ||||
|             filter = 'any'; | ||||
|              | ||||
|         sendAPI({"cmd":"MPD_API_SEARCH_ADD_PLIST", "data":{ "plist": plist, "filter": filter, "searchstr": app.current.search}}); | ||||
|         showNotification('Added '+ parseInt(document.getElementById('panel-heading-search').innerText) +' songs from search to ' + plist, '', '', 'success'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function scrollTo(pos) { | ||||
|     document.body.scrollTop = pos; // For Safari | ||||
|     document.documentElement.scrollTop = pos; // For Chrome, Firefox, IE and Opera | ||||
| @@ -1633,17 +1770,7 @@ function gotoPage(x) { | ||||
|     appGoto(app.current.app, app.current.tab, app.current.view, app.current.page + '/' + app.current.filter + '/' + app.current.search); | ||||
| } | ||||
|  | ||||
| function addStream() { | ||||
|     var streamUrl = document.getElementById('streamUrl').value; | ||||
|     if (streamUrl != '' && streamUrl.indexOf('http') == 0) { | ||||
|         sendAPI({"cmd": "MPD_API_ADD_TRACK", "data": {"uri": streamUrl}}); | ||||
|         modalAddstream.hide(); | ||||
|     } | ||||
|     else { | ||||
|         document.getElementById('streamUrl').classList.add('is-invalid'); | ||||
|         document.getElementById('addStreamFrm').classList.add('was-validated'); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| function saveQueue() { | ||||
|     var plName = document.getElementById('saveQueueName').value; | ||||
| @@ -1720,23 +1847,25 @@ function songChange(obj) { | ||||
|         textNotification += obj.data.artist; | ||||
|         htmlNotification += obj.data.artist; | ||||
|         pageTitle += obj.data.artist + ' - '; | ||||
|         document.getElementById('artist').innerText = obj.data.artist; | ||||
|         document.getElementById('currentArtist').innerText = obj.data.artist; | ||||
|     } else { | ||||
|         document.getElementById('artist').innerText = ''; | ||||
|         document.getElementById('currentArtist').innerText = ''; | ||||
|     } | ||||
|     if (typeof obj.data.album != 'undefined' && obj.data.album.length > 0 && obj.data.album != '-') { | ||||
|         textNotification += ' - ' + obj.data.album; | ||||
|         htmlNotification += '<br/>' + obj.data.album; | ||||
|         document.getElementById('album').innerText = obj.data.album; | ||||
|         document.getElementById('currentAlbum').innerText = obj.data.album; | ||||
|     } | ||||
|     else { | ||||
|         document.getElementById('album').innerText = ''; | ||||
|         document.getElementById('currentAlbum').innerText = ''; | ||||
|     } | ||||
|     if (typeof obj.data.title != 'undefined' && obj.data.title.length > 0) { | ||||
|         pageTitle += obj.data.title; | ||||
|         document.getElementById('currenttrack').innerText = obj.data.title; | ||||
|         domCache.currentTrack.innerText = obj.data.title; | ||||
|         domCache.currentTrack.setAttribute('data-uri', obj.data.uri); | ||||
|     } else { | ||||
|         document.getElementById('currenttrack').innerText = ''; | ||||
|         domCache.currentTrack.innerText = ''; | ||||
|         domCache.currentTrack.setAttribute('data-uri', ''); | ||||
|     } | ||||
|     document.title = pageTitle; | ||||
|     //Update Artist in queue view for http streams | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| var CACHE = 'myMPD-cache-v3.3.0'; | ||||
| var CACHE = 'myMPD-cache-v3.4.0'; | ||||
| var urlsToCache = [ | ||||
|     '/', | ||||
|     '/player.html', | ||||
|   | ||||
| @@ -59,7 +59,7 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) | ||||
|     unsigned int uint_buf1, uint_buf2, uint_rc; | ||||
|     int je, int_buf, int_rc;  | ||||
|     float float_buf; | ||||
|     char *p_charbuf1, *p_charbuf2; | ||||
|     char *p_charbuf1, *p_charbuf2, *p_charbuf3; | ||||
|     struct mympd_state { int a; int b; } state = { .a = 0, .b = 0 }; | ||||
|     enum mpd_cmd_ids cmd_id; | ||||
|      | ||||
| @@ -162,10 +162,13 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) | ||||
|             mpd_run_stop(mpd.conn); | ||||
|             n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}"); | ||||
|             break; | ||||
|         case MPD_API_RM_ALL: | ||||
|         case MPD_API_QUEUE_CLEAR: | ||||
|             mpd_run_clear(mpd.conn); | ||||
|             n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}"); | ||||
|             break; | ||||
|         case MPD_API_QUEUE_CROP: | ||||
|             n = mympd_queue_crop(mpd.buf); | ||||
|             break; | ||||
|         case MPD_API_RM_TRACK: | ||||
|             je = json_scanf(msg.p, msg.len, "{ data: { track:%u } }", &uint_buf1); | ||||
|             if (je == 1) { | ||||
| @@ -403,6 +406,19 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) | ||||
|                 n = mympd_search_add(mpd.buf, p_charbuf1, p_charbuf2); | ||||
|                 free(p_charbuf1); | ||||
|                 free(p_charbuf2); | ||||
|                 if (n == 0) | ||||
|                     n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}"); | ||||
|             } | ||||
|             break; | ||||
|         case MPD_API_SEARCH_ADD_PLIST: | ||||
|             je = json_scanf(msg.p, msg.len, "{ data: { plist:%Q, filter:%Q, searchstr:%Q } }", &p_charbuf1, &p_charbuf2, &p_charbuf3); | ||||
|             if (je == 3) { | ||||
|                 n = mympd_search_add_plist(p_charbuf1, p_charbuf2, p_charbuf3); | ||||
|                 free(p_charbuf1); | ||||
|                 free(p_charbuf2); | ||||
|                 free(p_charbuf3); | ||||
|                 if (n == 0) | ||||
|                     n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}"); | ||||
|             } | ||||
|             break;             | ||||
|         case MPD_API_SEARCH: | ||||
| @@ -1265,10 +1281,9 @@ int mympd_search(char *buffer, char *mpdtagtype, unsigned int offset, char *sear | ||||
| } | ||||
|  | ||||
| int mympd_search_add(char *buffer, char *mpdtagtype, char *searchstr) { | ||||
|     int len = 0; | ||||
|     struct mpd_song *song; | ||||
|     int len; | ||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||
|     len = 0; | ||||
|  | ||||
|     if (mpd_search_add_db_songs(mpd.conn, false) == false) { | ||||
|         RETURN_ERROR_AND_RECOVER("mpd_search_add_db_songs"); | ||||
| @@ -1295,6 +1310,50 @@ int mympd_search_add(char *buffer,char *mpdtagtype, char *searchstr) { | ||||
|     return len; | ||||
| } | ||||
|  | ||||
| int mympd_search_add_plist(char *plist, char *mpdtagtype, char *searchstr) { | ||||
|     int len = 0; | ||||
|     struct mpd_pair *pair;     | ||||
|  | ||||
|     mpd_send_command(mpd.conn, "searchaddpl", plist, mpdtagtype, searchstr, NULL); | ||||
|  | ||||
|     while ((pair = mpd_recv_pair(mpd.conn)) != NULL) { | ||||
|         mpd_return_pair(mpd.conn, pair); | ||||
|     }     | ||||
|  | ||||
|     if (len > MAX_SIZE) | ||||
|         fprintf(stderr,"Buffer truncated\n"); | ||||
|     return len; | ||||
| } | ||||
|  | ||||
| int mympd_queue_crop(char *buffer) { | ||||
|     int len = 0; | ||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||
|     struct mpd_status *status = mpd_run_status(mpd.conn); | ||||
|     int length = mpd_status_get_queue_length(status) - 1; | ||||
|     int playing_song_pos = mpd_status_get_song_pos(status); | ||||
|  | ||||
|     mpd_status_free(status); | ||||
|  | ||||
|     if (length < 0) { | ||||
|         len = json_printf(&out, "{ type: error, data: %Q }", "A playlist longer than 1 song in length is required to crop."); | ||||
|     } | ||||
|     else if (mpd_status_get_state(status) == MPD_STATE_PLAY || mpd_status_get_state(status) == MPD_STATE_PAUSE) { | ||||
|         playing_song_pos++; | ||||
|         if (playing_song_pos < length) | ||||
|             mpd_run_delete_range(mpd.conn, playing_song_pos, -1); | ||||
|         playing_song_pos--; | ||||
|         if (playing_song_pos > 0 ) | ||||
|             mpd_run_delete_range(mpd.conn, 0, playing_song_pos--);             | ||||
|         len = json_printf(&out, "{ type: result, data: ok }"); | ||||
|     } else { | ||||
|         len = json_printf(&out, "{ type: error, data: %Q }", "You need to be playing to crop the playlist"); | ||||
|     } | ||||
|      | ||||
|     if (len > MAX_SIZE) | ||||
|         fprintf(stderr,"Buffer truncated\n"); | ||||
|     return len;     | ||||
| } | ||||
|  | ||||
| int mympd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr) { | ||||
|     struct mpd_song *song; | ||||
|     unsigned long entity_count = 0; | ||||
|   | ||||
| @@ -61,9 +61,11 @@ | ||||
|     X(MPD_API_SAVE_QUEUE) \ | ||||
|     X(MPD_API_RM_TRACK) \ | ||||
|     X(MPD_API_RM_RANGE) \ | ||||
|     X(MPD_API_RM_ALL) \ | ||||
|     X(MPD_API_QUEUE_CLEAR) \ | ||||
|     X(MPD_API_QUEUE_CROP) \ | ||||
|     X(MPD_API_MOVE_TRACK) \ | ||||
|     X(MPD_API_SEARCH_QUEUE) \ | ||||
|     X(MPD_API_SEARCH_ADD_PLIST) \ | ||||
|     X(MPD_API_SEARCH_ADD) \ | ||||
|     X(MPD_API_SEARCH) \ | ||||
|     X(MPD_API_SEND_MESSAGE) \ | ||||
| @@ -145,6 +147,7 @@ int mympd_put_queue(char *buffer, unsigned int offset); | ||||
| int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter); | ||||
| int mympd_search(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr); | ||||
| int mympd_search_add(char *buffer, char *mpdtagtype, char *searchstr); | ||||
| int mympd_search_add_plist(char *plist, char *mpdtagtype, char *searchstr); | ||||
| int mympd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr); | ||||
| int mympd_put_welcome(char *buffer); | ||||
| int mympd_get_stats(char *buffer); | ||||
| @@ -154,6 +157,7 @@ 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_playlist_list(char *buffer, char *uri, unsigned int offset, char *filter); | ||||
| int mympd_put_songdetails(char *buffer, char *uri); | ||||
| int mympd_queue_crop(char *buffer); | ||||
| void mympd_disconnect(); | ||||
| #endif | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jürgen Mang
					Jürgen Mang