2018-06-21 21:29:49 +00:00
var $jscomp = $jscomp || { } ; $jscomp . scope = { } ; $jscomp . ASSUME _ES5 = ! 1 ; $jscomp . ASSUME _NO _NATIVE _MAP = ! 1 ; $jscomp . ASSUME _NO _NATIVE _SET = ! 1 ; $jscomp . defineProperty = $jscomp . ASSUME _ES5 || "function" == typeof Object . defineProperties ? Object . defineProperty : function ( a , b , c ) { a != Array . prototype && a != Object . prototype && ( a [ b ] = c . value ) } ; $jscomp . getGlobal = function ( a ) { return "undefined" != typeof window && window === a ? a : "undefined" != typeof global && null != global ? global : a } ; $jscomp . global = $jscomp . getGlobal ( this ) ; $jscomp . SYMBOL _PREFIX = "jscomp_symbol_" ;
$jscomp . initSymbol = function ( ) { $jscomp . initSymbol = function ( ) { } ; $jscomp . global . Symbol || ( $jscomp . global . Symbol = $jscomp . Symbol ) } ; $jscomp . Symbol = function ( ) { var a = 0 ; return function ( b ) { return $jscomp . SYMBOL _PREFIX + ( b || "" ) + a ++ } } ( ) ;
$jscomp . initSymbolIterator = function ( ) { $jscomp . initSymbol ( ) ; var a = $jscomp . global . Symbol . iterator ; a || ( a = $jscomp . global . Symbol . iterator = $jscomp . global . Symbol ( "iterator" ) ) ; "function" != typeof Array . prototype [ a ] && $jscomp . defineProperty ( Array . prototype , a , { configurable : ! 0 , writable : ! 0 , value : function ( ) { return $jscomp . arrayIterator ( this ) } } ) ; $jscomp . initSymbolIterator = function ( ) { } } ; $jscomp . arrayIterator = function ( a ) { var b = 0 ; return $jscomp . iteratorPrototype ( function ( ) { return b < a . length ? { done : ! 1 , value : a [ b ++ ] } : { done : ! 0 } } ) } ;
2018-07-03 21:46:07 +00:00
$jscomp . iteratorPrototype = function ( a ) { $jscomp . initSymbolIterator ( ) ; a = { next : a } ; a [ $jscomp . global . Symbol . iterator ] = function ( ) { return this } ; return a } ; $jscomp . makeIterator = function ( a ) { $jscomp . initSymbolIterator ( ) ; var b = a [ Symbol . iterator ] ; return b ? b . call ( a ) : $jscomp . arrayIterator ( a ) } ; $jscomp . arrayFromIterator = function ( a ) { for ( var b , c = [ ] ; ! ( b = a . next ( ) ) . done ; ) c . push ( b . value ) ; return c } ; $jscomp . arrayFromIterable = function ( a ) { return a instanceof Array ? a : $jscomp . arrayFromIterator ( $jscomp . makeIterator ( 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 , e ) { if ( b ) { c = $jscomp . global ; a = a . split ( "." ) ; for ( e = 0 ; e < a . length - 1 ; e ++ ) { var d = a [ e ] ; d in c || ( c [ d ] = { } ) ; c = c [ d ] } a = a [ a . length - 1 ] ; e = c [ a ] ; b = b ( e ) ; b != e && 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 e = "" ; a ; ) if ( a & 1 && ( e += b ) , a >>>= 1 ) b += b ; return e } } , "es6" , "es3" ) ;
2018-09-03 21:49:04 +00:00
var socket , lastSong = "" , lastState , currentSong = { } , playstate = "" , settings = { } , alertTimeout , progressTimer , deferredPrompt , dragEl , 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 : "Artist" , views : { Artist : { 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 ;
2018-08-21 22:02:22 +00:00
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" ) ;
2018-08-24 10:11:27 +00:00
var modalConnectionError = new Modal ( document . getElementById ( "modalConnectionError" ) ) , modalSettings = new Modal ( document . getElementById ( "modalSettings" ) ) , modalSavequeue = new Modal ( document . getElementById ( "modalSaveQueue" ) ) , modalSongDetails = new Modal ( document . getElementById ( "modalSongDetails" ) ) , modalAddToPlaylist = new Modal ( document . getElementById ( "modalAddToPlaylist" ) ) , modalRenamePlaylist = new Modal ( document . getElementById ( "modalRenamePlaylist" ) ) , modalUpdateDB = new Modal ( document . getElementById ( "modalUpdateDB" ) ) ;
2018-07-09 19:20:09 +00:00
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" ) ;
2018-07-03 21:46:07 +00:00
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 +
2018-07-24 22:52:59 +00:00
"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" ) }
2018-07-09 19:20:09 +00:00
function appGoto ( a , b , c , e ) { var d = document . body . scrollTop ? document . body . scrollTop : document . documentElement . scrollTop ; void 0 != app . apps [ app . current . app ] . scrollPos ? app . apps [ app . current . app ] . scrollPos = d : void 0 != app . apps [ app . current . app ] . tabs [ app . current . tab ] . scrollPos ? app . apps [ app . current . app ] . tabs [ app . current . tab ] . scrollPos = d : void 0 != app . apps [ app . current . app ] . tabs [ app . current . tab ] . views [ app . current . view ] . scrollPos && ( app . apps [ app . current . app ] . tabs [ app . current . tab ] . views [ app . current . view ] . scrollPos = d ) ; app . apps [ a ] . tabs ?
( void 0 == b && ( b = app . apps [ a ] . active ) , app . apps [ a ] . tabs [ b ] . views ? ( void 0 == c && ( c = app . apps [ a ] . tabs [ b ] . active ) , a = "/" + a + "/" + b + "/" + c + "!" + ( void 0 == e ? app . apps [ a ] . tabs [ b ] . views [ c ] . state : e ) ) : a = "/" + a + "/" + b + "!" + ( void 0 == e ? app . apps [ a ] . tabs [ b ] . state : e ) ) : a = "/" + a + "!" + ( void 0 == e ? app . apps [ a ] . state : e ) ; location . hash = a }
2018-07-19 19:35:54 +00:00
function appRoute ( ) { var a ; if ( a = decodeURI ( location . hash ) . match ( /^#\/(\w+)\/?(\w+)?\/?(\w+)?!((\d+)\/([^\/]+)\/(.*))$/ ) ) { app . current . app = a [ 1 ] ; app . current . tab = a [ 2 ] ; app . current . view = a [ 3 ] ; app . apps [ app . current . app ] . state ? ( app . apps [ app . current . app ] . state = a [ 4 ] , app . current . scrollPos = app . apps [ app . current . app ] . scrollPos ) : app . apps [ app . current . app ] . tabs [ app . current . tab ] . state ? ( app . apps [ app . current . app ] . tabs [ app . current . tab ] . state = a [ 4 ] , app . apps [ app . current . app ] . active = app . current . tab , app . current . scrollPos = app . apps [ app . current . app ] . tabs [ app . current . tab ] . scrollPos ) :
app . apps [ app . current . app ] . tabs [ app . current . tab ] . views [ app . current . view ] . state && ( app . apps [ app . current . app ] . tabs [ app . current . tab ] . views [ app . current . view ] . state = a [ 4 ] , app . apps [ app . current . app ] . active = app . current . tab , app . apps [ app . current . app ] . tabs [ app . current . tab ] . active = app . current . view , app . current . scrollPos = app . apps [ app . current . app ] . tabs [ app . current . tab ] . views [ app . current . view ] . scrollPos ) ; app . current . page = parseInt ( a [ 5 ] ) ; app . current . filter = a [ 6 ] ; app . current . search = a [ 7 ] ; appPrepare ( app . current . scrollPos ) ;
2018-09-03 20:01:50 +00:00
if ( "Playback" == app . current . app ) sendAPI ( { cmd : "MPD_API_PLAYER_CURRENT_SONG" } , songChange ) ; else if ( "Queue" == app . current . app ) { var b = document . getElementById ( "searchqueuetag" ) . getElementsByTagName ( "button" ) , c = b . length ; for ( a = 0 ; a < c ; a ++ ) b [ a ] . classList . remove ( "active" ) , b [ a ] . getAttribute ( "data-tag" ) == app . current . filter && ( b [ a ] . classList . add ( "active" ) , document . getElementById ( "searchqueuetagdesc" ) . innerText = b [ a ] . innerText ) ; getQueue ( ) } else if ( "Browse" == app . current . app && "Playlists" == app . current . tab && "All" == app . current . view ) sendAPI ( { cmd : "MPD_API_PLAYLIST_LIST" ,
2018-08-27 19:48:07 +00:00
data : { offset : app . current . page , filter : app . current . filter } } , parsePlaylists ) , doSetFilterLetter ( "BrowsePlaylistsFilter" ) ; else if ( "Browse" == app . current . app && "Playlists" == app . current . tab && "Detail" == app . current . view ) sendAPI ( { cmd : "MPD_API_PLAYLIST_CONTENT_LIST" , data : { offset : app . current . page , filter : app . current . filter , uri : app . current . search } } , parsePlaylists ) , doSetFilterLetter ( "BrowsePlaylistsFilter" ) ; else if ( "Browse" == app . current . app && "Database" == app . current . tab && "Artist" == app . current . view ) sendAPI ( { cmd : "MPD_API_DATABASE_ARTIST_LIST" ,
data : { offset : app . current . page , filter : app . current . filter } } , parseListDBtags ) , doSetFilterLetter ( "BrowseDatabaseFilter" ) ; else if ( "Browse" == app . current . app && "Database" == app . current . tab && "Album" == app . current . view ) sendAPI ( { cmd : "MPD_API_DATABASE_ARTISTALBUM_LIST" , data : { offset : app . current . page , filter : app . current . filter , albumartist : app . current . search } } , parseListDBtags ) , doSetFilterLetter ( "BrowseDatabaseFilter" ) ; else if ( "Browse" == app . current . app && "Filesystem" == app . current . tab ) { sendAPI ( { cmd : "MPD_API_DATABASE_FILESYSTEM_LIST" ,
data : { offset : app . current . page , path : app . current . search ? app . current . search : "/" , filter : app . current . filter } } , parseFilesystem ) ; app . current . search ? ( document . getElementById ( "BrowseFilesystemAddAllSongs" ) . removeAttribute ( "disabled" ) , document . getElementById ( "BrowseFilesystemAddAllSongsBtn" ) . removeAttribute ( "disabled" ) ) : ( document . getElementById ( "BrowseFilesystemAddAllSongs" ) . setAttribute ( "disabled" , "disabled" ) , document . getElementById ( "BrowseFilesystemAddAllSongsBtn" ) . setAttribute ( "disabled" , "disabled" ) ) ; b =
'<li class="breadcrumb-item"><a data-uri="">root</a></li>' ; c = app . current . search . split ( "/" ) ; var e = c . length , d = "" ; for ( a = 0 ; a < e ; a ++ ) { if ( e - 1 == a ) { b += '<li class="breadcrumb-item active">' + c [ a ] + "</li>" ; break } d += c [ a ] ; b += '<li class="breadcrumb-item"><a data-uri="' + d + '">' + c [ a ] + "</a></li>" ; d += "/" } a = document . getElementById ( "BrowseBreadcrumb" ) ; a . innerHTML = b ; b = a . getElementsByTagName ( "a" ) ; c = b . length ; for ( a = 0 ; a < c ; a ++ ) b [ a ] . addEventListener ( "click" , function ( ) { appGoto ( "Browse" , "Filesystem" , void 0 , "0/" + app . current . filter +
2018-09-03 20:01:50 +00:00
"/" + this . getAttribute ( "data-uri" ) ) } , ! 1 ) ; doSetFilterLetter ( "BrowseFilesystemFilter" ) } else if ( "Search" == app . current . app ) for ( document . getElementById ( "searchstr" ) . focus ( ) , app . last . app != app . current . app && "" != app . current . search && ( document . getElementById ( "SearchList" ) . getElementsByTagName ( "tbody" ) [ 0 ] . innerHTML = '<tr><td><span class="material-icons">search</span></td><td colspan="5">Searching...</td></tr>' ) , 2 <= app . current . search . length ? sendAPI ( { cmd : "MPD_API_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 ) ) , b = document . getElementById ( "searchtags" ) . getElementsByTagName ( "button" ) ,
c = b . length , a = 0 ; a < c ; a ++ ) b [ a ] . classList . remove ( "active" ) , b [ a ] . getAttribute ( "data-tag" ) == app . current . filter && ( b [ a ] . classList . add ( "active" ) , document . getElementById ( "searchtagsdesc" ) . innerText = b [ a ] . innerText ) ; else appGoto ( "Playback" ) ; app . last . app = app . current . app ; app . last . tab = app . current . tab ; app . last . view = app . current . view } else appGoto ( "Playback" ) }
2018-08-27 19:48:07 +00:00
function appInit ( ) { getSettings ( ) ; sendAPI ( { cmd : "MPD_API_PLAYER_STATE" } , parseState ) ; webSocketConnect ( ) ; domCache . volumeBar . value = 0 ; domCache . volumeBar . addEventListener ( "click" , function ( a ) { a . stopPropagation ( ) } , ! 1 ) ; domCache . volumeBar . addEventListener ( "change" , function ( a ) { sendAPI ( { cmd : "MPD_API_PLAYER_VOLUME" , 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 ( "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" ) ;
document . getElementById ( "inputMixrampdb" ) . classList . remove ( "is-invalid" ) ; document . getElementById ( "inputMixrampdelay" ) . classList . remove ( "is-invalid" ) } ) ; document . getElementById ( "addToPlaylistPlaylist" ) . addEventListener ( "change" , function ( a ) { "New Playlist" == this . options [ this . selectedIndex ] . text ? ( document . getElementById ( "addToPlaylistNewPlaylistDiv" ) . classList . remove ( "hide" ) , document . getElementById ( "addToPlaylistNewPlaylist" ) . focus ( ) ) : document . getElementById ( "addToPlaylistNewPlaylistDiv" ) . classList . add ( "hide" ) } ,
2018-09-03 21:49:04 +00:00
! 1 ) ; addFilterLetter ( "BrowseFilesystemFilterLetters" ) ; addFilterLetter ( "BrowseDatabaseFilterLetters" ) ; addFilterLetter ( "BrowsePlaylistsFilterLetters" ) ; for ( var a = document . querySelectorAll ( "[data-href]" ) , b = a . length , c = 0 ; c < b ; c ++ ) a [ c ] . classList . add ( "clickable" ) , a [ c ] . addEventListener ( "click" , function ( a ) { a . preventDefault ( ) ; a = JSON . parse ( this . getAttribute ( "data-href" ) . replace ( /'/g , '"' ) ) ; if ( "function" === typeof window [ a . cmd ] ) switch ( a . cmd ) { case "sendAPI" : sendAPI . apply ( null , $jscomp . arrayFromIterable ( a . options ) ) ;
2018-08-27 19:48:07 +00:00
break ; default : window [ a . cmd ] . apply ( null , $jscomp . arrayFromIterable ( a . options ) ) } } , ! 1 ) ; a = document . getElementsByClassName ( "pages" ) ; b = a . length ; for ( c = 0 ; c < b ; c ++ ) a [ c ] . addEventListener ( "click" , function ( a ) { "BUTTON" == a . target . nodeName && gotoPage ( a . target . getAttribute ( "data-page" ) ) } , ! 1 ) ; document . getElementById ( "outputs" ) . addEventListener ( "click" , function ( a ) { "BUTTON" == a . target . nodeName && a . stopPropagation ( ) ; sendAPI ( { cmd : "MPD_API_PLAYER_TOGGLE_OUTPUT" , data : { output : a . target . getAttribute ( "data-output-id" ) , state : a . target . classList . contains ( "active" ) ?
2018-09-03 20:01:50 +00:00
0 : 1 } } ) ; toggleBtn ( a . target . id ) } , ! 1 ) ; document . getElementById ( "QueueList" ) . addEventListener ( "click" , function ( a ) { "TD" == a . target . nodeName ? sendAPI ( { cmd : "MPD_API_PLAYER_PLAY_TRACK" , data : { track : a . target . parentNode . getAttribute ( "data-trackid" ) } } ) : "A" == a . target . nodeName && showMenu ( a . target , a ) } , ! 1 ) ; document . getElementById ( "BrowseFilesystemList" ) . addEventListener ( "click" , function ( a ) { if ( "TD" == a . target . nodeName ) switch ( a . target . parentNode . getAttribute ( "data-type" ) ) { case "dir" : appGoto ( "Browse" , "Filesystem" , void 0 ,
"0/" + app . current . filter + "/" + decodeURI ( a . target . parentNode . getAttribute ( "data-uri" ) ) ) ; break ; case "song" : appendQueue ( "song" , decodeURI ( a . target . parentNode . getAttribute ( "data-uri" ) ) , a . target . parentNode . getAttribute ( "data-name" ) ) ; break ; case "plist" : appendQueue ( "plist" , decodeURI ( a . target . parentNode . getAttribute ( "data-uri" ) ) , a . target . parentNode . getAttribute ( "data-name" ) ) } else "A" == a . target . nodeName && showMenu ( a . target , a ) } , ! 1 ) ; document . getElementById ( "BrowsePlaylistsAllList" ) . addEventListener ( "click" , function ( a ) { "TD" ==
a . target . nodeName ? appendQueue ( "plist" , decodeURI ( a . target . parentNode . getAttribute ( "data-uri" ) ) , a . target . parentNode . getAttribute ( "data-name" ) ) : "A" == a . target . nodeName && showMenu ( a . target , a ) } , ! 1 ) ; document . getElementById ( "BrowsePlaylistsDetailList" ) . addEventListener ( "click" , function ( a ) { "TD" == a . target . nodeName ? appendQueue ( "plist" , decodeURI ( a . target . parentNode . getAttribute ( "data-uri" ) ) , a . target . parentNode . getAttribute ( "data-name" ) ) : "A" == a . target . nodeName && showMenu ( a . target , a ) } , ! 1 ) ; document . getElementById ( "BrowseDatabaseArtistList" ) . addEventListener ( "click" ,
function ( a ) { "TD" == a . target . nodeName && appGoto ( "Browse" , "Database" , "Album" , "0/-/" + a . target . parentNode . getAttribute ( "data-uri" ) ) } , ! 1 ) ; document . getElementById ( "SearchList" ) . addEventListener ( "click" , function ( a ) { "TD" == a . target . nodeName ? appendQueue ( "song" , decodeURI ( a . target . parentNode . getAttribute ( "data-uri" ) ) , a . target . parentNode . getAttribute ( "data-name" ) ) : "A" == a . target . nodeName && showMenu ( a . target , a ) } , ! 1 ) ; document . getElementById ( "BrowseFilesystemAddAllSongsDropdown" ) . addEventListener ( "click" , function ( a ) { "BUTTON" ==
a . target . nodeName && ( "Add all to queue" == a . target . innerText ? addAllFromBrowse ( ) : "Add all to playlist" == a . target . innerText && showAddToPlaylist ( app . current . search ) ) } , ! 1 ) ; document . getElementById ( "searchAddAllSongsDropdown" ) . addEventListener ( "click" , function ( a ) { "BUTTON" == a . target . nodeName && ( "Add all to queue" == a . target . innerText ? addAllFromSearch ( ) : "Add all to playlist" == a . target . innerText && showAddToPlaylist ( "SEARCH" ) ) } , ! 1 ) ; document . getElementById ( "searchtags" ) . addEventListener ( "click" , function ( a ) { "BUTTON" ==
a . target . nodeName && appGoto ( app . current . app , app . current . tab , app . current . view , "0/" + a . target . getAttribute ( "data-tag" ) + "/" + app . current . search ) } , ! 1 ) ; document . getElementById ( "searchqueuestr" ) . addEventListener ( "keyup" , function ( a ) { appGoto ( app . current . app , app . current . tab , app . current . view , "0/" + app . current . filter + "/" + this . value ) } , ! 1 ) ; document . getElementById ( "searchqueuetag" ) . addEventListener ( "click" , function ( a ) { "BUTTON" == a . target . nodeName && appGoto ( app . current . app , app . current . tab , app . current . view , app . current . page +
2018-09-03 21:49:04 +00:00
"/" + a . target . getAttribute ( "data-tag" ) + "/" + app . current . search ) } , ! 1 ) ; document . getElementById ( "search" ) . addEventListener ( "submit" , function ( ) { return ! 1 } , ! 1 ) ; document . getElementById ( "searchqueue" ) . addEventListener ( "submit" , function ( ) { return ! 1 } , ! 1 ) ; document . getElementById ( "searchstr" ) . addEventListener ( "keyup" , function ( a ) { appGoto ( "Search" , void 0 , void 0 , "0/" + app . current . filter + "/" + this . value ) } , ! 1 ) ; document . getElementsByTagName ( "body" ) [ 0 ] . addEventListener ( "click" , function ( a ) { ( a = document . getElementsByClassName ( "popover" ) [ 0 ] ) &&
a . remove ( ) } , ! 1 ) ; dragAndDropTable ( "QueueList" ) ; dragAndDropTable ( "BrowsePlaylistsDetailList" ) ; window . addEventListener ( "hashchange" , appRoute , ! 1 ) ; window . addEventListener ( "focus" , function ( ) { sendAPI ( { cmd : "MPD_API_PLAYER_STATE" } , parseState ) } , ! 1 ) ; document . addEventListener ( "keydown" , function ( a ) { if ( "INPUT" != a . target . tagName ) { switch ( a . which ) { case 37 : clickPrev ( ) ; break ; case 39 : clickNext ( ) ; break ; case 32 : clickPlay ( ) ; break ; default : return } a . preventDefault ( ) } } , ! 1 ) ; "serviceWorker" in navigator && "https" == document . URL . substring ( 0 ,
2018-09-03 20:01:50 +00:00
5 ) && window . addEventListener ( "load" , function ( ) { navigator . serviceWorker . register ( "/sw.min.js" , { scope : "/" } ) . then ( function ( a ) { console . log ( "ServiceWorker registration successful with scope: " , a . scope ) ; a . update ( ) } , function ( a ) { console . log ( "ServiceWorker registration failed: " , a ) } ) } ) ; window . addEventListener ( "beforeinstallprompt" , function ( a ) { a . preventDefault ( ) ; deferredPrompt = a } ) ; window . addEventListener ( "beforeinstallprompt" , function ( a ) { a . preventDefault ( ) ; deferredPrompt = a ; domCache . btnAdd . classList . remove ( "hide" ) } ) ;
domCache . btnAdd . addEventListener ( "click" , function ( a ) { domCache . btnAdd . classList . add ( "hide" ) ; deferredPrompt . prompt ( ) ; deferredPrompt . userChoice . then ( function ( a ) { "accepted" === a . outcome ? console . log ( "User accepted the A2HS prompt" ) : console . log ( "User dismissed the A2HS prompt" ) ; deferredPrompt = null } ) } ) ; window . addEventListener ( "appinstalled" , function ( a ) { console . log ( "myMPD installed as app" ) } ) }
2018-07-29 22:05:47 +00:00
function dragAndDropTable ( a ) { var b = document . getElementById ( a ) . getElementsByTagName ( "tbody" ) [ 0 ] ; b . addEventListener ( "dragstart" , function ( a ) { "TR" == a . target . nodeName && ( a . target . classList . add ( "opacity05" ) , a . dataTransfer . setDragImage ( a . target , 0 , 0 ) , a . dataTransfer . effectAllowed = "move" , a . dataTransfer . setData ( "Text" , a . target . getAttribute ( "id" ) ) , dragEl = a . target . cloneNode ( ! 0 ) ) } , ! 1 ) ; b . addEventListener ( "dragleave" , function ( a ) { a . preventDefault ( ) ; var b = a . target ; "TD" == a . target . nodeName && ( b = a . target . parentNode ) ; "TR" ==
2018-08-21 22:02:22 +00:00
b . nodeName && b . classList . remove ( "dragover" ) } , ! 1 ) ; b . addEventListener ( "dragover" , function ( a ) { a . preventDefault ( ) ; for ( var c = b . getElementsByClassName ( "dragover" ) , d = c . length , f = 0 ; f < d ; f ++ ) c [ f ] . classList . remove ( "dragover" ) ; c = a . target ; "TD" == a . target . nodeName && ( c = a . target . parentNode ) ; "TR" == c . nodeName && c . classList . add ( "dragover" ) ; a . dataTransfer . dropEffect = "move" } , ! 1 ) ; b . addEventListener ( "dragend" , function ( a ) { for ( var c = b . getElementsByClassName ( "dragover" ) , d = c . length , f = 0 ; f < d ; f ++ ) c [ f ] . classList . remove ( "dragover" ) ;
document . getElementById ( a . dataTransfer . getData ( "Text" ) ) && document . getElementById ( a . dataTransfer . getData ( "Text" ) ) . classList . remove ( "opacity05" ) } , ! 1 ) ; b . addEventListener ( "drop" , function ( c ) { c . stopPropagation ( ) ; c . preventDefault ( ) ; var e = c . target ; "TD" == c . target . nodeName && ( e = c . target . parentNode ) ; var d = document . getElementById ( c . dataTransfer . getData ( "Text" ) ) . getAttribute ( "data-songpos" ) , f = e . getAttribute ( "data-songpos" ) ; document . getElementById ( c . dataTransfer . getData ( "Text" ) ) . remove ( ) ; dragEl . classList . remove ( "opacity05" ) ;
2018-08-27 19:48:07 +00:00
b . insertBefore ( dragEl , e ) ; c = b . getElementsByClassName ( "dragover" ) ; e = c . length ; for ( var g = 0 ; g < e ; 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 : d , to : f } } ) : "Browse" == app . current . app && "Playlists" == app . current . tab && "Detail" == app . current . view && playlistMoveTrack ( d , 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 webSocketConnect ( ) { socket = new WebSocket ( getWsUrl ( ) ) ; try { socket . onopen = function ( ) { console . log ( "connected" ) ; showNotification ( "Connected to myMPD" , "" , "" , "success" ) ; modalConnectionError . hide ( ) ; appRoute ( ) ; sendAPI ( { cmd : "MPD_API_PLAYER_STATE" } , parseState ) } , socket . onmessage = function ( a ) { if ( a . data !== lastState && 0 != a . data . length ) { try { var b = JSON . parse ( a . data ) } catch ( c ) { console . log ( "Invalid JSON data received: " + a . data ) } switch ( b . type ) { case "update_state" : parseState ( b ) ; break ; case "disconnected" : showNotification ( "myMPD lost connection to MPD" ,
"" , "" , "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 ( b . type ) ; break ; case "error" : showNotification ( b . data , "" , "" , "danger" ) } } } , socket . onclose = function ( ) { console . log ( "disconnected" ) ; modalConnectionError . show ( ) ;
2018-08-24 10:11:27 +00:00
setTimeout ( function ( ) { console . log ( "reconnect" ) ; webSocketConnect ( ) } , 3E3 ) } } catch ( a ) { alert ( "Error: " + a ) } } function getWsUrl ( ) { var a = document . URL ; if ( "https" == a . substring ( 0 , 5 ) ) { var b = "wss://" ; a = a . substr ( 8 ) } else b = "ws://" , "http" == a . substring ( 0 , 4 ) && ( a = a . substr ( 7 ) ) ; a = a . split ( "#" ) ; var c = /\/$/ . test ( a [ 0 ] ) ? "" : "/" ; return b + a [ 0 ] + c + "ws" }
2018-08-22 12:06:22 +00:00
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 ? a . classList . add ( "active" ) : a . classList . remove ( "active" ) }
2018-07-03 21:46:07 +00:00
function parseSettings ( a ) { toggleBtn ( "btnRandom" , a . data . random ) ; toggleBtn ( "btnConsume" , a . data . consume ) ; toggleBtn ( "btnSingle" , a . data . single ) ; toggleBtn ( "btnRepeat" , a . data . repeat ) ; void 0 != a . data . crossfade ? ( document . getElementById ( "inputCrossfade" ) . removeAttribute ( "disabled" ) , document . getElementById ( "inputCrossfade" ) . value = a . data . crossfade ) : document . getElementById ( "inputCrossfade" ) . setAttribute ( "disabled" , "disabled" ) ; void 0 != a . data . mixrampdb ? ( document . getElementById ( "inputMixrampdb" ) . removeAttribute ( "disabled" ) ,
document . getElementById ( "inputMixrampdb" ) . value = a . data . mixrampdb ) : document . getElementById ( "inputMixrampdb" ) . setAttribute ( "disabled" , "disabled" ) ; void 0 != a . data . mixrampdelay ? ( document . getElementById ( "inputMixrampdelay" ) . removeAttribute ( "disabled" ) , document . getElementById ( "inputMixrampdelay" ) . value = a . data . mixrampdelay ) : document . getElementById ( "inputMixrampdelay" ) . setAttribute ( "disabled" , "disabled" ) ; document . getElementById ( "selectReplaygain" ) . value = a . data . replaygain ; var b = document . getElementById ( "btnnotifyWeb" ) ;
2018-08-21 22:02:22 +00:00
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 ) ; b = document . getElementsByClassName ( "stickers" ) ; for ( var c =
b . length , e = 1 == a . data . stickers ? "" : "none" , d = 0 ; d < c ; d ++ ) b [ d ] . style . display = e ; 1 == a . data . mixramp ? document . getElementsByClassName ( "mixramp" ) [ 0 ] . style . display = "" : document . getElementsByClassName ( "mixramp" ) [ 0 ] . style . display = "none" ; settings = a . data ; 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 + "/" }
2018-08-27 19:48:07 +00:00
function getSettings ( ) { sendAPI ( { cmd : "MPD_API_SETTINGS_GET" } , parseSettings ) } function parseOutputs ( a ) { for ( var b = "" , c = a . data . outputs . length , e = 0 ; e < c ; e ++ ) b += '<button id="btnOutput' + a . data . outputs [ e ] . id + '" data-output-id="' + a . data . outputs [ e ] . id + '" class="btn btn-secondary btn-block' , 1 == a . data . outputs [ e ] . state && ( b += " active" ) , b += '"><span class="material-icons float-left">volume_up</span> ' + a . data . outputs [ e ] . name + "</button>" ; domCache . outputs . innerHTML = b }
2018-08-14 14:32:17 +00:00
function setCounter ( a , b , c ) { currentSong . totalTime = b ; currentSong . elapsedTime = c ; currentSong . currentSongId = a ; var e = Math . floor ( b / 60 ) , d = b - 60 * e , f = Math . floor ( c / 60 ) , g = c - 60 * f ; domCache . progressBar . value = Math . floor ( 100 * c / b ) ; b = f + ":" + ( 10 > g ? "0" : "" ) + g + " / " + e + ":" + ( 10 > d ? "0" : "" ) + d ; domCache . counter . innerText = b ; lastState && ( c = document . getElementById ( "queueTrackId" + lastState . data . currentSongId ) ) && ( e = c . getElementsByTagName ( "td" ) , e [ 4 ] . innerText = c . getAttribute ( "data-duration" ) , e [ 0 ] . classList . remove ( "material-icons" ) , e [ 0 ] . innerText =
c . getAttribute ( "data-songpos" ) , c . classList . remove ( "font-weight-bold" ) ) ; if ( c = document . getElementById ( "queueTrackId" + a ) ) e = c . getElementsByTagName ( "td" ) , e [ 4 ] . innerText = b , e [ 0 ] . classList . add ( "material-icons" ) , e [ 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 ) ) }
2018-08-21 22:02:22 +00:00
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 ? 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 =
2018-08-27 19:48:07 +00:00
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 ) ; 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 } }
2018-09-03 20:01:50 +00:00
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 ) }
2018-08-22 12:06:22 +00:00
function parseQueue ( a ) { if ( "Queue" === app . current . app ) { 0 < a . totalTime && a . totalEntities <= settings . maxElementsPerPage ? document . getElementById ( "panel-heading-queue" ) . innerText = a . totalEntities + " Songs \u2013 " + beautifyDuration ( a . totalTime ) : 0 < a . totalEntities ? document . getElementById ( "panel-heading-queue" ) . innerText = a . totalEntities + " Songs" : 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 e = c . getElementsByTagName ( "tr" ) , d = 0 ; d < b ; d ++ ) if ( ! e [ d ] || e [ d ] . getAttribute ( "data-trackid" ) != a . data [ d ] . id || e [ d ] . getAttribute ( "data-songpos" ) != a . data [ d ] . pos + 1 ) { var f = Math . floor ( a . data [ d ] . duration / 60 ) , g = a . data [ d ] . duration - 60 * f ; f = f + ":" + ( 10 > g ? "0" : "" ) + g ; g = document . createElement ( "tr" ) ; g . setAttribute ( "draggable" , "true" ) ; g . setAttribute ( "data-trackid" , a . data [ d ] . id ) ; g . setAttribute ( "id" , "queueTrackId" + a . data [ d ] . id ) ; g . setAttribute ( "data-songpos" , a . data [ d ] . pos + 1 ) ; g . setAttribute ( "data-duration" ,
f ) ; g . setAttribute ( "data-uri" , a . data [ d ] . uri ) ; g . innerHTML = "<td>" + ( a . data [ d ] . pos + 1 ) + "</td><td>" + a . data [ d ] . title + "</td><td>" + a . data [ d ] . artist + "</td><td>" + a . data [ d ] . album + "</td><td>" + f + '</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>' ; d < e . length ? e [ d ] . replaceWith ( g ) : c . append ( g ) } for ( d = e . length - 1 ; d >= b ; d -- ) e [ d ] . remove ( ) ; "queuesearch" == a . type && 0 == b ? c . innerHTML = '<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">No results, please refine your search!</td></tr>' :
"queue" == a . type && 0 == b && ( c . innerHTML = '<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">Empty queue</td></tr>' ) ; setPagination ( a . totalEntities ) ; document . getElementById ( "QueueList" ) . classList . remove ( "opacity05" ) } }
2018-08-01 17:55:26 +00:00
function parseSearch ( a ) { "Search" === app . current . app && ( document . getElementById ( "panel-heading-search" ) . innerHTML = a . totalEntities + " Songs found" , 0 < a . totalEntities ? ( document . getElementById ( "searchAddAllSongs" ) . removeAttribute ( "disabled" ) , document . getElementById ( "searchAddAllSongsBtn" ) . removeAttribute ( "disabled" ) ) : ( document . getElementById ( "searchAddAllSongs" ) . setAttribute ( "disabled" , "disabled" ) , document . getElementById ( "searchAddAllSongsBtn" ) . setAttribute ( "disabled" , "disabled" ) ) , parseFilesystem ( a ) ) }
2018-07-09 19:20:09 +00:00
function parseFilesystem ( a ) { if ( "Browse" === app . current . app || "Filesystem" === app . current . tab || "Search" === app . current . app ) { for ( var b = a . data . length , c = document . getElementById ( app . current . app + ( void 0 == app . current . tab ? "" : app . current . tab ) + "List" ) . getElementsByTagName ( "tbody" ) [ 0 ] , e = c . getElementsByTagName ( "tr" ) , d = 0 ; d < b ; d ++ ) { var f = encodeURI ( a . data [ d ] . uri ) ; if ( ! e [ d ] || e [ d ] . getAttribute ( "data-uri" ) != f ) { var g = document . createElement ( "tr" ) ; g . setAttribute ( "data-type" , a . data [ d ] . type ) ; g . setAttribute ( "data-uri" , f ) ; g . setAttribute ( "data-name" ,
a . data [ d ] . name ) ; switch ( a . data [ d ] . type ) { case "dir" : g . innerHTML = '<td><span class="material-icons">folder_open</span></td><td colspan="4">' + a . data [ d ] . name + '</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>' ; break ; case "song" : f = Math . floor ( a . data [ d ] . duration / 60 ) ; var h = a . data [ d ] . duration - 60 * f ; g . innerHTML = '<td><span class="material-icons">music_note</span></td><td>' + a . data [ d ] . title + "</td><td>" + a . data [ d ] . artist + "</td><td>" + a . data [ d ] . album + "</td><td>" + f + ":" + ( 10 > h ? "0" : "" ) + h + '</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>' ;
break ; case "plist" : g . innerHTML = '<td><span class="material-icons">list</span></td><td colspan="4">' + a . data [ d ] . name + '</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>' } d < e . length ? e [ d ] . replaceWith ( g ) : c . append ( g ) } } for ( d = e . length - 1 ; d >= b ; d -- ) e [ d ] . remove ( ) ; setPagination ( a . totalEntities ) ; 0 == b && ( c . innerHTML = '<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">No results</td></tr>' ) ; document . getElementById ( app . current . app + ( void 0 == app . current . tab ? "" :
2018-07-05 22:02:14 +00:00
app . current . tab ) + "List" ) . classList . remove ( "opacity05" ) } }
2018-07-24 22:52:59 +00:00
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 ( "." ) ? ( 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 ) , 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 ] , e = c . getElementsByTagName ( "tr" ) ; if ( "All" == app . current . view ) for ( var d = 0 ; d < b ; d ++ ) { var f = encodeURI ( a . data [ d ] . uri ) ; if ( ! e [ d ] || e [ d ] . getAttribute ( "data-uri" ) != f ) { var g = new Date ( 1E3 * a . data [ d ] . last _modified ) , h = document . createElement ( "tr" ) ;
2018-07-29 22:05:47 +00:00
h . setAttribute ( "data-uri" , f ) ; h . setAttribute ( "data-type" , "plist" ) ; h . setAttribute ( "data-name" , a . data [ d ] . name ) ; h . innerHTML = '<td><span class="material-icons">list</span></td><td>' + a . data [ d ] . name + "</td><td>" + g . toUTCString ( ) + '</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>' ; d < e . length ? e [ d ] . replaceWith ( h ) : c . append ( h ) } } else if ( "Detail" == app . current . view ) for ( d = 0 ; d < b ; d ++ ) if ( f = encodeURI ( a . data [ d ] . uri ) , g = a . offset + d + 1 , ! e [ d ] || e [ d ] . getAttribute ( "data-uri" ) != f || e [ d ] . getAttribute ( "id" ) !=
"playlistTrackId" + g ) { h = document . createElement ( "tr" ) ; h . setAttribute ( "draggable" , "true" ) ; h . setAttribute ( "id" , "playlistTrackId" + g ) ; h . setAttribute ( "data-type" , a . data [ d ] . type ) ; h . setAttribute ( "data-uri" , f ) ; h . setAttribute ( "data-name" , a . data [ d ] . name ) ; h . setAttribute ( "data-songpos" , g ) ; f = Math . floor ( a . data [ d ] . duration / 60 ) ; var k = a . data [ d ] . duration - 60 * f ; h . innerHTML = "<td>" + g + "</td><td>" + a . data [ d ] . title + "</td><td>" + a . data [ d ] . artist + "</td><td>" + a . data [ d ] . album + "</td><td>" + f + ":" + ( 10 > k ? "0" : "" ) + k + '</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>' ;
d < e . length ? e [ d ] . replaceWith ( h ) : c . append ( h ) } for ( d = e . length - 1 ; d >= b ; d -- ) e [ d ] . 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" ) } }
2018-08-06 20:51:48 +00:00
function parseListDBtags ( a ) { if ( "Browse" === app . current . app || "Database" === app . current . tab || "Artist" === app . current . view ) if ( "AlbumArtist" == a . tagtype ) { document . getElementById ( "BrowseDatabaseAlbumList" ) . classList . add ( "hide" ) ; document . getElementById ( "BrowseDatabaseArtistList" ) . classList . remove ( "hide" ) ; document . getElementById ( "btnBrowseDatabaseArtist" ) . parentNode . classList . add ( "hide" ) ; for ( var b = a . data . length , c = document . getElementById ( app . current . app + app . current . tab + app . current . view + "List" ) . getElementsByTagName ( "tbody" ) [ 0 ] ,
2018-08-22 21:56:58 +00:00
e = c . getElementsByTagName ( "tr" ) , d = 0 ; d < b ; d ++ ) { var f = encodeURI ( a . data [ d ] . value ) ; if ( ! e [ d ] || e [ d ] . getAttribute ( "data-uri" ) != f ) { var g = document . createElement ( "tr" ) ; g . setAttribute ( "data-uri" , f ) ; g . innerHTML = '<td><span class="material-icons">album</span></td><td>' + a . data [ d ] . value + "</td>" ; d < e . length ? e [ d ] . replaceWith ( g ) : c . append ( g ) } } for ( d = e . length - 1 ; d >= b ; d -- ) e [ d ] . remove ( ) ; setPagination ( a . totalEntities ) ; 0 == b && ( c . innerHTML = '<tr><td><span class="material-icons">error_outline</span></td><td>No entries found.</td></tr>' ) ;
2018-08-21 22:02:22 +00:00
document . getElementById ( "BrowseDatabaseArtistList" ) . classList . remove ( "opacity05" ) } else if ( "Album" == a . tagtype ) { document . getElementById ( "BrowseDatabaseAlbumList" ) . classList . remove ( "hide" ) ; document . getElementById ( "BrowseDatabaseArtistList" ) . classList . add ( "hide" ) ; document . getElementById ( "btnBrowseDatabaseArtist" ) . parentNode . classList . remove ( "hide" ) ; b = a . data . length ; c = document . getElementById ( "BrowseDatabaseAlbumList" ) ; e = c . getElementsByClassName ( "col-md" ) ; for ( d = 0 ; d < b ; d ++ ) f = genId ( a . data [ d ] . value ) , e [ d ] && e [ d ] . getAttribute ( "id" ) ==
2018-08-27 19:48:07 +00:00
f || ( 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">' + a . searchstr + '</h5> <h4 class="card-title">' + a . data [ d ] . value + '</h4> <table class="table table-sm table-hover" id="tbl' + f + '"><tbody></tbody></table </div></div>' , d < e . length ? e [ d ] . replaceWith ( g ) : c . append ( g ) , sendAPI ( { cmd : "MPD_API_DATABASE_ARTISTALBUMTITLE_LIST" ,
2018-08-06 20:51:48 +00:00
data : { albumartist : a . searchstr , album : a . data [ d ] . value } } , parseListTitles ) ) ; for ( d = e . length - 1 ; d >= b ; d -- ) e [ d ] . remove ( ) ; setPagination ( a . totalEntities ) ; document . getElementById ( "BrowseDatabaseAlbumList" ) . classList . remove ( "opacity05" ) } }
2018-07-09 19:20:09 +00:00
function parseListTitles ( a ) { if ( "Browse" === app . current . app || "Database" === app . current . tab || "Album" === app . current . view ) { var b = genId ( a . album ) , c = document . getElementById ( "card" + b ) ; b = c . getElementsByTagName ( "tbody" ) [ 0 ] ; var 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" ) ; e = "" ; for ( var d = a . data . length , f = 0 ; f < d ; f ++ ) e += '<tr data-type="song" data-name="' +
2018-09-03 20:01:50 +00:00
a . data [ f ] . title + '" data-uri="' + encodeURI ( a . data [ f ] . uri ) + '"><td>' + a . data [ f ] . track + "</td><td>" + a . data [ f ] . title + '</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td></tr>' ; b . innerHTML = e ; c . addEventListener ( "click" , function ( a ) { showMenu ( this , a ) } , ! 1 ) ; b . parentNode . addEventListener ( "click" , function ( a ) { "TD" == a . target . nodeName ? appendQueue ( "song" , decodeURI ( a . target . parentNode . getAttribute ( "data-uri" ) ) , a . target . parentNode . getAttribute ( "data-name" ) ) : "A" == a . target . nodeName && 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 e = [ "PaginationTop" , "PaginationBottom" ] , d = 0 ; 2 > d ; d ++ ) { document . getElementById ( c + e [ d ] + "Page" ) . innerText = app . current . page / settings . maxElementsPerPage + 1 + " / " + b ; if ( 1 < b ) { document . getElementById ( c + e [ d ] + "Page" ) . removeAttribute ( "disabled" ) ; for ( var f = "" , g = 0 ; g < b ; g ++ ) f += '<button data-page="' + g * settings . maxElementsPerPage + '" type="button" class="mr-1 mb-1 btn-sm btn btn-secondary">' + ( g +
1 ) + "</button>" ; document . getElementById ( c + e [ d ] + "Pages" ) . innerHTML = f } else document . getElementById ( c + e [ d ] + "Page" ) . setAttribute ( "disabled" , "disabled" ) ; a > app . current . page + settings . maxElementsPerPage ? ( document . getElementById ( c + e [ d ] + "Next" ) . removeAttribute ( "disabled" ) , document . getElementById ( c + e [ d ] ) . classList . remove ( "hide" ) , document . getElementById ( c + "ButtonsBottom" ) . classList . remove ( "hide" ) ) : ( document . getElementById ( c + e [ d ] + "Next" ) . setAttribute ( "disabled" , "disabled" ) , document . getElementById ( c + e [ d ] ) . classList . add ( "hide" ) ,
2018-08-01 17:55:26 +00:00
document . getElementById ( c + "ButtonsBottom" ) . classList . add ( "hide" ) ) ; 0 < app . current . page ? ( document . getElementById ( c + e [ d ] + "Prev" ) . removeAttribute ( "disabled" ) , document . getElementById ( c + e [ d ] ) . classList . remove ( "hide" ) , document . getElementById ( c + "ButtonsBottom" ) . classList . remove ( "hide" ) ) : document . getElementById ( c + e [ d ] + "Prev" ) . setAttribute ( "disabled" , "disabled" ) } }
2018-08-27 19:48:07 +00:00
function appendQueue ( a , b , c ) { switch ( a ) { case "song" : case "dir" : sendAPI ( { cmd : "MPD_API_QUEUE_ADD_TRACK" , data : { uri : b } } ) ; showNotification ( '"' + c + '" added' , "" , "" , "success" ) ; break ; case "plist" : sendAPI ( { cmd : "MPD_API_QUEUE_ADD_PLAYLIST" , data : { plist : b } } ) , showNotification ( '"' + c + '" added' , "" , "" , "success" ) } } function appendAfterQueue ( a , b , c , e ) { switch ( a ) { case "song" : sendAPI ( { cmd : "MPD_API_QUEUE_ADD_TRACK_AFTER" , data : { uri : b , to : c } } ) , showNotification ( '"' + e + '" added to pos ' + c , "" , "" , "success" ) } }
function replaceQueue ( a , b , c ) { switch ( a ) { case "song" : case "dir" : sendAPI ( { cmd : "MPD_API_QUEUE_REPLACE_TRACK" , data : { uri : b } } ) ; showNotification ( '"' + c + '" replaced' , "" , "" , "success" ) ; break ; case "plist" : sendAPI ( { cmd : "MPD_API_QUEUE_REPLACE_PLAYLIST" , data : { plist : b } } ) , showNotification ( '"' + c + '" replaced' , "" , "" , "success" ) } } function songClick ( ) { var a = domCache . currentTrack . getAttribute ( "data-uri" ) ; "" != a && songDetails ( a ) }
function artistClick ( ) { var a = domCache . currentArtist . getAttribute ( "data-albumartist" ) ; "" != a && appGoto ( "Browse" , "Database" , "Album" , "0/-/" + a ) } function songDetails ( a ) { sendAPI ( { cmd : "MPD_API_DATABASE_SONGDETAILS" , data : { uri : a } } , parseSongDetails ) ; modalSongDetails . show ( ) }
2018-08-21 22:02:22 +00:00
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 ; b = b . getElementsByTagName ( "tr" ) ; for ( var c = b . length , e = 0 ; e < c ; e ++ ) { var d = b [ e ] . getAttribute ( "data-name" ) ; if ( d ) { var f = a . data [ d ] ; "duration" == d ? ( d = Math . floor ( f / 60 ) , f -= 60 * d , f = d + ":" + ( 10 > f ? "0" : "" ) + f ) : "lastPlayed" == d ? f = 0 == f ? "never" : ( new Date ( 1E3 * f ) ) . toUTCString ( ) : "like" == d ? f = 0 == f ? '<span class="material-icons">thumb_down_alt</span>' :
2018-08-18 14:26:12 +00:00
2 == f ? '<span class="material-icons">thumb_up_alt</span>' : "not voted" : "uri" == d && ( f = '<a class="text-success" href="/library/' + f + '">' + f + "</a>" ) ; b [ e ] . getElementsByTagName ( "td" ) [ 0 ] . innerHTML = f } } } function playlistDetails ( a ) { appGoto ( "Browse" , "Playlists" , "Detail" , "0/-/" + a ) }
2018-08-27 19:48:07 +00:00
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 ) }
function getAllPlaylists ( a ) { for ( var b = a . data . length , c = "<option></option><option>New Playlist</option>" , e = 0 ; e < b ; e ++ ) c += "<option>" + a . data [ e ] . uri + "</option>" ; document . getElementById ( "addToPlaylistPlaylist" ) . innerHTML += c ; a . totalEntities > a . returnedEntities && ( a . offset += settings . maxElementsPerPage , sendAPI ( { cmd : "MPD_API_PLAYLIST_LIST" , data : { offset : a . offset , filter : "-" } } , getAllPlaylists ) ) }
2018-08-21 22:02:22 +00:00
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 ) ) }
function setVoteSongBtns ( a , b ) { "" == b || 0 == b . indexOf ( "http://" ) || 0 == b . indexOf ( "https://" ) ? ( domCache . btnVoteUp . setAttribute ( "disabled" , "disabled" ) , domCache . btnVoteDown . setAttribute ( "disabled" , "disabled" ) ) : ( domCache . btnVoteUp . removeAttribute ( "disabled" ) , domCache . btnVoteDown . removeAttribute ( "disabled" ) ) ; 0 == a ? ( domCache . btnVoteUp . classList . remove ( "active-fg-green" ) , domCache . btnVoteDown . classList . add ( "active-fg-red" ) ) : 1 == a ? ( domCache . btnVoteUp . classList . remove ( "active-fg-green" ) , domCache . btnVoteDown . classList . remove ( "active-fg-red" ) ) :
2 == a && ( domCache . btnVoteUp . classList . add ( "active-fg-green" ) , domCache . btnVoteDown . classList . remove ( "active-fg-red" ) ) }
2018-08-05 22:02:29 +00:00
function toggleAddToPlaylistFrm ( ) { var a = document . getElementById ( "toggleAddToPlaylistBtn" ) ; toggleBtn ( "toggleAddToPlaylistBtn" ) ; a . classList . contains ( "active" ) ? ( document . getElementById ( "addToPlaylistFrm" ) . classList . remove ( "hide" ) , document . getElementById ( "addStreamFooter" ) . classList . add ( "hide" ) , document . getElementById ( "addToPlaylistFooter" ) . classList . remove ( "hide" ) ) : ( document . getElementById ( "addToPlaylistFrm" ) . classList . add ( "hide" ) , document . getElementById ( "addStreamFooter" ) . classList . remove ( "hide" ) , document . getElementById ( "addToPlaylistFooter" ) . classList . add ( "hide" ) ) }
2018-08-27 19:48:07 +00:00
function showAddToPlaylist ( a ) { document . getElementById ( "addToPlaylistUri" ) . value = a ; document . getElementById ( "addToPlaylistPlaylist" ) . innerHTML = "" ; document . getElementById ( "addToPlaylistNewPlaylist" ) . value = "" ; document . getElementById ( "addToPlaylistNewPlaylistDiv" ) . classList . add ( "hide" ) ; document . getElementById ( "addToPlaylistFrm" ) . classList . remove ( "was-validated" ) ; document . getElementById ( "addToPlaylistNewPlaylist" ) . classList . remove ( "is-invalid" ) ; toggleBtn ( "toggleAddToPlaylistBtn" , 0 ) ; var b = document . getElementById ( "streamUrl" ) ;
b . focus ( ) ; b . value = "" ; b . classList . remove ( "is-invalid" ) ; document . getElementById ( "addStreamFrm" ) . classList . remove ( "was-validated" ) ; "stream" != a ? ( document . getElementById ( "addStreamFooter" ) . classList . add ( "hide" ) , document . getElementById ( "addStreamFrm" ) . classList . add ( "hide" ) , document . getElementById ( "addToPlaylistFooter" ) . classList . remove ( "hide" ) , document . getElementById ( "addToPlaylistFrm" ) . classList . remove ( "hide" ) , document . getElementById ( "addToPlaylistLabel" ) . innerText = "Add to playlist" ) : ( document . getElementById ( "addStreamFooter" ) . classList . remove ( "hide" ) ,
document . getElementById ( "addStreamFrm" ) . classList . remove ( "hide" ) , document . getElementById ( "addToPlaylistFooter" ) . classList . add ( "hide" ) , document . getElementById ( "addToPlaylistFrm" ) . classList . add ( "hide" ) , document . getElementById ( "addToPlaylistLabel" ) . innerText = "Add Stream" ) ; modalAddToPlaylist . show ( ) ; sendAPI ( { cmd : "MPD_API_PLAYLIST_LIST" , data : { offset : 0 , filter : "-" } } , getAllPlaylists ) }
2018-08-05 22:02:29 +00:00
function addToPlaylist ( ) { var a = document . getElementById ( "addToPlaylistUri" ) . value ; if ( "stream" == a && ( a = document . getElementById ( "streamUrl" ) . value , "" == a || - 1 == a . indexOf ( "http" ) ) ) { document . getElementById ( "streamUrl" ) . classList . add ( "is-invalid" ) ; document . getElementById ( "addStreamFrm" ) . classList . add ( "was-validated" ) ; return } var b = document . getElementById ( "addToPlaylistPlaylist" ) ; b = b . options [ b . selectedIndex ] . text ; if ( "New Playlist" == b ) { b = document . getElementById ( "addToPlaylistNewPlaylist" ) . value ; var c = b . replace ( /\w/g ,
2018-08-27 19:48:07 +00:00
"" ) ; if ( "" == b || "" != c ) { document . getElementById ( "addToPlaylistNewPlaylist" ) . classList . add ( "is-invalid" ) ; document . getElementById ( "addToPlaylistFrm" ) . classList . add ( "was-validated" ) ; return } } "" != b ? ( "SEARCH" != a ? sendAPI ( { cmd : "MPD_API_PLAYLIST_ADD_TRACK" , data : { uri : a , plist : b } } ) : addAllFromSearchPlist ( b ) , modalAddToPlaylist . hide ( ) ) : ( document . getElementById ( "addToPlaylistPlaylist" ) . classList . add ( "is-invalid" ) , document . getElementById ( "addToPlaylistFrm" ) . classList . add ( "was-validated" ) ) }
function addStream ( ) { var a = document . getElementById ( "streamUrl" ) . value ; "" != a && 0 == a . indexOf ( "http" ) ? ( sendAPI ( { cmd : "MPD_API_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" ) ) }
2018-07-24 22:52:59 +00:00
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 = "" }
2018-08-27 19:48:07 +00:00
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" ) ) }
2018-09-03 20:01:50 +00:00
function dirname ( a ) { return a . replace ( /\/[^\/]*$/ , "" ) }
function showMenu ( a , b ) { b . preventDefault ( ) ; b . stopPropagation ( ) ; ( b = document . getElementsByClassName ( "popover" ) [ 0 ] ) && b . remove ( ) ; b = a . getAttribute ( "data-type" ) ; var c = decodeURI ( a . getAttribute ( "data-uri" ) ) , e = a . getAttribute ( "data-name" ) , d = 0 ; if ( null == b || null == c ) b = a . parentNode . parentNode . getAttribute ( "data-type" ) , c = decodeURI ( a . parentNode . parentNode . getAttribute ( "data-uri" ) ) , e = a . parentNode . parentNode . getAttribute ( "data-name" ) ; lastState && ( d = 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 && "Album" == app . current . view ? ( f += "<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendQueue', 'options': ['" + b + "','" + c + "','" + e + "']}\">Append to queue</a>" + ( "song" == b ? "<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendAfterQueue', 'options': ['" + b + "','" + c + "'," + d + ",'" + e + "']}\">Add after current playing song</a>" : "" ) + "<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['" +
2018-09-03 21:49:04 +00:00
b + "','" + c + "','" + e + "']}\">Replace queue</a>" + ( "plist" != b ? "<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'showAddToPlaylist', 'options': ['" + c + "']}\">Add to playlist</a>" : "" ) + ( "song" == b ? "<a class=\"dropdown-item\" data-href=\"{'cmd': 'songDetails', 'options': ['" + c + '\']}" href="#">Songdetails</a>' : "" ) + ( "plist" == b ? "<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'playlistDetails', 'options': ['" + c + "']}\">Show playlist</a>" : "" ) , "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"><a class="dropdown-item" href="#" data-href="{\'cmd\': \'appendQueue\', \'options\': [\'' +
2018-09-03 20:01:50 +00:00
b + "','" + c + "','" + e + "']}\">Append to queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendAfterQueue', 'options': ['" + b + "','" + c + "'," + d + ",'" + e + "']}\">Add after current playing song</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['" + b + "','" + c + "','" + e + "']}\">Replace queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'showAddToPlaylist', 'options': ['" + c + "']}\">Add to playlist</a></div>" ) ) : "Browse" == app . current . app && "Playlists" ==
2018-09-03 22:35:40 +00:00
app . current . tab && "All" == app . current . view ? f += "<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendQueue', 'options': ['" + b + "','" + c + "','" + e + "']}\">Append to queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['" + b + "','" + c + "','" + e + "']}\">Replace queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'playlistDetails', 'options': ['" + c + "']}\">Edit playlist</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'showRenamePlaylist', 'options': ['" +
2018-09-03 20:01:50 +00:00
c + "']}\">Rename playlist</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delPlaylist', 'options': ['" + c + "']}\">Delete playlist</a>" : "Browse" == app . current . app && "Playlists" == app . current . tab && "Detail" == app . current . view ? f += "<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendQueue', 'options': ['" + b + "','" + c + "','" + e + "']}\">Append to queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['" + b + "','" + c + "','" + e + "']}\">Replace queue</a>" + ( "false" ==
2018-09-03 22:35:40 +00:00
document . getElementById ( "BrowsePlaylistsDetailList" ) . getAttribute ( "data-ro" ) ? "<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'removeFromPlaylist', 'options': ['" + document . getElementById ( "BrowsePlaylistsDetailList" ) . getAttribute ( "data-uri" ) + "', '" + a . parentNode . parentNode . getAttribute ( "data-songpos" ) + "']}\">Remove</a>" : "" ) + ( "plist" != b ? "<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'showAddToPlaylist', 'options': ['" + c + "']}\">Add to playlist</a>" : "" ) : "Queue" == app . current . app &&
( f += "<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['single'," + a . parentNode . parentNode . getAttribute ( "data-trackid" ) + "]}\">Remove</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['range',0," + a . parentNode . parentNode . getAttribute ( "data-songpos" ) + "]}\">Remove all upwards</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['range'," + ( parseInt ( a . parentNode . parentNode . getAttribute ( "data-songpos" ) ) -
1 ) + ',-1]}">Remove all downwards</a>' + ( - 1 == c . indexOf ( "http" ) ? "<a class=\"dropdown-item\" data-href=\"{'cmd': 'songDetails', 'options': ['" + c + '\']}" href="#">Songdetails</a>' : "" ) ) ; 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>" } ) ; var g = a . Popover ; a . addEventListener ( "shown.bs.popover" , function ( a ) { 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 ( a . replace ( /'/g , '"' ) ) ; if ( "function" === typeof window [ a . cmd ] ) switch ( a . cmd ) { case "sendAPI" : sendAPI . apply ( null , $jscomp . arrayFromIterable ( a . options ) ) ; break ; default : window [ a . cmd ] . apply ( null , $jscomp . arrayFromIterable ( a . options ) ) } g . hide ( ) } } , ! 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 ) ; g . show ( ) }
2018-07-24 22:52:59 +00:00
function sendAPI ( a , b ) { var c = new XMLHttpRequest ; c . open ( "POST" , "/api" , ! 0 ) ; c . setRequestHeader ( "Content-type" , "application/json" ) ; c . onreadystatechange = function ( ) { if ( 4 == c . readyState ) if ( "" != c . responseText ) { var e = JSON . parse ( c . responseText ) ; "error" == e . type ? ( showNotification ( "Error" , e . data , e . data , "danger" ) , console . log ( "Error: " + e . data ) ) : "result" == e . type && "ok" != e . data ? showNotification ( e . data , "" , "" , "success" ) : void 0 != b && "function" == typeof b && b ( e ) } else console . log ( "Empty response for request: " + JSON . stringify ( a ) ) } ;
2018-08-27 19:48:07 +00:00
c . send ( JSON . stringify ( a ) ) } function openLocalPlayer ( ) { window . open ( "/player.html#" + settings . mpdstream , "LocalPlayer" ) } function updateDB ( ) { sendAPI ( { cmd : "MPD_API_DATABASE_UPDATE" } ) ; updateDBstarted ( ! 0 ) }
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 ) }
2018-08-21 22:02:22 +00:00
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 } 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 ) ?
2018-08-27 19:48:07 +00:00
( b . classList . add ( "is-invalid" ) , a = ! 1 ) : b . value = c ) ) ; 1 == a ? ( a = document . getElementById ( "selectReplaygain" ) , 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 ,
2018-08-21 22:02:22 +00:00
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" ) ? 1 : 0 , notificationPage : document . getElementById ( "btnnotifyPage" ) . classList . contains ( "active" ) ? 1 : 0 } } , getSettings ) , modalSettings . hide ( ) ) : document . getElementById ( "settingsFrm" ) . classList . add ( "was-validated" ) }
2018-09-03 20:01:50 +00:00
function addAllFromBrowse ( ) { sendAPI ( { cmd : "MPD_API_QUEUE_ADD_TRACK" , data : { uri : app . current . search } } ) ; showNotification ( "Added all songs" , "" , "" , "success" ) } function addAllFromSearch ( ) { 2 <= app . current . search . length && ( sendAPI ( { cmd : "MPD_API_DATABASE_SEARCH" , data : { plist : "queue" , filter : app . current . filter , searchstr : app . current . search , offset : 0 } } ) , showNotification ( "Added " + parseInt ( document . getElementById ( "panel-heading-search" ) . innerText ) + " songs from search" , "" , "" , "success" ) ) }
function addAllFromSearchPlist ( a ) { 2 <= app . current . search . length && ( sendAPI ( { cmd : "MPD_API_DATABASE_SEARCH" , data : { plist : a , filter : app . current . filter , searchstr : app . current . search , offset : 0 } } ) , showNotification ( "Added " + parseInt ( document . getElementById ( "panel-heading-search" ) . innerText ) + " songs from search to " + a , "" , "" , "success" ) ) } function scrollTo ( a ) { document . body . scrollTop = a ; document . documentElement . scrollTop = a }
2018-08-22 12:06:22 +00:00
function gotoPage ( a ) { switch ( a ) { case "next" : app . current . page += settings . maxElementsPerPage ; break ; case "prev" : app . current . page -= settings . maxElementsPerPage ; 0 > app . current . page && ( app . current . page = 0 ) ; break ; default : app . current . page = a } appGoto ( app . current . app , app . current . tab , app . current . view , app . current . page + "/" + app . current . filter + "/" + app . current . search ) }
2018-08-27 19:48:07 +00:00
function saveQueue ( ) { var a = document . getElementById ( "saveQueueName" ) . value , b = a . replace ( /\w/g , "" ) ; "" != a && "" == b ? ( sendAPI ( { cmd : "MPD_API_QUEUE_SAVE" , data : { plist : a } } ) , modalSavequeue . hide ( ) ) : ( document . getElementById ( "saveQueueName" ) . classList . add ( "is-invalid" ) , document . getElementById ( "saveQueueFrm" ) . classList . add ( "was-validated" ) ) }
2018-07-24 22:52:59 +00:00
function showNotification ( a , b , c , e ) { 1 == settings . notificationWeb && ( b = new Notification ( a , { icon : "assets/favicon.ico" , body : b } ) , setTimeout ( function ( a ) { a . close ( ) } , 3E3 , b ) ) ; 1 == settings . notificationPage && ( document . getElementById ( "alertBox" ) ? b = document . getElementById ( "alertBox" ) : ( b = document . createElement ( "div" ) , b . setAttribute ( "id" , "alertBox" ) , b . addEventListener ( "click" , function ( ) { hideNotification ( ) } , ! 1 ) ) , b . classList . remove ( "alert-success" , "alert-danger" ) , b . classList . add ( "alert" , "alert-" + e ) , b . innerHTML = "<div><strong>" +
2018-08-22 12:06:22 +00:00
a + "</strong><br/>" + c + "</div>" , document . getElementsByTagName ( "main" ) [ 0 ] . append ( b ) , document . getElementById ( "alertBox" ) . classList . add ( "alertBoxActive" ) , alertTimeout && clearTimeout ( alertTimeout ) , alertTimeout = setTimeout ( function ( ) { hideNotification ( ) } , 3E3 ) ) } function hideNotification ( ) { document . getElementById ( "alertBox" ) && ( document . getElementById ( "alertBox" ) . classList . remove ( "alertBoxActive" ) , setTimeout ( function ( ) { var a = document . getElementById ( "alertBox" ) ; a && a . remove ( ) } , 600 ) ) }
2018-07-19 17:57:53 +00:00
function notificationsSupported ( ) { return "Notification" in window }
2018-08-21 22:02:22 +00:00
function songChange ( a ) { if ( "error" != a . type && "result" != a . type ) { var b = a . data . title + a . data . artist + a . data . album + a . data . uri + a . data . currentSongId ; if ( lastSong != b ) { var c = "" , e = "" , d = "myMPD: " ; domCache . currentCover . style . backgroundImage = 'url("' + a . data . cover + '")' ; "undefined" != typeof a . data . artist && 0 < a . data . artist . length && "-" != a . data . artist ? ( c += a . data . artist , e += a . data . artist , d += a . data . artist + " - " , domCache . currentArtist . innerText = a . data . artist , domCache . currentArtist . setAttribute ( "data-albumartist" , a . data . albumartist ) ) :
domCache . currentArtist . innerText = "" ; "undefined" != typeof a . data . album && 0 < a . data . album . length && "-" != a . data . album ? ( c += " - " + a . data . album , e += "<br/>" + a . data . album , domCache . currentAlbum . innerText = a . data . album ) : domCache . currentAlbum . innerText = "" ; "undefined" != typeof a . data . title && 0 < a . data . title . length ? ( d += a . data . title , domCache . currentTrack . innerText = a . data . title , domCache . currentTrack . setAttribute ( "data-uri" , a . data . uri ) ) : ( domCache . currentTrack . innerText = "" , domCache . currentTrack . setAttribute ( "data-uri" , "" ) ) ;
document . title = d ; 1 == settings . stickers && setVoteSongBtns ( a . data . like , a . data . uri ) ; if ( d = document . getElementById ( "queueTrackId" + a . data . currentSongId ) ) d . getElementsByTagName ( "td" ) [ 1 ] . innerText = a . data . title ; showNotification ( a . data . title , c , e , "success" ) ; lastSong = b } } }
function doSetFilterLetter ( a ) { var b = document . getElementById ( a + "Letters" ) . getElementsByClassName ( "active" ) [ 0 ] ; b && b . classList . remove ( "active" ) ; b = app . current . filter ; "0" == b && ( b = "#" ) ; document . getElementById ( a ) . innerText = "Filter" + ( "-" != b ? ": " + b : "" ) ; if ( "-" != b ) { a = document . getElementById ( a + "Letters" ) . getElementsByTagName ( "button" ) ; for ( var c = a . length , e = 0 ; e < c ; e ++ ) if ( a [ e ] . innerText == b ) { a [ e ] . classList . add ( "active" ) ; break } } }
2018-07-19 19:35:54 +00:00
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 ,
2018-08-27 19:48:07 +00:00
app . current . tab , app . current . view , "0/" + b + "/" + app . current . search ) } , ! 1 ) } 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 , e = Math . floor ( a / 60 ) - 60 * c - 1440 * b ; a = a - 86400 * b - 3600 * c - 60 * e ; return ( 0 < b ? b + "\u2009d " : "" ) + ( 0 < c ? c + "\u2009h " + ( 10 > e ? "0" : "" ) : "" ) + e + "\u2009m " + ( 10 > a ? "0" : "" ) + a + "\u2009s" }
2018-07-03 21:46:07 +00:00
function genId ( a ) { return "id" + a . replace ( /[^\w]/g , "" ) } appInit ( ) ;