mirror of
https://github.com/SuperBFG7/ympd
synced 2025-03-04 02:28:19 +00:00
Merge pull request #67 from jcorporation/devel
Merge devel into master for 4.4.0 release
This commit is contained in:
commit
98c0ba873b
@ -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 "4")
|
||||
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 "/usr/share/${PROJECT_NAME}/htdocs")
|
||||
|
2
PKGBUILD
2
PKGBUILD
@ -4,7 +4,7 @@
|
||||
|
||||
pkgname=mympd
|
||||
_pkgname=myMPD
|
||||
pkgver=4.3.1
|
||||
pkgver=4.4.0
|
||||
pkgrel=1
|
||||
pkgdesc="myMPD is a standalone and mobile friendly web mpdclient."
|
||||
arch=('x86_64' 'armv7h' 'aarch64')
|
||||
|
@ -4,7 +4,7 @@
|
||||
# (c) 2018 Juergen Mang <mail@jcgames.de>
|
||||
|
||||
Name: myMPD
|
||||
Version: 4.3.1
|
||||
Version: 4.4.0
|
||||
Release: 0
|
||||
License: GPL-2.0
|
||||
Group: Productivity/Multimedia/Sound/Players
|
||||
|
@ -37,3 +37,6 @@ taglist = Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer
|
||||
|
||||
#Enable smart playlists
|
||||
smartpls = true
|
||||
|
||||
#Elements per page for pagination, max: 400
|
||||
max_elements_per_page = 100
|
||||
|
2
dist/htdocs/css/mympd.min.css
vendored
2
dist/htdocs/css/mympd.min.css
vendored
@ -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}.card{min-height:350px}@media only screen and (max-width:576px){.header-logo{display:none!important}}.clickable{cursor:pointer}.tblnum,.tblaction{width:30px}small{color:#aaa}.card-footer-playback{padding:0}.album-cover{background-size:cover;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.eot);src:local('Material Icons'),local('MaterialIcons-Regular');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}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:25px solid transparent}[draggable]{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;user-select:none;-khtml-user-drag:element;-webkit-user-drag:element}@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{width:100%;margin-left:15px}#menu-dbupdate{padding-left:1rem}
|
||||
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}.tblnum,.tblaction{width:30px}small{color:#aaa}.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)}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:25px solid transparent}[draggable]{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;user-select:none;-khtml-user-drag:element;-webkit-user-drag:element}@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}
|
2
dist/htdocs/index.html
vendored
2
dist/htdocs/index.html
vendored
File diff suppressed because one or more lines are too long
73
dist/htdocs/js/mympd.min.js
vendored
73
dist/htdocs/js/mympd.min.js
vendored
@ -5,13 +5,12 @@ $jscomp.iteratorPrototype=function(a){$jscomp.initSymbolIterator();a={next:a};a[
|
||||
$jscomp.checkStringArgs=function(a,b,c){if(null==a)throw new TypeError("The 'this' value for String.prototype."+c+" must not be null or undefined");if(b instanceof RegExp)throw new TypeError("First argument to String.prototype."+c+" must not be a regular expression");return a+""};
|
||||
$jscomp.polyfill=function(a,b,c,d){if(b){c=$jscomp.global;a=a.split(".");for(d=0;d<a.length-1;d++){var e=a[d];e in c||(c[e]={});c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&$jscomp.defineProperty(c,a,{configurable:!0,writable:!0,value:b})}};
|
||||
$jscomp.polyfill("String.prototype.repeat",function(a){return a?a:function(a){var b=$jscomp.checkStringArgs(this,null,"repeat");if(0>a||1342177279<a)throw new RangeError("Invalid count value");a|=0;for(var d="";a;)if(a&1&&(d+=b),a>>>=1)b+=b;return d}},"es6","es3");
|
||||
var socket,lastSong="",lastState,currentSong={},playstate="",settings={},alertTimeout,progressTimer,deferredPrompt,dragEl,playlistEl,app={apps:{Playback:{state:"0/-/",scrollPos:0},Queue:{state:"0/any/",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:"AlbumArtist",views:{AlbumArtist:{state:"0/-/",scrollPos:0},Genre:{state:"0/-/",scrollPos:0},Artist:{state:"0/-/",
|
||||
scrollPos:0},Composer:{state:"0/-/",scrollPos:0},Performer:{state:"0/-/",scrollPos:0},Date:{state:"0/-/",scrollPos:0},Album:{state:"0/-/",scrollPos:0}}}}},Search:{state:"0/any/",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.btnsPlay=document.getElementsByClassName("btnPlay");domCache.btnsPlayLen=domCache.btnsPlay.length;
|
||||
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("nav-add2homescreen");domCache.currentTrack=document.getElementById("currentTrack");domCache.currentArtist=document.getElementById("currentArtist");domCache.currentAlbum=document.getElementById("currentAlbum");
|
||||
domCache.currentCover=document.getElementById("currentCover");domCache.btnVoteUp=document.getElementById("btnVoteUp");domCache.btnVoteDown=document.getElementById("btnVoteDown");
|
||||
var socket,lastSong="",lastState,currentSong={},playstate="",settings={},alertTimeout,progressTimer,deferredPrompt,dragEl,playlistEl,app={apps:{Playback:{state:"0/-/",scrollPos:0},Queue:{state:"0/any/",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:"AlbumArtist",views:{}}}},Search:{state:"0/any/",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.btnsPlay=document.getElementsByClassName("btnPlay");domCache.btnsPlayLen=domCache.btnsPlay.length;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("nav-add2homescreen");domCache.currentTrack=document.getElementById("currentTrack");domCache.currentArtist=document.getElementById("currentArtist");domCache.currentAlbum=document.getElementById("currentAlbum");domCache.currentCover=document.getElementById("currentCover");domCache.btnVoteUp=document.getElementById("btnVoteUp");domCache.btnVoteDown=document.getElementById("btnVoteDown");
|
||||
var modalConnectionError=new Modal(document.getElementById("modalConnectionError"),{backdrop:"static",keyboard:!1}),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")),modalUpdateDB=new Modal(document.getElementById("modalUpdateDB")),
|
||||
modalSaveSmartPlaylist=new Modal(document.getElementById("modalSaveSmartPlaylist"));
|
||||
modalSaveSmartPlaylist=new Modal(document.getElementById("modalSaveSmartPlaylist")),modalDeletePlaylist=new Modal(document.getElementById("modalDeletePlaylist"));
|
||||
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")}
|
||||
@ -26,7 +25,7 @@ if("Playback"==app.current.app)sendAPI({cmd:"MPD_API_PLAYER_CURRENT_SONG"},songC
|
||||
'<li class="breadcrumb-item active">'+c[a]+"</li>";break}e+=c[a];b+='<li class="breadcrumb-item"><a data-uri="'+e+'">'+c[a]+"</a></li>";e+="/"}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"Search"==app.current.app?(a=document.getElementById("searchstr"),
|
||||
a.focus(),""==a.value&&""!=app.current.search&&(a.value=app.current.search),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_DATABASE_SEARCH",data:{plist:"",offset:app.current.page,filter:app.current.filter,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)),selectTag("searchtags","searchtagsdesc",app.current.filter)):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_PLAYER_STATE"},parseState);webSocketConnect();domCache.volumeBar.value=0;document.getElementById("btnChVolumeDown").addEventListener("click",function(a){a.stopPropagation()},!1);document.getElementById("btnChVolumeUp").addEventListener("click",function(a){a.stopPropagation()},!1);domCache.volumeBar.addEventListener("click",function(a){a.stopPropagation()},!1);domCache.volumeBar.addEventListener("change",function(a){sendAPI({cmd:"MPD_API_PLAYER_VOLUME",
|
||||
function appInit(){getSettings();sendAPI({cmd:"MPD_API_PLAYER_STATE"},parseState);webSocketConnect();domCache.volumeBar.value=0;document.getElementById("btnChVolumeDown").addEventListener("click",function(a){a.stopPropagation()},!1);document.getElementById("btnChVolumeUp").addEventListener("click",function(a){a.stopPropagation()},!1);domCache.volumeBar.addEventListener("click",function(a){a.stopPropagation()},!1);domCache.volumeBar.addEventListener("change",function(a){sendAPI({cmd:"MPD_API_PLAYER_VOLUME_SET",
|
||||
data:{volume:domCache.volumeBar.value}})},!1);domCache.progressBar.value=0;domCache.progressBar.addEventListener("change",function(a){currentSong&&0<=currentSong.currentSongId&&sendAPI({cmd:"MPD_API_PLAYER_SEEK",data:{songid:currentSong.currentSongId,seek:Math.ceil(domCache.progressBar.value/100*currentSong.totalTime)}})},!1);document.getElementById("navDBupdate").addEventListener("click",function(a){a.stopPropagation();a.preventDefault();a=this.getElementsByTagName("span")[0];a.innerText="keyboard_arrow_right"==
|
||||
a.innerText?"keyboard_arrow_down":"keyboard_arrow_right"},!1);document.getElementById("volumeIcon").parentNode.addEventListener("show.bs.dropdown",function(){sendAPI({cmd:"MPD_API_PLAYER_OUTPUT_LIST"},parseOutputs)});document.getElementById("modalAbout").addEventListener("shown.bs.modal",function(){sendAPI({cmd:"MPD_API_DATABASE_STATS"},parseStats)});document.getElementById("modalUpdateDB").addEventListener("hidden.bs.modal",function(){document.getElementById("updateDBprogress").classList.remove("updateDBprogressAnimate")});
|
||||
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");
|
||||
@ -50,9 +49,10 @@ function dragAndDropTable(a){var b=document.getElementById(a).getElementsByTagNa
|
||||
b.nodeName&&b.classList.remove("dragover")},!1);b.addEventListener("dragover",function(a){a.preventDefault();for(var c=b.getElementsByClassName("dragover"),e=c.length,f=0;f<e;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.getElementsByClassName("dragover"),e=c.length,f=0;f<e;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 d=c.target;"TD"==c.target.nodeName&&(d=c.target.parentNode);var e=document.getElementById(c.dataTransfer.getData("Text")).getAttribute("data-songpos"),f=d.getAttribute("data-songpos");document.getElementById(c.dataTransfer.getData("Text")).remove();dragEl.classList.remove("opacity05");
|
||||
b.insertBefore(dragEl,d);c=b.getElementsByClassName("dragover");d=c.length;for(var g=0;g<d;g++)c[g].classList.remove("dragover");document.getElementById(a).classList.add("opacity05");"Queue"==app.current.app?sendAPI({cmd:"MPD_API_QUEUE_MOVE_TRACK",data:{from:e,to:f}}):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view&&playlistMoveTrack(e,f)},!1)}
|
||||
function playlistMoveTrack(a,b){sendAPI({cmd:"MPD_API_PLAYLIST_MOVE_TRACK",data:{plist:app.current.search,from:a,to:b}});sendAPI({cmd:"MPD_API_PLAYLIST_CONTENT_LIST",data:{offset:app.current.page,filter:app.current.filter,uri:app.current.search}},parsePlaylists)}
|
||||
function playlistMoveTrack(a,b){sendAPI({cmd:"MPD_API_PLAYLIST_MOVE_TRACK",data:{plist:app.current.search,from:a,to:b}})}
|
||||
function webSocketConnect(){var a=getWsUrl();socket=new WebSocket(a);try{socket.onopen=function(){console.log("connected");showNotification("Connected to myMPD: "+a,"","","success");modalConnectionError.hide();appRoute();sendAPI({cmd:"MPD_API_PLAYER_STATE"},parseState)},socket.onmessage=function(b){if(b.data!==lastState&&0!=b.data.length){try{var c=JSON.parse(b.data)}catch(d){console.log("Invalid JSON data received: "+b.data)}switch(c.type){case "update_state":parseState(c);break;case "disconnected":showNotification("Lost connection to myMPD: "+
|
||||
a,"","","danger");break;case "update_queue":"Queue"===app.current.app&&getQueue();sendAPI({cmd:"MPD_API_PLAYER_STATE"},parseState);break;case "update_options":getSettings();break;case "update_outputs":sendAPI({cmd:"MPD_API_PLAYER_OUTPUT_LIST"},parseOutputs);break;case "update_started":updateDBstarted(!1);break;case "update_database":case "update_finished":updateDBfinished(c.type);break;case "error":showNotification(c.data,"","","danger")}}},socket.onclose=function(){console.log("disconnected");modalConnectionError.show();
|
||||
a,"","","danger");break;case "update_queue":"Queue"===app.current.app&&getQueue();sendAPI({cmd:"MPD_API_PLAYER_STATE"},parseState);break;case "update_options":getSettings();break;case "update_outputs":sendAPI({cmd:"MPD_API_PLAYER_OUTPUT_LIST"},parseOutputs);break;case "update_started":updateDBstarted(!1);break;case "update_database":case "update_finished":updateDBfinished(c.type);break;case "update_volume":parseVolume(c);break;case "update_stored_playlist":"Browse"==app.current.app&&"Playlists"==
|
||||
app.current.tab&&"All"==app.current.view?sendAPI({cmd:"MPD_API_PLAYLIST_LIST",data:{offset:app.current.page,filter:app.current.filter}},parsePlaylists):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view&&sendAPI({cmd:"MPD_API_PLAYLIST_CONTENT_LIST",data:{offset:app.current.page,filter:app.current.filter,uri:app.current.search}},parsePlaylists);break;case "error":showNotification(c.data,"","","danger")}}},socket.onclose=function(){console.log("disconnected");modalConnectionError.show();
|
||||
setTimeout(function(){console.log("reconnect");webSocketConnect()},3E3)}}catch(b){alert("Error: "+b)}}function getWsUrl(){var a=window.location.hostname,b=window.location.protocol,c=window.location.port;a=("https:"==b?"wss://":"ws://")+a+(""!=c?":"+c:"")+"/ws";return document.getElementById("wsUrl").innerText=a}
|
||||
function parseStats(a){document.getElementById("mpdstats_artists").innerText=a.data.artists;document.getElementById("mpdstats_albums").innerText=a.data.albums;document.getElementById("mpdstats_songs").innerText=a.data.songs;document.getElementById("mpdstats_dbPlaytime").innerText=beautifyDuration(a.data.dbPlaytime);document.getElementById("mpdstats_playtime").innerText=beautifyDuration(a.data.playtime);document.getElementById("mpdstats_uptime").innerText=beautifyDuration(a.data.uptime);var b=new Date(1E3*
|
||||
a.data.dbUpdated);document.getElementById("mpdstats_dbUpdated").innerText=b.toUTCString();document.getElementById("mympdVersion").innerText=a.data.mympdVersion;document.getElementById("mpdVersion").innerText=a.data.mpdVersion}function toggleBtn(a,b){if(a=document.getElementById(a))void 0==b&&(b=a.classList.contains("active")?0:1),1==b||1==b?a.classList.add("active"):a.classList.remove("active")}
|
||||
@ -61,14 +61,15 @@ document.getElementById("inputMixrampdb").value=a.data.mixrampdb):document.getEl
|
||||
notificationsSupported()?a.data.notificationWeb?(toggleBtn("btnnotifyWeb",a.data.notificationWeb),Notification.requestPermission(function(b){"permission"in Notification||(Notification.permission=b);"granted"===b?toggleBtn("btnnotifyWeb",1):(toggleBtn("btnnotifyWeb",0),a.data.notificationWeb=!0)})):toggleBtn("btnnotifyWeb",0):(b.setAttribute("disabled","disabled"),toggleBtn("btnnotifyWeb",0));toggleBtn("btnnotifyPage",a.data.notificationPage);var c=document.getElementsByClassName("stickers"),d=c.length,
|
||||
e=1==a.data.stickers?"":"none";for(b=0;b<d;b++)c[b].style.display=e;c=document.getElementsByClassName("smartpls");d=c.length;e=1==a.data.smartpls?"":"none";for(b=0;b<d;b++)c[b].style.display=e;1==a.data.mixramp?document.getElementsByClassName("mixramp")[0].style.display="":document.getElementsByClassName("mixramp")[0].style.display="none";document.getElementById("selectJukeboxMode").value=a.data.jukeboxMode;document.getElementById("inputJukeboxQueueLength").value=a.data.jukeboxQueueLength;0==a.data.jukeboxMode||
|
||||
2==a.data.jukeboxMode?(document.getElementById("inputJukeboxQueueLength").setAttribute("disabled","disabled"),document.getElementById("selectJukeboxPlaylist").setAttribute("disabled","disabled")):1==a.data.jukeboxMode&&(document.getElementById("inputJukeboxQueueLength").removeAttribute("disabled"),document.getElementById("selectJukeboxPlaylist").removeAttribute("disabled"));settings=a.data;playlistEl="selectJukeboxPlaylist";sendAPI({cmd:"MPD_API_PLAYLIST_LIST",data:{offset:0,filter:"-"}},getAllPlaylists);
|
||||
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+"/";addTagList("BrowseDatabaseByTagDropdown",!1);addTagList("searchqueuetag",!0);addTagList("searchtags",!0)}function getSettings(){sendAPI({cmd:"MPD_API_SETTINGS_GET"},parseSettings)}
|
||||
function parseOutputs(a){for(var b="",c=a.data.outputs.length,d=0;d<c;d++)b+='<button id="btnOutput'+a.data.outputs[d].id+'" data-output-id="'+a.data.outputs[d].id+'" class="btn btn-secondary btn-block',1==a.data.outputs[d].state&&(b+=" active"),b+='"><span class="material-icons float-left">volume_up</span> '+a.data.outputs[d].name+"</button>";domCache.outputs.innerHTML=b}
|
||||
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+"/";addTagList("BrowseDatabaseByTagDropdown",!1);addTagList("searchqueuetag",!0);addTagList("searchtags",!0);for(b=0;b<a.data.tags.length;b++)app.apps.Browse.tabs.Database.views[a.data.tags[b]]={state:"0/-/",scrollPos:0}}
|
||||
function getSettings(){sendAPI({cmd:"MPD_API_SETTINGS_GET"},parseSettings)}function parseOutputs(a){for(var b="",c=a.data.outputs.length,d=0;d<c;d++)b+='<button id="btnOutput'+a.data.outputs[d].id+'" data-output-id="'+a.data.outputs[d].id+'" class="btn btn-secondary btn-block',1==a.data.outputs[d].state&&(b+=" active"),b+='"><span class="material-icons float-left">volume_up</span> '+a.data.outputs[d].name+"</button>";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;lastState&&(c=document.getElementById("queueTrackId"+lastState.data.currentSongId))&&(d=c.getElementsByTagName("td"),d[4].innerText=c.getAttribute("data-duration"),d[0].classList.remove("material-icons"),d[0].innerText=
|
||||
c.getAttribute("data-songpos"),c.classList.remove("font-weight-bold"));if(c=document.getElementById("queueTrackId"+a))d=c.getElementsByTagName("td"),d[4].innerText=b,d[0].classList.add("material-icons"),d[0].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))}
|
||||
function parseState(a){if(JSON.stringify(a)!==JSON.stringify(lastState)){if(1==a.data.state){for(var b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].innerText="play_arrow";playstate="stop"}else if(2==a.data.state){for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].innerText="pause";playstate="play"}else{for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].innerText="play_arrow";playstate="pause"}-1==a.data.nextSongPos&&0==settings.jukeboxMode?domCache.btnNext.setAttribute("disabled","disabled"):
|
||||
domCache.btnNext.removeAttribute("disabled");0>=a.data.songPos?domCache.btnPrev.setAttribute("disabled","disabled"):domCache.btnPrev.removeAttribute("disabled");if(0==a.data.queueLength)for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].setAttribute("disabled","disabled");else for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].removeAttribute("disabled");-1==a.data.volume?(domCache.volumePrct.innerText="Volumecontrol disabled",domCache.volumeControl.classList.add("hide")):(domCache.volumeControl.classList.remove("hide"),
|
||||
domCache.volumePrct.innerText=a.data.volume+" %",domCache.volumeIcon.innerText=0==a.data.volume?"volume_off":50>a.data.volume?"volume_down":"volume_up");domCache.volumeBar.value=a.data.volume;setCounter(a.data.currentSongId,a.data.totalTime,a.data.elapsedTime);lastState&&lastState.data.currentSongId!=a.data.currentSongId&&sendAPI({cmd:"MPD_API_PLAYER_CURRENT_SONG"},songChange);"-1"==a.data.songPos&&(domCache.currentTrack.innerText="Not playing",domCache.currentAlbum.innerText="",domCache.currentArtist.innerText=
|
||||
"",domCache.currentCover.style.backgroundImage="");lastState=a}}function getQueue(){2<=app.current.search.length?sendAPI({cmd:"MPD_API_QUEUE_SEARCH",data:{filter:app.current.filter,offset:app.current.page,searchstr:app.current.search}},parseQueue):sendAPI({cmd:"MPD_API_QUEUE_LIST",data:{offset:app.current.page}},parseQueue)}
|
||||
domCache.btnNext.removeAttribute("disabled");0>=a.data.songPos?domCache.btnPrev.setAttribute("disabled","disabled"):domCache.btnPrev.removeAttribute("disabled");if(0==a.data.queueLength)for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].setAttribute("disabled","disabled");else for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].removeAttribute("disabled");parseVolume(a);setCounter(a.data.currentSongId,a.data.totalTime,a.data.elapsedTime);lastState&&lastState.data.currentSongId!=a.data.currentSongId&&
|
||||
sendAPI({cmd:"MPD_API_PLAYER_CURRENT_SONG"},songChange);"-1"==a.data.songPos&&(domCache.currentTrack.innerText="Not playing",domCache.currentAlbum.innerText="",domCache.currentArtist.innerText="",domCache.currentCover.style.backgroundImage="");lastState=a}}
|
||||
function parseVolume(a){-1==a.data.volume?(domCache.volumePrct.innerText="Volumecontrol disabled",domCache.volumeControl.classList.add("hide")):(domCache.volumeControl.classList.remove("hide"),domCache.volumePrct.innerText=a.data.volume+" %",domCache.volumeIcon.innerText=0==a.data.volume?"volume_off":50>a.data.volume?"volume_down":"volume_up");domCache.volumeBar.value=a.data.volume}
|
||||
function getQueue(){2<=app.current.search.length?sendAPI({cmd:"MPD_API_QUEUE_SEARCH",data:{filter:app.current.filter,offset:app.current.page,searchstr:app.current.search}},parseQueue):sendAPI({cmd:"MPD_API_QUEUE_LIST",data:{offset:app.current.page}},parseQueue)}
|
||||
function parseQueue(a){if("Queue"===app.current.app){0<a.totalTime&&a.totalEntities<=settings.maxElementsPerPage?document.getElementById("panel-heading-queue").innerText=a.totalEntities+" "+(1<a.totalEntities?"Songs":"Song")+" \u2013 "+beautifyDuration(a.totalTime):0<a.totalEntities?document.getElementById("panel-heading-queue").innerText=a.totalEntities+" "+(1<a.totalEntities?"Songs":"Song"):document.getElementById("panel-heading-queue").innerText="";var b=a.data.length,c=document.getElementById(app.current.app+
|
||||
"List");c.setAttribute("data-version",a.queueVersion);c=c.getElementsByTagName("tbody")[0];for(var d=c.getElementsByTagName("tr"),e=0;e<b;e++)if(!d[e]||d[e].getAttribute("data-trackid")!=a.data[e].id||d[e].getAttribute("data-songpos")!=a.data[e].pos+1){var f=Math.floor(a.data[e].duration/60),g=a.data[e].duration-60*f;f=f+":"+(10>g?"0":"")+g;g=document.createElement("tr");g.setAttribute("draggable","true");g.setAttribute("data-trackid",a.data[e].id);g.setAttribute("id","queueTrackId"+a.data[e].id);
|
||||
g.setAttribute("data-songpos",a.data[e].pos+1);g.setAttribute("data-duration",f);g.setAttribute("data-uri",a.data[e].uri);g.innerHTML="<td>"+(a.data[e].pos+1)+"</td><td>"+a.data[e].title+"</td><td>"+a.data[e].artist+"</td><td>"+a.data[e].album+"</td><td>"+f+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';e<d.length?d[e].replaceWith(g):c.append(g)}for(e=d.length-1;e>=b;e--)d[e].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>':
|
||||
@ -79,19 +80,22 @@ a.data[e].name);switch(a.data[e].type){case "dir":g.innerHTML='<td><span class="
|
||||
break;case "smartpls":case "plist":g.innerHTML='<td><span class="material-icons">list</span></td><td colspan="4">'+a.data[e].name+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>'}e<d.length?d[e].replaceWith(g):c.append(g)}}for(e=d.length-1;e>=b;e--)d[e].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?
|
||||
"":app.current.tab)+"List").classList.remove("opacity05")}}
|
||||
function parsePlaylists(a){if("Browse"===app.current.app||"Playlists"===app.current.tab){"All"==app.current.view?(document.getElementById("BrowsePlaylistsAllList").classList.remove("hide"),document.getElementById("BrowsePlaylistsDetailList").classList.add("hide"),document.getElementById("btnBrowsePlaylistsAll").parentNode.classList.add("hide"),document.getElementById("btnPlaylistClear").parentNode.classList.add("hide")):(-1<a.uri.indexOf(".")||1==a.smartpls?(document.getElementById("BrowsePlaylistsDetailList").setAttribute("data-ro",
|
||||
"true"),document.getElementById("btnPlaylistClear").parentNode.classList.add("hide")):(document.getElementById("BrowsePlaylistsDetailList").setAttribute("data-ro","false"),document.getElementById("btnPlaylistClear").parentNode.classList.remove("hide")),document.getElementById("BrowsePlaylistsDetailList").setAttribute("data-uri",a.uri),1==a.smartpls?document.getElementById("BrowsePlaylistsDetailList").getElementsByTagName("caption")[0].innerText="Smart playlist: "+a.uri:document.getElementById("BrowsePlaylistsDetailList").getElementsByTagName("caption")[0].innerText=
|
||||
"Playlist: "+a.uri,document.getElementById("BrowsePlaylistsDetailList").classList.remove("hide"),document.getElementById("BrowsePlaylistsAllList").classList.add("hide"),document.getElementById("btnBrowsePlaylistsAll").parentNode.classList.remove("hide"));var b=a.data.length,c=document.getElementById(app.current.app+app.current.tab+app.current.view+"List").getElementsByTagName("tbody")[0],d=c.getElementsByTagName("tr");if("All"==app.current.view)for(var e=0;e<b;e++){var f=encodeURI(a.data[e].uri);
|
||||
if(!d[e]||d[e].getAttribute("data-uri")!=f){var g=new Date(1E3*a.data[e].last_modified),h=document.createElement("tr");h.setAttribute("data-uri",f);h.setAttribute("data-type",a.data[e].type);h.setAttribute("data-name",a.data[e].name);h.innerHTML='<td><span class="material-icons">list</span></td><td>'+a.data[e].name+"</td><td>"+g.toUTCString()+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';e<d.length?d[e].replaceWith(h):c.append(h)}}else if("Detail"==app.current.view)for(e=
|
||||
0;e<b;e++)if(f=encodeURI(a.data[e].uri),g=a.offset+e+1,!d[e]||d[e].getAttribute("data-uri")!=f||d[e].getAttribute("id")!="playlistTrackId"+g){h=document.createElement("tr");0==a.smartpls&&h.setAttribute("draggable","true");h.setAttribute("id","playlistTrackId"+g);h.setAttribute("data-type",a.data[e].type);h.setAttribute("data-uri",f);h.setAttribute("data-name",a.data[e].name);h.setAttribute("data-songpos",g);f=Math.floor(a.data[e].duration/60);var k=a.data[e].duration-60*f;h.innerHTML="<td>"+g+"</td><td>"+
|
||||
a.data[e].title+"</td><td>"+a.data[e].artist+"</td><td>"+a.data[e].album+"</td><td>"+f+":"+(10>k?"0":"")+k+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';e<d.length?d[e].replaceWith(h):c.append(h)}for(e=d.length-1;e>=b;e--)d[e].remove();setPagination(a.totalEntities);0==b&&(c.innerHTML="All"==app.current.view?'<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">No playlists found.</td></tr>':'<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">Empty playlist.</td></tr>');
|
||||
document.getElementById(app.current.app+app.current.tab+app.current.view+"List").classList.remove("opacity05")}}
|
||||
function parseListDBtags(a){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").innerText=a.searchtagtype+": "+a.searchstr;for(var b=a.data.length,c=document.getElementById("BrowseDatabaseAlbumList"),d=c.getElementsByClassName("col-md"),e=0;e<b;e++){var f=genId(a.data[e].value);if(!d[e]||d[e].getAttribute("id")!=f){var g=document.createElement("div");g.classList.add("col-md");g.classList.add("mr-0");g.setAttribute("id",f);g.innerHTML='<div class="card mb-4" id="card'+f+'"> <a href="#" class="card-img-top"><img class="card-img-top" src="" ></a> <div class="card-body"> <h5 class="card-title" id="albumartist'+
|
||||
f+'"></h5> <h4 class="card-title">'+a.data[e].value+'</h4> <table class="table table-sm table-hover" id="tbl'+f+'"><tbody></tbody></table </div></div>';e<d.length?d[e].replaceWith(g):c.append(g);sendAPI({cmd:"MPD_API_DATABASE_TAG_ALBUM_TITLE_LIST",data:{album:a.data[e].value,search:app.current.search,tag:app.current.view}},parseListTitles)}}for(e=d.length-1;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");b=a.data.length;c=document.getElementById(app.current.app+app.current.tab+"TagList").getElementsByTagName("tbody")[0];d=c.getElementsByTagName("tr");for(e=0;e<b;e++)f=
|
||||
encodeURI(a.data[e].value),d[e]&&d[e].getAttribute("data-uri")==f||(g=document.createElement("tr"),g.setAttribute("data-uri",f),g.innerHTML='<td><span class="material-icons">album</span></td><td>'+a.data[e].value+"</td>",e<d.length?d[e].replaceWith(g):c.append(g));for(e=d.length-1;e>=b;e--)d[e].remove();setPagination(a.totalEntities);0==b&&(c.innerHTML='<tr><td><span class="material-icons">error_outline</span></td><td>No entries found.</td></tr>');document.getElementById("BrowseDatabaseTagList").classList.remove("opacity05")}}
|
||||
function parseListTitles(a){var b=genId(a.album),c=document.getElementById("card"+b),d=c.getElementsByTagName("tbody")[0],e=c.getElementsByTagName("img")[0];c=e.parentNode;e.setAttribute("src",a.cover);c.setAttribute("data-uri",encodeURI(a.data[0].uri.replace(/\/[^\/]+$/,"")));c.setAttribute("data-name",a.album);c.setAttribute("data-type","dir");document.getElementById("albumartist"+b).innerText=a.albumartist;b="";e=a.data.length;for(var f=0;f<e;f++)b+='<tr data-type="song" data-name="'+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>';d.innerHTML=b;c.addEventListener("click",function(a){showMenu(this,a)},!1);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)}
|
||||
"true"),document.getElementById("btnPlaylistClear").parentNode.classList.add("hide")):(document.getElementById("BrowsePlaylistsDetailList").setAttribute("data-ro","false"),document.getElementById("btnPlaylistClear").parentNode.classList.remove("hide")),document.getElementById("BrowsePlaylistsDetailList").setAttribute("data-uri",a.uri),1==a.smartpls?document.getElementById("BrowsePlaylistsDetailList").getElementsByTagName("caption")[0].innerHTML="Smart playlist: "+a.uri+'<small class="pull-right">'+
|
||||
a.totalEntities+" Songs </small>":document.getElementById("BrowsePlaylistsDetailList").getElementsByTagName("caption")[0].innerHTML="Playlist: "+a.uri+'<small class="pull-right">'+a.totalEntities+" Songs </small>",document.getElementById("BrowsePlaylistsDetailList").classList.remove("hide"),document.getElementById("BrowsePlaylistsAllList").classList.add("hide"),document.getElementById("btnBrowsePlaylistsAll").parentNode.classList.remove("hide"));var b=a.data.length,c=document.getElementById(app.current.app+
|
||||
app.current.tab+app.current.view+"List").getElementsByTagName("tbody")[0],d=c.getElementsByTagName("tr");if("All"==app.current.view)for(var e=0;e<b;e++){var f=encodeURI(a.data[e].uri);if(!d[e]||d[e].getAttribute("data-uri")!=f){var g=new Date(1E3*a.data[e].last_modified),h=document.createElement("tr");h.setAttribute("data-uri",f);h.setAttribute("data-type",a.data[e].type);h.setAttribute("data-name",a.data[e].name);h.innerHTML='<td><span class="material-icons">list</span></td><td>'+a.data[e].name+
|
||||
"</td><td>"+g.toUTCString()+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';e<d.length?d[e].replaceWith(h):c.append(h)}}else if("Detail"==app.current.view)for(e=0;e<b;e++)if(f=encodeURI(a.data[e].uri),g=a.offset+e+1,!d[e]||d[e].getAttribute("data-uri")!=f||d[e].getAttribute("id")!="playlistTrackId"+g){h=document.createElement("tr");0==a.smartpls&&h.setAttribute("draggable","true");h.setAttribute("id","playlistTrackId"+g);h.setAttribute("data-type",a.data[e].type);
|
||||
h.setAttribute("data-uri",f);h.setAttribute("data-name",a.data[e].name);h.setAttribute("data-songpos",g);f=Math.floor(a.data[e].duration/60);var k=a.data[e].duration-60*f;h.innerHTML="<td>"+g+"</td><td>"+a.data[e].title+"</td><td>"+a.data[e].artist+"</td><td>"+a.data[e].album+"</td><td>"+f+":"+(10>k?"0":"")+k+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';e<d.length?d[e].replaceWith(h):c.append(h)}for(e=d.length-1;e>=b;e--)d[e].remove();setPagination(a.totalEntities);
|
||||
0==b&&(c.innerHTML="All"==app.current.view?'<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">No playlists found.</td></tr>':'<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">Empty playlist.</td></tr>');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="<h2>"+a.searchtagtype+": "+a.searchstr+'</h2><small class="pull-right">'+a.totalEntities+" Entries</small><hr/>";for(var b=a.data.length,c=document.getElementById("BrowseDatabaseAlbumList"),d=c.getElementsByClassName("col-md"),e=0;e<b;e++){var f=genId(a.data[e].value);if(!d[e]||d[e].getAttribute("id")!=f){var g=document.createElement("div");g.classList.add("col-md");g.classList.add("mr-0");g.setAttribute("id",
|
||||
f);g.setAttribute("data-album",encodeURI(a.data[e].value));g.innerHTML='<div class="card mb-4" id="card'+f+'"> <a href="#" class="card-img-top"></a> <div class="card-body"> <h5 class="card-title" id="albumartist'+f+'"></h5> <h4 class="card-title">'+a.data[e].value+'</h4> <a class="color-darkgrey" data-toggle="collapse" href="#collapse'+f+'" id="collapseLink'+f+'"> <span class="material-icons">keyboard_arrow_right</span> Show Titles</a> <div class="collapse" id="collapse'+f+'"> <table class="table table-sm table-hover" id="tbl'+
|
||||
f+'"><tbody></tbody></table> </div> </div></div>';e<d.length?d[e].replaceWith(g):c.append(g);"IntersectionObserver"in window?createListTitleObserver(document.getElementById(f)):sendAPI({cmd:"MPD_API_DATABASE_TAG_ALBUM_TITLE_LIST",data:{album:a.data[e].value,search:app.current.search,tag:app.current.view}},parseListTitles)}}for(e=d.length-1;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+'<small class="pull-right">'+a.totalEntities+" Tags</small>";b=a.data.length;c=document.getElementById(app.current.app+
|
||||
app.current.tab+"TagList").getElementsByTagName("tbody")[0];d=c.getElementsByTagName("tr");for(e=0;e<b;e++)f=encodeURI(a.data[e].value),d[e]&&d[e].getAttribute("data-uri")==f||(g=document.createElement("tr"),g.setAttribute("data-uri",f),g.innerHTML='<td><span class="material-icons">album</span></td><td>'+a.data[e].value+"</td>",e<d.length?d[e].replaceWith(g):c.append(g));for(e=d.length-1;e>=b;e--)d[e].remove();setPagination(a.totalEntities);0==b&&(c.innerHTML='<tr><td><span class="material-icons">error_outline</span></td><td>No entries found.</td></tr>');
|
||||
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){0<a.intersectionRatio&&(b.unobserve(a.target),a=decodeURI(a.target.getAttribute("data-album")),sendAPI({cmd:"MPD_API_DATABASE_TAG_ALBUM_TITLE_LIST",data:{album:a,search:app.current.search,tag:app.current.view}},parseListTitles))})}
|
||||
function parseListTitles(a){var b=genId(a.album),c=document.getElementById("card"+b),d=c.getElementsByTagName("tbody")[0];c=c.getElementsByTagName("a")[0];c.style.backgroundImage='url("'+a.cover+'")';c.setAttribute("data-uri",encodeURI(a.data[0].uri.replace(/\/[^\/]+$/,"")));c.setAttribute("data-name",a.album);c.setAttribute("data-type","dir");document.getElementById("albumartist"+b).innerText=a.albumartist;var e=document.getElementById("collapseLink"+b);new Collapse(e);document.getElementById("collapse"+
|
||||
b).addEventListener("show.bs.collapse",function(){e.innerHTML='<span class="material-icons">keyboard_arrow_down</span> Hide Titles'},!1);document.getElementById("collapse"+b).addEventListener("hidden.bs.collapse",function(){e.innerHTML='<span class="material-icons">keyboard_arrow_right</span> Show Titles'},!1);b="";for(var f=a.data.length,g=0;g<f;g++)b+='<tr data-type="song" data-name="'+a.data[g].title+'" data-uri="'+encodeURI(a.data[g].uri)+'"><td>'+a.data[g].track+"</td><td>"+a.data[g].title+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td></tr>';
|
||||
d.innerHTML=b;c.addEventListener("click",function(a){showMenu(this,a)},!1);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<b){document.getElementById(c+d[e]+"Page").removeAttribute("disabled");for(var f="",g=0;g<b;g++)f+='<button data-page="'+g*settings.maxElementsPerPage+'" type="button" class="mr-1 mb-1 btn-sm btn btn-secondary">'+
|
||||
(g+1)+"</button>";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<app.current.page?(document.getElementById(c+d[e]+"Prev").removeAttribute("disabled"),document.getElementById(c+d[e]).classList.remove("hide"),document.getElementById(c+"ButtonsBottom").classList.remove("hide")):document.getElementById(c+d[e]+"Prev").setAttribute("disabled","disabled")}}
|
||||
@ -100,9 +104,8 @@ function replaceQueue(a,b,c){switch(a){case "song":case "dir":sendAPI({cmd:"MPD_
|
||||
function artistClick(){var a=domCache.currentArtist.getAttribute("data-albumartist");""!=a&&appGoto("Browse","Database","AlbumArtist","0/-/"+a)}function albumClick(){var a=domCache.currentAlbum.getAttribute("data-album");""!=a&&appGoto("Browse","Database","Album","0/-/"+a)}function songDetails(a){sendAPI({cmd:"MPD_API_DATABASE_SONGDETAILS",data:{uri:a}},parseSongDetails);modalSongDetails.show()}
|
||||
function parseSongDetails(a){var b=document.getElementById("modalSongDetails");b.getElementsByClassName("album-cover")[0].style.backgroundImage='url("'+a.data.cover+'")';b.getElementsByTagName("h1")[0].innerText=a.data.title;for(var c="",d=0;d<settings.tags.length;d++){var e=a.data[settings.tags[d].toLowerCase()];if("duration"==settings.tags[d]){var f=Math.floor(e/60);e-=60*f;e=f+":"+(10>e?"0":"")+e}c+="<tr><th>"+settings.tags[d]+"</th><td>"+e+"</td></tr>"}c+='<tr><th>Uri</th><td><a class="text-success" href="/library/'+
|
||||
a.data.uri+'">'+a.data.uri+"</a></td></tr>";1==settings.stickers&&(d="not voted",0==a.data.like?d='<span class="material-icons">thumb_down_alt</span>':2==a.data.like&&(d='<span class="material-icons">thumb_up_alt</span>'),c+='<tr><th colspan="2">Statistics</th></tr><tr><th>Play count</th><td>'+a.data.playCount+"</td></tr><tr><th>Skip count</th><td>"+a.data.skipCount+"</td></tr><tr><th>Last played</th><td>"+(0==a.data.lastPlayed?"never":(new Date(1E3*a.data.lastPlayed)).toUTCString())+"</td></tr><tr><th>Like</th><td>"+
|
||||
d+"</td></tr>");b.getElementsByTagName("tbody")[0].innerHTML=c}function playlistDetails(a){document.getElementById("BrowsePlaylistsAllList").classList.add("opacity05");appGoto("Browse","Playlists","Detail","0/-/"+a)}
|
||||
function removeFromPlaylist(a,b){b--;sendAPI({cmd:"MPD_API_PLAYLIST_RM_TRACK",data:{uri:a,track:b}});document.getElementById("BrowsePlaylistsDetailList").classList.add("opacity05");sendAPI({cmd:"MPD_API_PLAYLIST_CONTENT_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_PLAYLIST_CONTENT_LIST",data:{offset:app.current.page,filter:app.current.filter,uri:app.current.search}},parsePlaylists)}
|
||||
d+"</td></tr>");b.getElementsByTagName("tbody")[0].innerHTML=c}function playlistDetails(a){document.getElementById("BrowsePlaylistsAllList").classList.add("opacity05");appGoto("Browse","Playlists","Detail","0/-/"+a)}function removeFromPlaylist(a,b){b--;sendAPI({cmd:"MPD_API_PLAYLIST_RM_TRACK",data:{uri:a,track:b}});document.getElementById("BrowsePlaylistsDetailList").classList.add("opacity05")}
|
||||
function playlistClear(){var a=document.getElementById("BrowsePlaylistsDetailList").getAttribute("data-uri");sendAPI({cmd:"MPD_API_PLAYLIST_CLEAR_AND_LIST",data:{uri:a}});document.getElementById("BrowsePlaylistsDetailList").classList.add("opacity05")}
|
||||
function getAllPlaylists(a){var b=a.data.length,c="";0==a.offset&&("addToPlaylistPlaylist"==playlistEl?c="<option></option><option>New Playlist</option>":"selectJukeboxPlaylist"==playlistEl&&(c="<option>Database</option>"));for(var d=0;d<b;d++)c+="<option","selectJukeboxPlaylist"==playlistEl&&a.data[d].uri==settings.jukeboxPlaylist&&(c+=" selected"),c+=">"+a.data[d].uri+"</option>";0==a.offset?document.getElementById(playlistEl).innerHTML=c:document.getElementById(playlistEl).innerHTML+=c;a.totalEntities>
|
||||
a.returnedEntities&&(a.offset+=settings.maxElementsPerPage,sendAPI({cmd:"MPD_API_PLAYLIST_LIST",data:{offset:a.offset,filter:"-"}},getAllPlaylists))}function updateSmartPlaylists(){sendAPI({cmd:"MPD_API_SMARTPLS_UPDATE_ALL"})}
|
||||
function voteSong(a){var b=domCache.currentTrack.getAttribute("data-uri");""!=b&&(2==a&&domCache.btnVoteUp.classList.contains("active-fg-green")?a=1:0==a&&domCache.btnVoteDown.classList.contains("active-fg-red")&&(a=1),sendAPI({cmd:"MPD_API_LIKE",data:{uri:b,like:a}}),setVoteSongBtns(a,b))}
|
||||
@ -124,15 +127,15 @@ function addToPlaylist(){var a=document.getElementById("addToPlaylistUri").value
|
||||
"");if(""==b||""!=c){document.getElementById("addToPlaylistNewPlaylist").classList.add("is-invalid");document.getElementById("addToPlaylistFrm").classList.add("was-validated");return}}""!=b?("SEARCH"==a?addAllFromSearchPlist(b):"DATABASE"==a?addAllFromBrowseDatabasePlist(b):sendAPI({cmd:"MPD_API_PLAYLIST_ADD_TRACK",data:{uri:a,plist: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_QUEUE_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_PLAYLIST_LIST",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 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()):(document.getElementById("renamePlaylistTo").classList.add("is-invalid"),document.getElementById("renamePlaylistFrm").classList.add("was-validated"))}
|
||||
function showSmartPlaylist(a){sendAPI({cmd:"MPD_API_SMARTPLS_GET",data:{playlist:a}},parseSmartPlaylist)}function dirname(a){return a.replace(/\/[^\/]*$/,"")}function b64EncodeUnicode(a){return btoa(encodeURIComponent(a).replace(/%([0-9A-F]{2})/g,function(a,c){return String.fromCharCode("0x"+c)}))}function b64DecodeUnicode(a){return decodeURIComponent(atob(a).split("").map(function(a){return"%"+("00"+a.charCodeAt(0).toString(16)).slice(-2)}).join(""))}
|
||||
function addMenuItem(a,b){return'<a class="dropdown-item" href="#" data-href=\''+b64EncodeUnicode(JSON.stringify(a))+"'>"+b+"</a>"}function hideMenu(){var a=document.querySelector("[data-popover]");a&&(new Popover(a,{}),a.Popover.hide(),a.removeAttribute("data-popover"))}
|
||||
function showMenu(a,b){b.preventDefault();b.stopPropagation();if(!a.getAttribute("data-init")){hideMenu();b=a.getAttribute("data-type");var c=decodeURI(a.getAttribute("data-uri")),d=a.getAttribute("data-name"),e=0;if(null==b||null==c)b=a.parentNode.parentNode.getAttribute("data-type"),c=decodeURI(a.parentNode.parentNode.getAttribute("data-uri")),d=a.parentNode.parentNode.getAttribute("data-name");lastState&&(e=lastState.data.nextSongPos);var f="";"Browse"==app.current.app&&"Filesystem"==app.current.tab||
|
||||
"Search"==app.current.app||"Browse"==app.current.app&&"Database"==app.current.tab?(f+=addMenuItem({cmd:"appendQueue",options:[b,c,d]},"Append to queue")+("song"==b?addMenuItem({cmd:"appendAfterQueue",options:[b,c,e,d]},"Add after current playing song"):"")+addMenuItem({cmd:"replaceQueue",options:[b,c,d]},"Replace queue")+("plist"!=b&&"smartpls"!=b?addMenuItem({cmd:"showAddToPlaylist",options:[c]},"Add to playlist"):"")+("song"==b?addMenuItem({cmd:"songDetails",options:[c]},"Songdetails"):"")+("plist"==
|
||||
b||"smartpls"==b?addMenuItem({cmd:"playlistDetails",options:[c]},"View playlist"):""),"Search"==app.current.app&&(c=dirname(c),f+='<div class="dropdown-divider"></div><a class="dropdown-item" id="advancedMenuLink" data-toggle="collapse" href="#advancedMenu"><span class="material-icons material-icons-small-left">keyboard_arrow_right</span>Album actions</a><div class="collapse" id="advancedMenu">'+addMenuItem({cmd:"appendQueue",options:[b,c,d]},"Append to queue")+addMenuItem({cmd:"appendAfterQueue",
|
||||
options:[b,c,e,d]},"Add after current playing song")+addMenuItem({cmd:"replaceQueue",options:[b,c,d]},"Replace queue")+addMenuItem({cmd:"showAddToPlaylist",options:[c]},"Add to playlist")+"</div>")):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"All"==app.current.view?f+=addMenuItem({cmd:"appendQueue",options:[b,c,d]},"Append to queue")+addMenuItem({cmd:"replaceQueue",options:[b,c,d]},"Replace queue")+("smartpls"==b?addMenuItem({cmd:"playlistDetails",options:[c]},"View playlist"):addMenuItem({cmd:"playlistDetails",
|
||||
options:[c]},"Edit playlist"))+("smartpls"==b?addMenuItem({cmd:"showSmartPlaylist",options:[c]},"Edit smart playlist"):"")+(0!=c.indexOf("myMPDsmart")?addMenuItem({cmd:"showRenamePlaylist",options:[c]},"Rename playlist")+addMenuItem({cmd:"delPlaylist",options:[c]},"Delete playlist"):""):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view?(e=document.getElementById("BrowsePlaylistsDetailList"),f+=addMenuItem({cmd:"appendQueue",options:[b,c,d]},"Append to queue")+addMenuItem({cmd:"replaceQueue",
|
||||
options:[b,c,d]},"Replace queue")+("false"==e.getAttribute("data-ro")?addMenuItem({cmd:"removeFromPlaylist",options:[e.getAttribute("data-uri"),a.parentNode.parentNode.getAttribute("data-songpos")]},"Remove"):"")+addMenuItem({cmd:"showAddToPlaylist",options:[c]},"Add to playlist")+(-1==c.indexOf("http")?addMenuItem({cmd:"songDetails",options:[c]},"Songdetails"):"")):"Queue"==app.current.app&&(f+=addMenuItem({cmd:"delQueueSong",options:["single",a.parentNode.parentNode.getAttribute("data-trackid")]},
|
||||
options:[c]},"Edit playlist"))+("smartpls"==b?addMenuItem({cmd:"showSmartPlaylist",options:[c]},"Edit smart playlist"):"")+(0!=c.indexOf("myMPDsmart")?addMenuItem({cmd:"showRenamePlaylist",options:[c]},"Rename playlist")+addMenuItem({cmd:"showDelPlaylist",options:[c]},"Delete playlist"):""):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view?(e=document.getElementById("BrowsePlaylistsDetailList"),f+=addMenuItem({cmd:"appendQueue",options:[b,c,d]},"Append to queue")+
|
||||
addMenuItem({cmd:"replaceQueue",options:[b,c,d]},"Replace queue")+("false"==e.getAttribute("data-ro")?addMenuItem({cmd:"removeFromPlaylist",options:[e.getAttribute("data-uri"),a.parentNode.parentNode.getAttribute("data-songpos")]},"Remove"):"")+addMenuItem({cmd:"showAddToPlaylist",options:[c]},"Add to playlist")+(-1==c.indexOf("http")?addMenuItem({cmd:"songDetails",options:[c]},"Songdetails"):"")):"Queue"==app.current.app&&(f+=addMenuItem({cmd:"delQueueSong",options:["single",a.parentNode.parentNode.getAttribute("data-trackid")]},
|
||||
"Remove")+addMenuItem({cmd:"delQueueSong",options:["range",0,a.parentNode.parentNode.getAttribute("data-songpos")]},"Remove all upwards")+addMenuItem({cmd:"delQueueSong",options:["range",parseInt(a.parentNode.parentNode.getAttribute("data-songpos"))-1,-1]},"Remove all downwards")+(-1==c.indexOf("http")?addMenuItem({cmd:"songDetails",options:[c]},"Songdetails"):""));new Popover(a,{trigger:"click",delay:0,dismissible:!0,template:'<div class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content">'+
|
||||
f+"</div></div>"});b=a.Popover;a.setAttribute("data-init","true");a.addEventListener("shown.bs.popover",function(a){a.target.setAttribute("data-popover","true");document.getElementsByClassName("popover-content")[0].addEventListener("click",function(a){a.preventDefault();a.stopPropagation();if("A"==a.target.nodeName&&(a=a.target.getAttribute("data-href"))){a=JSON.parse(b64DecodeUnicode(a));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))}hideMenu()}},!1);if(a=document.getElementById("advancedMenuLink"))a.addEventListener("click",function(a){a=this.getElementsByTagName("span")[0];a.innerText="keyboard_arrow_right"==a.innerText?"keyboard_arrow_down":"keyboard_arrow_right"},!1),new Collapse(a)},!1);b.show()}}
|
||||
@ -141,7 +144,7 @@ c.send(JSON.stringify(a))}function openLocalPlayer(){window.open("/player.html#"
|
||||
function updateDBstarted(a){1==a?(document.getElementById("updateDBfinished").innerText="",document.getElementById("updateDBfooter").classList.add("hide"),updateDBprogress.style.width="20px",updateDBprogress.style.marginLeft="-20px",modalUpdateDB.show(),document.getElementById("updateDBprogress").classList.add("updateDBprogressAnimate")):showNotification("Database update started","","","success")}
|
||||
function updateDBfinished(a){document.getElementById("modalUpdateDB").classList.contains("show")?("update_database"==a?document.getElementById("updateDBfinished").innerText="Database successfully updated.":"update_finished"==a&&(document.getElementById("updateDBfinished").innerText="Database update finished."),a=document.getElementById("updateDBprogress"),a.classList.remove("updateDBprogressAnimate"),a.style.width="100%",a.style.marginLeft="0px",document.getElementById("updateDBfooter").classList.remove("hide")):
|
||||
"update_database"==a?showNotification("Database successfully updated.","","","success"):"update_finished"==a&&showNotification("Database update finished.","","","success")}function clickPlay(){"play"!=playstate?sendAPI({cmd:"MPD_API_PLAYER_PLAY"}):sendAPI({cmd:"MPD_API_PLAYER_PAUSE"})}function clickStop(){sendAPI({cmd:"MPD_API_PLAYER_STOP"})}function clickPrev(){sendAPI({cmd:"MPD_API_PLAYER_PREV"})}function clickNext(){sendAPI({cmd:"MPD_API_PLAYER_NEXT"})}
|
||||
function delQueueSong(a,b,c){"range"==a?sendAPI({cmd:"MPD_API_QUEUE_RM_RANGE",data:{start:b,end:c}}):"single"==a&&sendAPI({cmd:"MPD_API_QUEUE_RM_TRACK",data:{track:b}})}function delPlaylist(a){sendAPI({cmd:"MPD_API_PLAYLIST_RM",data:{uri:a}});sendAPI({cmd:"MPD_API_PLAYLIST_LIST",data:{offset:app.current.page,filter:app.current.filter}},parsePlaylists)}
|
||||
function delQueueSong(a,b,c){"range"==a?sendAPI({cmd:"MPD_API_QUEUE_RM_RANGE",data:{start:b,end:c}}):"single"==a&&sendAPI({cmd:"MPD_API_QUEUE_RM_TRACK",data:{track:b}})}function showDelPlaylist(a){document.getElementById("deletePlaylist").value=a;modalDeletePlaylist.show()}function delPlaylist(){var a=document.getElementById("deletePlaylist").value;sendAPI({cmd:"MPD_API_PLAYLIST_RM",data:{uri:a}});modalDeletePlaylist.hide()}
|
||||
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("inputJukeboxQueueLength");c=parseInt(b.value);isNaN(c)?(b.classList.add("is-invalid"),a=!1):0<c?b.value=c:(b.classList.add("is-invalid"),a=!1);settings.mixramp&&(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"),c=document.getElementById("selectJukeboxPlaylist"),b=document.getElementById("selectJukeboxMode"),sendAPI({cmd:"MPD_API_SETTINGS_SET",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:1==settings.mixramp?document.getElementById("inputMixrampdb").value:settings.mixrampdb,mixrampdelay:1==settings.mixramp?document.getElementById("inputMixrampdelay").value:settings.mixrampdelay,notificationWeb:document.getElementById("btnnotifyWeb").classList.contains("active")?
|
||||
@ -160,5 +163,5 @@ function doSetFilterLetter(a){var b=document.getElementById(a+"Letters").getElem
|
||||
function addFilterLetter(a){for(var b='<button class="mr-1 mb-1 btn btn-sm btn-secondary material-icons material-icons-small">delete</button><button class="mr-1 mb-1 btn btn-sm btn-secondary">#</button>',c=65;90>=c;c++)b+='<button class="mr-1 mb-1 btn-sm btn btn-secondary">'+String.fromCharCode(c)+"</button>";a=document.getElementById(a);a.innerHTML=b;a.addEventListener("click",function(a){switch(a.target.innerText){case "delete":b="-";break;case "#":b="0";break;default:b=a.target.innerText}appGoto(app.current.app,
|
||||
app.current.tab,app.current.view,"0/"+b+"/"+app.current.search)},!1)}function selectTag(a,b,c){a=document.getElementById(a);var d=a.querySelector(".active");d&&d.classList.remove("active");if(d=a.querySelector("[data-tag="+c+"]"))d.classList.add("active"),document.getElementById(b).innerText=d.innerText}
|
||||
function addTagList(a,b){var c="",d="Title MUSICBRAINZ_TRACKID Count Disc Comment Name".split(" ");1==b&&(c+='<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="any">Any Tag</button>');for(var e=0;e<settings.tags.length;e++)"Track"!=settings.tags[e]&&(0==b&&-1<d.indexOf(settings.tags[e])||(c+='<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="'+settings.tags[e]+'">'+settings.tags[e]+"</button>"));document.getElementById(a).innerHTML=c}
|
||||
function gotoTagList(){appGoto(app.current.app,app.current.tab,app.current.view,"0/-/")}function chVolume(a){a=parseInt(domCache.volumeBar.value)+a;0>a?a=0:100<a&&(a=100);domCache.volumeBar.value=a;sendAPI({cmd:"MPD_API_PLAYER_VOLUME",data:{volume:a}})}function beautifyDuration(a){var b=Math.floor(a/86400),c=Math.floor(a/3600)-24*b,d=Math.floor(a/60)-60*c-1440*b;a=a-86400*b-3600*c-60*d;return(0<b?b+"\u2009d ":"")+(0<c?c+"\u2009h "+(10>d?"0":""):"")+d+"\u2009m "+(10>a?"0":"")+a+"\u2009s"}
|
||||
function gotoTagList(){appGoto(app.current.app,app.current.tab,app.current.view,"0/-/")}function chVolume(a){a=parseInt(domCache.volumeBar.value)+a;0>a?a=0:100<a&&(a=100);domCache.volumeBar.value=a;sendAPI({cmd:"MPD_API_PLAYER_VOLUME_SET",data:{volume:a}})}function beautifyDuration(a){var b=Math.floor(a/86400),c=Math.floor(a/3600)-24*b,d=Math.floor(a/60)-60*c-1440*b;a=a-86400*b-3600*c-60*d;return(0<b?b+"\u2009d ":"")+(0<c?c+"\u2009h "+(10>d?"0":""):"")+d+"\u2009m "+(10>a?"0":"")+a+"\u2009s"}
|
||||
function genId(a){return"id"+a.replace(/[^\w\-]/g,"")}appInit();
|
||||
|
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-v4.3.1",urlsToCache="/ /player.html /css/bootstrap.min.css /css/mympd.min.css /js/bootstrap-native-v4.min.js /js/mympd.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-v4.4.0",urlsToCache="/ /player.html /css/bootstrap.min.css /css/mympd.min.css /js/bootstrap-native-v4.min.js /js/mympd.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/coverimage-loading.png /assets/favicon.ico /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){if(a.request.url.match("^http://"))return!1;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)}))}))});
|
||||
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 4.5 KiB |
BIN
htdocs/assets/coverimage-loading.png
Normal file
BIN
htdocs/assets/coverimage-loading.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 4.4 KiB |
@ -33,10 +33,6 @@ button {
|
||||
}
|
||||
|
||||
|
||||
.card {
|
||||
min-height: 350px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 576px) {
|
||||
.header-logo {
|
||||
display:none !important;
|
||||
@ -61,6 +57,7 @@ small {
|
||||
|
||||
.album-cover {
|
||||
background-size: cover;
|
||||
background-image: url("/assets/coverimage-loading.png");
|
||||
border: 1px solid black;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
@ -78,28 +75,25 @@ small {
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.pull-right {
|
||||
float: right !important;
|
||||
float: right !important;
|
||||
}
|
||||
|
||||
.card-toolbar {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.card-toolbar > div, .card-toolbar > form {
|
||||
margin-bottom: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Material Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(/assets/MaterialIcons-Regular.eot); /* For IE6-8 */
|
||||
src: local('Material Icons'),
|
||||
local('MaterialIcons-Regular');
|
||||
src: url(/assets/MaterialIcons-Regular.woff2) format('woff2'),
|
||||
url(/assets/MaterialIcons-Regular.woff) format('woff'),
|
||||
url(/assets/MaterialIcons-Regular.ttf) format('truetype');
|
||||
@ -179,24 +173,27 @@ small {
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
font-size:2rem;
|
||||
float:left;
|
||||
margin-right:5px;
|
||||
font-size: 2rem;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.letters > button {
|
||||
width:28px;
|
||||
height:28px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.col-md {
|
||||
max-width:250px;
|
||||
min-width:250px;
|
||||
max-width: 250px;
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
a.card-img-top {
|
||||
overflow:hidden;
|
||||
display:block;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
background-size: cover;
|
||||
background-image: url(/assets/coverimage-loading.png);
|
||||
}
|
||||
|
||||
button.active {
|
||||
@ -269,6 +266,7 @@ caption {
|
||||
#updateDBprogress {
|
||||
width:20px;
|
||||
}
|
||||
|
||||
.updateDBprogressAnimate {
|
||||
animation-duration: 2s;
|
||||
animation-name: changewidth;
|
||||
@ -284,8 +282,17 @@ caption {
|
||||
}
|
||||
|
||||
#BrowseDatabaseAlbumListCaption {
|
||||
width:100%;
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#BrowseDatabaseAlbumListCaption h2 {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#BrowseDatabaseAlbumListCaption small {
|
||||
padding-top: 0.8rem;
|
||||
}
|
||||
|
||||
#menu-dbupdate {
|
||||
|
@ -337,7 +337,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Artist</th>
|
||||
<th id="BrowseDatabaseTagListCaption"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="clickable">
|
||||
@ -346,7 +346,7 @@
|
||||
</div>
|
||||
|
||||
<div id="BrowseDatabaseAlbumList" class="row hide">
|
||||
<h2 id="BrowseDatabaseAlbumListCaption"></h2>
|
||||
<div id="BrowseDatabaseAlbumListCaption"></div>
|
||||
</div>
|
||||
|
||||
<div class="btn-toolbar hide" id="BrowseDatabaseButtonsBottom">
|
||||
@ -646,6 +646,29 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="modalDeletePlaylist" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><span class="material-icons title-icon">delete</span>Delete playlist</h5>
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="deletePlaylistFrm">
|
||||
<div class="form-group">
|
||||
<label for="deletePlaylist">Playlist</label>
|
||||
<input type="text" class="form-control" id="deletePlaylist" readonly>
|
||||
</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": "delPlaylist", "options": []}'>Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="modalSaveSmartPlaylist" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
@ -838,7 +861,7 @@
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<h4><a class="text-success" rel="noreferrer" href="https://github.com/jcorporation/ympd">myMPD</a> – <small>MPD Web GUI - written in C, utilizing Websockets and Bootstrap/JS</small></h4>
|
||||
<h4><a class="text-success" rel="noreferrer" href="https://github.com/jcorporation/ympd">myMPD</a> – <small>a standalone and mobile friendly web mpdclient</small></h4>
|
||||
<p>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 <a class="text-success" href="http://www.ympd.org">ympd</a>.</p>
|
||||
<ul>
|
||||
<li>Version: <span id="mympdVersion"></span></li>
|
||||
|
@ -49,20 +49,14 @@ app.apps = { "Playback": { "state": "0/-/", "scrollPos": 0 },
|
||||
},
|
||||
"Database": {
|
||||
"active": "AlbumArtist",
|
||||
"views": { "AlbumArtist": { "state": "0/-/", "scrollPos": 0 },
|
||||
"Genre": { "state": "0/-/", "scrollPos": 0 },
|
||||
"Artist": { "state": "0/-/", "scrollPos": 0 },
|
||||
"Composer": { "state": "0/-/", "scrollPos": 0 },
|
||||
"Performer": { "state": "0/-/", "scrollPos": 0 },
|
||||
"Date": { "state": "0/-/", "scrollPos": 0 },
|
||||
"Album": { "state": "0/-/", "scrollPos": 0 },
|
||||
"views": {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Search": { "state": "0/any/", "scrollPos": 0 }
|
||||
};
|
||||
|
||||
|
||||
app.current = { "app": "Playback", "tab": undefined, "view": undefined, "page": 0, "filter": "", "search": "", "scrollPos": 0 };
|
||||
app.last = { "app": undefined, "tab": undefined, "view": undefined, "filter": "", "search": "", "scrollPos": 0 };
|
||||
|
||||
@ -98,8 +92,7 @@ var modalAddToPlaylist = new Modal(document.getElementById('modalAddToPlaylist')
|
||||
var modalRenamePlaylist = new Modal(document.getElementById('modalRenamePlaylist'));
|
||||
var modalUpdateDB = new Modal(document.getElementById('modalUpdateDB'));
|
||||
var modalSaveSmartPlaylist = new Modal(document.getElementById('modalSaveSmartPlaylist'));
|
||||
//var mainMenu = new Dropdown(document.getElementById('mainMenu'));
|
||||
//var volumeMenu = new Dropdown(document.getElementById('volumeIcon'));
|
||||
var modalDeletePlaylist = new Modal(document.getElementById('modalDeletePlaylist'));
|
||||
|
||||
function appPrepare(scrollPos) {
|
||||
if (app.current.app != app.last.app || app.current.tab != app.last.tab || app.current.view != app.last.view) {
|
||||
@ -311,7 +304,7 @@ function appInit() {
|
||||
event.stopPropagation();
|
||||
}, false);
|
||||
domCache.volumeBar.addEventListener('change', function(event) {
|
||||
sendAPI({"cmd": "MPD_API_PLAYER_VOLUME", "data": {"volume": domCache.volumeBar.value}});
|
||||
sendAPI({"cmd": "MPD_API_PLAYER_VOLUME_SET", "data": {"volume": domCache.volumeBar.value}});
|
||||
}, false);
|
||||
|
||||
domCache.progressBar.value = 0;
|
||||
@ -551,9 +544,6 @@ function appInit() {
|
||||
}, false);
|
||||
|
||||
document.getElementsByTagName('body')[0].addEventListener('click', function(event) {
|
||||
// var oldPopover = document.getElementsByClassName('popover');
|
||||
// for (var i = 0; i < oldPopover.length; i++)
|
||||
// oldPopover[i].remove();
|
||||
hideMenu();
|
||||
}, false);
|
||||
|
||||
@ -726,7 +716,6 @@ function dragAndDropTable(table) {
|
||||
|
||||
function playlistMoveTrack(from, to) {
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_MOVE_TRACK","data": { "plist": app.current.search, "from": from, "to": to}});
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_CONTENT_LIST","data": {"offset": app.current.page, "filter": app.current.filter, "uri": app.current.search}}, parsePlaylists);
|
||||
}
|
||||
|
||||
function webSocketConnect() {
|
||||
@ -777,6 +766,15 @@ function webSocketConnect() {
|
||||
case 'update_finished':
|
||||
updateDBfinished(obj.type);
|
||||
break;
|
||||
case 'update_volume':
|
||||
parseVolume(obj);
|
||||
break;
|
||||
case 'update_stored_playlist':
|
||||
if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'All')
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_LIST","data": {"offset": app.current.page, "filter": app.current.filter}}, parsePlaylists);
|
||||
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'Detail')
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_CONTENT_LIST", "data": {"offset": app.current.page, "filter": app.current.filter, "uri": app.current.search}}, parsePlaylists);
|
||||
break;
|
||||
case 'error':
|
||||
showNotification(obj.data, '', '', 'danger');
|
||||
break;
|
||||
@ -935,6 +933,10 @@ function parseSettings(obj) {
|
||||
addTagList('BrowseDatabaseByTagDropdown', false);
|
||||
addTagList('searchqueuetag', true);
|
||||
addTagList('searchtags', true);
|
||||
|
||||
for (var i = 0; i < obj.data.tags.length; i++) {
|
||||
app.apps.Browse.tabs.Database.views[obj.data.tags[i]] = { "state": "0/-/", "scrollPos": 0 };
|
||||
}
|
||||
}
|
||||
|
||||
function getSettings() {
|
||||
@ -1036,20 +1038,7 @@ function parseState(obj) {
|
||||
domCache.btnsPlay[i].removeAttribute('disabled');
|
||||
|
||||
//Set volume
|
||||
if (obj.data.volume == -1) {
|
||||
domCache.volumePrct.innerText = 'Volumecontrol disabled';
|
||||
domCache.volumeControl.classList.add('hide');
|
||||
} else {
|
||||
domCache.volumeControl.classList.remove('hide');
|
||||
domCache.volumePrct.innerText = obj.data.volume + ' %';
|
||||
if (obj.data.volume == 0)
|
||||
domCache.volumeIcon.innerText = 'volume_off';
|
||||
else if (obj.data.volume < 50)
|
||||
domCache.volumeIcon.innerText = 'volume_down';
|
||||
else
|
||||
domCache.volumeIcon.innerText = 'volume_up';
|
||||
}
|
||||
domCache.volumeBar.value = obj.data.volume;
|
||||
parseVolume(obj);
|
||||
|
||||
//Set play counters
|
||||
setCounter(obj.data.currentSongId, obj.data.totalTime, obj.data.elapsedTime);
|
||||
@ -1068,12 +1057,29 @@ function parseState(obj) {
|
||||
lastState = obj;
|
||||
}
|
||||
|
||||
function parseVolume(obj) {
|
||||
if (obj.data.volume == -1) {
|
||||
domCache.volumePrct.innerText = 'Volumecontrol disabled';
|
||||
domCache.volumeControl.classList.add('hide');
|
||||
}
|
||||
else {
|
||||
domCache.volumeControl.classList.remove('hide');
|
||||
domCache.volumePrct.innerText = obj.data.volume + ' %';
|
||||
if (obj.data.volume == 0)
|
||||
domCache.volumeIcon.innerText = 'volume_off';
|
||||
else if (obj.data.volume < 50)
|
||||
domCache.volumeIcon.innerText = 'volume_down';
|
||||
else
|
||||
domCache.volumeIcon.innerText = 'volume_up';
|
||||
}
|
||||
domCache.volumeBar.value = obj.data.volume;
|
||||
}
|
||||
|
||||
function getQueue() {
|
||||
if (app.current.search.length >= 2)
|
||||
sendAPI({"cmd": "MPD_API_QUEUE_SEARCH", "data": {"filter": app.current.filter, "offset": app.current.page, "searchstr": app.current.search}}, parseQueue);
|
||||
else {
|
||||
else
|
||||
sendAPI({"cmd": "MPD_API_QUEUE_LIST", "data": {"offset": app.current.page}}, parseQueue);
|
||||
}
|
||||
}
|
||||
|
||||
function parseQueue(obj) {
|
||||
@ -1225,9 +1231,11 @@ function parsePlaylists(obj) {
|
||||
}
|
||||
document.getElementById('BrowsePlaylistsDetailList').setAttribute('data-uri', obj.uri);
|
||||
if (obj.smartpls == true)
|
||||
document.getElementById('BrowsePlaylistsDetailList').getElementsByTagName('caption')[0].innerText = 'Smart playlist: ' + obj.uri;
|
||||
document.getElementById('BrowsePlaylistsDetailList').getElementsByTagName('caption')[0].innerHTML = 'Smart playlist: ' + obj.uri +
|
||||
'<small class="pull-right">' + obj.totalEntities + ' Songs </small>';
|
||||
else
|
||||
document.getElementById('BrowsePlaylistsDetailList').getElementsByTagName('caption')[0].innerText = 'Playlist: ' + obj.uri;
|
||||
document.getElementById('BrowsePlaylistsDetailList').getElementsByTagName('caption')[0].innerHTML = 'Playlist: ' + obj.uri +
|
||||
'<small class="pull-right">' + obj.totalEntities + ' Songs </small>';
|
||||
document.getElementById('BrowsePlaylistsDetailList').classList.remove('hide');
|
||||
document.getElementById('BrowsePlaylistsAllList').classList.add('hide');
|
||||
document.getElementById('btnBrowsePlaylistsAll').parentNode.classList.remove('hide');
|
||||
@ -1305,8 +1313,7 @@ function parsePlaylists(obj) {
|
||||
}
|
||||
|
||||
function parseListDBtags(obj) {
|
||||
// if (app.current.app !== 'Browse' && app.current.tab !== 'Database' && app.current.view !== 'AlbumArtist')
|
||||
// return;
|
||||
scrollTo(0);
|
||||
if (app.current.search != '') {
|
||||
document.getElementById('BrowseDatabaseAlbumList').classList.remove('hide');
|
||||
document.getElementById('BrowseDatabaseTagList').classList.add('hide');
|
||||
@ -1314,12 +1321,13 @@ function parseListDBtags(obj) {
|
||||
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').innerText = obj.searchtagtype + ': ' + obj.searchstr;
|
||||
document.getElementById('BrowseDatabaseAlbumListCaption').innerHTML = '<h2>' + obj.searchtagtype + ': ' + obj.searchstr + '</h2>' +
|
||||
'<small class="pull-right">' + obj.totalEntities + ' Entries</small><hr/>';
|
||||
var nrItems = obj.data.length;
|
||||
var cardContainer = document.getElementById('BrowseDatabaseAlbumList');
|
||||
var cards = cardContainer.getElementsByClassName('col-md');
|
||||
for (var i = 0; i < nrItems; i++) {
|
||||
var id=genId(obj.data[i].value);
|
||||
var id = genId(obj.data[i].value);
|
||||
if (cards[i])
|
||||
if (cards[i].getAttribute('id') == id)
|
||||
continue;
|
||||
@ -1327,12 +1335,17 @@ function parseListDBtags(obj) {
|
||||
card.classList.add('col-md');
|
||||
card.classList.add('mr-0');
|
||||
card.setAttribute('id', id);
|
||||
card.setAttribute('data-album', encodeURI(obj.data[i].value));
|
||||
card.innerHTML = '<div class="card mb-4" id="card' + id + '">' +
|
||||
' <a href="#" class="card-img-top"><img class="card-img-top" src="" ></a>' +
|
||||
' <a href="#" class="card-img-top"></a>' +
|
||||
' <div class="card-body">' +
|
||||
' <h5 class="card-title" id="albumartist' + id + '"></h5>' +
|
||||
' <h4 class="card-title">' + obj.data[i].value + '</h4>' +
|
||||
' <table class="table table-sm table-hover" id="tbl' + id + '"><tbody></tbody></table'+
|
||||
' <a class="color-darkgrey" data-toggle="collapse" href="#collapse' + id +'" id="collapseLink' + id +'">' +
|
||||
' <span class="material-icons">keyboard_arrow_right</span> Show Titles</a> ' +
|
||||
' <div class="collapse" id="collapse' + id +'">' +
|
||||
' <table class="table table-sm table-hover" id="tbl' + id + '"><tbody></tbody></table>'+
|
||||
' </div>' +
|
||||
' </div>'+
|
||||
'</div>';
|
||||
|
||||
@ -1340,8 +1353,11 @@ function parseListDBtags(obj) {
|
||||
cards[i].replaceWith(card);
|
||||
else
|
||||
cardContainer.append(card);
|
||||
|
||||
sendAPI({"cmd": "MPD_API_DATABASE_TAG_ALBUM_TITLE_LIST", "data": { "album": obj.data[i].value, "search": app.current.search, "tag": app.current.view}}, parseListTitles);
|
||||
|
||||
if ('IntersectionObserver' in window)
|
||||
createListTitleObserver(document.getElementById(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);
|
||||
}
|
||||
var cardsLen = cards.length - 1;
|
||||
for (var i = cardsLen; i >= nrItems; i --) {
|
||||
@ -1356,7 +1372,7 @@ function parseListDBtags(obj) {
|
||||
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 + '<small class="pull-right">' + obj.totalEntities +' Tags</small>';
|
||||
var nrItems = obj.data.length;
|
||||
var tbody = document.getElementById(app.current.app + app.current.tab + 'TagList').getElementsByTagName('tbody')[0];
|
||||
var tr = tbody.getElementsByTagName('tr');
|
||||
@ -1390,21 +1406,47 @@ function parseListDBtags(obj) {
|
||||
}
|
||||
}
|
||||
|
||||
function createListTitleObserver(ele) {
|
||||
var options = {
|
||||
root: null,
|
||||
rootMargin: "0px",
|
||||
};
|
||||
|
||||
var observer = new IntersectionObserver(getListTitles, options);
|
||||
observer.observe(ele);
|
||||
}
|
||||
|
||||
function getListTitles(changes, observer) {
|
||||
changes.forEach(change => {
|
||||
if (change.intersectionRatio > 0) {
|
||||
observer.unobserve(change.target);
|
||||
var album = decodeURI(change.target.getAttribute('data-album'));
|
||||
sendAPI({"cmd": "MPD_API_DATABASE_TAG_ALBUM_TITLE_LIST", "data": { "album": album, "search": app.current.search, "tag": app.current.view}}, parseListTitles);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function parseListTitles(obj) {
|
||||
// if (app.current.app !== 'Browse' && app.current.tab !== 'Database' && app.current.view !== 'Album')
|
||||
// return;
|
||||
|
||||
var id = genId(obj.album);
|
||||
var card = document.getElementById('card' + id)
|
||||
var tbody = card.getElementsByTagName('tbody')[0];
|
||||
var img = card.getElementsByTagName('img')[0];
|
||||
var imga = img.parentNode;
|
||||
img.setAttribute('src', obj.cover);
|
||||
imga.setAttribute('data-uri', encodeURI(obj.data[0].uri.replace(/\/[^\/]+$/, '')));
|
||||
imga.setAttribute('data-name', obj.album);
|
||||
imga.setAttribute('data-type', 'dir');
|
||||
var img = card.getElementsByTagName('a')[0];
|
||||
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');
|
||||
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 = '<span class="material-icons">keyboard_arrow_down</span> Hide Titles';
|
||||
}, false);
|
||||
document.getElementById('collapse' + id).addEventListener('hidden.bs.collapse', function() {
|
||||
titleTable.innerHTML = '<span class="material-icons">keyboard_arrow_right</span> Show Titles';
|
||||
}, false);
|
||||
|
||||
var titleList = '';
|
||||
var nrItems = obj.data.length;
|
||||
for (var i = 0; i < nrItems; i++) {
|
||||
@ -1415,7 +1457,7 @@ function parseListTitles(obj) {
|
||||
}
|
||||
tbody.innerHTML = titleList;
|
||||
|
||||
imga.addEventListener('click', function(event) {
|
||||
img.addEventListener('click', function(event) {
|
||||
showMenu(this, event);
|
||||
}, false);
|
||||
|
||||
@ -1572,14 +1614,12 @@ function removeFromPlaylist(uri, pos) {
|
||||
pos--;
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_RM_TRACK", "data": {"uri": uri, "track": pos}});
|
||||
document.getElementById('BrowsePlaylistsDetailList').classList.add('opacity05');
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_CONTENT_LIST", "data": {"offset": app.current.page, "filter": app.current.filter, "uri": app.current.search}}, parsePlaylists);
|
||||
}
|
||||
|
||||
function playlistClear() {
|
||||
var uri = document.getElementById('BrowsePlaylistsDetailList').getAttribute('data-uri');
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_CLEAR", "data": {"uri": uri}});
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_CLEAR_AND_LIST", "data": {"uri": uri}});
|
||||
document.getElementById('BrowsePlaylistsDetailList').classList.add('opacity05');
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_CONTENT_LIST", "data": {"offset": app.current.page, "filter": app.current.filter, "uri": app.current.search}}, parsePlaylists);
|
||||
}
|
||||
|
||||
function getAllPlaylists(obj) {
|
||||
@ -1847,7 +1887,6 @@ function renamePlaylist() {
|
||||
if (to != '' && to != from && valid == '') {
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_RENAME", "data": {"from": from, "to": to}});
|
||||
modalRenamePlaylist.hide();
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_LIST","data": {"offset": app.current.page, "filter": app.current.filter}}, parsePlaylists);
|
||||
}
|
||||
else {
|
||||
document.getElementById('renamePlaylistTo').classList.add('is-invalid');
|
||||
@ -1939,7 +1978,7 @@ function showMenu(el, event) {
|
||||
(type == 'smartpls' ? addMenuItem({"cmd": "showSmartPlaylist", "options": [uri]}, 'Edit smart playlist') : '') +
|
||||
(uri.indexOf('myMPDsmart') != 0 ?
|
||||
addMenuItem({"cmd": "showRenamePlaylist", "options": [uri]}, 'Rename playlist') +
|
||||
addMenuItem({"cmd": "delPlaylist", "options": [uri]}, 'Delete playlist') : '');
|
||||
addMenuItem({"cmd": "showDelPlaylist", "options": [uri]}, 'Delete playlist') : '');
|
||||
}
|
||||
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'Detail') {
|
||||
var x = document.getElementById('BrowsePlaylistsDetailList');
|
||||
@ -2099,9 +2138,15 @@ function delQueueSong(mode, start, end) {
|
||||
sendAPI({"cmd": "MPD_API_QUEUE_RM_TRACK", "data": { "track": start}});
|
||||
}
|
||||
|
||||
function delPlaylist(uri) {
|
||||
function showDelPlaylist(uri) {
|
||||
document.getElementById('deletePlaylist').value = uri;
|
||||
modalDeletePlaylist.show();
|
||||
}
|
||||
|
||||
function delPlaylist() {
|
||||
var uri = document.getElementById('deletePlaylist').value;
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_RM", "data": {"uri": uri}});
|
||||
sendAPI({"cmd": "MPD_API_PLAYLIST_LIST","data": {"offset": app.current.page, "filter": app.current.filter}}, parsePlaylists);
|
||||
modalDeletePlaylist.hide();
|
||||
}
|
||||
|
||||
function confirmSettings() {
|
||||
@ -2419,7 +2464,7 @@ function chVolume(increment) {
|
||||
else if (newValue > 100)
|
||||
newValue = 100;
|
||||
domCache.volumeBar.value = newValue;
|
||||
sendAPI({"cmd": "MPD_API_PLAYER_VOLUME", "data": {"volume": newValue}});
|
||||
sendAPI({"cmd": "MPD_API_PLAYER_VOLUME_SET", "data": {"volume": newValue}});
|
||||
}
|
||||
|
||||
function beautifyDuration(x) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
var CACHE = 'myMPD-cache-v4.3.1';
|
||||
var CACHE = 'myMPD-cache-v4.4.0';
|
||||
var urlsToCache = [
|
||||
'/',
|
||||
'/player.html',
|
||||
@ -12,8 +12,8 @@ var urlsToCache = [
|
||||
'/assets/appicon-512.png',
|
||||
'/assets/coverimage-httpstream.png',
|
||||
'/assets/coverimage-notavailable.png',
|
||||
'/assets/coverimage-loading.png',
|
||||
'/assets/favicon.ico',
|
||||
'/assets/MaterialIcons-Regular.eot',
|
||||
'/assets/MaterialIcons-Regular.ttf',
|
||||
'/assets/MaterialIcons-Regular.woff',
|
||||
'/assets/MaterialIcons-Regular.woff2'
|
||||
|
121
src/mpd_client.c
121
src/mpd_client.c
@ -322,13 +322,16 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||
}
|
||||
break;
|
||||
case MPD_API_PLAYER_VOLUME:
|
||||
case MPD_API_PLAYER_VOLUME_SET:
|
||||
je = json_scanf(msg.p, msg.len, "{data: {volume:%u}}", &uint_buf1);
|
||||
if (je == 1) {
|
||||
mpd_run_set_volume(mpd.conn, uint_buf1);
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||
}
|
||||
break;
|
||||
case MPD_API_PLAYER_VOLUME_GET:
|
||||
n = mympd_put_volume(mpd.buf);
|
||||
break;
|
||||
case MPD_API_PLAYER_SEEK:
|
||||
je = json_scanf(msg.p, msg.len, "{data: {songid: %u, seek: %u}}", &uint_buf1, &uint_buf2);
|
||||
if (je == 2) {
|
||||
@ -641,7 +644,7 @@ void mympd_parse_idle(struct mg_mgr *s, int idle_bitmask) {
|
||||
}
|
||||
break;
|
||||
case MPD_IDLE_MIXER:
|
||||
len = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.last_song_id, &mpd.queue_version, &mpd.queue_length);
|
||||
len = mympd_put_volume(mpd.buf);
|
||||
break;
|
||||
case MPD_IDLE_OUTPUT:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_outputs\"}");
|
||||
@ -811,11 +814,8 @@ int mympd_get_updatedb_state(char *buffer) {
|
||||
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
||||
|
||||
status = mpd_run_status(mpd.conn);
|
||||
if (!status) {
|
||||
printf("MPD mpd_run_status: %s\n", mpd_connection_get_error_message(mpd.conn));
|
||||
mpd.conn_state = MPD_FAILURE;
|
||||
return 0;
|
||||
}
|
||||
if (!status)
|
||||
RETURN_ERROR_AND_RECOVER("replay_gain_status");
|
||||
update_id = mpd_status_get_update_id(status);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Update database ID: %d\n", update_id);
|
||||
@ -827,8 +827,7 @@ int mympd_get_updatedb_state(char *buffer) {
|
||||
|
||||
mpd_status_free(status);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1139,8 +1138,28 @@ int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *
|
||||
*queue_length = mpd_status_get_queue_length(status);
|
||||
mpd_status_free(status);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
int mympd_put_volume(char *buffer) {
|
||||
struct mpd_status *status;
|
||||
int len;
|
||||
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
||||
|
||||
status = mpd_run_status(mpd.conn);
|
||||
if (!status) {
|
||||
printf("MPD mpd_run_status: %s\n", mpd_connection_get_error_message(mpd.conn));
|
||||
mpd.conn_state = MPD_FAILURE;
|
||||
return 0;
|
||||
}
|
||||
len = json_printf(&out, "{type: update_volume, data: {"
|
||||
"volume: %d}}",
|
||||
mpd_status_get_volume(status)
|
||||
);
|
||||
mpd_status_free(status);
|
||||
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1150,8 +1169,7 @@ int mympd_put_welcome(char *buffer) {
|
||||
|
||||
len = json_printf(&out, "{type: welcome, data: {version: %Q}}", MYMPD_VERSION);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1239,7 +1257,7 @@ int mympd_put_settings(char *buffer) {
|
||||
config.stickers,
|
||||
config.mixramp,
|
||||
config.smartpls,
|
||||
MAX_ELEMENTS_PER_PAGE,
|
||||
config.max_elements_per_page,
|
||||
replaygain,
|
||||
mympd_state.notificationWeb,
|
||||
mympd_state.notificationPage,
|
||||
@ -1260,8 +1278,7 @@ int mympd_put_settings(char *buffer) {
|
||||
|
||||
len += json_printf(&out, "]}}");
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1292,15 +1309,14 @@ int mympd_put_outputs(char *buffer) {
|
||||
|
||||
len += json_printf(&out,"]}}");
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
int replacechar(char *str, char orig, char rep) {
|
||||
char *ix = str;
|
||||
int n = 0;
|
||||
while((ix = strchr(ix, orig)) != NULL) {
|
||||
while ((ix = strchr(ix, orig)) != NULL) {
|
||||
*ix++ = rep;
|
||||
n++;
|
||||
}
|
||||
@ -1384,8 +1400,7 @@ int mympd_put_current_song(char *buffer) {
|
||||
len += json_printf(&out, "}}");
|
||||
mpd_song_free(song);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1434,8 +1449,7 @@ int mympd_put_songdetails(char *buffer, char *uri) {
|
||||
}
|
||||
len += json_printf(&out, "}}");
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1451,7 +1465,7 @@ int mympd_put_queue(char *buffer, unsigned int offset, unsigned *queue_version,
|
||||
if (!status)
|
||||
RETURN_ERROR_AND_RECOVER("mpd_run_status");
|
||||
|
||||
if (!mpd_send_list_queue_range_meta(mpd.conn, offset, offset + MAX_ELEMENTS_PER_PAGE))
|
||||
if (!mpd_send_list_queue_range_meta(mpd.conn, offset, offset + config.max_elements_per_page))
|
||||
RETURN_ERROR_AND_RECOVER("mpd_send_list_queue_meta");
|
||||
|
||||
len = json_printf(&out, "{type: queue, data: [");
|
||||
@ -1491,8 +1505,7 @@ int mympd_put_queue(char *buffer, unsigned int offset, unsigned *queue_version,
|
||||
*queue_length = mpd_status_get_queue_length(status);
|
||||
mpd_status_free(status);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1512,11 +1525,11 @@ int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter
|
||||
|
||||
len = json_printf(&out, "{type: browse, data: [");
|
||||
|
||||
while((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
||||
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
||||
const struct mpd_song *song;
|
||||
const struct mpd_directory *dir;
|
||||
entity_count ++;
|
||||
if (entity_count > offset && entity_count <= offset + MAX_ELEMENTS_PER_PAGE) {
|
||||
if (entity_count > offset && entity_count <= offset + config.max_elements_per_page) {
|
||||
switch (mpd_entity_get_type(entity)) {
|
||||
case MPD_ENTITY_TYPE_UNKNOWN:
|
||||
entity_count --;
|
||||
@ -1612,8 +1625,7 @@ int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter
|
||||
filter
|
||||
);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1636,9 +1648,9 @@ int mympd_put_db_tag(char *buffer, unsigned int offset, char *mpdtagtype, char *
|
||||
RETURN_ERROR_AND_RECOVER("mpd_search_commit");
|
||||
|
||||
len = json_printf(&out, "{type: listDBtags, data: [");
|
||||
while((pair = mpd_recv_pair_tag(mpd.conn, mpd_tag_name_parse(mpdtagtype))) != NULL) {
|
||||
while ((pair = mpd_recv_pair_tag(mpd.conn, mpd_tag_name_parse(mpdtagtype))) != NULL) {
|
||||
entity_count ++;
|
||||
if (entity_count > offset && entity_count <= offset + MAX_ELEMENTS_PER_PAGE) {
|
||||
if (entity_count > offset && entity_count <= offset + config.max_elements_per_page) {
|
||||
if (strcmp(pair->value, "") == 0) {
|
||||
entity_count --;
|
||||
}
|
||||
@ -1669,8 +1681,7 @@ int mympd_put_db_tag(char *buffer, unsigned int offset, char *mpdtagtype, char *
|
||||
filter
|
||||
);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1697,9 +1708,9 @@ int mympd_put_songs_in_album(char *buffer, char *album, char *search, char *tag)
|
||||
else {
|
||||
len = json_printf(&out, "{type: listTitles, data: [");
|
||||
|
||||
while((song = mpd_recv_song(mpd.conn)) != NULL) {
|
||||
while ((song = mpd_recv_song(mpd.conn)) != NULL) {
|
||||
entity_count ++;
|
||||
if (entity_count <= MAX_ELEMENTS_PER_PAGE) {
|
||||
if (entity_count <= config.max_elements_per_page) {
|
||||
if (entities_returned ++)
|
||||
len += json_printf(&out, ", ");
|
||||
else {
|
||||
@ -1728,8 +1739,7 @@ int mympd_put_songs_in_album(char *buffer, char *album, char *search, char *tag)
|
||||
}
|
||||
free(albumartist);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1748,9 +1758,9 @@ int mympd_put_playlists(char *buffer, unsigned int offset, char *filter) {
|
||||
|
||||
len = json_printf(&out, "{type: playlists, data: [");
|
||||
|
||||
while((pl = mpd_recv_playlist(mpd.conn)) != NULL) {
|
||||
while ((pl = mpd_recv_playlist(mpd.conn)) != NULL) {
|
||||
entity_count ++;
|
||||
if (entity_count > offset && entity_count <= offset + MAX_ELEMENTS_PER_PAGE) {
|
||||
if (entity_count > offset && entity_count <= offset + config.max_elements_per_page) {
|
||||
plpath = mpd_playlist_get_path(pl);
|
||||
if (strncmp(filter,"-",1) == 0 || strncasecmp(filter, plpath, 1) == 0 ||
|
||||
(strncmp(filter, "0", 1) == 0 && isalpha(*plpath) == 0 )
|
||||
@ -1775,17 +1785,13 @@ int mympd_put_playlists(char *buffer, unsigned int offset, char *filter) {
|
||||
mpd_playlist_free(pl);
|
||||
}
|
||||
|
||||
if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(mpd.conn))
|
||||
RETURN_ERROR_AND_RECOVER("mpd_send_list_playlists");
|
||||
|
||||
len += json_printf(&out, "], totalEntities: %d, offset: %d, returnedEntities: %d}",
|
||||
entity_count,
|
||||
offset,
|
||||
entities_returned
|
||||
);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1804,10 +1810,10 @@ int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char *
|
||||
|
||||
len = json_printf(&out, "{type: playlist_detail, data: [");
|
||||
|
||||
while((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
||||
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
||||
const struct mpd_song *song;
|
||||
entity_count ++;
|
||||
if (entity_count > offset && entity_count <= offset + MAX_ELEMENTS_PER_PAGE) {
|
||||
if (entity_count > offset && entity_count <= offset + config.max_elements_per_page) {
|
||||
song = mpd_entity_get_song(entity);
|
||||
entityName = mympd_get_tag(song, MPD_TAG_TITLE);
|
||||
if (strncmp(filter, "-", 1) == 0 || strncasecmp(filter, entityName, 1) == 0 ||
|
||||
@ -1843,8 +1849,7 @@ int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char *
|
||||
smartpls
|
||||
);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1872,7 +1877,7 @@ int mympd_search(char *buffer, char *searchstr, char *filter, char *plist, unsig
|
||||
if (strcmp(plist, "") == 0) {
|
||||
while ((song = mpd_recv_song(mpd.conn)) != NULL) {
|
||||
entity_count ++;
|
||||
if (entity_count > offset && entity_count <= offset + MAX_ELEMENTS_PER_PAGE) {
|
||||
if (entity_count > offset && entity_count <= offset + config.max_elements_per_page) {
|
||||
if (entities_returned ++)
|
||||
len += json_printf(&out, ", ");
|
||||
len += json_printf(&out, "{type: song, uri: %Q, album: %Q, artist: %Q, duration: %d, title: %Q, name: %Q}",
|
||||
@ -1901,8 +1906,7 @@ int mympd_search(char *buffer, char *searchstr, char *filter, char *plist, unsig
|
||||
else
|
||||
len = json_printf(&out, "{type: result, data: ok}");
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1930,8 +1934,7 @@ int mympd_queue_crop(char *buffer) {
|
||||
|
||||
mpd_status_free(status);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1962,7 +1965,7 @@ int mympd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char
|
||||
|
||||
while ((song = mpd_recv_song(mpd.conn)) != NULL) {
|
||||
entity_count ++;
|
||||
if (entity_count > offset && entity_count <= offset + MAX_ELEMENTS_PER_PAGE) {
|
||||
if (entity_count > offset && entity_count <= offset + config.max_elements_per_page) {
|
||||
if (entities_returned ++)
|
||||
len += json_printf(&out, ", ");
|
||||
len += json_printf(&out, "{type: song, id: %d, pos: %d, album: %Q, artist: %Q, duration: %d, title: %Q}",
|
||||
@ -1985,8 +1988,7 @@ int mympd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char
|
||||
);
|
||||
}
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -2014,8 +2016,7 @@ int mympd_put_stats(char *buffer) {
|
||||
);
|
||||
mpd_stats_free(stats);
|
||||
|
||||
if (len > MAX_SIZE)
|
||||
printf("Buffer truncated\n");
|
||||
CHECK_RETURN_LEN();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -2164,7 +2165,7 @@ int mympd_smartpls_clear(char *playlist) {
|
||||
LOG_ERROR_AND_RECOVER("mpd_send_list_playlists");
|
||||
return 1;
|
||||
}
|
||||
while((pl = mpd_recv_playlist(mpd.conn)) != NULL) {
|
||||
while ((pl = mpd_recv_playlist(mpd.conn)) != NULL) {
|
||||
plpath = mpd_playlist_get_path(pl);
|
||||
if (strcmp(playlist, plpath) == 0)
|
||||
exists = true;
|
||||
|
@ -44,8 +44,14 @@
|
||||
mpd.conn_state = MPD_FAILURE; \
|
||||
} while (0)
|
||||
|
||||
#define MAX_SIZE 1024 * 100
|
||||
#define MAX_ELEMENTS_PER_PAGE 100
|
||||
#define CHECK_RETURN_LEN() do { \
|
||||
if (len > MAX_SIZE) \
|
||||
printf("Buffer truncated: %d, %d\n", len, MAX_SIZE); \
|
||||
return len; \
|
||||
} while (0)
|
||||
|
||||
#define MAX_SIZE 2048 * 400
|
||||
#define MAX_ELEMENTS_PER_PAGE 400
|
||||
|
||||
#define GEN_ENUM(X) X,
|
||||
#define GEN_STR(X) #X,
|
||||
@ -65,12 +71,12 @@
|
||||
X(MPD_API_QUEUE_ADD_PLAYLIST) \
|
||||
X(MPD_API_QUEUE_REPLACE_PLAYLIST) \
|
||||
X(MPD_API_QUEUE_SHUFFLE) \
|
||||
X(MPD_API_PLAYLIST_RM) \
|
||||
X(MPD_API_PLAYLIST_CLEAR) \
|
||||
X(MPD_API_PLAYLIST_RENAME) \
|
||||
X(MPD_API_PLAYLIST_MOVE_TRACK) \
|
||||
X(MPD_API_PLAYLIST_ADD_TRACK) \
|
||||
X(MPD_API_PLAYLIST_RM_TRACK) \
|
||||
X(MPD_API_PLAYLIST_RM) \
|
||||
X(MPD_API_PLAYLIST_LIST) \
|
||||
X(MPD_API_PLAYLIST_CONTENT_LIST) \
|
||||
X(MPD_API_SMARTPLS_UPDATE_ALL) \
|
||||
@ -86,7 +92,8 @@
|
||||
X(MPD_API_DATABASE_STATS) \
|
||||
X(MPD_API_DATABASE_SONGDETAILS) \
|
||||
X(MPD_API_PLAYER_PLAY_TRACK) \
|
||||
X(MPD_API_PLAYER_VOLUME) \
|
||||
X(MPD_API_PLAYER_VOLUME_SET) \
|
||||
X(MPD_API_PLAYER_VOLUME_GET) \
|
||||
X(MPD_API_PLAYER_PAUSE) \
|
||||
X(MPD_API_PLAYER_PLAY) \
|
||||
X(MPD_API_PLAYER_STOP) \
|
||||
@ -160,6 +167,7 @@ typedef struct {
|
||||
const char* taglist;
|
||||
bool smartpls;
|
||||
const char* varlibdir;
|
||||
long max_elements_per_page;
|
||||
} t_config;
|
||||
|
||||
t_config config;
|
||||
@ -215,6 +223,7 @@ int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter
|
||||
int mympd_search(char *buffer, char *searchstr, char *filter, char *plist, unsigned int offset);
|
||||
int mympd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr);
|
||||
int mympd_put_welcome(char *buffer);
|
||||
int mympd_put_volume(char *buffer);
|
||||
int mympd_put_stats(char *buffer);
|
||||
int mympd_put_settings(char *buffer);
|
||||
int mympd_put_db_tag(char *buffer, unsigned int offset, char *mpdtagtype, char *mpdsearchtagtype, char *searchstr, char *filter);
|
||||
|
10
src/mympd.c
10
src/mympd.c
@ -173,7 +173,14 @@ static int inihandler(void* user, const char* section, const char* name, const c
|
||||
else
|
||||
p_config->mixramp = false;
|
||||
else if (MATCH("taglist"))
|
||||
p_config->taglist = strdup(value);
|
||||
p_config->taglist = strdup(value);
|
||||
else if (MATCH("max_elements_per_page")) {
|
||||
p_config->max_elements_per_page = strtol(value, &crap, 10);
|
||||
if (p_config->max_elements_per_page > MAX_ELEMENTS_PER_PAGE) {
|
||||
printf("Setting max_elements_per_page to maximal value %d", MAX_ELEMENTS_PER_PAGE);
|
||||
p_config->max_elements_per_page = MAX_ELEMENTS_PER_PAGE;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0; /* unknown section/name, error */
|
||||
|
||||
@ -267,6 +274,7 @@ int main(int argc, char **argv) {
|
||||
config.mixramp = true;
|
||||
config.taglist = "Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer";
|
||||
config.smartpls = true;
|
||||
config.max_elements_per_page = 100;
|
||||
|
||||
mpd.timeout = 3000;
|
||||
mpd.last_update_sticker_song_id = -1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user