diff --git a/contrib/archlinux.install b/contrib/archlinux.install
index 6d8430a..69b8ad8 100644
--- a/contrib/archlinux.install
+++ b/contrib/archlinux.install
@@ -66,7 +66,7 @@ post_upgrade() {
[ -f /var/lib/mympd/state/jukeboxQueueLength ] || echo -n "1" > /var/lib/mympd/state/jukeboxQueueLength
[ -f /var/lib/mympd/state/notificationPage ] || echo -n "true" > /var/lib/mympd/state/notificationPage
[ -f /var/lib/mympd/state/notificationWeb ] || echo -n "false" > /var/lib/mympd/state/notificationWeb
- [ -f /var/lib/mympd/state/colsBrowseDatabase ] || echo -n '["Track","Title"]' > /var/lib/mympd/state/colsBrowseDatabase
+ [ -f /var/lib/mympd/state/colsBrowseDatabase ] || echo -n '["Track","Title","Duration"]' > /var/lib/mympd/state/colsBrowseDatabase
[ -f /var/lib/mympd/state/colsBrowseFilesystem ] || echo -n '["Type","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowseFilesystem
[ -f /var/lib/mympd/state/colsBrowsePlaylistsDetail ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowsePlaylistsDetail
[ -f /var/lib/mympd/state/colsQueue ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsQueue
diff --git a/contrib/myMPD.spec b/contrib/myMPD.spec
index 3a5b674..db0df34 100644
--- a/contrib/myMPD.spec
+++ b/contrib/myMPD.spec
@@ -81,7 +81,7 @@ done
[ -f /var/lib/mympd/state/jukeboxQueueLength ] || echo -n "1" > /var/lib/mympd/state/jukeboxQueueLength
[ -f /var/lib/mympd/state/notificationPage ] || echo -n "true" > /var/lib/mympd/state/notificationPage
[ -f /var/lib/mympd/state/notificationWeb ] || echo -n "false" > /var/lib/mympd/state/notificationWeb
-[ -f /var/lib/mympd/state/colsBrowseDatabase ] || echo -n '["Track","Title"]' > /var/lib/mympd/state/colsBrowseDatabase
+[ -f /var/lib/mympd/state/colsBrowseDatabase ] || echo -n '["Track","Title","Duration"]' > /var/lib/mympd/state/colsBrowseDatabase
[ -f /var/lib/mympd/state/colsBrowseFilesystem ] || echo -n '["Type","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowseFilesystem
[ -f /var/lib/mympd/state/colsBrowsePlaylistsDetail ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowsePlaylistsDetail
[ -f /var/lib/mympd/state/colsQueue ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsQueue
diff --git a/debian/postinst b/debian/postinst
index 2ddc3b2..97128a0 100755
--- a/debian/postinst
+++ b/debian/postinst
@@ -61,7 +61,7 @@ fi
[ -f /var/lib/mympd/state/jukeboxQueueLength ] || echo -n "1" > /var/lib/mympd/state/jukeboxQueueLength
[ -f /var/lib/mympd/state/notificationPage ] || echo -n "true" > /var/lib/mympd/state/notificationPage
[ -f /var/lib/mympd/state/notificationWeb ] || echo -n "false" > /var/lib/mympd/state/notificationWeb
-[ -f /var/lib/mympd/state/colsBrowseDatabase ] || echo -n '["Track","Title"]' > /var/lib/mympd/state/colsBrowseDatabase
+[ -f /var/lib/mympd/state/colsBrowseDatabase ] || echo -n '["Track","Title","Duration"]' > /var/lib/mympd/state/colsBrowseDatabase
[ -f /var/lib/mympd/state/colsBrowseFilesystem ] || echo -n '["Type","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowseFilesystem
[ -f /var/lib/mympd/state/colsBrowsePlaylistsDetail ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowsePlaylistsDetail
[ -f /var/lib/mympd/state/colsQueue ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsQueue
diff --git a/dist/htdocs/css/mympd.min.css b/dist/htdocs/css/mympd.min.css
index e115f7a..5cf3f92 100644
--- a/dist/htdocs/css/mympd.min.css
+++ b/dist/htdocs/css/mympd.min.css
@@ -1 +1 @@
-html{position:relative;min-height:100%}body{margin-bottom:60px;padding-top:50px;padding-bottom:50px;background-color:#888}main{padding-top:20px}footer{position:absolute;bottom:0}button{overflow:hidden}#BrowseBreadrumb{overflow:auto;white-space:nowrap}#BrowseBreadcrumb>li>a{cursor:pointer}@media only screen and (max-width:576px){.header-logo{display:none!important}}.clickable{cursor:pointer}[data-col=Pos],[data-col=Type],[data-col=Track],[data-col=Action]{width:30px}small{color:#aaa}.card{min-height:300px}.card-footer-playback{padding:0}.album-cover{background-size:cover;background-image:url("/assets/coverimage-loading.png");border:1px solid black;border-radius:5px;overflow:hidden;width:240px;height:240px;background-color:#eee;float:left;margin-right:20px;margin-bottom:20px}.album-desc{min-width:240px;float:left}.hide{display:none!important}.pull-right{float:right!important}.card-toolbar{margin-bottom:10px}.card-toolbar>div,.card-toolbar>form{margin-bottom:5px}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(/assets/MaterialIcons-Regular.woff2) format('woff2'),url(/assets/MaterialIcons-Regular.woff) format('woff'),url(/assets/MaterialIcons-Regular.ttf) format('truetype')}.material-icons{font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:18px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;vertical-align:top;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:'liga'}.material-icons-left{font-size:1rem;margin-left:-1em;vertical-align:middle}.material-icons-small{font-size:16px}.material-icons-small-left{font-size:1rem;margin-left:-1em}.color-darkgrey,.color-darkgrey:hover{color:#6c757d!important}#btn-outputs-block>button{margin-bottom:10px}#btn-outputs-block>button:last-child{margin-bottom:0}.card-body{overflow-x:hidden}.progressBarPlay{font-size:22px}#counter{cursor:text}#volumeBar{margin-top:2px;width:160px}.title-icon{float:left;margin-right:5px;font-size:1.8rem}.header-logo{font-size:2rem;float:left;margin-right:5px}.letters>button{width:28px;height:28px}.col-md{max-width:250px;min-width:250px}a.card-img-top{overflow:hidden;display:block;padding-top:100%;background-size:cover;background-image:url(/assets/coverimage-loading.png)}a.card-img-top-nc{display:block;height:20px;background-color:#ccc}button.active{color:#fff;background-color:#28a745!important;border-color:#28a745!important}button.active-fg-green{color:#28a745!important}button.active-fg-red{color:#bd2130!important}div#alertBox{position:fixed;top:50px;right:10px;width:80%;max-width:400px;z-index:1000;opacity:0;visibility:visible;transition:opacity .5s ease-in}div.alertBoxActive{opacity:1!important;visibility:visible!important;transition:opacity .5s ease-in}.popover-content{padding-top:4px;padding-bottom:4px}.opacity05{opacity:.5}caption{caption-side:top;font-size:120%;font-weight:bold;color:black}.dragover>td{border-top:2px solid #28a745}.dragover-th{border-left:2px solid #28a745}[draggable]{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;user-select:none;-khtml-user-drag:element;-webkit-user-drag:element;cursor:pointer}@keyframes changewidth{0%{margin-left:-20px}to{margin-left:100%}}#updateDBprogress{width:20px}.updateDBprogressAnimate{animation-duration:2s;animation-name:changewidth;animation-iteration-count:infinite}.modal-body{overflow-x:hidden}.modal-body .album-cover{float:none}#BrowseDatabaseAlbumListCaption{margin-left:15px;margin-right:15px;width:100%}#BrowseDatabaseAlbumListCaption h2{display:inline}#BrowseDatabaseAlbumListCaption small{padding-top:.8rem}#menu-dbupdate{padding-left:1rem}
\ No newline at end of file
+html{position:relative;min-height:100%}body{margin-bottom:60px;padding-top:50px;padding-bottom:50px;background-color:#888}main{padding-top:20px}footer{position:absolute;bottom:0}button{overflow:hidden}#BrowseBreadrumb{overflow:auto;white-space:nowrap}#BrowseBreadcrumb>li>a{cursor:pointer}@media only screen and (max-width:576px){.header-logo{display:none!important}}.clickable{cursor:pointer}[data-col=Pos],[data-col=Type],[data-col=Track],[data-col=Action]{width:30px}small{color:#aaa}.card{min-height:300px}.card-footer-playback{padding:0}.album-cover{background-size:cover;background-image:url("/assets/coverimage-loading.png");border:1px solid black;border-radius:5px;overflow:hidden;width:240px;height:240px;background-color:#eee;float:left;margin-right:20px;margin-bottom:20px}.album-desc{min-width:240px;float:left}.hide{display:none!important}.pull-right{float:right!important}.card-toolbar{margin-bottom:10px}.card-toolbar>div,.card-toolbar>form{margin-bottom:5px}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(/assets/MaterialIcons-Regular.woff2) format('woff2'),url(/assets/MaterialIcons-Regular.woff) format('woff'),url(/assets/MaterialIcons-Regular.ttf) format('truetype')}.material-icons{font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:18px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;vertical-align:top;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:'liga'}.material-icons-left{font-size:1rem;margin-left:-1em;vertical-align:middle}.material-icons-small{font-size:16px}.material-icons-small-left{font-size:1rem;margin-left:-1em}.color-darkgrey,.color-darkgrey:hover{color:#6c757d!important}#btn-outputs-block>button{margin-bottom:10px}#btn-outputs-block>button:last-child{margin-bottom:0}.card-body{overflow-x:hidden}.progressBarPlay{font-size:22px}#counter{cursor:text}#volumeBar{margin-top:2px;width:160px}.title-icon{float:left;margin-right:5px;font-size:1.8rem}.header-logo{font-size:2rem;float:left;margin-right:5px}.letters>button{width:28px;height:28px}.col-md{max-width:250px;min-width:250px}a.card-img-left{overflow:hidden;display:block;width:250px;height:250px;border-radius:5px;background-size:cover;background-image:url(/assets/coverimage-loading.png);margin-bottom:5px;cursor:pointer}button.active{color:#fff;background-color:#28a745!important;border-color:#28a745!important}button.active-fg-green{color:#28a745!important}button.active-fg-red{color:#bd2130!important}div#alertBox{position:fixed;top:50px;right:10px;width:80%;max-width:400px;z-index:1000;opacity:0;visibility:visible;transition:opacity .5s ease-in}div.alertBoxActive{opacity:1!important;visibility:visible!important;transition:opacity .5s ease-in}.popover-content{padding-top:4px;padding-bottom:4px}.opacity05{opacity:.5}caption{caption-side:top;font-size:120%;font-weight:bold;color:black}.dragover>td{border-top:2px solid #28a745}.dragover-th{border-left:2px solid #28a745}[draggable]{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;user-select:none;-khtml-user-drag:element;-webkit-user-drag:element;cursor:pointer}@keyframes changewidth{0%{margin-left:-20px}to{margin-left:100%}}#updateDBprogress{width:20px}.updateDBprogressAnimate{animation-duration:2s;animation-name:changewidth;animation-iteration-count:infinite}.modal-body{overflow-x:hidden}.modal-body .album-cover{float:none}#BrowseDatabaseAlbumListCaption{margin-left:15px;margin-right:15px;width:100%}#BrowseDatabaseAlbumListCaption h2{display:inline}#BrowseDatabaseAlbumListCaption small{padding-top:.8rem}#menu-dbupdate{padding-left:1rem}
\ No newline at end of file
diff --git a/dist/htdocs/index.html b/dist/htdocs/index.html
index 8ad28d0..dff2299 100644
--- a/dist/htdocs/index.html
+++ b/dist/htdocs/index.html
@@ -1 +1 @@
-
myMPD JavaScript is disabled!
# Title Artist Album Duration
Playlist List # Title Artist Album Duration
Connection to myMPD failed. Trying to reconnect to
Dependent on the size of your music collection this can take a while.
myMPD – a standalone and mobile friendly web mpdclient myMPD is a lightweight MPD web client that runs without a dedicated webserver or interpreter. It's tuned for minimal resource usage and requires only very litte dependencies. myMPD is a fork of ympd .
Database Statistics Artists Albums Songs DB Play Time DB Updated Play Statistics Uptime Play Time MPD Protocol Version
\ No newline at end of file
+myMPD JavaScript is disabled!
# Title Artist Album Duration
Playlist List # Title Artist Album Duration
Connection to myMPD failed. Trying to reconnect to
Dependent on the size of your music collection this can take a while.
myMPD – a standalone and mobile friendly web mpdclient myMPD is a lightweight MPD web client that runs without a dedicated webserver or interpreter. It's tuned for minimal resource usage and requires only very litte dependencies. myMPD is a fork of ympd .
Database Statistics Artists Albums Songs DB Play Time DB Updated Play Statistics Uptime Play Time MPD Protocol Version
\ No newline at end of file
diff --git a/dist/htdocs/js/mympd.min.js b/dist/htdocs/js/mympd.min.js
index 7c91010..b43ee3e 100644
--- a/dist/htdocs/js/mympd.min.js
+++ b/dist/htdocs/js/mympd.min.js
@@ -42,21 +42,21 @@ a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&showMenu(
"Add all to playlist"==a.target.innerText?showAddToPlaylist("SEARCH"):"Save as smart playlist"==a.target.innerText&&saveSearchAsSmartPlaylist())},!1);document.getElementById("BrowseDatabaseAddAllSongsDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&("Add all to queue"==a.target.innerText?addAllFromBrowseDatabasePlist("queue"):"Add all to playlist"==a.target.innerText&&showAddToPlaylist("DATABASE"))},!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.getAttribute("data-tag")+"/"+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("searchqueuetags").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,app.current.page+
"/"+a.target.getAttribute("data-tag")+"/"+app.current.search)},!1);document.getElementById("QueueColsDropdown").addEventListener("click",function(a){"INPUT"==a.target.nodeName&&a.stopPropagation()},!1);document.getElementById("BrowseFilesystemColsDropdown").addEventListener("click",function(a){"INPUT"==a.target.nodeName&&a.stopPropagation()},!1);document.getElementById("SearchColsDropdown").addEventListener("click",function(a){"INPUT"==a.target.nodeName&&a.stopPropagation()},!1);document.getElementById("BrowsePlaylistsDetailColsDropdown").addEventListener("click",
-function(a){"INPUT"==a.target.nodeName&&a.stopPropagation()},!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);document.getElementById("BrowseDatabaseByTagDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&
-appGoto(app.current.app,app.current.tab,a.target.getAttribute("data-tag"),"0/"+app.current.filter+"/"+app.current.search)},!1);document.getElementsByTagName("body")[0].addEventListener("click",function(a){hideMenu()},!1);dragAndDropTable("QueueList");dragAndDropTable("BrowsePlaylistsDetailList");dragAndDropTableHeader("Queue");dragAndDropTableHeader("Search");dragAndDropTableHeader("BrowseFilesystem");dragAndDropTableHeader("BrowsePlaylistsDetail");window.addEventListener("hashchange",appRoute,!1);
-window.addEventListener("focus",function(){sendAPI({cmd:"MPD_API_PLAYER_STATE"},parseState)},!1);document.addEventListener("keydown",function(a){if("INPUT"!=a.target.tagName&&"SELECT"!=a.target.tagName){if(a.shiftKey)switch(a.which){case 83:sendAPI({cmd:"MPD_API_QUEUE_SHUFFLE"});break;case 67:sendAPI({cmd:"MPD_API_QUEUE_CROP"});break;default:return}else switch(a.which){case 37:clickPrev();break;case 39:clickNext();break;case 32:clickPlay();break;case 83:clickStop();break;case 173:chVolume(-5);break;
-case 171:chVolume(5);break;case 67:sendAPI({cmd:"MPD_API_QUEUE_CLEAR"});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(a){"INPUT"==a.target.nodeName&&a.stopPropagation()},!1);document.getElementById("BrowseDatabaseColsDropdown").addEventListener("click",function(a){"INPUT"==a.target.nodeName&&a.stopPropagation()},!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);document.getElementById("BrowseDatabaseByTagDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,a.target.getAttribute("data-tag"),"0/"+app.current.filter+"/"+app.current.search)},!1);document.getElementsByTagName("body")[0].addEventListener("click",function(a){hideMenu()},!1);dragAndDropTable("QueueList");dragAndDropTable("BrowsePlaylistsDetailList");dragAndDropTableHeader("Queue");dragAndDropTableHeader("Search");
+dragAndDropTableHeader("BrowseFilesystem");dragAndDropTableHeader("BrowsePlaylistsDetail");window.addEventListener("hashchange",appRoute,!1);window.addEventListener("focus",function(){sendAPI({cmd:"MPD_API_PLAYER_STATE"},parseState)},!1);document.addEventListener("keydown",function(a){if("INPUT"!=a.target.tagName&&"SELECT"!=a.target.tagName){if(a.shiftKey)switch(a.which){case 83:sendAPI({cmd:"MPD_API_QUEUE_SHUFFLE"});break;case 67:sendAPI({cmd:"MPD_API_QUEUE_CROP"});break;default:return}else switch(a.which){case 37:clickPrev();
+break;case 39:clickNext();break;case 32:clickPlay();break;case 83:clickStop();break;case 173:chVolume(-5);break;case 171:chVolume(5);break;case 67:sendAPI({cmd:"MPD_API_QUEUE_CLEAR"});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();if("TR"==dragEl.nodeName){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();if("TR"==dragEl.nodeName){for(var c=b.getElementsByClassName("dragover"),e=c.length,f=0;fDatabase";
-settings.tags.sort();settings.searchtags.sort();settings.browsetags.sort();filterCols("colsSearch");filterCols("colsQueue");filterCols("colsBrowsePlaylistsDetail");filterCols("colsBrowseFilesystem");settings.featLocalplayer&&(""==settings.streamurl?(settings.mpdstream="http://",settings.mpdstream="127.0.0.1"==settings.mpdhost||"localhost"==settings.mpdhost?settings.mpdstream+window.location.hostname:settings.mpdstream+settings.mpdhost,settings.mpdstream+=":"+settings.streamport+"/"):settings.mpdstream=
-settings.streamurl);addTagList("BrowseDatabaseByTagDropdown","browsetags");addTagList("searchqueuetags","searchtags");addTagList("searchtags","searchtags");for(a=0;a',a=0;a"+settings.syscmds[a]+"";document.getElementById("syscmds").innerHTML=b}else document.getElementById("syscmds").innerHTML="";setCols("Queue");setCols("Search");setCols("BrowseFilesystem");setCols("BrowsePlaylistsDetail");"Queue"==app.current.app?getQueue():"Search"==app.current.app?appRoute():"Browse"==app.current.app&&"Filesystem"==app.current.tab?appRoute():"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view&&appRoute()}
-function setCols(a){var b="",c=settings.tags.slice();0==settings.featTags&&c.push("Title");c.push("Duration");"Queue"!=a&&"BrowsePlaylistsDetail"!=a||c.push("Pos");"BrowseFilesystem"==a&&c.push("Type");c.sort();for(var d=0;d '+c[d]+" ";document.getElementById(a+
-"ColsDropdown").firstChild.innerHTML=b;b="";for(d=0;d';if("Track"==c||"Pos"==c)c="#";b+=c+""}b+=" ";document.getElementById(a+"List").getElementsByTagName("tr")[0].innerHTML=b}function getSettings(){sendAPI({cmd:"MPD_API_SETTINGS_GET"},parseSettings)}
-function saveCols(a){for(var b=document.getElementById(a+"ColsDropdown").firstChild.getElementsByTagName("input"),c=document.getElementById(a+"List").getElementsByTagName("tr")[0],d=0;dvolume_up '+a.data.outputs[d].name+"";domCache.outputs.innerHTML=b}
+settings.tags.sort();settings.searchtags.sort();settings.browsetags.sort();filterCols("colsSearch");filterCols("colsQueue");filterCols("colsBrowsePlaylistsDetail");filterCols("colsBrowseFilesystem");filterCols("colsBrowseDatabase");settings.featLocalplayer&&(""==settings.streamurl?(settings.mpdstream="http://",settings.mpdstream="127.0.0.1"==settings.mpdhost||"localhost"==settings.mpdhost?settings.mpdstream+window.location.hostname:settings.mpdstream+settings.mpdhost,settings.mpdstream+=":"+settings.streamport+
+"/"):settings.mpdstream=settings.streamurl);addTagList("BrowseDatabaseByTagDropdown","browsetags");addTagList("searchqueuetags","searchtags");addTagList("searchtags","searchtags");for(a=0;a',a=0;a"+settings.syscmds[a]+"";document.getElementById("syscmds").innerHTML=b}else document.getElementById("syscmds").innerHTML="";setCols("Queue");setCols("Search");setCols("BrowseFilesystem");setCols("BrowsePlaylistsDetail");setCols("BrowseDatabase",".tblAlbumTitles");"Queue"==app.current.app?getQueue():"Search"==app.current.app?appRoute():"Browse"==app.current.app&&"Filesystem"==app.current.tab?appRoute():"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==
+app.current.view?appRoute():"Browse"==app.current.app&&"Database"==app.current.tab&&""!=app.current.search&&appRoute()}
+function setCols(a,b){var c="",d=settings.tags.slice();0==settings.featTags&&d.push("Title");d.push("Duration");"Queue"!=a&&"BrowsePlaylistsDetail"!=a||d.push("Pos");"BrowseFilesystem"==a&&d.push("Type");d.sort();for(var e=0;e '+d[e]+" ";document.getElementById(a+
+"ColsDropdown").firstChild.innerHTML=c;c="";for(e=0;e';if("Track"==d||"Pos"==d)d="#";c+=d+""}c+=" ";if(void 0==b)document.getElementById(a+"List").getElementsByTagName("tr")[0].innerHTML=c;else for(a=document.querySelectorAll(b),e=0;evolume_up '+a.data.outputs[d].name+"";domCache.outputs.innerHTML=b}
function setCounter(a,b,c){currentSong.totalTime=b;currentSong.elapsedTime=c;currentSong.currentSongId=a;var d=Math.floor(b/60),e=b-60*d,f=Math.floor(c/60),g=c-60*f;domCache.progressBar.value=Math.floor(100*c/b);b=f+":"+(10>g?"0":"")+g+" / "+d+":"+(10>e?"0":"")+e;domCache.counter.innerText=b;if(lastState&&lastState.data.currentSongId!=a&&(c=document.getElementById("queueTrackId"+lastState.data.currentSongId))){if(d=c.querySelector("[data-col=Duration]"))d.innerText=c.getAttribute("data-duration");
if(d=c.querySelector("[data-col=Pos]"))d.classList.remove("material-icons"),d.innerText=c.getAttribute("data-songpos");c.classList.remove("font-weight-bold")}if(c=document.getElementById("queueTrackId"+a)){if(d=c.querySelector("[data-col=Duration]"))d.innerText=b;(d=c.querySelector("[data-col=Pos]"))&&!d.classList.contains("material-icons")&&(d.classList.add("material-icons"),d.innerText="play_arrow");c.classList.add("font-weight-bold")}progressTimer&&clearTimeout(progressTimer);"play"==playstate&&
(progressTimer=setTimeout(function(){currentSong.elapsedTime++;setCounter(currentSong.currentSongId,currentSong.totalTime,currentSong.elapsedTime)},1E3))}
@@ -102,16 +104,17 @@ f);h.setAttribute("data-type",a.data[e].Type);h.setAttribute("data-name",a.data[
"true");h.setAttribute("id","playlistTrackId"+a.data[e].Pos);h.setAttribute("data-type",a.data[e].Type);h.setAttribute("data-uri",f);h.setAttribute("data-name",a.data[e].Title);h.setAttribute("data-songpos",a.data[e].Pos);f=Math.floor(a.data[e].Duration/60);g=a.data[e].Duration-60*f;a.data[e].Duration=f+":"+(10>g?"0":"")+g;f="";for(g=0;g'+a.data[e][settings.colsBrowsePlaylistsDetail[g]]+"";
f+='playlist_add ';h.innerHTML=f;e=b;e--)d[e].remove();setPagination(a.totalEntities);0==b&&(c.innerHTML="All"==app.current.view?'error_outline No playlists found. ':'error_outline Empty playlist. ');document.getElementById(app.current.app+
app.current.tab+app.current.view+"List").classList.remove("opacity05")}}
-function parseListDBtags(a){scrollTo(0);if(""!=app.current.search){document.getElementById("BrowseDatabaseAlbumList").classList.remove("hide");document.getElementById("BrowseDatabaseTagList").classList.add("hide");document.getElementById("btnBrowseDatabaseByTag").parentNode.classList.add("hide");document.getElementById("btnBrowseDatabaseTag").parentNode.classList.remove("hide");document.getElementById("BrowseDatabaseAddAllSongs").parentNode.parentNode.classList.remove("hide");document.getElementById("btnBrowseDatabaseTag").innerHTML=
-"« "+app.current.view;document.getElementById("BrowseDatabaseAlbumListCaption").innerHTML=""+a.searchtagtype+": "+a.searchstr+' '+a.totalEntities+" Entries ";for(var b=a.data.length,c=document.getElementById("BrowseDatabaseAlbumList"),d=c.getElementsByClassName("col-md"),e=0;e'+(settings.featCoverimage?' ':' ')+' ';e=b;e--)d[e].remove();setPagination(a.totalEntities);document.getElementById("BrowseDatabaseAlbumList").classList.remove("opacity05")}else{document.getElementById("BrowseDatabaseAlbumList").classList.add("hide");
-document.getElementById("BrowseDatabaseTagList").classList.remove("hide");document.getElementById("btnBrowseDatabaseByTag").parentNode.classList.remove("hide");document.getElementById("BrowseDatabaseAddAllSongs").parentNode.parentNode.classList.add("hide");document.getElementById("btnBrowseDatabaseTag").parentNode.classList.add("hide");document.getElementById("BrowseDatabaseTagListCaption").innerHTML=app.current.view+''+a.totalEntities+" Tags ";b=a.data.length;c=document.getElementById(app.current.app+
-app.current.tab+"TagList").getElementsByTagName("tbody")[0];d=c.getElementsByTagName("tr");for(e=0;ealbum '+a.data[e].value+" ",e=b;e--)d[e].remove();setPagination(a.totalEntities);0==b&&(c.innerHTML='error_outline No entries found. ');
-document.getElementById("BrowseDatabaseTagList").classList.remove("opacity05")}}function createListTitleObserver(a){(new IntersectionObserver(getListTitles,{root:null,rootMargin:"0px"})).observe(a)}function getListTitles(a,b){a.forEach(function(a){0keyboard_arrow_down Hide Titles'},!1);document.getElementById("collapse"+b).addEventListener("hidden.bs.collapse",function(){e.innerHTML='keyboard_arrow_right Show Titles'},!1);b="";c=a.data.length;for(var f=0;f'+a.data[f].Track+" "+a.data[f].Title+' playlist_add ';d.innerHTML=b;d.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&&showMenu(a.target,a)},!1)}
+function parseListDBtags(a){scrollTo(0);if(""!=app.current.search){document.getElementById("BrowseDatabaseAlbumList").classList.remove("hide");document.getElementById("BrowseDatabaseTagList").classList.add("hide");document.getElementById("btnBrowseDatabaseByTag").parentNode.classList.add("hide");document.getElementById("btnBrowseDatabaseTag").parentNode.classList.remove("hide");document.getElementById("BrowseDatabaseAddAllSongs").parentNode.parentNode.classList.remove("hide");document.getElementById("BrowseDatabaseColsBtn").parentNode.classList.remove("hide");
+document.getElementById("btnBrowseDatabaseTag").innerHTML="« "+app.current.view;document.getElementById("BrowseDatabaseAlbumListCaption").innerHTML=""+a.searchtagtype+": "+a.searchstr+' '+a.totalEntities+" Entries ";for(var b=a.data.length,c=document.getElementById("BrowseDatabaseAlbumList"),d=c.getElementsByClassName("card"),e=0;e – '+a.data[e].value+' ';settings.featCoverimage&&(h+='
');h+='
';g.innerHTML=
+h;e=b;e--)d[e].remove();setPagination(a.totalEntities);setCols("BrowseDatabase",".tblAlbumTitles");a=document.querySelectorAll(".tblAlbumTitles");for(e=0;e'+a.totalEntities+" Tags";b=a.data.length;c=document.getElementById(app.current.app+app.current.tab+"TagList").getElementsByTagName("tbody")[0];d=c.getElementsByTagName("tr");for(e=0;ealbum '+a.data[e].value+" ",e=b;e--)d[e].remove();setPagination(a.totalEntities);0==b&&(c.innerHTML='error_outline No entries found. ');document.getElementById("BrowseDatabaseTagList").classList.remove("opacity05")}}function createListTitleObserver(a){(new IntersectionObserver(getListTitles,{root:null,rootMargin:"0px"})).observe(a)}
+function getListTitles(a,b){a.forEach(function(a){0g?"0":"")+g}b+='';for(f=0;f'+a.data[e][settings.colsBrowseDatabase[f]]+"";b+='playlist_add '}d.innerHTML=b;d.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&&showMenu(a.target,a)},!1)}
function setPagination(a){var b=Math.ceil(a/settings.maxElementsPerPage),c=app.current.app+(void 0==app.current.tab?"":app.current.tab);0==b&&(b=1);for(var d=["PaginationTop","PaginationBottom"],e=0;2>e;e++){document.getElementById(c+d[e]+"Page").innerText=app.current.page/settings.maxElementsPerPage+1+" / "+b;if(1'+
(g+1)+"";document.getElementById(c+d[e]+"Pages").innerHTML=f}else document.getElementById(c+d[e]+"Page").setAttribute("disabled","disabled");a>app.current.page+settings.maxElementsPerPage?(document.getElementById(c+d[e]+"Next").removeAttribute("disabled"),document.getElementById(c+d[e]).classList.remove("hide"),document.getElementById(c+"ButtonsBottom").classList.remove("hide")):(document.getElementById(c+d[e]+"Next").setAttribute("disabled","disabled"),document.getElementById(c+d[e]).classList.add("hide"),
document.getElementById(c+"ButtonsBottom").classList.add("hide"));0
+
+
+ settings
+
+
';
+
+ card.innerHTML = html;
if (i < cards.length)
cards[i].replaceWith(card);
else
cardContainer.append(card);
if ('IntersectionObserver' in window)
- createListTitleObserver(document.getElementById(id));
+ createListTitleObserver(document.getElementById('card' + id));
else
sendAPI({"cmd": "MPD_API_DATABASE_TAG_ALBUM_TITLE_LIST", "data": { "album": obj.data[i].value, "search": app.current.search, "tag": app.current.view}}, parseListTitles);
}
@@ -1647,6 +1677,10 @@ function parseListDBtags(obj) {
cards[i].remove();
}
setPagination(obj.totalEntities);
+ setCols('BrowseDatabase', '.tblAlbumTitles');
+ var tbls = document.querySelectorAll('.tblAlbumTitles');
+ for (var i = 0; i < tbls.length; i++)
+ dragAndDropTableHeader(tbls[i]);
document.getElementById('BrowseDatabaseAlbumList').classList.remove('opacity05');
}
else {
@@ -1654,6 +1688,7 @@ function parseListDBtags(obj) {
document.getElementById('BrowseDatabaseTagList').classList.remove('hide');
document.getElementById('btnBrowseDatabaseByTag').parentNode.classList.remove('hide');
document.getElementById('BrowseDatabaseAddAllSongs').parentNode.parentNode.classList.add('hide');
+ document.getElementById('BrowseDatabaseColsBtn').parentNode.classList.add('hide');
document.getElementById('btnBrowseDatabaseTag').parentNode.classList.add('hide');
document.getElementById('BrowseDatabaseTagListCaption').innerHTML = app.current.view + '' + obj.totalEntities +' Tags ';
var nrItems = obj.data.length;
@@ -1713,37 +1748,40 @@ function parseListTitles(obj) {
var id = genId(obj.Album);
var card = document.getElementById('card' + id)
var tbody = card.getElementsByTagName('tbody')[0];
- var img = card.getElementsByTagName('a')[0];
- if (img.classList.contains('card-img-top'))
- img.style.backgroundImage = 'url("' + obj.cover + '")';
- else
- img.style.backgroundImage = '';
- img.setAttribute('data-uri', encodeURI(obj.data[0].uri.replace(/\/[^\/]+$/, '')));
- img.setAttribute('data-name', obj.Album);
- img.setAttribute('data-type', 'dir');
- img.addEventListener('click', function(event) {
+ var cardHeader = card.querySelector('.card-header');
+ cardHeader.setAttribute('data-uri', encodeURI(obj.data[0].uri.replace(/\/[^\/]+$/, '')));
+ cardHeader.setAttribute('data-name', obj.Album);
+ cardHeader.setAttribute('data-type', 'dir');
+ cardHeader.addEventListener('click', function(event) {
showMenu(this, event);
}, false);
+ cardHeader.classList.add('clickable');
+ var img = card.getElementsByTagName('a')[0];
+ if (img) {
+ img.style.backgroundImage = 'url("' + obj.cover + '")';
+ img.setAttribute('data-uri', encodeURI(obj.data[0].uri.replace(/\/[^\/]+$/, '')));
+ img.setAttribute('data-name', obj.Album);
+ img.setAttribute('data-type', 'dir');
+ img.addEventListener('click', function(event) {
+ showMenu(this, event);
+ }, false);
+ }
document.getElementById('albumartist' + id).innerText = obj.AlbumArtist;
- var titleTable = document.getElementById('collapseLink' + id);
- var myCollapseInit = new Collapse(titleTable);
-
- document.getElementById('collapse' + id).addEventListener('show.bs.collapse', function() {
- titleTable.innerHTML = 'keyboard_arrow_down Hide Titles';
- }, false);
- document.getElementById('collapse' + id).addEventListener('hidden.bs.collapse', function() {
- titleTable.innerHTML = 'keyboard_arrow_right Show Titles';
- }, false);
-
var titleList = '';
var nrItems = obj.data.length;
for (var i = 0; i < nrItems; i++) {
- titleList += '' +
- '' + obj.data[i].Track + ' ' + obj.data[i].Title + ' ' +
- 'playlist_add ' +
- ' ';
+ if (obj.data[i].Duration) {
+ var minutes = Math.floor(obj.data[i].Duration / 60);
+ var seconds = obj.data[i].Duration - minutes * 60;
+ obj.data[i].Duration = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
+ }
+ titleList += '';
+ for (var c = 0; c < settings.colsBrowseDatabase.length; c++) {
+ titleList += '' + obj.data[i][settings.colsBrowseDatabase[c]] + ' ';
+ }
+ titleList += 'playlist_add ';
}
tbody.innerHTML = titleList;
diff --git a/src/mpd_client.c b/src/mpd_client.c
index 948f5e7..cddad9e 100644
--- a/src/mpd_client.c
+++ b/src/mpd_client.c
@@ -1439,7 +1439,7 @@ int mympd_put_settings(char *buffer) {
}
len += json_printf(&out, ", colsQueue: %s", mympd_state.colsQueue);
len += json_printf(&out, ", colsSearch: %s", mympd_state.colsSearch);
- len += json_printf(&out, ", colsBrowseDatabase: %s", mympd_state.colsBrowseFilesystem);
+ len += json_printf(&out, ", colsBrowseDatabase: %s", mympd_state.colsBrowseDatabase);
len += json_printf(&out, ", colsBrowsePlaylistsDetail: %s", mympd_state.colsBrowsePlaylistsDetail);
len += json_printf(&out, ", colsBrowseFilesystem: %s", mympd_state.colsBrowseFilesystem);
len += json_printf(&out, "}}");
@@ -1873,12 +1873,9 @@ int mympd_put_songs_in_album(char *buffer, char *album, char *search, char *tag)
mympd_get_cover(mpd_song_get_uri(song), cover, 500);
albumartist = strdup(mympd_get_tag(song, MPD_TAG_ALBUM_ARTIST));
}
- len += json_printf(&out, "{type: song, uri: %Q, Duration: %d, Title: %Q, Track: %Q}",
- mpd_song_get_uri(song),
- mpd_song_get_duration(song),
- mympd_get_tag(song, MPD_TAG_TITLE),
- mympd_get_tag(song, MPD_TAG_TRACK)
- );
+ len += json_printf(&out, "{Type: song, ");
+ PUT_SONG_TAGS();
+ len += json_printf(&out, "}");
}
mpd_song_free(song);
}
diff --git a/src/mympd.c b/src/mympd.c
index 5432f70..c679ec1 100644
--- a/src/mympd.c
+++ b/src/mympd.c
@@ -294,7 +294,7 @@ void read_statefiles() {
if (mympd_state_get("colsBrowseDatabase", value))
mympd_state.colsBrowseDatabase = strdup(value);
else {
- mympd_state.colsBrowseDatabase = strdup("[\"Track\",\"Title\"]");
+ mympd_state.colsBrowseDatabase = strdup("[\"Track\",\"Title\",\"Duration\"]");
mympd_state_set("colsBrowseDatabase", mympd_state.colsBrowseDatabase);
}