mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-30 21:33:00 +00:00 
			
		
		
		
	Merge pull request #48 from jcorporation/devel
Merge Devel into master for release 4.1.0
This commit is contained in:
		| @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.6) | |||||||
| project (mympd C) | project (mympd C) | ||||||
| set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/") | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/") | ||||||
| set(CPACK_PACKAGE_VERSION_MAJOR "4") | set(CPACK_PACKAGE_VERSION_MAJOR "4") | ||||||
| set(CPACK_PACKAGE_VERSION_MINOR "0") | set(CPACK_PACKAGE_VERSION_MINOR "1") | ||||||
| set(CPACK_PACKAGE_VERSION_PATCH "0") | set(CPACK_PACKAGE_VERSION_PATCH "0") | ||||||
|  |  | ||||||
| if(CMAKE_BUILD_TYPE MATCHES RELEASE) | if(CMAKE_BUILD_TYPE MATCHES RELEASE) | ||||||
| @@ -40,10 +40,10 @@ add_executable(mympd ${SOURCES}) | |||||||
| target_link_libraries(mympd ${LIBMPDCLIENT_LIBRARY} ${OPENSSL_LIBRARIES}) | target_link_libraries(mympd ${LIBMPDCLIENT_LIBRARY} ${OPENSSL_LIBRARIES}) | ||||||
|  |  | ||||||
| install(TARGETS mympd DESTINATION bin) | install(TARGETS mympd DESTINATION bin) | ||||||
| install(FILES contrib/mympd.1 DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) | install(FILES contrib/mympd.1 DESTINATION share/man/man1) | ||||||
| install(FILES contrib/crcert.sh DESTINATION ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/) | install(PROGRAMS contrib/crcert.sh DESTINATION share/${PROJECT_NAME}/) | ||||||
| install(FILES contrib/mympd.service DESTINATION ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/) | install(FILES contrib/mympd.service DESTINATION share/${PROJECT_NAME}/) | ||||||
| install(FILES contrib/mympd.conf DESTINATION /etc/${PROJECT_NAME}/) | install(FILES contrib/mympd.conf DESTINATION ../etc/${PROJECT_NAME}/) | ||||||
| install(FILES htdocs/mympd.webmanifest DESTINATION share/${PROJECT_NAME}/htdocs/) | install(FILES htdocs/mympd.webmanifest DESTINATION share/${PROJECT_NAME}/htdocs/) | ||||||
| install(FILES dist/htdocs/index.html DESTINATION share/${PROJECT_NAME}/htdocs/) | install(FILES dist/htdocs/index.html DESTINATION share/${PROJECT_NAME}/htdocs/) | ||||||
| install(FILES dist/htdocs/player.html DESTINATION share/${PROJECT_NAME}/htdocs/) | install(FILES dist/htdocs/player.html DESTINATION share/${PROJECT_NAME}/htdocs/) | ||||||
| @@ -55,4 +55,4 @@ install(FILES dist/htdocs/css/bootstrap.min.css DESTINATION share/${PROJECT_NAME | |||||||
| install(FILES dist/htdocs/css/mympd.min.css DESTINATION share/${PROJECT_NAME}/htdocs/css/) | install(FILES dist/htdocs/css/mympd.min.css DESTINATION share/${PROJECT_NAME}/htdocs/css/) | ||||||
| install(DIRECTORY htdocs/assets DESTINATION share/${PROJECT_NAME}/htdocs) | install(DIRECTORY htdocs/assets DESTINATION share/${PROJECT_NAME}/htdocs) | ||||||
| install(DIRECTORY DESTINATION share/${PROJECT_NAME}/htdocs/pics) | install(DIRECTORY DESTINATION share/${PROJECT_NAME}/htdocs/pics) | ||||||
| install(DIRECTORY DESTINATION /var/lib/${PROJECT_NAME}/) | install(DIRECTORY DESTINATION ../var/lib/${PROJECT_NAME}/) | ||||||
|   | |||||||
| @@ -3,10 +3,11 @@ | |||||||
| if [ -d /etc/mympd/ssl ] | if [ -d /etc/mympd/ssl ] | ||||||
| then | then | ||||||
|   echo "SSL directory exists, to recreate certificates: \"rm -r /etc/mympd/ssl\"" |   echo "SSL directory exists, to recreate certificates: \"rm -r /etc/mympd/ssl\"" | ||||||
|   exit 1 |   exit 0 | ||||||
| fi | fi | ||||||
|  |  | ||||||
| mkdir -p /etc/mympd/ssl/ca/certs | mkdir -p /etc/mympd/ssl/ca/certs | ||||||
|  | chmod 700 /etc/mympd/ssl | ||||||
| cd /etc/mympd/ssl/ca | cd /etc/mympd/ssl/ca | ||||||
|  |  | ||||||
| echo '01' > serial | echo '01' > serial | ||||||
| @@ -98,3 +99,5 @@ openssl ca -in server.csr -cert ca/ca.pem -keyfile ca/ca.key -config ca/ca.cnf \ | |||||||
| rm server.csr | rm server.csr | ||||||
| rm ca/ca.cnf | rm ca/ca.cnf | ||||||
| rm req.cnf | rm req.cnf | ||||||
|  |  | ||||||
|  | chown -R mympd.mympd /etc/mympd/ | ||||||
| @@ -4,22 +4,22 @@ | |||||||
| # (c) 2018 Juergen Mang <mail@jcgames.de | # (c) 2018 Juergen Mang <mail@jcgames.de | ||||||
|  |  | ||||||
| Name:           myMPD | Name:           myMPD | ||||||
| Version:        master | Version:        devel | ||||||
| Release:        0  | Release:        0  | ||||||
| License:        GPL-2.0  | License:        GPL-2.0  | ||||||
| Group:          Productivity/Multimedia/Sound/Players | Group:          Productivity/Multimedia/Sound/Players | ||||||
| Summary:        Standalone webclient for mpd | Summary:        Standalone webclient for mpd | ||||||
| Url:            https://github.com/jcorporation/myMPD | Url:            https://github.com/jcorporation/myMPD | ||||||
| Source:         https://github.com/jcorporation/myMPD/archive/master.zip | Source:         https://github.com/jcorporation/myMPD/archive/devel.zip | ||||||
| BuildRequires:  gcc | BuildRequires:  gcc | ||||||
| BuildRequires:  cmake | BuildRequires:  cmake | ||||||
| BuildRequires:  unzip | BuildRequires:  unzip | ||||||
| BuildRequires:	libmpdclient-devel | BuildRequires:	libmpdclient-devel | ||||||
| BuildRequires:	libmpdclient2 |  | ||||||
| BuildRequires:	pkgconfig | BuildRequires:	pkgconfig | ||||||
| BuildRequires:	openssl-devel | BuildRequires:	openssl-devel | ||||||
| BuildRoot:      %{_tmppath}/%{name}-%{version}-build | BuildRoot:      %{_tmppath}/%{name}-%{version}-build | ||||||
|  |  | ||||||
|  | %global debug_package %{nil} | ||||||
|  |  | ||||||
| %description  | %description  | ||||||
| myMPD is a standalone and mobile friendly web mpdclient. | myMPD is a standalone and mobile friendly web mpdclient. | ||||||
| @@ -36,7 +36,24 @@ make | |||||||
| %install | %install | ||||||
| cd release | cd release | ||||||
| make install DESTDIR=%{buildroot} | make install DESTDIR=%{buildroot} | ||||||
| chmod 755 %{buildroot}/usr/share/mympd/crcert.sh |  | ||||||
|  | %post | ||||||
|  | getent group mympd > /dev/null | ||||||
|  | [ "$?" = "2" ] && groupadd mympd | ||||||
|  | getent passwd mympd > /dev/null | ||||||
|  | [ "$?" = "2" ] && useradd mympd -g mympd -d /var/lib/mympd -s /usr/sbin/nologin | ||||||
|  | if [ -d /usr/lib/systemd/ ] | ||||||
|  | then | ||||||
|  |   [ -d /usr/lib/systemd/system ] || sudo mkdir /usr/lib/systemd/system  | ||||||
|  |   cp /usr/share/mympd/mympd.service /usr/lib/systemd/system/ | ||||||
|  | fi | ||||||
|  | if [ -f /etc/mpd.conf ] | ||||||
|  | then | ||||||
|  |   LIBRARY=$(grep ^music_directory /etc/mpd.conf | awk {'print $2'} | sed -e 's/"//g') | ||||||
|  |   [ "$LIBRARY" != "" ] && [ ! -e /usr/share/mympd/htdocs/library ] && ln -s "$LIBRARY" /usr/share/mympd/htdocs/library | ||||||
|  | fi | ||||||
|  | chown -R mympd /var/lib/mympd | ||||||
|  | /usr/share/mympd/crcert.sh | ||||||
|  |  | ||||||
| %files  | %files  | ||||||
| %defattr(-,root,root,-) | %defattr(-,root,root,-) | ||||||
| @@ -48,5 +65,5 @@ chmod 755 %{buildroot}/usr/share/mympd/crcert.sh | |||||||
| /var/lib/mympd | /var/lib/mympd | ||||||
|  |  | ||||||
| %changelog | %changelog | ||||||
| * Tue Aug 28 2018 Juergen Mang <mail@jcgames.de> - master | * Wed Sep 05 2018 Juergen Mang <mail@jcgames.de> - master | ||||||
| - Version from master | - Version from master | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ sslcert = /etc/mympd/ssl/server.pem | |||||||
| sslkey = /etc/mympd/ssl/server.key | sslkey = /etc/mympd/ssl/server.key | ||||||
|  |  | ||||||
| #myMPD user | #myMPD user | ||||||
| user = nobody | user = mympd | ||||||
|  |  | ||||||
| #Port for mpd http stream | #Port for mpd http stream | ||||||
| streamport = 8000 | streamport = 8000 | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | mympd (4.1.0-1) unstable; urgency=medium | ||||||
|  |  | ||||||
|  |   * Initial release  | ||||||
|  |  | ||||||
|  |  -- Juergen Mang <mail@jcgames.de>  Thu, 06 Sep 2018 22:57:18 +0200 | ||||||
							
								
								
									
										12
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | Source: mympd | ||||||
|  | Section: unknown | ||||||
|  | Priority: optional | ||||||
|  | Maintainer: Juergen Mang <mail@jcgames.de> | ||||||
|  | Build-Depends: debhelper (>= 10), libmpdclient-dev, cmake, libssl-dev | ||||||
|  | Standards-Version: 4.1.2 | ||||||
|  | Homepage: https://github.com/jcorporation/myMPD | ||||||
|  |  | ||||||
|  | Package: mympd | ||||||
|  | Architecture: any | ||||||
|  | Depends: libmpdclient2, openssl | ||||||
|  | Description: myMPD is a standalone and modern web mpdclient. | ||||||
							
								
								
									
										39
									
								
								debian/postinst
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										39
									
								
								debian/postinst
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | #/bin/bash | ||||||
|  |  | ||||||
|  | echo "Fixing ownership of /var/lib/mympd" | ||||||
|  | getent group mympd > /dev/null | ||||||
|  | [ "$?" = "2" ] && groupadd mympd | ||||||
|  | getent passwd mympd > /dev/null | ||||||
|  | [ "$?" = "2" ] && useradd mympd -g mympd-d /var/lib/mympd -s /usr/sbin/nologin | ||||||
|  |  | ||||||
|  | chown -R mympd.mympd /var/lib/mympd | ||||||
|  |  | ||||||
|  | echo "Trying to link musicdir to library" | ||||||
|  | if [ -f /etc/mpd.conf ] | ||||||
|  | then | ||||||
|  |   LIBRARY=$(grep ^music_directory /etc/mpd.conf | awk {'print $2'} | sed -e 's/"//g') | ||||||
|  |   [ "$LIBRARY" != "" ] && [ ! -e /usr/share/mympd/htdocs/library ] && ln -s "$LIBRARY" /usr/share/mympd/htdocs/library | ||||||
|  | else | ||||||
|  |   echo "/etc/mpd.conf not found, you must link your music_directory manually to /usr/share/mympd/htdocs/library" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [ -d /usr/lib/systemd/ ] | ||||||
|  | then | ||||||
|  |   echo "Installing systemd service" | ||||||
|  |   [ -d /usr/lib/systemd/system ] || mkdir /usr/lib/systemd/system  | ||||||
|  |   if [ contrib/mympd.service -nt /usr/lib/systemd/system/mympd.service ] | ||||||
|  |   then | ||||||
|  |     cp contrib/mympd.service /usr/lib/systemd/system/ | ||||||
|  |   fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [ -d /etc/mympd/ssl ] | ||||||
|  | then | ||||||
|  |   echo "Certificates already created" | ||||||
|  | else | ||||||
|  |   echo "Creating certificates" | ||||||
|  |   sudo contrib/crcert.sh | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | echo "myMPD installed" | ||||||
|  | echo "Edit /etc/mympd/mympd.conf before starting myMPD" | ||||||
							
								
								
									
										25
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										25
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | #!/usr/bin/make -f | ||||||
|  | export DH_VERBOSE = 1 | ||||||
|  |  | ||||||
|  | BUILDDIR = release | ||||||
|  |  | ||||||
|  | build: | ||||||
|  | 	mkdir $(BUILDDIR) | ||||||
|  | 	cd $(BUILDDIR); cmake -DCMAKE_INSTALL_PREFIX:PATH=../debian/tmp/usr -DCMAKE_BUILD_TYPE=RELEASE .. | ||||||
|  | 	make -C $(BUILDDIR) | ||||||
|  |  | ||||||
|  | binary: binary-indep binary-arch | ||||||
|  |  | ||||||
|  | binary-indep: | ||||||
|  |  | ||||||
|  | binary-arch: | ||||||
|  | 	cd $(BUILDDIR); cmake -P cmake_install.cmake | ||||||
|  | 	mkdir debian/tmp/DEBIAN | ||||||
|  | 	cp debian/postinst debian/tmp/DEBIAN | ||||||
|  | 	dpkg-gencontrol -pmympd | ||||||
|  | 	dpkg --build debian/tmp .. | ||||||
|  |  | ||||||
|  | clean: | ||||||
|  | 	rm -rf $(BUILDDIR) | ||||||
|  |  | ||||||
|  | .PHONY: binary binary-arch binary-indep clean | ||||||
							
								
								
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | 3.0 (quilt) | ||||||
							
								
								
									
										1
									
								
								debian/source/options
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/source/options
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | extend-diff-ignore = "(\.git\/|\.github\/)" | ||||||
							
								
								
									
										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-small{font-size:16px}.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} | 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-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} | ||||||
							
								
								
									
										2
									
								
								dist/htdocs/index.html
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/htdocs/index.html
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										168
									
								
								dist/htdocs/js/mympd.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										168
									
								
								dist/htdocs/js/mympd.min.js
									
									
									
									
										vendored
									
									
								
							| @@ -3,48 +3,49 @@ $jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Sym | |||||||
| $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}})}; | $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}})}; | ||||||
| $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.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.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=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 e="";a;)if(a&1&&(e+=b),a>>>=1)b+=b;return e}},"es6","es3"); | $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,app={apps:{Playback:{state:"0/-/",scrollPos:0},Queue:{state:"0/Any Tag/",scrollPos:0},Browse:{active:"Database",tabs:{Filesystem:{state:"0/-/",scrollPos:0},Playlists:{active:"All",views:{All:{state:"0/-/",scrollPos:0},Detail:{state:"0/-/",scrollPos:0}}},Database:{active:"Artist",views:{Artist:{state:"0/-/",scrollPos:0},Album:{state:"0/-/",scrollPos:0}}}}},Search:{state:"0/Any Tag/", | 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:"AlbumArtist",views:{AlbumArtist:{state:"0/-/",scrollPos:0},Genre:{state:"0/-/",scrollPos:0},Artist:{state:"0/-/", | ||||||
| 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; | 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.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.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.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"); | 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")),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")); | 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")); | ||||||
| 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"); | 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+ | 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")} | "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")} | ||||||
| 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? | function appGoto(a,b,c,d){var e=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop;void 0!=app.apps[app.current.app].scrollPos?app.apps[app.current.app].scrollPos=e:void 0!=app.apps[app.current.app].tabs[app.current.tab].scrollPos?app.apps[app.current.app].tabs[app.current.tab].scrollPos=e: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=e);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} | (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==d?app.apps[a].tabs[b].views[c].state:d)):a="/"+a+"/"+b+"!"+(void 0==d?app.apps[a].tabs[b].state:d)):a="/"+a+"!"+(void 0==d?app.apps[a].state:d);location.hash=a} | ||||||
| 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): | 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); | 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); | ||||||
| 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].innerText==app.current.filter&&(b[a].classList.add("active"),document.getElementById("searchqueuetagdesc").innerText=b[a].innerText);getQueue()}else if("Browse"==app.current.app&&"Playlists"==app.current.tab&&"All"==app.current.view)sendAPI({cmd:"MPD_API_PLAYLIST_LIST", | if("Playback"==app.current.app)sendAPI({cmd:"MPD_API_PLAYER_CURRENT_SONG"},songChange);else if("Queue"==app.current.app)selectTag("searchqueuetag","searchqueuetagdesc",app.current.filter),getQueue();else if("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),doSetFilterLetter("BrowsePlaylistsFilter");else if("Browse"==app.current.app&&"Playlists"==app.current.tab&& | ||||||
| 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", | "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)""!=app.current.search?(sendAPI({cmd:"MPD_API_DATABASE_TAG_ALBUM_LIST",data:{offset:app.current.page,filter:app.current.filter,search:app.current.search,tag:app.current.view}},parseListDBtags),doSetFilterLetter("BrowseDatabaseFilter")): | ||||||
| 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", | (sendAPI({cmd:"MPD_API_DATABASE_TAG_LIST",data:{offset:app.current.page,filter:app.current.filter,tag:app.current.view}},parseListDBtags),doSetFilterLetter("BrowseDatabaseFilter"),selectTag("BrowseDatabaseByTagDropdown","btnBrowseDatabaseByTag",app.current.view));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? | ||||||
| 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= | (document.getElementById("BrowseFilesystemAddAllSongs").removeAttribute("disabled"),document.getElementById("BrowseFilesystemAddAllSongsBtn").removeAttribute("disabled")):(document.getElementById("BrowseFilesystemAddAllSongs").setAttribute("disabled","disabled"),document.getElementById("BrowseFilesystemAddAllSongsBtn").setAttribute("disabled","disabled"));var b='<li class="breadcrumb-item"><a data-uri="">root</a></li>',c=app.current.search.split("/"),d=c.length,e="";for(a=0;a<d;a++){if(d-1==a){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+ | '<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?(document.getElementById("searchstr").focus(), | ||||||
| "/"+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:{mpdtag:app.current.filter, | 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", | ||||||
| offset:app.current.page,searchstr:app.current.search}},parseSearch):(document.getElementById("SearchList").getElementsByTagName("tbody")[0].innerHTML="",document.getElementById("searchAddAllSongs").setAttribute("disabled","disabled"),document.getElementById("searchAddAllSongsBtn").setAttribute("disabled","disabled"),document.getElementById("panel-heading-search").innerText="",document.getElementById("SearchList").classList.remove("opacity05"),setPagination(0)),b=document.getElementById("searchtags").getElementsByTagName("button"), | "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")} | ||||||
| c=b.length,a=0;a<c;a++)b[a].classList.remove("active"),b[a].innerText==app.current.filter&&(b[a].classList.add("active"),document.getElementById("searchtagsdesc").innerText=b[a].innerText);else appGoto("Playback");app.last.app=app.current.app;app.last.tab=app.current.tab;app.last.view=app.current.view}else appGoto("Playback")} |  | ||||||
| function appInit(){getSettings();sendAPI({cmd:"MPD_API_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", | 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")}); | 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("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")}, | document.getElementById("inputMixrampdb").classList.remove("is-invalid");document.getElementById("inputMixrampdelay").classList.remove("is-invalid")});document.getElementById("addToPlaylistPlaylist").addEventListener("change",function(a){"New Playlist"==this.options[this.selectedIndex].text?(document.getElementById("addToPlaylistNewPlaylistDiv").classList.remove("hide"),document.getElementById("addToPlaylistNewPlaylist").focus()):document.getElementById("addToPlaylistNewPlaylistDiv").classList.add("hide")}, | ||||||
| !1);addFilterLetter("BrowseFilesystemFilterLetters");addFilterLetter("BrowseDatabaseFilterLetters");addFilterLetter("BrowsePlaylistsFilterLetters");for(var a=document.querySelectorAll("[data-href]"),b=a.length,c=0;c<b;c++)a[c].classList.add("clickable"),a[c].addEventListener("click",function(a){a.preventDefault();a.stopPropagation();a=JSON.parse(this.getAttribute("data-href").replace(/'/g,'"'));if("function"===typeof window[a.cmd])switch(a.cmd){case "sendAPI":sendAPI.apply(null,$jscomp.arrayFromIterable(a.options)); | !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)); | ||||||
| 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")? | 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")? | ||||||
| 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&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowseFilesystemList").addEventListener("click",function(a){if("TD"==a.target.nodeName)switch(a.target.parentNode.getAttribute("data-type")){case "dir":appGoto("Browse", | 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, | ||||||
| "Filesystem",void 0,"0/"+app.current.filter+"/"+decodeURI(a.target.parentNode.getAttribute("data-uri")));break;case "song":appendQueue("song",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name"));break;case "plist":appendQueue("plist",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name"))}else"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowsePlaylistsAllList").addEventListener("click", | "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"== | ||||||
| function(a){"TD"==a.target.nodeName?appendQueue("plist",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))},!1);document.getElementById("BrowsePlaylistsDetailList").addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("plist",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&(a.preventDefault(), | 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("BrowseDatabaseTagList").addEventListener("click", | ||||||
| showMenu(a.target))},!1);document.getElementById("BrowseDatabaseArtistList").addEventListener("click",function(a){"TD"==a.target.nodeName&&appGoto("Browse","Database","Album","0/-/"+a.target.parentNode.getAttribute("data-uri"))},!1);document.getElementById("SearchList").addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("song",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&(a.preventDefault(),showMenu(a.target))}, | function(a){"TD"==a.target.nodeName&&appGoto("Browse","Database",app.current.view,"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"== | ||||||
| !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"))}, | 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?addAllFromSearchPlist("queue"):"Add all to playlist"==a.target.innerText&&showAddToPlaylist("SEARCH"))},!1);document.getElementById("BrowseDatabaseAddAllSongsDropdown").addEventListener("click", | ||||||
| !1);document.getElementById("searchtags").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,"0/"+a.target.innerText+"/"+app.current.search)},!1);document.getElementById("searchqueuestr").addEventListener("keyup",function(a){appGoto(app.current.app,app.current.tab,app.current.view,"0/"+app.current.filter+"/"+this.value)},!1);document.getElementById("searchqueuetag").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&& | function(a){"BUTTON"==a.target.nodeName&&("Add all to queue"==a.target.innerText?addAllFromBrowseDatabasePlist("queue"):"Add all to playlist"==a.target.innerText&&showAddToPlaylist("DATABASE"))},!1);document.getElementById("searchtags").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,"0/"+a.target.getAttribute("data-tag")+"/"+app.current.search)},!1);document.getElementById("searchqueuestr").addEventListener("keyup",function(a){appGoto(app.current.app, | ||||||
| appGoto(app.current.app,app.current.tab,app.current.view,app.current.page+"/"+a.target.innerText+"/"+app.current.search)},!1);document.getElementById("search").addEventListener("submit",function(){return!1},!1);document.getElementById("searchqueue").addEventListener("submit",function(){return!1},!1);document.getElementById("searchstr").addEventListener("keyup",function(a){appGoto("Search",void 0,void 0,"0/"+app.current.filter+"/"+this.value)},!1);dragAndDropTable("QueueList");dragAndDropTable("BrowsePlaylistsDetailList"); | app.current.tab,app.current.view,"0/"+app.current.filter+"/"+this.value)},!1);document.getElementById("searchqueuetag").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,app.current.page+"/"+a.target.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); | ||||||
| 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,5)&&window.addEventListener("load",function(){navigator.serviceWorker.register("/sw.min.js", | document.getElementById("searchstr").addEventListener("keyup",function(a){appGoto("Search",void 0,void 0,"0/"+app.current.filter+"/"+this.value)},!1);document.getElementById("BrowseDatabaseByTagDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,a.target.getAttribute("data-tag"),"0/"+app.current.filter+"/"+app.current.search)},!1);document.getElementsByTagName("body")[0].addEventListener("click",function(a){(a=document.getElementsByClassName("popover")[0])&& | ||||||
| {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"); | 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, | ||||||
| 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")})} | 5)&&window.addEventListener("load",function(){navigator.serviceWorker.register("/sw.min.js",{scope:"/"}).then(function(a){console.log("ServiceWorker registration successful with scope: ",a.scope);a.update()},function(a){console.log("ServiceWorker registration failed: ",a)})});window.addEventListener("beforeinstallprompt",function(a){a.preventDefault();deferredPrompt=a});window.addEventListener("beforeinstallprompt",function(a){a.preventDefault();deferredPrompt=a;domCache.btnAdd.classList.remove("hide")}); | ||||||
|  | domCache.btnAdd.addEventListener("click",function(a){domCache.btnAdd.classList.add("hide");deferredPrompt.prompt();deferredPrompt.userChoice.then(function(a){"accepted"===a.outcome?console.log("User accepted the A2HS prompt"):console.log("User dismissed the A2HS prompt");deferredPrompt=null})});window.addEventListener("appinstalled",function(a){console.log("myMPD installed as app")})} | ||||||
| function dragAndDropTable(a){var b=document.getElementById(a).getElementsByTagName("tbody")[0];b.addEventListener("dragstart",function(a){"TR"==a.target.nodeName&&(a.target.classList.add("opacity05"),a.dataTransfer.setDragImage(a.target,0,0),a.dataTransfer.effectAllowed="move",a.dataTransfer.setData("Text",a.target.getAttribute("id")),dragEl=a.target.cloneNode(!0))},!1);b.addEventListener("dragleave",function(a){a.preventDefault();var b=a.target;"TD"==a.target.nodeName&&(b=a.target.parentNode);"TR"== | function dragAndDropTable(a){var b=document.getElementById(a).getElementsByTagName("tbody")[0];b.addEventListener("dragstart",function(a){"TR"==a.target.nodeName&&(a.target.classList.add("opacity05"),a.dataTransfer.setDragImage(a.target,0,0),a.dataTransfer.effectAllowed="move",a.dataTransfer.setData("Text",a.target.getAttribute("id")),dragEl=a.target.cloneNode(!0))},!1);b.addEventListener("dragleave",function(a){a.preventDefault();var b=a.target;"TD"==a.target.nodeName&&(b=a.target.parentNode);"TR"== | ||||||
| b.nodeName&&b.classList.remove("dragover")},!1);b.addEventListener("dragover",function(a){a.preventDefault();for(var c=b.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"); | 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 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"); | 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,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)} | 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}});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", | 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(); | "","","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(); | ||||||
| @@ -54,48 +55,49 @@ a.data.dbUpdated);document.getElementById("mpdstats_dbUpdated").innerText=b.toUT | |||||||
| 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"), | 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"); | 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"); | ||||||
| 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= | 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+"/"} | b.length,d=1==a.data.stickers?"":"none",e=0;e<c;e++)b[e].style.display=d;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+"/";addTagList("BrowseDatabaseByTagDropdown", | ||||||
| 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} | !1);addTagList("searchqueuetag",!0);addTagList("searchtags",!0)}function getSettings(){sendAPI({cmd:"MPD_API_SETTINGS_GET"},parseSettings)} | ||||||
| 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= | 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} | ||||||
| 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))} | 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?domCache.btnNext.setAttribute("disabled","disabled"):domCache.btnNext.removeAttribute("disabled"); | 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= | 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);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}} | 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}} | ||||||
| function getQueue(){2<=app.current.search.length?sendAPI({cmd:"MPD_API_QUEUE_SEARCH",data:{mpdtag: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 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+" 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); | 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", | 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[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>': | 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>': | ||||||
| "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")}} | "queue"==a.type&&0==b&&(c.innerHTML='<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">Empty queue</td></tr>');setPagination(a.totalEntities);document.getElementById("QueueList").classList.remove("opacity05")}} | ||||||
| function parseSearch(a){"Search"===app.current.app&&(document.getElementById("panel-heading-search").innerHTML=a.totalEntities+" Songs found",0<a.totalEntities?(document.getElementById("searchAddAllSongs").removeAttribute("disabled"),document.getElementById("searchAddAllSongsBtn").removeAttribute("disabled")):(document.getElementById("searchAddAllSongs").setAttribute("disabled","disabled"),document.getElementById("searchAddAllSongsBtn").setAttribute("disabled","disabled")),parseFilesystem(a))} | function parseSearch(a){"Search"===app.current.app&&(document.getElementById("panel-heading-search").innerHTML=a.totalEntities+" Songs found",0<a.totalEntities?(document.getElementById("searchAddAllSongs").removeAttribute("disabled"),document.getElementById("searchAddAllSongsBtn").removeAttribute("disabled")):(document.getElementById("searchAddAllSongs").setAttribute("disabled","disabled"),document.getElementById("searchAddAllSongsBtn").setAttribute("disabled","disabled")),parseFilesystem(a))} | ||||||
| function parseFilesystem(a){if("Browse"===app.current.app||"Filesystem"===app.current.tab||"Search"===app.current.app){for(var b=a.data.length,c=document.getElementById(app.current.app+(void 0==app.current.tab?"":app.current.tab)+"List").getElementsByTagName("tbody")[0],e=c.getElementsByTagName("tr"),d=0;d<b;d++){var f=encodeURI(a.data[d].uri);if(!e[d]||e[d].getAttribute("data-uri")!=f){var g=document.createElement("tr");g.setAttribute("data-type",a.data[d].type);g.setAttribute("data-uri",f);g.setAttribute("data-name", | 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],d=c.getElementsByTagName("tr"),e=0;e<b;e++){var f=encodeURI(a.data[e].uri);if(!d[e]||d[e].getAttribute("data-uri")!=f){var g=document.createElement("tr");g.setAttribute("data-type",a.data[e].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>'; | a.data[e].name);switch(a.data[e].type){case "dir":g.innerHTML='<td><span class="material-icons">folder_open</span></td><td colspan="4">'+a.data[e].name+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';break;case "song":f=Math.floor(a.data[e].duration/60);var h=a.data[e].duration-60*f;g.innerHTML='<td><span class="material-icons">music_note</span></td><td>'+a.data[e].title+"</td><td>"+a.data[e].artist+"</td><td>"+a.data[e].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?"": | break;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")}} | 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(".")?(document.getElementById("BrowsePlaylistsDetailList").setAttribute("data-ro", | 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"), | "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"); | 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","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")!= | h.setAttribute("data-uri",f);h.setAttribute("data-type","plist");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");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>'; | "playlistTrackId"+g){h=document.createElement("tr");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>'; | ||||||
| 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")}} | 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("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], | 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= | ||||||
| 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>'); | "« "+app.current.view;document.getElementById("BrowseDatabaseAlbumListCaption").innerText=a.searchtagtype+": "+a.searchstr;var b=a.data.length;1==b&&""==a.data[0].value&&(b=0);for(var 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'+ | ||||||
| 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")== | 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- | ||||||
| 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", | 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"); | ||||||
| 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")}} | a.data[0]&&""==a.data[0].value&&a.data.shift();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(); | ||||||
| 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="'+ | 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")}} | ||||||
| a.data[f].title+'" data-uri="'+encodeURI(a.data[f].uri)+'"><td>'+a.data[f].track+"</td><td>"+a.data[f].title+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td></tr>';b.innerHTML=e;c.addEventListener("click",function(a){a.preventDefault();showMenu(this)},!1);b.parentNode.addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("song",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&& | 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+ | ||||||
| (a.preventDefault(),showMenu(a.target))},!1)}} | '" 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)} | ||||||
| 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">'+ | 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+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"), | (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+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")}} | 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")}} | ||||||
| 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 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,d){switch(a){case "song":sendAPI({cmd:"MPD_API_QUEUE_ADD_TRACK_AFTER",data:{uri:b,to:c}}),showNotification('"'+d+'" 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 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()} | 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;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>': | 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;var c="";for(f in settings.tags)if(1==settings.tags[f]){var d=a.data[f.toLowerCase()];if("duration"==f){var e=Math.floor(d/60);d-=60*e;d=e+":"+(10>d?"0":"")+d}c+="<tr><th>"+f+"</th><td>"+d+"</td></tr>"}c+='<tr><th>Uri</th><td><a class="text-success" href="/library/'+a.data.uri+ | ||||||
| 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)} | '">'+a.data.uri+"</a></td></tr>";if(1==settings.stickers){var f="not voted";0==a.data.like?f='<span class="material-icons">thumb_down_alt</span>':2==a.data.like&&(f='<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*d)).toUTCString())+"</td></tr><tr><th>Like</th><td>"+ | ||||||
| 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)} | f+"</td></tr>"}b.getElementsByTagName("tbody")[0].innerHTML=c}function playlistDetails(a){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)} | 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))} | function getAllPlaylists(a){for(var b=a.data.length,c="<option></option><option>New Playlist</option>",d=0;d<b;d++)c+="<option>"+a.data[d].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))} | ||||||
| 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 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")): | 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"))} | 2==a&&(domCache.btnVoteUp.classList.add("active-fg-green"),domCache.btnVoteDown.classList.remove("active-fg-red"))} | ||||||
| @@ -104,20 +106,23 @@ function showAddToPlaylist(a){document.getElementById("addToPlaylistUri").value= | |||||||
| 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"), | 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)} | 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)} | ||||||
| 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, | function addToPlaylist(){var a=document.getElementById("addToPlaylistUri").value;if("stream"==a&&(a=document.getElementById("streamUrl").value,""==a||-1==a.indexOf("http"))){document.getElementById("streamUrl").classList.add("is-invalid");document.getElementById("addStreamFrm").classList.add("was-validated");return}var b=document.getElementById("addToPlaylistPlaylist");b=b.options[b.selectedIndex].text;if("New Playlist"==b){b=document.getElementById("addToPlaylistNewPlaylist").value;var c=b.replace(/\w/g, | ||||||
| "");if(""==b||""!=c){document.getElementById("addToPlaylistNewPlaylist").classList.add("is-invalid");document.getElementById("addToPlaylistFrm").classList.add("was-validated");return}}""!=b?("SEARCH"!=a?sendAPI({cmd:"MPD_API_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"))} | "");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 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 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(),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 showMenu(a){var b=a.getAttribute("data-type"),c=decodeURI(a.getAttribute("data-uri")),e=a.getAttribute("data-name"),d=0;if(null==b||null==c)b=a.parentNode.parentNode.getAttribute("data-type"),c=decodeURI(a.parentNode.parentNode.getAttribute("data-uri")),e=a.parentNode.parentNode.getAttribute("data-name");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&& | function dirname(a){return a.replace(/\/[^\/]*$/,"")} | ||||||
| "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': ['"+b+"','"+c+"','"+e+"']}\">Replace queue</a>"+("plist"!=b?"<div class=\"dropdown-divider\"></div><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'showAddToPlaylist', 'options': ['"+ | 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")),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"== | ||||||
| c+"']}\">Add to playlist</a>":"")+("dir"!=b?'<div class="dropdown-divider"></div>':"")+("song"==b?"<a class=\"dropdown-item\" data-href=\"{'cmd': 'songDetails', 'options': ['"+c+'\']}" href="#">Songdetails</a>':"")+("plist"==b?"<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'playlistDetails', 'options': ['"+c+"']}\">Show playlist</a>":""):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"All"==app.current.view?f+="<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendQueue', 'options': ['"+ | 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+"','"+d+"']}\">Append to queue</a>"+("song"==b?"<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendAfterQueue', 'options': ['"+b+"','"+c+"',"+e+",'"+d+"']}\">Add after current playing song</a>":"")+"<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['"+ | ||||||
| b+"','"+c+"','"+e+"']}\">Append to queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['"+b+"','"+c+"','"+e+"']}\">Replace queue</a><div class=\"dropdown-divider\"></div><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'playlistDetails', 'options': ['"+c+"']}\">Edit playlist</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'showRenamePlaylist', 'options': ['"+c+"']}\">Rename playlist</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delPlaylist', 'options': ['"+ | b+"','"+c+"','"+d+"']}\">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\': [\''+ | ||||||
| c+"']}\">Delete playlist</a>":"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view?f+="<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendQueue', 'options': ['"+b+"','"+c+"','"+e+"']}\">Append to queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['"+b+"','"+c+"','"+e+"']}\">Replace queue</a>"+("false"==document.getElementById("BrowsePlaylistsDetailList").getAttribute("data-ro")?"<div class=\"dropdown-divider\"></div><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'removeFromPlaylist', 'options': ['"+ | b+"','"+c+"','"+d+"']}\">Append to queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendAfterQueue', 'options': ['"+b+"','"+c+"',"+e+",'"+d+"']}\">Add after current playing song</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['"+b+"','"+c+"','"+d+"']}\">Replace queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'showAddToPlaylist', 'options': ['"+c+"']}\">Add to playlist</a></div>")):"Browse"==app.current.app&&"Playlists"== | ||||||
| document.getElementById("BrowsePlaylistsDetailList").getAttribute("data-uri")+"', '"+a.parentNode.parentNode.getAttribute("data-songpos")+"']}\">Remove</a>":"")+("plist"!=b?"<div class=\"dropdown-divider\"></div><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'showAddToPlaylist', 'options': ['"+c+"']}\">Add to playlist</a>":""):"Queue"==app.current.app&&(f+="<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['single',"+a.parentNode.parentNode.getAttribute("data-trackid")+ | app.current.tab&&"All"==app.current.view?f+="<a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'appendQueue', 'options': ['"+b+"','"+c+"','"+d+"']}\">Append to queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['"+b+"','"+c+"','"+d+"']}\">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': ['"+ | ||||||
| "]}\">Remove</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['range',0,"+a.parentNode.parentNode.getAttribute("data-songpos")+"]}\">Remove all upwards</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'delQueueSong', 'options': ['range',"+(parseInt(a.parentNode.parentNode.getAttribute("data-songpos"))-1)+',-1]}">Remove all downwards</a><div class="dropdown-divider"></div>'+(-1==c.indexOf("http")?"<a class=\"dropdown-item\" data-href=\"{'cmd': 'songDetails', 'options': ['"+ | c+"']}\">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+"','"+d+"']}\">Append to queue</a><a class=\"dropdown-item\" href=\"#\" data-href=\"{'cmd': 'replaceQueue', 'options': ['"+b+"','"+c+"','"+d+"']}\">Replace queue</a>"+("false"== | ||||||
| c+'\']}" href="#">Songdetails</a>':""));void 0==a.Popover&&(new Popover(a,{trigger:"click",template:'<div class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content">'+f+"</div></div>"}),b=a.Popover,a.addEventListener("shown.bs.popover",function(a){document.getElementsByClassName("popover-content")[0].addEventListener("click",function(a){a.preventDefault();a.stopPropagation();if("A"==a.target.nodeName&&(a=JSON.parse(a.target.getAttribute("data-href").replace(/'/g,'"')),"function"=== | 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&& | ||||||
| typeof window[a.cmd]))switch(a.cmd){case "sendAPI":sendAPI.apply(null,$jscomp.arrayFromIterable(a.options));break;default:window[a.cmd].apply(null,$jscomp.arrayFromIterable(a.options))}},!1)},!1),b.show())} | (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"))- | ||||||
| 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))}; | 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()} | ||||||
|  | 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 d=JSON.parse(c.responseText);"error"==d.type?(showNotification("Error",d.data,d.data,"danger"),console.log("Error: "+d.data)):"result"==d.type&&"ok"!=d.data?showNotification(d.data,"","","success"):void 0!=b&&"function"==typeof b&&b(d)}else console.log("Empty response for request: "+JSON.stringify(a))}; | ||||||
| c.send(JSON.stringify(a))}function openLocalPlayer(){window.open("/player.html#"+settings.mpdstream,"LocalPlayer")}function updateDB(){sendAPI({cmd:"MPD_API_DATABASE_UPDATE"});updateDBstarted(!0)} | 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 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")): | 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")): | ||||||
| @@ -126,17 +131,18 @@ function delQueueSong(a,b,c){"range"==a?sendAPI({cmd:"MPD_API_QUEUE_RM_RANGE",da | |||||||
| 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)? | 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)? | ||||||
| (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, | (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, | ||||||
| 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")} | 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")} | ||||||
| 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_ADD_QUEUE",data:{filter:app.current.filter,searchstr:app.current.search}}),showNotification("Added "+parseInt(document.getElementById("panel-heading-search").innerText)+" songs from search","","","success"))} | function addAllFromBrowseFilesystem(){sendAPI({cmd:"MPD_API_QUEUE_ADD_TRACK",data:{uri:app.current.search}});showNotification("Added all songs","","","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 addAllFromSearchPlist(a){if(2<=app.current.search.length){var b=app.current.filter;"Any Tag"==b&&(b="any");sendAPI({cmd:"MPD_API_DATABASE_SEARCH_ADD_PLAYLIST",data:{plist:a,filter:b,searchstr:app.current.search}});showNotification("Added "+parseInt(document.getElementById("panel-heading-search").innerText)+" songs from search to "+a,"","","success")}}function scrollTo(a){document.body.scrollTop=a;document.documentElement.scrollTop=a} | function addAllFromBrowseDatabasePlist(a){2<=app.current.search.length&&(sendAPI({cmd:"MPD_API_DATABASE_SEARCH",data:{plist:a,filter:app.current.view,searchstr:app.current.search,offset:0}}),showNotification("Added songs from database selection to "+a,"","","success"))}function scrollTo(a){document.body.scrollTop=a;document.documentElement.scrollTop=a} | ||||||
| function gotoPage(a){switch(a){case "next":app.current.page+=settings.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)} | 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)} | ||||||
| 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"))} | 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"))} | ||||||
| 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>"+ | function showNotification(a,b,c,d){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-"+d),b.innerHTML="<div><strong>"+ | ||||||
| a+"</strong><br/>"+c+"</div>",document.getElementsByTagName("main")[0].append(b),document.getElementById("alertBox").classList.add("alertBoxActive"),alertTimeout&&clearTimeout(alertTimeout),alertTimeout=setTimeout(function(){hideNotification()},3E3))}function hideNotification(){document.getElementById("alertBox")&&(document.getElementById("alertBox").classList.remove("alertBoxActive"),setTimeout(function(){var a=document.getElementById("alertBox");a&&a.remove()},600))} | 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))} | ||||||
| function notificationsSupported(){return"Notification"in window} | function notificationsSupported(){return"Notification"in window} | ||||||
| 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)): | 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="",d="",e="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,d+=a.data.artist,e+=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","")); | domCache.currentArtist.innerText="";"undefined"!=typeof a.data.album&&0<a.data.album.length&&"-"!=a.data.album?(c+=" - "+a.data.album,d+="<br/>"+a.data.album,domCache.currentAlbum.innerText=a.data.album,domCache.currentAlbum.setAttribute("data-album",a.data.album)):domCache.currentAlbum.innerText="";"undefined"!=typeof a.data.title&&0<a.data.title.length?(e+=a.data.title,domCache.currentTrack.innerText=a.data.title,domCache.currentTrack.setAttribute("data-uri",a.data.uri)):(domCache.currentTrack.innerText= | ||||||
| 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}}} | "",domCache.currentTrack.setAttribute("data-uri",""));document.title=e;1==settings.stickers&&setVoteSongBtns(a.data.like,a.data.uri);if(e=document.getElementById("queueTrackId"+a.data.currentSongId))e.getElementsByTagName("td")[1].innerText=a.data.title;showNotification(a.data.title,c,d,"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}}} | 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,d=0;d<c;d++)if(a[d].innerText==b){a[d].classList.add("active");break}}} | ||||||
| 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, | 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 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"} | 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 genId(a){return"id"+a.replace(/[^\w]/g,"")}appInit(); | function addTagList(a,b){var c="";1==b&&(c+='<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="any">Any Tag</button>');for(var d in settings.tags)1==settings.tags[d]&&"Track"!=d&&(c+='<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="'+d+'">'+d+"</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 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= | 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)}}: | 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, | 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.0.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/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.1.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/favicon.ico /assets/MaterialIcons-Regular.eot /assets/MaterialIcons-Regular.ttf /assets/MaterialIcons-Regular.woff /assets/MaterialIcons-Regular.woff2".split(" "); | ||||||
| self.addEventListener("install",function(a){a.waitUntil(caches.open(CACHE).then(function(a){return a.addAll(urlsToCache)}))});self.addEventListener("fetch",function(a){a.respondWith(caches.match(a.request).then(function(b){return b?b:fetch(a.request)}))});self.addEventListener("activate",function(a){a.waitUntil(caches.keys().then(function(a){return Promise.all(a.map(function(a){if(a!=CACHE)return caches.delete(a)}))}))}); | self.addEventListener("install",function(a){a.waitUntil(caches.open(CACHE).then(function(a){return a.addAll(urlsToCache)}))});self.addEventListener("fetch",function(a){a.respondWith(caches.match(a.request).then(function(b){return b?b:fetch(a.request)}))});self.addEventListener("activate",function(a){a.waitUntil(caches.keys().then(function(a){return Promise.all(a.map(function(a){if(a!=CACHE)return caches.delete(a)}))}))}); | ||||||
|   | |||||||
| @@ -132,6 +132,11 @@ small { | |||||||
|   font-size: 16px; |   font-size: 16px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .material-icons-small-left { | ||||||
|  |   font-size: 1rem; | ||||||
|  |   margin-left: -1em; | ||||||
|  | } | ||||||
|  |  | ||||||
| .color-darkgrey, .color-darkgrey:hover { | .color-darkgrey, .color-darkgrey:hover { | ||||||
|   color:#6c757d !important; |   color:#6c757d !important; | ||||||
| } | } | ||||||
| @@ -263,3 +268,16 @@ caption { | |||||||
|   animation-name: changewidth; |   animation-name: changewidth; | ||||||
|   animation-iteration-count: infinite; |   animation-iteration-count: infinite; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .modal-body { | ||||||
|  |   overflow-x: hidden; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .modal-body .album-cover { | ||||||
|  |   float:none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #BrowseDatabaseAlbumListCaption { | ||||||
|  |   width:100%; | ||||||
|  |   margin-left: 15px; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -87,7 +87,7 @@ | |||||||
|           <small>Artist</small> |           <small>Artist</small> | ||||||
|           <h4 id="currentArtist" data-href="{'cmd': 'artistClick', 'options': []}"></h4> |           <h4 id="currentArtist" data-href="{'cmd': 'artistClick', 'options': []}"></h4> | ||||||
|           <small>Album</small> |           <small>Album</small> | ||||||
|           <h4 id="currentAlbum"></h4> |           <h4 id="currentAlbum" data-href="{'cmd': 'albumClick', 'options': []}"></h4> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|       <div class="card-footer card-footer-playback"> |       <div class="card-footer card-footer-playback"> | ||||||
| @@ -120,8 +120,8 @@ | |||||||
|               <button type="button" class="btn btn-secondary material-icons" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_QUEUE_CLEAR'}]}" title="Clear queue">clear_all</button> |               <button type="button" class="btn btn-secondary material-icons" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_QUEUE_CLEAR'}]}" title="Clear queue">clear_all</button> | ||||||
|               <button id="clearQueueBtn" class="btn btn-secondary dropdown-toggle dropdown-toggle-split rounded-right" type="button" data-toggle="dropdown"></button> |               <button id="clearQueueBtn" class="btn btn-secondary dropdown-toggle dropdown-toggle-split rounded-right" type="button" data-toggle="dropdown"></button> | ||||||
|               <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="clearQueueDropdown"> |               <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="clearQueueDropdown"> | ||||||
|                   <button type="button" class="btn btn-secondary btn-block" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_QUEUE_CLEAR'}]}" >Clear queue</button> |                   <button type="button" class="btn btn-secondary btn-sm btn-block" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_QUEUE_CLEAR'}]}" >Clear queue</button> | ||||||
|                   <button type="button" class="btn btn-secondary btn-block" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_QUEUE_CROP'}]}" >Crop queue</button> |                   <button type="button" class="btn btn-secondary btn-sm btn-block" data-href="{'cmd': 'sendAPI', 'options': [{'cmd':'MPD_API_QUEUE_CROP'}]}" >Crop queue</button> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
| @@ -134,11 +134,6 @@ | |||||||
|                   <span id="searchqueuetagdesc">Any Tag</span> |                   <span id="searchqueuetagdesc">Any Tag</span> | ||||||
|                 </button> |                 </button> | ||||||
|                 <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchqueuetag"> |                 <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchqueuetag"> | ||||||
|                   <h6 class="dropdown-header text-light">Search in Tag</h6> |  | ||||||
|                   <button type="button" class="btn btn-secondary btn-block active">Any Tag</button> |  | ||||||
|                   <button type="button" class="btn btn-secondary btn-block">Title</button> |  | ||||||
|                   <button type="button" class="btn btn-secondary btn-block">Artist</button> |  | ||||||
|                   <button type="button" class="btn btn-secondary btn-block">Album</button> |  | ||||||
|                 </div> |                 </div> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
| @@ -294,14 +289,30 @@ | |||||||
|  |  | ||||||
|       <div class="card-body hide" id="cardBrowseDatabase"> |       <div class="card-body hide" id="cardBrowseDatabase"> | ||||||
|         <div class="btn-toolbar card-toolbar" id="BrowseDatabaseButtons"> |         <div class="btn-toolbar card-toolbar" id="BrowseDatabaseButtons"> | ||||||
|  |           <div class="btn-group mr-2"> | ||||||
|  |             <button id="btnBrowseDatabaseByTag" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">AlbumArtist</button> | ||||||
|  |             <div class="dropdown-menu bg-dark px-2" id="BrowseDatabaseByTagDropdown"> | ||||||
|  |             </div> | ||||||
|  |           </div>         | ||||||
|           <div class="btn-group mr-2 hide"> |           <div class="btn-group mr-2 hide"> | ||||||
|             <button data-href="{'cmd': 'appGoto', 'options': ['Browse','Database','Artist']}" id="btnBrowseDatabaseArtist" type="button" class="btn btn-secondary">« Artists</button> |             <button data-href="{'cmd': 'gotoTagList', 'options': []}" id="btnBrowseDatabaseTag" type="button" class="btn btn-secondary">« Artists</button> | ||||||
|           </div> |           </div> | ||||||
|           <div class="btn-group mr-2"> |           <div class="btn-group mr-2"> | ||||||
|             <button id="BrowseDatabaseFilter" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Filter</button> |             <button id="BrowseDatabaseFilter" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Filter</button> | ||||||
|             <div class="dropdown-menu bg-dark px-2 letters" id="BrowseDatabaseFilterLetters"> |             <div class="dropdown-menu bg-dark px-2 letters" id="BrowseDatabaseFilterLetters"> | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
|  |           <div class="input-group mr-2 hide"> | ||||||
|  |             <div class="input-group-prepend"> | ||||||
|  |               <button data-href="{'cmd': 'addAllFromBrowseDatabase', 'options': []}" id="BrowseDatabaseAddAllSongs" class="btn btn-secondary">Add all</button> | ||||||
|  |               <button id="BrowseDatabaseAddAllSongsBtn" class="btn btn-secondary dropdown-toggle dropdown-toggle-split rounded-right" type="button" data-toggle="dropdown"></button> | ||||||
|  |               <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="BrowseDatabaseAddAllSongsDropdown"> | ||||||
|  |                 <button type="button" class="btn btn-secondary btn-sm btn-block">Add all to queue</button> | ||||||
|  |                 <button type="button" class="btn btn-secondary btn-sm btn-block">Add all to playlist</button> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |  | ||||||
|           <div id="BrowseDatabasePaginationTop" class="btn-group mr-2 hide"> |           <div id="BrowseDatabasePaginationTop" class="btn-group mr-2 hide"> | ||||||
|             <button data-href="{'cmd': 'gotoPage', 'options': ['prev']}" id="BrowseDatabasePaginationTopPrev" title="Previous Page" type="button" class="btn btn-secondary">«</button> |             <button data-href="{'cmd': 'gotoPage', 'options': ['prev']}" id="BrowseDatabasePaginationTopPrev" title="Previous Page" type="button" class="btn btn-secondary">«</button> | ||||||
|               <div class="input-group-append"> |               <div class="input-group-append"> | ||||||
| @@ -314,7 +325,7 @@ | |||||||
|         </div> |         </div> | ||||||
|  |  | ||||||
|         <div class="table-responsive-md"> |         <div class="table-responsive-md"> | ||||||
|           <table id="BrowseDatabaseArtistList" class="table table-hover table-sm"> |           <table id="BrowseDatabaseTagList" class="table table-hover table-sm"> | ||||||
|             <col class="tblnum"/> |             <col class="tblnum"/> | ||||||
|             <col class="tbltitle"/>             |             <col class="tbltitle"/>             | ||||||
|             <thead> |             <thead> | ||||||
| @@ -328,7 +339,9 @@ | |||||||
|           </table> |           </table> | ||||||
|         </div> |         </div> | ||||||
|          |          | ||||||
|         <div id="BrowseDatabaseAlbumList" class="row hide"></div> |         <div id="BrowseDatabaseAlbumList" class="row hide"> | ||||||
|  |           <h2 id="BrowseDatabaseAlbumListCaption"></h2> | ||||||
|  |         </div> | ||||||
|          |          | ||||||
|         <div class="btn-toolbar hide" id="BrowseDatabaseButtonsBottom"> |         <div class="btn-toolbar hide" id="BrowseDatabaseButtonsBottom"> | ||||||
|           <div class="btn-group mr-2"> |           <div class="btn-group mr-2"> | ||||||
| @@ -358,11 +371,11 @@ | |||||||
|           </div>           |           </div>           | ||||||
|           <div class="input-group mr-2"> |           <div class="input-group mr-2"> | ||||||
|             <div class="input-group-prepend"> |             <div class="input-group-prepend"> | ||||||
|               <button data-href="{'cmd': 'addAllFromBrowse', 'options': []}" id="BrowseFilesystemAddAllSongs" class="btn btn-secondary">Add all</button> |               <button data-href="{'cmd': 'addAllFromBrowseFilesystem', 'options': []}" id="BrowseFilesystemAddAllSongs" class="btn btn-secondary">Add all</button> | ||||||
|               <button id="BrowseFilesystemAddAllSongsBtn" class="btn btn-secondary dropdown-toggle dropdown-toggle-split rounded-right" type="button" data-toggle="dropdown"></button> |               <button id="BrowseFilesystemAddAllSongsBtn" class="btn btn-secondary dropdown-toggle dropdown-toggle-split rounded-right" type="button" data-toggle="dropdown"></button> | ||||||
|               <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="BrowseFilesystemAddAllSongsDropdown"> |               <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="BrowseFilesystemAddAllSongsDropdown"> | ||||||
|                 <button type="button" class="btn btn-secondary btn-block">Add all to queue</button> |                 <button type="button" class="btn btn-secondary btn-sm btn-block">Add all to queue</button> | ||||||
|                 <button type="button" class="btn btn-secondary btn-block">Add all to playlist</button> |                 <button type="button" class="btn btn-secondary btn-sm btn-block">Add all to playlist</button> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
| @@ -437,11 +450,6 @@ | |||||||
|                   <span id="searchtagsdesc">Any Tag</span> |                   <span id="searchtagsdesc">Any Tag</span> | ||||||
|                 </button> |                 </button> | ||||||
|                 <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchtags"> |                 <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchtags"> | ||||||
|                   <h6 class="dropdown-header text-light">Search in Tag</h6> |  | ||||||
|                   <button type="button" class="btn btn-secondary active btn-block">Any Tag</button> |  | ||||||
|                   <button type="button" class="btn btn-secondary btn-block">Title</button> |  | ||||||
|                   <button type="button" class="btn btn-secondary btn-block">Artist</button> |  | ||||||
|                   <button type="button" class="btn btn-secondary btn-block">Album</button> |  | ||||||
|                 </div> |                 </div> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
| @@ -451,8 +459,8 @@ | |||||||
|               <button id="searchAddAllSongs" class="btn btn-secondary" data-href="{'cmd': 'addAllFromSearch', 'options': []}">Add all</button> |               <button id="searchAddAllSongs" class="btn btn-secondary" data-href="{'cmd': 'addAllFromSearch', 'options': []}">Add all</button> | ||||||
|               <button id="searchAddAllSongsBtn" class="btn btn-secondary dropdown-toggle dropdown-toggle-split rounded-right" type="button" data-toggle="dropdown"></button> |               <button id="searchAddAllSongsBtn" class="btn btn-secondary dropdown-toggle dropdown-toggle-split rounded-right" type="button" data-toggle="dropdown"></button> | ||||||
|               <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchAddAllSongsDropdown"> |               <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchAddAllSongsDropdown"> | ||||||
|                   <button type="button" class="btn btn-secondary btn-block">Add all to queue</button> |                   <button type="button" class="btn btn-secondary btn-sm btn-block">Add all to queue</button> | ||||||
|                   <button type="button" class="btn btn-secondary btn-block">Add all to playlist</button> |                   <button type="button" class="btn btn-secondary btn-sm btn-block">Add all to playlist</button> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
| @@ -794,22 +802,12 @@ | |||||||
|         <div class="modal-body"> |         <div class="modal-body"> | ||||||
|           <div class="album-cover"></div> |           <div class="album-cover"></div> | ||||||
|           <h1></h1> |           <h1></h1> | ||||||
|           <table class="table table-sm"> |           <div class="table-responsive-md"> | ||||||
|             <tbody> |             <table class="table table-sm"> | ||||||
|               <tr data-name="artist"><th>Artist</th><td></td></tr> |               <tbody> | ||||||
|               <tr data-name="album"><th>Album</th><td></td></tr> |               </tbody> | ||||||
|               <tr data-name="track"><th>Track</th><td></td></tr> |             </table> | ||||||
|               <tr data-name="albumartist"><th>Albumartist</th><td></td></tr> |           </div> | ||||||
|               <tr data-name="genre"><th>Genre</th><td></td></tr> |  | ||||||
|               <tr data-name="date"><th>Date</th><td></td></tr> |  | ||||||
|               <tr data-name="uri"><th>Uri</th><td></td></tr> |  | ||||||
|               <tr class="stickers"><th colspan="2">Statistics</th></tr> |  | ||||||
|               <tr class="stickers" data-name="playCount"><th>Play count</th><td></td></tr> |  | ||||||
|               <tr class="stickers" data-name="skipCount"><th>Skip count</th><td></td></tr> |  | ||||||
|               <tr class="stickers" data-name="lastPlayed"><th>Last played</th><td></td></tr> |  | ||||||
|               <tr class="stickers" data-name="like"><th>Like</th><td></td></tr> |  | ||||||
|             </tbody> |  | ||||||
|           </table> |  | ||||||
|         </div> |         </div> | ||||||
|         <div class="modal-footer"> |         <div class="modal-footer"> | ||||||
|           <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> |           <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ var dragEl; | |||||||
|  |  | ||||||
| var app = {}; | var app = {}; | ||||||
| app.apps = { "Playback": { "state": "0/-/", "scrollPos": 0 }, | app.apps = { "Playback": { "state": "0/-/", "scrollPos": 0 }, | ||||||
|              "Queue": 	 { "state": "0/Any Tag/", "scrollPos": 0 }, |              "Queue": 	 { "state": "0/any/", "scrollPos": 0 }, | ||||||
|              "Browse":   {  |              "Browse":   {  | ||||||
|                   "active": "Database",  |                   "active": "Database",  | ||||||
|                   "tabs":  { "Filesystem": { "state": "0/-/", "scrollPos": 0 }, |                   "tabs":  { "Filesystem": { "state": "0/-/", "scrollPos": 0 }, | ||||||
| @@ -47,14 +47,19 @@ app.apps = { "Playback": { "state": "0/-/", "scrollPos": 0 }, | |||||||
|                                     } |                                     } | ||||||
|                              }, |                              }, | ||||||
|                              "Database":   {  |                              "Database":   {  | ||||||
|                                     "active": "Artist", |                                     "active": "AlbumArtist", | ||||||
|                                     "views": { "Artist": { "state": "0/-/", "scrollPos": 0 }, |                                     "views": { "AlbumArtist": { "state": "0/-/", "scrollPos": 0 }, | ||||||
|                                                "Album":  { "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 Tag/", "scrollPos": 0 } |              "Search": { "state": "0/any/", "scrollPos": 0 } | ||||||
|            }; |            }; | ||||||
|             |             | ||||||
| app.current = { "app": "Playback", "tab": undefined, "view": undefined, "page": 0, "filter": "", "search": "", "scrollPos": 0 }; | app.current = { "app": "Playback", "tab": undefined, "view": undefined, "page": 0, "filter": "", "search": "", "scrollPos": 0 }; | ||||||
| @@ -193,15 +198,7 @@ function appRoute() { | |||||||
|         sendAPI({"cmd": "MPD_API_PLAYER_CURRENT_SONG"}, songChange); |         sendAPI({"cmd": "MPD_API_PLAYER_CURRENT_SONG"}, songChange); | ||||||
|     }     |     }     | ||||||
|     else if (app.current.app == 'Queue' ) { |     else if (app.current.app == 'Queue' ) { | ||||||
|         var btns = document.getElementById('searchqueuetag').getElementsByTagName('button'); |         selectTag('searchqueuetag', 'searchqueuetagdesc', app.current.filter); | ||||||
|         var btnsLen = btns.length; |  | ||||||
|         for (var i = 0; i < btnsLen; i++) { |  | ||||||
|             btns[i].classList.remove('active'); |  | ||||||
|             if (btns[i].innerText == app.current.filter) {  |  | ||||||
|                 btns[i].classList.add('active');  |  | ||||||
|                 document.getElementById('searchqueuetagdesc').innerText = btns[i].innerText; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         getQueue(); |         getQueue(); | ||||||
|     } |     } | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'All') { |     else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'All') { | ||||||
| @@ -212,13 +209,17 @@ function appRoute() { | |||||||
|         sendAPI({"cmd": "MPD_API_PLAYLIST_CONTENT_LIST", "data": {"offset": app.current.page, "filter": app.current.filter, "uri": app.current.search}}, parsePlaylists); |         sendAPI({"cmd": "MPD_API_PLAYLIST_CONTENT_LIST", "data": {"offset": app.current.page, "filter": app.current.filter, "uri": app.current.search}}, parsePlaylists); | ||||||
|         doSetFilterLetter('BrowsePlaylistsFilter'); |         doSetFilterLetter('BrowsePlaylistsFilter'); | ||||||
|     }     |     }     | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.view == 'Artist') { |  | ||||||
|         sendAPI({"cmd": "MPD_API_DATABASE_ARTIST_LIST","data": {"offset": app.current.page, "filter": app.current.filter}}, parseListDBtags); |     else if (app.current.app == 'Browse' && app.current.tab == 'Database') { | ||||||
|         doSetFilterLetter('BrowseDatabaseFilter'); |         if (app.current.search != '') { | ||||||
|     } |             sendAPI({"cmd": "MPD_API_DATABASE_TAG_ALBUM_LIST", "data": {"offset": app.current.page, "filter": app.current.filter, "search": app.current.search, "tag": app.current.view}}, parseListDBtags); | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.view == 'Album') { |             doSetFilterLetter('BrowseDatabaseFilter'); | ||||||
|         sendAPI({"cmd": "MPD_API_DATABASE_ARTISTALBUM_LIST", "data": {"offset": app.current.page, "filter": app.current.filter, "albumartist": app.current.search}}, parseListDBtags); |         } | ||||||
|         doSetFilterLetter('BrowseDatabaseFilter'); |         else { | ||||||
|  |             sendAPI({"cmd": "MPD_API_DATABASE_TAG_LIST","data": {"offset": app.current.page, "filter": app.current.filter, "tag": app.current.view}}, parseListDBtags); | ||||||
|  |             doSetFilterLetter('BrowseDatabaseFilter'); | ||||||
|  |             selectTag('BrowseDatabaseByTagDropdown', 'btnBrowseDatabaseByTag', app.current.view); | ||||||
|  |         } | ||||||
|     }     |     }     | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Filesystem') { |     else if (app.current.app == 'Browse' && app.current.tab == 'Filesystem') { | ||||||
|         sendAPI({"cmd": "MPD_API_DATABASE_FILESYSTEM_LIST", "data": {"offset": app.current.page, "path": (app.current.search ? app.current.search : "/"), "filter": app.current.filter}}, parseFilesystem); |         sendAPI({"cmd": "MPD_API_DATABASE_FILESYSTEM_LIST", "data": {"offset": app.current.page, "path": (app.current.search ? app.current.search : "/"), "filter": app.current.filter}}, parseFilesystem); | ||||||
| @@ -266,7 +267,7 @@ function appRoute() { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (app.current.search.length >= 2) { |         if (app.current.search.length >= 2) { | ||||||
|             sendAPI({"cmd": "MPD_API_DATABASE_SEARCH", "data": { "mpdtag": app.current.filter, "offset": app.current.page, "searchstr": app.current.search}}, parseSearch); |             sendAPI({"cmd": "MPD_API_DATABASE_SEARCH", "data": { "plist": "", "offset": app.current.page, "filter": app.current.filter, "searchstr": app.current.search}}, parseSearch); | ||||||
|         } else { |         } else { | ||||||
|             document.getElementById('SearchList').getElementsByTagName('tbody')[0].innerHTML = ''; |             document.getElementById('SearchList').getElementsByTagName('tbody')[0].innerHTML = ''; | ||||||
|             document.getElementById('searchAddAllSongs').setAttribute('disabled', 'disabled'); |             document.getElementById('searchAddAllSongs').setAttribute('disabled', 'disabled'); | ||||||
| @@ -275,16 +276,7 @@ function appRoute() { | |||||||
|             document.getElementById('SearchList').classList.remove('opacity05'); |             document.getElementById('SearchList').classList.remove('opacity05'); | ||||||
|             setPagination(0); |             setPagination(0); | ||||||
|         } |         } | ||||||
|          |         selectTag('searchtags', 'searchtagsdesc', app.current.filter); | ||||||
|         var btns = document.getElementById('searchtags').getElementsByTagName('button'); |  | ||||||
|         var btnsLen = btns.length; |  | ||||||
|         for (var i = 0; i < btnsLen; i++) { |  | ||||||
|             btns[i].classList.remove('active'); |  | ||||||
|             if (btns[i].innerText == app.current.filter) {  |  | ||||||
|                 btns[i].classList.add('active');  |  | ||||||
|                 document.getElementById('searchtagsdesc').innerText = btns[i].innerText; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         appGoto("Playback"); |         appGoto("Playback"); | ||||||
| @@ -366,7 +358,7 @@ function appInit() { | |||||||
|         hrefs[i].classList.add('clickable'); |         hrefs[i].classList.add('clickable'); | ||||||
|         hrefs[i].addEventListener('click', function(event) { |         hrefs[i].addEventListener('click', function(event) { | ||||||
|             event.preventDefault(); |             event.preventDefault(); | ||||||
|             event.stopPropagation(); |             //event.stopPropagation(); | ||||||
|             var cmd = JSON.parse(this.getAttribute('data-href').replace(/\'/g, '"')); |             var cmd = JSON.parse(this.getAttribute('data-href').replace(/\'/g, '"')); | ||||||
|             if (typeof window[cmd.cmd] === 'function') { |             if (typeof window[cmd.cmd] === 'function') { | ||||||
|                 switch(cmd.cmd) { |                 switch(cmd.cmd) { | ||||||
| @@ -401,8 +393,7 @@ function appInit() { | |||||||
|         if (event.target.nodeName == 'TD')  |         if (event.target.nodeName == 'TD')  | ||||||
|             sendAPI({"cmd": "MPD_API_PLAYER_PLAY_TRACK","data": {"track": event.target.parentNode.getAttribute('data-trackid')}}); |             sendAPI({"cmd": "MPD_API_PLAYER_PLAY_TRACK","data": {"track": event.target.parentNode.getAttribute('data-trackid')}}); | ||||||
|         else if (event.target.nodeName == 'A') { |         else if (event.target.nodeName == 'A') { | ||||||
|             event.preventDefault(); |             showMenu(event.target, event); | ||||||
|             showMenu(event.target); |  | ||||||
|         } |         } | ||||||
|     }, false); |     }, false); | ||||||
|  |  | ||||||
| @@ -421,8 +412,7 @@ function appInit() { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else if (event.target.nodeName == 'A') { |         else if (event.target.nodeName == 'A') { | ||||||
|             event.preventDefault(); |             showMenu(event.target, event); | ||||||
|             showMenu(event.target); |  | ||||||
|         } |         } | ||||||
|     }, false); |     }, false); | ||||||
|      |      | ||||||
| @@ -431,8 +421,7 @@ function appInit() { | |||||||
|             appendQueue('plist', decodeURI(event.target.parentNode.getAttribute("data-uri")), event.target.parentNode.getAttribute("data-name")); |             appendQueue('plist', decodeURI(event.target.parentNode.getAttribute("data-uri")), event.target.parentNode.getAttribute("data-name")); | ||||||
|         } |         } | ||||||
|         else if (event.target.nodeName == 'A') { |         else if (event.target.nodeName == 'A') { | ||||||
|             event.preventDefault(); |             showMenu(event.target, event); | ||||||
|             showMenu(event.target); |  | ||||||
|         } |         } | ||||||
|     }, false); |     }, false); | ||||||
|  |  | ||||||
| @@ -441,14 +430,13 @@ function appInit() { | |||||||
|             appendQueue('plist', decodeURI(event.target.parentNode.getAttribute("data-uri")), event.target.parentNode.getAttribute("data-name")); |             appendQueue('plist', decodeURI(event.target.parentNode.getAttribute("data-uri")), event.target.parentNode.getAttribute("data-name")); | ||||||
|         } |         } | ||||||
|         else if (event.target.nodeName == 'A') { |         else if (event.target.nodeName == 'A') { | ||||||
|             event.preventDefault(); |             showMenu(event.target, event); | ||||||
|             showMenu(event.target); |  | ||||||
|         } |         } | ||||||
|     }, false);     |     }, false);     | ||||||
|      |      | ||||||
|     document.getElementById('BrowseDatabaseArtistList').addEventListener('click', function(event) { |     document.getElementById('BrowseDatabaseTagList').addEventListener('click', function(event) { | ||||||
|         if (event.target.nodeName == 'TD') { |         if (event.target.nodeName == 'TD') { | ||||||
|             appGoto('Browse', 'Database', 'Album', '0/-/' + event.target.parentNode.getAttribute('data-uri')); |             appGoto('Browse', 'Database', app.current.view, '0/-/' + event.target.parentNode.getAttribute('data-uri')); | ||||||
|         } |         } | ||||||
|     }, false); |     }, false); | ||||||
|      |      | ||||||
| @@ -457,8 +445,7 @@ function appInit() { | |||||||
|             appendQueue('song', decodeURI(event.target.parentNode.getAttribute("data-uri")), event.target.parentNode.getAttribute("data-name")); |             appendQueue('song', decodeURI(event.target.parentNode.getAttribute("data-uri")), event.target.parentNode.getAttribute("data-name")); | ||||||
|         } |         } | ||||||
|         else if (event.target.nodeName == 'A') { |         else if (event.target.nodeName == 'A') { | ||||||
|             event.preventDefault(); |             showMenu(event.target, event); | ||||||
|             showMenu(event.target); |  | ||||||
|         } |         } | ||||||
|     }, false); |     }, false); | ||||||
|  |  | ||||||
| @@ -476,45 +463,67 @@ function appInit() { | |||||||
|     document.getElementById('searchAddAllSongsDropdown').addEventListener('click', function(event) { |     document.getElementById('searchAddAllSongsDropdown').addEventListener('click', function(event) { | ||||||
|         if (event.target.nodeName == 'BUTTON') { |         if (event.target.nodeName == 'BUTTON') { | ||||||
|             if (event.target.innerText == 'Add all to queue') { |             if (event.target.innerText == 'Add all to queue') { | ||||||
|                 addAllFromSearch(); |                 addAllFromSearchPlist('queue'); | ||||||
|             } |             } | ||||||
|             else if (event.target.innerText == 'Add all to playlist') { |             else if (event.target.innerText == 'Add all to playlist') { | ||||||
|                 showAddToPlaylist('SEARCH');                 |                 showAddToPlaylist('SEARCH');                 | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }, false); |     }, false); | ||||||
|  |      | ||||||
|  |     document.getElementById('BrowseDatabaseAddAllSongsDropdown').addEventListener('click', function(event) { | ||||||
|  |         if (event.target.nodeName == 'BUTTON') { | ||||||
|  |             if (event.target.innerText == 'Add all to queue') { | ||||||
|  |                 addAllFromBrowseDatabasePlist('queue'); | ||||||
|  |             } | ||||||
|  |             else if (event.target.innerText == 'Add all to playlist') { | ||||||
|  |                 showAddToPlaylist('DATABASE'); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }, false); | ||||||
|  |  | ||||||
|     document.getElementById('searchtags').addEventListener('click', function(event) { |     document.getElementById('searchtags').addEventListener('click', function(event) { | ||||||
|         if (event.target.nodeName == 'BUTTON') |         if (event.target.nodeName == 'BUTTON') | ||||||
|             appGoto(app.current.app, app.current.tab, app.current.view, '0/' + event.target.innerText + '/' + app.current.search);             |             appGoto(app.current.app, app.current.tab, app.current.view, '0/' + event.target.getAttribute('data-tag') + '/' + app.current.search);             | ||||||
|     }, false); |     }, false); | ||||||
|  |  | ||||||
|     document.getElementById('searchqueuestr').addEventListener('keyup', function(event) { |     document.getElementById('searchqueuestr').addEventListener('keyup', function(event) { | ||||||
|         appGoto(app.current.app, app.current.tab, app.current.view, '0/' + app.current.filter + '/' + this.value); |         appGoto(app.current.app, app.current.tab, app.current.view, '0/' + app.current.filter + '/' + this.value); | ||||||
|     }, false); |     }, false); | ||||||
|  |  | ||||||
|     document.getElementById('searchqueuetag').addEventListener('click', function (event) { |     document.getElementById('searchqueuetag').addEventListener('click', function(event) { | ||||||
|         if (event.target.nodeName == 'BUTTON') |         if (event.target.nodeName == 'BUTTON') | ||||||
|             appGoto(app.current.app, app.current.tab, app.current.view, app.current.page + '/' + event.target.innerText + '/' + app.current.search); |             appGoto(app.current.app, app.current.tab, app.current.view, app.current.page + '/' + event.target.getAttribute('data-tag') + '/' + app.current.search); | ||||||
|     }, false); |     }, false); | ||||||
|  |  | ||||||
|     document.getElementById('search').addEventListener('submit', function () { |     document.getElementById('search').addEventListener('submit', function() { | ||||||
|         return false; |         return false; | ||||||
|     }, false); |     }, false); | ||||||
|  |  | ||||||
|     document.getElementById('searchqueue').addEventListener('submit', function () { |     document.getElementById('searchqueue').addEventListener('submit', function() { | ||||||
|         return false; |         return false; | ||||||
|     }, false); |     }, false); | ||||||
|  |  | ||||||
|     document.getElementById('searchstr').addEventListener('keyup', function (event) { |     document.getElementById('searchstr').addEventListener('keyup', function(event) { | ||||||
|         appGoto('Search', undefined, undefined, '0/' + app.current.filter + '/' + this.value); |         appGoto('Search', undefined, undefined, '0/' + app.current.filter + '/' + this.value); | ||||||
|     }, false); |     }, false); | ||||||
|  |  | ||||||
|  |     document.getElementById('BrowseDatabaseByTagDropdown').addEventListener('click', function(event) { | ||||||
|  |         if (event.target.nodeName == 'BUTTON') | ||||||
|  |             appGoto(app.current.app, app.current.tab, event.target.getAttribute('data-tag') , '0/' + app.current.filter  + '/' + app.current.search); | ||||||
|  |     }, false); | ||||||
|  |  | ||||||
|  |     document.getElementsByTagName('body')[0].addEventListener('click', function(event) { | ||||||
|  |         var oldPopover = document.getElementsByClassName('popover')[0]; | ||||||
|  |         if (oldPopover) | ||||||
|  |             oldPopover.remove(); | ||||||
|  |     }, false); | ||||||
|  |  | ||||||
|     dragAndDropTable('QueueList'); |     dragAndDropTable('QueueList'); | ||||||
|     dragAndDropTable('BrowsePlaylistsDetailList'); |     dragAndDropTable('BrowsePlaylistsDetailList'); | ||||||
|  |  | ||||||
|     window.addEventListener('hashchange', appRoute, false); |     window.addEventListener('hashchange', appRoute, false); | ||||||
|      |  | ||||||
|     window.addEventListener('focus', function() { |     window.addEventListener('focus', function() { | ||||||
|         sendAPI({"cmd": "MPD_API_PLAYER_STATE"}, parseState); |         sendAPI({"cmd": "MPD_API_PLAYER_STATE"}, parseState); | ||||||
|     }, false); |     }, false); | ||||||
| @@ -839,13 +848,17 @@ function parseSettings(obj) { | |||||||
|         document.getElementsByClassName('mixramp')[0].style.display = 'none'; |         document.getElementsByClassName('mixramp')[0].style.display = 'none'; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     settings=obj.data; |     settings = obj.data; | ||||||
|     settings.mpdstream = 'http://'; |     settings.mpdstream = 'http://'; | ||||||
|     if (settings.mpdhost == '127.0.0.1' || settings.mpdhost == 'localhost') |     if (settings.mpdhost == '127.0.0.1' || settings.mpdhost == 'localhost') | ||||||
|         settings.mpdstream += window.location.hostname; |         settings.mpdstream += window.location.hostname; | ||||||
|     else |     else | ||||||
|         settings.mpdstream += settings.mpdhost; |         settings.mpdstream += settings.mpdhost; | ||||||
|     settings.mpdstream += ':' + settings.streamport + '/'; |     settings.mpdstream += ':' + settings.streamport + '/'; | ||||||
|  |      | ||||||
|  |     addTagList('BrowseDatabaseByTagDropdown', false); | ||||||
|  |     addTagList('searchqueuetag', true); | ||||||
|  |     addTagList('searchtags', true); | ||||||
| } | } | ||||||
|  |  | ||||||
| function getSettings() { | function getSettings() { | ||||||
| @@ -980,7 +993,7 @@ function parseState(obj) { | |||||||
|  |  | ||||||
| function getQueue() { | function getQueue() { | ||||||
|     if (app.current.search.length >= 2)  |     if (app.current.search.length >= 2)  | ||||||
|         sendAPI({"cmd": "MPD_API_QUEUE_SEARCH", "data": {"mpdtag": app.current.filter, "offset": app.current.page, "searchstr": app.current.search}}, parseQueue); |         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); |         sendAPI({"cmd": "MPD_API_QUEUE_LIST", "data": {"offset": app.current.page}}, parseQueue); | ||||||
|     } |     } | ||||||
| @@ -1210,15 +1223,66 @@ function parsePlaylists(obj) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function parseListDBtags(obj) { | function parseListDBtags(obj) { | ||||||
|     if (app.current.app !== 'Browse' && app.current.tab !== 'Database' && app.current.view !== 'Artist') return; | //    if (app.current.app !== 'Browse' && app.current.tab !== 'Database' && app.current.view !== 'AlbumArtist') | ||||||
|    | //    return; | ||||||
|     if (obj.tagtype == 'AlbumArtist') { |     if (app.current.search != '') { | ||||||
|         document.getElementById('BrowseDatabaseAlbumList').classList.add('hide'); |         document.getElementById('BrowseDatabaseAlbumList').classList.remove('hide'); | ||||||
|         document.getElementById('BrowseDatabaseArtistList').classList.remove('hide'); |         document.getElementById('BrowseDatabaseTagList').classList.add('hide'); | ||||||
|         document.getElementById('btnBrowseDatabaseArtist').parentNode.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 = obj.searchtagtype + ': ' + obj.searchstr; | ||||||
|         var nrItems = obj.data.length; |         var nrItems = obj.data.length; | ||||||
|         var tbody = document.getElementById(app.current.app + app.current.tab + app.current.view + 'List').getElementsByTagName('tbody')[0]; |         if (nrItems == 1 && obj.data[0].value == '') | ||||||
|  |             nrItems = 0; | ||||||
|  |         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); | ||||||
|  |             if (cards[i]) | ||||||
|  |                 if (cards[i].getAttribute('id') == id) | ||||||
|  |                     continue;               | ||||||
|  |             var card=document.createElement('div'); | ||||||
|  |             card.classList.add('col-md'); | ||||||
|  |             card.classList.add('mr-0'); | ||||||
|  |             card.setAttribute('id', id); | ||||||
|  |             card.innerHTML = '<div class="card mb-4" id="card' + id + '">' + | ||||||
|  |                              ' <a href="#" class="card-img-top"><img class="card-img-top" src="" ></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'+ | ||||||
|  |                              ' </div>'+ | ||||||
|  |                              '</div>'; | ||||||
|  |           | ||||||
|  |             if (i < cards.length) | ||||||
|  |                 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); | ||||||
|  |         } | ||||||
|  |         var cardsLen = cards.length - 1; | ||||||
|  |         for (var i = cardsLen; i >= nrItems; i --) { | ||||||
|  |             cards[i].remove(); | ||||||
|  |         } | ||||||
|  |         setPagination(obj.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'); | ||||||
|  |          | ||||||
|  |         if (obj.data[0] && obj.data[0].value == '') | ||||||
|  |             obj.data.shift(); | ||||||
|  |         var nrItems = obj.data.length; | ||||||
|  |         var tbody = document.getElementById(app.current.app + app.current.tab + 'TagList').getElementsByTagName('tbody')[0]; | ||||||
|         var tr = tbody.getElementsByTagName('tr'); |         var tr = tbody.getElementsByTagName('tr'); | ||||||
|  |         var skipped = 0; | ||||||
|         for (var i = 0; i < nrItems; i++) { |         for (var i = 0; i < nrItems; i++) { | ||||||
|             var uri = encodeURI(obj.data[i].value); |             var uri = encodeURI(obj.data[i].value); | ||||||
|             if (tr[i]) |             if (tr[i]) | ||||||
| @@ -1245,52 +1309,13 @@ function parseListDBtags(obj) { | |||||||
|         if (nrItems == 0)  |         if (nrItems == 0)  | ||||||
|             tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + |             tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + | ||||||
|                               '<td>No entries found.</td></tr>'; |                               '<td>No entries found.</td></tr>'; | ||||||
|         document.getElementById('BrowseDatabaseArtistList').classList.remove('opacity05');                               |         document.getElementById('BrowseDatabaseTagList').classList.remove('opacity05');                               | ||||||
|                                 |  | ||||||
|     } else if (obj.tagtype == 'Album') { |  | ||||||
|         document.getElementById('BrowseDatabaseAlbumList').classList.remove('hide'); |  | ||||||
|         document.getElementById('BrowseDatabaseArtistList').classList.add('hide'); |  | ||||||
|         document.getElementById('btnBrowseDatabaseArtist').parentNode.classList.remove('hide');     |  | ||||||
|         var nrItems = obj.data.length; |  | ||||||
|         var cardContainer = document.getElementById('BrowseDatabaseAlbumList'); |  | ||||||
|         var cards = cardContainer.getElementsByClassName('col-md'); |  | ||||||
|         for (var i = 0; i < nrItems; i++) { |  | ||||||
|             var id=genId(obj.data[i].value); |  | ||||||
|             if (cards[i]) |  | ||||||
|                 if (cards[i].getAttribute('id') == id) |  | ||||||
|                     continue;               |  | ||||||
|             var card=document.createElement('div'); |  | ||||||
|             card.classList.add('col-md'); |  | ||||||
|             card.classList.add('mr-0'); |  | ||||||
|             card.setAttribute('id', id); |  | ||||||
|             card.innerHTML = '<div class="card mb-4" id="card' + id + '">' + |  | ||||||
|                              ' <a href="#" class="card-img-top"><img class="card-img-top" src="" ></a>' + |  | ||||||
|                              ' <div class="card-body">' + |  | ||||||
|                              '  <h5 class="card-title">' + obj.searchstr + '</h5>' + |  | ||||||
|                              '  <h4 class="card-title">' + obj.data[i].value + '</h4>' + |  | ||||||
|                              '  <table class="table table-sm table-hover" id="tbl' + id + '"><tbody></tbody></table'+ |  | ||||||
|                              ' </div>'+ |  | ||||||
|                              '</div>'; |  | ||||||
|           |  | ||||||
|             if (i < cards.length) |  | ||||||
|                 cards[i].replaceWith(card);  |  | ||||||
|             else  |  | ||||||
|                 cardContainer.append(card); |  | ||||||
|                  |  | ||||||
|             sendAPI({"cmd": "MPD_API_DATABASE_ARTISTALBUMTITLE_LIST", "data": { "albumartist": obj.searchstr, "album": obj.data[i].value}}, parseListTitles); |  | ||||||
|         } |  | ||||||
|         var cardsLen = cards.length - 1; |  | ||||||
|         for (var i = cardsLen; i >= nrItems; i --) { |  | ||||||
|             cards[i].remove(); |  | ||||||
|         } |  | ||||||
|         setPagination(obj.totalEntities); |  | ||||||
|         document.getElementById('BrowseDatabaseAlbumList').classList.remove('opacity05');         |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function parseListTitles(obj) { | function parseListTitles(obj) { | ||||||
|     if (app.current.app !== 'Browse' && app.current.tab !== 'Database' && app.current.view !== 'Album')  | //    if (app.current.app !== 'Browse' && app.current.tab !== 'Database' && app.current.view !== 'Album')  | ||||||
|           return; | //          return; | ||||||
|    |    | ||||||
|     var id = genId(obj.album); |     var id = genId(obj.album); | ||||||
|     var card = document.getElementById('card' + id) |     var card = document.getElementById('card' + id) | ||||||
| @@ -1301,6 +1326,7 @@ function parseListTitles(obj) { | |||||||
|     imga.setAttribute('data-uri', encodeURI(obj.data[0].uri.replace(/\/[^\/]+$/, ''))); |     imga.setAttribute('data-uri', encodeURI(obj.data[0].uri.replace(/\/[^\/]+$/, ''))); | ||||||
|     imga.setAttribute('data-name', obj.album); |     imga.setAttribute('data-name', obj.album); | ||||||
|     imga.setAttribute('data-type', 'dir'); |     imga.setAttribute('data-type', 'dir'); | ||||||
|  |     document.getElementById('albumartist' + id).innerText = obj.albumartist; | ||||||
|    |    | ||||||
|     var titleList = ''; |     var titleList = ''; | ||||||
|     var nrItems = obj.data.length; |     var nrItems = obj.data.length; | ||||||
| @@ -1313,8 +1339,7 @@ function parseListTitles(obj) { | |||||||
|     tbody.innerHTML = titleList; |     tbody.innerHTML = titleList; | ||||||
|    |    | ||||||
|     imga.addEventListener('click', function(event) { |     imga.addEventListener('click', function(event) { | ||||||
|         event.preventDefault(); |         showMenu(this, event); | ||||||
|         showMenu(this); |  | ||||||
|     }, false); |     }, false); | ||||||
|  |  | ||||||
|     tbody.parentNode.addEventListener('click', function(event) { |     tbody.parentNode.addEventListener('click', function(event) { | ||||||
| @@ -1322,8 +1347,7 @@ function parseListTitles(obj) { | |||||||
|             appendQueue('song', decodeURI(event.target.parentNode.getAttribute('data-uri')), event.target.parentNode.getAttribute('data-name')); |             appendQueue('song', decodeURI(event.target.parentNode.getAttribute('data-uri')), event.target.parentNode.getAttribute('data-name')); | ||||||
|         } |         } | ||||||
|         else if (event.target.nodeName == 'A') { |         else if (event.target.nodeName == 'A') { | ||||||
|             event.preventDefault(); |             showMenu(event.target, event); | ||||||
|             showMenu(event.target); |  | ||||||
|         } |         } | ||||||
|     }, false); |     }, false); | ||||||
| } | } | ||||||
| @@ -1414,7 +1438,13 @@ function songClick() { | |||||||
| function artistClick() { | function artistClick() { | ||||||
|     var albumartist = domCache.currentArtist.getAttribute('data-albumartist'); |     var albumartist = domCache.currentArtist.getAttribute('data-albumartist'); | ||||||
|     if (albumartist != '')  |     if (albumartist != '')  | ||||||
|         appGoto('Browse', 'Database', 'Album', '0/-/' + albumartist); |         appGoto('Browse', 'Database', 'AlbumArtist', '0/-/' + albumartist); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function albumClick() { | ||||||
|  |     var album = domCache.currentAlbum.getAttribute('data-album'); | ||||||
|  |     if (album != '')  | ||||||
|  |         appGoto('Browse', 'Database', 'Album', '0/-/' + album); | ||||||
| } | } | ||||||
|  |  | ||||||
| function songDetails(uri) { | function songDetails(uri) { | ||||||
| @@ -1426,36 +1456,36 @@ function parseSongDetails(obj) { | |||||||
|     var modal = document.getElementById('modalSongDetails'); |     var modal = document.getElementById('modalSongDetails'); | ||||||
|     modal.getElementsByClassName('album-cover')[0].style.backgroundImage = 'url("' + obj.data.cover + '")'; |     modal.getElementsByClassName('album-cover')[0].style.backgroundImage = 'url("' + obj.data.cover + '")'; | ||||||
|     modal.getElementsByTagName('h1')[0].innerText = obj.data.title; |     modal.getElementsByTagName('h1')[0].innerText = obj.data.title; | ||||||
|     var tr = modal.getElementsByTagName('tr'); |      | ||||||
|     var trLen = tr.length; |     var songDetails = ''; | ||||||
|     for (var i = 0; i < trLen; i++) { |     for (var key in settings.tags) { | ||||||
|         var key = tr[i].getAttribute('data-name'); |         if (settings.tags[key] == true) { | ||||||
|         if (!key) |             var value = obj.data[key.toLowerCase()]; | ||||||
|             continue; |             if (key == 'duration') { | ||||||
|         var value = obj.data[key]; |                 var minutes = Math.floor(value / 60); | ||||||
|         if (key == 'duration') { |                 var seconds = value - minutes * 60; | ||||||
|             var minutes = Math.floor(value / 60); |                 value = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;         | ||||||
|             var seconds = value - minutes * 60; |  | ||||||
|             value = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;         |  | ||||||
|         } |  | ||||||
|         else if (key == 'lastPlayed') { |  | ||||||
|             if (value == 0)  |  | ||||||
|                 value = 'never';     |  | ||||||
|             else { |  | ||||||
|                 var d = new Date(value * 1000); |  | ||||||
|                 value = d.toUTCString(); |  | ||||||
|             } |             } | ||||||
|  |             songDetails += '<tr><th>' + key + '</th><td>' + value + '</td></tr>'; | ||||||
|         } |         } | ||||||
|         else if (key == 'like') { |  | ||||||
|             if (value == 0) value = '<span class="material-icons">thumb_down_alt</span>'; |  | ||||||
|             else if (value == 2) value = '<span class="material-icons">thumb_up_alt</span>'; |  | ||||||
|             else value = 'not voted'; |  | ||||||
|         } |  | ||||||
|         else if (key == 'uri') { |  | ||||||
|             value = '<a class="text-success" href="/library/' + value + '">' + value + '</a>'; |  | ||||||
|         } |  | ||||||
|         tr[i].getElementsByTagName('td')[0].innerHTML = value; |  | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     songDetails += '<tr><th>Uri</th><td><a class="text-success" href="/library/' + obj.data.uri + '">' + obj.data.uri + '</a></td></tr>'; | ||||||
|  |      | ||||||
|  |     if (settings.stickers == true) { | ||||||
|  |         var like = 'not voted'; | ||||||
|  |         if (obj.data.like == 0) | ||||||
|  |             like = '<span class="material-icons">thumb_down_alt</span>'; | ||||||
|  |         else if (obj.data.like == 2) | ||||||
|  |             like = '<span class="material-icons">thumb_up_alt</span>'; | ||||||
|  |         songDetails += '<tr><th colspan="2">Statistics</th></tr>' + | ||||||
|  |             '<tr><th>Play count</th><td>' + obj.data.playCount + '</td></tr>' + | ||||||
|  |             '<tr><th>Skip count</th><td>' + obj.data.skipCount + '</td></tr>' + | ||||||
|  |             '<tr><th>Last played</th><td>' + (obj.data.lastPlayed == 0 ? 'never' : new Date(value * 1000).toUTCString()) + '</td></tr>' + | ||||||
|  |             '<tr><th>Like</th><td>' + like + '</td></tr>'; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     modal.getElementsByTagName('tbody')[0].innerHTML = songDetails; | ||||||
| } | } | ||||||
|  |  | ||||||
| function playlistDetails(uri) { | function playlistDetails(uri) { | ||||||
| @@ -1592,10 +1622,12 @@ function addToPlaylist() { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     if (plist != '') { |     if (plist != '') { | ||||||
|         if (uri != 'SEARCH')  |         if (uri == 'SEARCH') | ||||||
|             sendAPI({"cmd": "MPD_API_PLAYLIST_ADD_TRACK", "data": {"uri": uri, "plist": plist}}); |             addAllFromSearchPlist(plist); | ||||||
|  |         else if (uri == 'DATABASE') | ||||||
|  |             addAllFromBrowseDatabasePlist(plist); | ||||||
|         else |         else | ||||||
|             addAllFromSearchPlist(plist);             |             sendAPI({"cmd": "MPD_API_PLAYLIST_ADD_TRACK", "data": {"uri": uri, "plist": plist}}); | ||||||
|         modalAddToPlaylist.hide(); |         modalAddToPlaylist.hide(); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
| @@ -1640,7 +1672,16 @@ function renamePlaylist() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function showMenu(el) { | function dirname(uri) { | ||||||
|  |     return uri.replace(/\/[^\/]*$/, ''); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function showMenu(el, event) { | ||||||
|  |     event.preventDefault(); | ||||||
|  |     event.stopPropagation(); | ||||||
|  |     var oldPopover = document.getElementsByClassName('popover')[0]; | ||||||
|  |     if (oldPopover) | ||||||
|  |         oldPopover.remove(); | ||||||
|     var type = el.getAttribute('data-type'); |     var type = el.getAttribute('data-type'); | ||||||
|     var uri = decodeURI(el.getAttribute('data-uri')); |     var uri = decodeURI(el.getAttribute('data-uri')); | ||||||
|     var name = el.getAttribute('data-name'); |     var name = el.getAttribute('data-name'); | ||||||
| @@ -1663,17 +1704,29 @@ function showMenu(el) { | |||||||
|             uri + '\',' + nextsongpos + ',\'' + name + '\']}">Add after current playing song</a>' : '') + |             uri + '\',' + nextsongpos + ',\'' + name + '\']}">Add after current playing song</a>' : '') + | ||||||
|             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +  |             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +  | ||||||
|             uri + '\',\'' + name + '\']}">Replace queue</a>' + |             uri + '\',\'' + name + '\']}">Replace queue</a>' + | ||||||
|             ( type != 'plist' ? '<div class="dropdown-divider"></div><a class="dropdown-item" href="#" data-href="{\'cmd\': \'showAddToPlaylist\', \'options\': [\'' + uri + '\']}">Add to playlist</a>' : '') + |             ( type != 'plist' ? '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'showAddToPlaylist\', \'options\': [\'' + uri + '\']}">Add to playlist</a>' : '') + | ||||||
|             ( type != 'dir' ? '<div class="dropdown-divider"></div>' : '') + |  | ||||||
|             ( type == 'song' ? '<a class="dropdown-item" data-href="{\'cmd\': \'songDetails\', \'options\': [\'' + uri + '\']}" href="#">Songdetails</a>' : '') + |             ( type == 'song' ? '<a class="dropdown-item" data-href="{\'cmd\': \'songDetails\', \'options\': [\'' + uri + '\']}" href="#">Songdetails</a>' : '') + | ||||||
|             ( type == 'plist' ? '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'playlistDetails\', \'options\': [\'' + uri + '\']}">Show playlist</a>' : ''); |             ( type == 'plist' ? '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'playlistDetails\', \'options\': [\'' + uri + '\']}">Show playlist</a>' : ''); | ||||||
|  |         if (app.current.app == 'Search') { | ||||||
|  |             var baseuri = dirname(uri); | ||||||
|  |             menu += '<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\': [\'' + type + '\',\'' +  | ||||||
|  |                     baseuri + '\',\'' + name + '\']}">Append to queue</a>' + | ||||||
|  |                     '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'appendAfterQueue\', \'options\': [\'' + type + '\',\'' + | ||||||
|  |                     baseuri + '\',' + nextsongpos + ',\'' + name + '\']}">Add after current playing song</a>' + | ||||||
|  |                     '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +  | ||||||
|  |                     baseuri + '\',\'' + name + '\']}">Replace queue</a>' + | ||||||
|  |                     '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'showAddToPlaylist\', \'options\': [\'' + baseuri + '\']}">Add to playlist</a>' + | ||||||
|  |                 '</div>'; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'All') { |     else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'All') { | ||||||
|         menu += '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'appendQueue\', \'options\': [\'' + type + '\',\'' +  |         menu += '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'appendQueue\', \'options\': [\'' + type + '\',\'' +  | ||||||
|             uri + '\',\'' + name + '\']}">Append to queue</a>' + |             uri + '\',\'' + name + '\']}">Append to queue</a>' + | ||||||
|             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +  |             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +  | ||||||
|             uri + '\',\'' + name + '\']}">Replace queue</a>' + |             uri + '\',\'' + name + '\']}">Replace queue</a>' + | ||||||
|             '<div class="dropdown-divider"></div>' + |  | ||||||
|             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'playlistDetails\', \'options\': [\'' + uri + '\']}">Edit playlist</a>' + |             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'playlistDetails\', \'options\': [\'' + uri + '\']}">Edit playlist</a>' + | ||||||
|             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'showRenamePlaylist\', \'options\': [\'' + uri + '\']}">Rename playlist</a>' +  |             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'showRenamePlaylist\', \'options\': [\'' + uri + '\']}">Rename playlist</a>' +  | ||||||
|             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delPlaylist\', \'options\': [\'' +  |             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delPlaylist\', \'options\': [\'' +  | ||||||
| @@ -1685,10 +1738,9 @@ function showMenu(el) { | |||||||
|             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +  |             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +  | ||||||
|             uri + '\',\'' + name + '\']}">Replace queue</a>' + |             uri + '\',\'' + name + '\']}">Replace queue</a>' + | ||||||
|             ( document.getElementById('BrowsePlaylistsDetailList').getAttribute('data-ro') == 'false' ? |             ( document.getElementById('BrowsePlaylistsDetailList').getAttribute('data-ro') == 'false' ? | ||||||
|             '<div class="dropdown-divider"></div>' + |  | ||||||
|             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'removeFromPlaylist\', \'options\': [\'' + document.getElementById('BrowsePlaylistsDetailList').getAttribute('data-uri') + '\', \'' +  |             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'removeFromPlaylist\', \'options\': [\'' + document.getElementById('BrowsePlaylistsDetailList').getAttribute('data-uri') + '\', \'' +  | ||||||
|             el.parentNode.parentNode.getAttribute('data-songpos') + '\']}">Remove</a>' : '') + |             el.parentNode.parentNode.getAttribute('data-songpos') + '\']}">Remove</a>' : '') + | ||||||
|             ( type != 'plist' ? '<div class="dropdown-divider"></div><a class="dropdown-item" href="#" data-href="{\'cmd\': \'showAddToPlaylist\', \'options\': [\'' + uri + '\']}">Add to playlist</a>' : ''); |             ( type != 'plist' ? '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'showAddToPlaylist\', \'options\': [\'' + uri + '\']}">Add to playlist</a>' : ''); | ||||||
|     } |     } | ||||||
|     else if (app.current.app == 'Queue') { |     else if (app.current.app == 'Queue') { | ||||||
|         menu += '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delQueueSong\', \'options\': [\'single\',' +  |         menu += '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delQueueSong\', \'options\': [\'single\',' +  | ||||||
| @@ -1697,21 +1749,21 @@ function showMenu(el) { | |||||||
|             el.parentNode.parentNode.getAttribute('data-songpos') + ']}">Remove all upwards</a>' + |             el.parentNode.parentNode.getAttribute('data-songpos') + ']}">Remove all upwards</a>' + | ||||||
|             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delQueueSong\', \'options\': [\'range\',' +  |             '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delQueueSong\', \'options\': [\'range\',' +  | ||||||
|             (parseInt(el.parentNode.parentNode.getAttribute('data-songpos'))-1) + ',-1]}">Remove all downwards</a>' + |             (parseInt(el.parentNode.parentNode.getAttribute('data-songpos'))-1) + ',-1]}">Remove all downwards</a>' + | ||||||
|             '<div class="dropdown-divider"></div>' + |  | ||||||
|             ( uri.indexOf('http') == -1 ? '<a class="dropdown-item" data-href="{\'cmd\': \'songDetails\', \'options\': [\'' + uri + '\']}" href="#">Songdetails</a>' : ''); |             ( uri.indexOf('http') == -1 ? '<a class="dropdown-item" data-href="{\'cmd\': \'songDetails\', \'options\': [\'' + uri + '\']}" href="#">Songdetails</a>' : ''); | ||||||
|     }     |     }     | ||||||
|     if (el.Popover == undefined) { |     new Popover(el, { trigger: 'click', delay: 0, dismissible: true, template: '<div class="popover" role="tooltip">' + | ||||||
|         new Popover(el, { trigger: 'click', template: '<div class="popover" role="tooltip">' + |         '<div class="arrow"></div>' + | ||||||
|             '<div class="arrow"></div>' + |         '<div class="popover-content">' + menu + '</div>' + | ||||||
|             '<div class="popover-content">' + menu + '</div>' + |         '</div>'}); | ||||||
|             '</div>'}); |     var popoverInit = el.Popover; | ||||||
|         var popoverInit = el.Popover; |     el.addEventListener('shown.bs.popover', function(event) { | ||||||
|         el.addEventListener('shown.bs.popover', function(event) { |         document.getElementsByClassName('popover-content')[0].addEventListener('click', function(event) { | ||||||
|             document.getElementsByClassName('popover-content')[0].addEventListener('click', function(event) { |             event.preventDefault(); | ||||||
|                 event.preventDefault(); |             event.stopPropagation(); | ||||||
|                 event.stopPropagation(); |             if (event.target.nodeName == 'A') { | ||||||
|                 if (event.target.nodeName == 'A') { |                 var dh = event.target.getAttribute('data-href'); | ||||||
|                     var cmd = JSON.parse(event.target.getAttribute('data-href').replace(/\'/g, '"')); |                 if (dh) { | ||||||
|  |                     var cmd = JSON.parse(dh.replace(/\'/g, '"')); | ||||||
|                     if (typeof window[cmd.cmd] === 'function') { |                     if (typeof window[cmd.cmd] === 'function') { | ||||||
|                         switch(cmd.cmd) { |                         switch(cmd.cmd) { | ||||||
|                             case 'sendAPI': |                             case 'sendAPI': | ||||||
| @@ -1721,11 +1773,23 @@ function showMenu(el) { | |||||||
|                                 window[cmd.cmd](... cmd.options);                     |                                 window[cmd.cmd](... cmd.options);                     | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |                     popoverInit.hide(); | ||||||
|                 } |                 } | ||||||
|             }, false);         |             } | ||||||
|  |         }, false);         | ||||||
|  |         var collapseLink = document.getElementById('advancedMenuLink'); | ||||||
|  |         if (collapseLink) { | ||||||
|  |             collapseLink.addEventListener('click', function(event) { | ||||||
|  |             var icon = this.getElementsByTagName('span')[0]; | ||||||
|  |             if (icon.innerText == 'keyboard_arrow_right') | ||||||
|  |                 icon.innerText = 'keyboard_arrow_down'; | ||||||
|  |             else | ||||||
|  |                 icon.innerText = 'keyboard_arrow_right'; | ||||||
|         }, false); |         }, false); | ||||||
|         popoverInit.show(); |             var myCollapseInit = new Collapse(collapseLink); | ||||||
|     } |         } | ||||||
|  |     }, false); | ||||||
|  |     popoverInit.show(); | ||||||
| } | } | ||||||
|  |  | ||||||
| function sendAPI(request, callback) { | function sendAPI(request, callback) { | ||||||
| @@ -1883,26 +1947,22 @@ function confirmSettings() { | |||||||
|         document.getElementById('settingsFrm').classList.add('was-validated'); |         document.getElementById('settingsFrm').classList.add('was-validated'); | ||||||
| } | } | ||||||
|  |  | ||||||
| function addAllFromBrowse() { | function addAllFromBrowseFilesystem() { | ||||||
|     sendAPI({"cmd": "MPD_API_QUEUE_ADD_TRACK", "data": {"uri": app.current.search}}); |     sendAPI({"cmd": "MPD_API_QUEUE_ADD_TRACK", "data": {"uri": app.current.search}}); | ||||||
|     showNotification('Added all songs', '', '', 'success'); |     showNotification('Added all songs', '', '', 'success'); | ||||||
| } | } | ||||||
|  |  | ||||||
| function addAllFromSearch() { | function addAllFromSearchPlist(plist) { | ||||||
|     if (app.current.search.length >= 2) { |     if (app.current.search.length >= 2) { | ||||||
|         sendAPI({"cmd": "MPD_API_DATABASE_SEARCH_ADD_QUEUE", "data":{"filter": app.current.filter, "searchstr": app.current.search}}); |         sendAPI({"cmd": "MPD_API_DATABASE_SEARCH", "data": {"plist": plist, "filter": app.current.filter, "searchstr": app.current.search, "offset": 0}}); | ||||||
|         showNotification('Added '+ parseInt(document.getElementById('panel-heading-search').innerText) +' songs from search', '', '', 'success'); |         showNotification('Added '+ parseInt(document.getElementById('panel-heading-search').innerText) +' songs from search to ' + plist, '', '', 'success'); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function addAllFromSearchPlist(plist) { | function addAllFromBrowseDatabasePlist(plist) { | ||||||
|     if (app.current.search.length >= 2) { |     if (app.current.search.length >= 2) { | ||||||
|         var filter = app.current.filter; |         sendAPI({"cmd": "MPD_API_DATABASE_SEARCH", "data": {"plist": plist, "filter": app.current.view, "searchstr": app.current.search, "offset": 0}}); | ||||||
|         if (filter == 'Any Tag') |         showNotification('Added songs from database selection to ' + plist, '', '', 'success'); | ||||||
|             filter = 'any'; |  | ||||||
|              |  | ||||||
|         sendAPI({"cmd": "MPD_API_DATABASE_SEARCH_ADD_PLAYLIST", "data":{"plist": plist, "filter": filter, "searchstr": app.current.search}}); |  | ||||||
|         showNotification('Added '+ parseInt(document.getElementById('panel-heading-search').innerText) +' songs from search to ' + plist, '', '', 'success'); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -2012,6 +2072,7 @@ function songChange(obj) { | |||||||
|         textNotification += ' - ' + obj.data.album; |         textNotification += ' - ' + obj.data.album; | ||||||
|         htmlNotification += '<br/>' + obj.data.album; |         htmlNotification += '<br/>' + obj.data.album; | ||||||
|         domCache.currentAlbum.innerText = obj.data.album; |         domCache.currentAlbum.innerText = obj.data.album; | ||||||
|  |         domCache.currentAlbum.setAttribute('data-album', obj.data.album); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|         domCache.currentAlbum.innerText = ''; |         domCache.currentAlbum.innerText = ''; | ||||||
| @@ -2086,6 +2147,35 @@ function addFilterLetter(x) { | |||||||
|     }, false); |     }, false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function selectTag(btnsEl, desc, setTo) { | ||||||
|  |     var btns = document.getElementById(btnsEl); | ||||||
|  |     var aBtn = btns.querySelector('.active') | ||||||
|  |     if (aBtn) | ||||||
|  |         aBtn.classList.remove('active'); | ||||||
|  |     aBtn = btns.querySelector('[data-tag=' + setTo + ']'); | ||||||
|  |     if (aBtn) { | ||||||
|  |         aBtn.classList.add('active'); | ||||||
|  |         document.getElementById(desc).innerText = aBtn.innerText; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function addTagList(x, any) { | ||||||
|  |     var tagList = ''; | ||||||
|  |     if (any == true) | ||||||
|  |         tagList += '<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="any">Any Tag</button>'; | ||||||
|  |     for (var key in settings.tags) { | ||||||
|  |         if (settings.tags[key] == true && key != 'Track') { | ||||||
|  |             tagList += '<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="' + key + '">' + key + '</button>'; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     var tagListEl = document.getElementById(x); | ||||||
|  |     tagListEl.innerHTML = tagList; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function gotoTagList() { | ||||||
|  |     appGoto(app.current.app, app.current.tab, app.current.view, '0/-/'); | ||||||
|  | } | ||||||
|  |  | ||||||
| function chVolume(increment) { | function chVolume(increment) { | ||||||
|     var newValue = parseInt(domCache.volumeBar.value) + increment; |     var newValue = parseInt(domCache.volumeBar.value) + increment; | ||||||
|     if (newValue < 0)  |     if (newValue < 0)  | ||||||
| @@ -2108,7 +2198,7 @@ function beautifyDuration(x) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function genId(x) { | function genId(x) { | ||||||
|     return 'id' + x.replace(/[^\w]/g, ''); |     return 'id' + x.replace(/[^\w\-\_]/g, ''); | ||||||
| } | } | ||||||
|  |  | ||||||
| //Init app | //Init app | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var CACHE = 'myMPD-cache-v4.0.0'; | var CACHE = 'myMPD-cache-v4.1.0'; | ||||||
| var urlsToCache = [ | var urlsToCache = [ | ||||||
|     '/', |     '/', | ||||||
|     '/player.html', |     '/player.html', | ||||||
|   | |||||||
| @@ -1,6 +1,8 @@ | |||||||
| #!/bin/sh | #!/bin/sh | ||||||
| rm -rf release | rm -rf release | ||||||
| rm -rf debug | rm -rf debug | ||||||
|  | rm -rf debian/tmp | ||||||
|  | rm -f debian/files | ||||||
| rm -f htdocs/js/bootstrap-native-v4.min.js | rm -f htdocs/js/bootstrap-native-v4.min.js | ||||||
| rm -f htdocs/css/bootstrap.min.css | rm -f htdocs/css/bootstrap.min.css | ||||||
| find ./ -name \*~ -delete | find ./ -name \*~ -delete | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								mkrelease.sh
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								mkrelease.sh
									
									
									
									
									
								
							| @@ -50,23 +50,28 @@ sudo make install | |||||||
| cd .. | cd .. | ||||||
|  |  | ||||||
| echo "Fixing ownership of /var/lib/mympd" | echo "Fixing ownership of /var/lib/mympd" | ||||||
| sudo chown nobody /var/lib/mympd | getent group mympd > /dev/null | ||||||
|  | [ "$?" = "2" ] && sudo groupadd mympd | ||||||
|  | getent passwd mympd > /dev/null | ||||||
|  | [ "$?" = "2" ] && sudo useradd mympd -g mympd -d /var/lib/mympd -s /usr/sbin/nologin | ||||||
|  | sudo chown -R mympd.mympd /var/lib/mympd | ||||||
|  |  | ||||||
| echo "Trying to link musicdir to library" | echo "Trying to link musicdir to library" | ||||||
| if [ -f /etc/mpd.conf ] | if [ -f /etc/mpd.conf ] | ||||||
| then | then | ||||||
|   LIBRARY=$(grep ^music_directory /etc/mpd.conf | awk {'print $2'} | sed -e 's/"//g') |   LIBRARY=$(sudo grep ^music_directory /etc/mpd.conf | awk {'print $2'} | sed -e 's/"//g') | ||||||
|   [ "$LIBRARY" != "" ] && [ ! -e /usr/share/mympd/htdocs/library ] && sudo ln -s "$LIBRARY" /usr/share/mympd/htdocs/library |   [ "$LIBRARY" != "" ] && [ ! -e /usr/share/mympd/htdocs/library ] && sudo ln -s "$LIBRARY" /usr/share/mympd/htdocs/library | ||||||
| else | else | ||||||
|   echo "/etc/mpd.conf not found, you must link your music_directory manually to /usr/share/mympd/htdocs/library" |   echo "/etc/mpd.conf not found, you must link your music_directory manually to /usr/share/mympd/htdocs/library" | ||||||
| fi | fi | ||||||
|  |  | ||||||
| echo "Installing systemd service" | echo "Installing systemd service" | ||||||
| if [ -d /etc/systemd/system ] | if [ -d /usr/lib/systemd/ ] | ||||||
| then | then | ||||||
|   if [ contrib/mympd.service -nt /etc/systemd/system/mympd.service ] |   [ -d /usr/lib/systemd/system ] || sudo mkdir /usr/lib/systemd/system  | ||||||
|  |   if [ contrib/mympd.service -nt /usr/lib/systemd/system/mympd.service ] | ||||||
|   then |   then | ||||||
|     sudo cp contrib/mympd.service /etc/systemd/system/ |     sudo cp contrib/mympd.service /usr/lib/systemd/system/ | ||||||
|     sudo systemctl daemon-reload |     sudo systemctl daemon-reload | ||||||
|   fi |   fi | ||||||
|   sudo systemctl enable mympd   |   sudo systemctl enable mympd   | ||||||
|   | |||||||
							
								
								
									
										304
									
								
								src/mpd_client.c
									
									
									
									
									
								
							
							
						
						
									
										304
									
								
								src/mpd_client.c
									
									
									
									
									
								
							| @@ -162,14 +162,6 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) { | |||||||
|             } |             } | ||||||
|             n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}"); |             n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}"); | ||||||
|             break; |             break; | ||||||
|         case MPD_API_DATABASE_ARTISTALBUMTITLE_LIST: |  | ||||||
|             je = json_scanf(msg.p, msg.len, "{data: {albumartist: %Q, album: %Q}}", &p_charbuf1, &p_charbuf2); |  | ||||||
|             if (je == 2) { |  | ||||||
|                 n = mympd_put_songs_in_album(mpd.buf, p_charbuf1, p_charbuf2); |  | ||||||
|                 free(p_charbuf1); |  | ||||||
|                 free(p_charbuf2); |  | ||||||
|             }  |  | ||||||
|             break; |  | ||||||
|         case MPD_API_WELCOME: |         case MPD_API_WELCOME: | ||||||
|             n = mympd_put_welcome(mpd.buf); |             n = mympd_put_welcome(mpd.buf); | ||||||
|             break; |             break; | ||||||
| @@ -295,21 +287,32 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) { | |||||||
|                 free(p_charbuf1); |                 free(p_charbuf1); | ||||||
|             } |             } | ||||||
|             break;             |             break;             | ||||||
|         case MPD_API_DATABASE_ARTIST_LIST: |         case MPD_API_DATABASE_TAG_LIST: | ||||||
|             je = json_scanf(msg.p, msg.len, "{data: {offset: %u, filter: %Q}}", &uint_buf1, &p_charbuf1); |             je = json_scanf(msg.p, msg.len, "{data: {offset: %u, filter: %Q, tag: %Q}}", &uint_buf1, &p_charbuf1, &p_charbuf2); | ||||||
|             if (je == 2) { |  | ||||||
|                 n = mympd_put_db_tag(mpd.buf, uint_buf1, "AlbumArtist", "", "", p_charbuf1); |  | ||||||
|                 free(p_charbuf1); |  | ||||||
|             } |  | ||||||
|             break; |  | ||||||
|         case MPD_API_DATABASE_ARTISTALBUM_LIST: |  | ||||||
|             je = json_scanf(msg.p, msg.len, "{data: {offset: %u, filter: %Q, albumartist: %Q}}", &uint_buf1, &p_charbuf1, &p_charbuf2); |  | ||||||
|             if (je == 3) { |             if (je == 3) { | ||||||
|                 n = mympd_put_db_tag(mpd.buf, uint_buf1, "Album", "AlbumArtist", p_charbuf2, p_charbuf1); |                 n = mympd_put_db_tag(mpd.buf, uint_buf1, p_charbuf2, "", "", p_charbuf1); | ||||||
|                 free(p_charbuf1); |                 free(p_charbuf1); | ||||||
|                 free(p_charbuf2); |                 free(p_charbuf2); | ||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|  |         case MPD_API_DATABASE_TAG_ALBUM_LIST: | ||||||
|  |             je = json_scanf(msg.p, msg.len, "{data: {offset: %u, filter: %Q, search: %Q, tag: %Q}}", &uint_buf1, &p_charbuf1, &p_charbuf2, &p_charbuf3); | ||||||
|  |             if (je == 4) { | ||||||
|  |                 n = mympd_put_db_tag(mpd.buf, uint_buf1, "Album", p_charbuf3, p_charbuf2, p_charbuf1); | ||||||
|  |                 free(p_charbuf1); | ||||||
|  |                 free(p_charbuf2); | ||||||
|  |                 free(p_charbuf3); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         case MPD_API_DATABASE_TAG_ALBUM_TITLE_LIST: | ||||||
|  |             je = json_scanf(msg.p, msg.len, "{data: {album: %Q, search: %Q, tag: %Q}}", &p_charbuf1, &p_charbuf2, &p_charbuf3); | ||||||
|  |             if (je == 3) { | ||||||
|  |                 n = mympd_put_songs_in_album(mpd.buf, p_charbuf1, p_charbuf2, p_charbuf3); | ||||||
|  |                 free(p_charbuf1); | ||||||
|  |                 free(p_charbuf2); | ||||||
|  |                 free(p_charbuf3); | ||||||
|  |             }  | ||||||
|  |             break; | ||||||
|         case MPD_API_PLAYLIST_RENAME: |         case MPD_API_PLAYLIST_RENAME: | ||||||
|             je = json_scanf(msg.p, msg.len, "{data: {from: %Q, to: %Q}}", &p_charbuf1, &p_charbuf2); |             je = json_scanf(msg.p, msg.len, "{data: {from: %Q, to: %Q}}", &p_charbuf1, &p_charbuf2); | ||||||
|             if (je == 2) { |             if (je == 2) { | ||||||
| @@ -431,38 +434,17 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) { | |||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|         case MPD_API_QUEUE_SEARCH: |         case MPD_API_QUEUE_SEARCH: | ||||||
|             je = json_scanf(msg.p, msg.len, "{data: {offset:%u, mpdtag:%Q, searchstr:%Q}}", &uint_buf1, &p_charbuf1, &p_charbuf2); |             je = json_scanf(msg.p, msg.len, "{data: {offset:%u, filter:%Q, searchstr:%Q}}", &uint_buf1, &p_charbuf1, &p_charbuf2); | ||||||
|             if (je == 3) { |             if (je == 3) { | ||||||
|                 n = mympd_search_queue(mpd.buf, p_charbuf1, uint_buf1, p_charbuf2); |                 n = mympd_search_queue(mpd.buf, p_charbuf1, uint_buf1, p_charbuf2); | ||||||
|                 free(p_charbuf1); |                 free(p_charbuf1); | ||||||
|                 free(p_charbuf2); |                 free(p_charbuf2); | ||||||
|             } |             } | ||||||
|             break;             |             break;             | ||||||
|         case MPD_API_DATABASE_SEARCH_ADD_QUEUE: |  | ||||||
|             je = json_scanf(msg.p, msg.len, "{data: {filter:%Q, searchstr:%Q}}", &p_charbuf1, &p_charbuf2); |  | ||||||
|             if (je == 2) { |  | ||||||
|                 n = mympd_search_add(mpd.buf, p_charbuf1, p_charbuf2); |  | ||||||
|                 free(p_charbuf1); |  | ||||||
|                 free(p_charbuf2); |  | ||||||
|                 if (n == 0) |  | ||||||
|                     n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}"); |  | ||||||
|             } |  | ||||||
|             break; |  | ||||||
|         case MPD_API_DATABASE_SEARCH_ADD_PLAYLIST: |  | ||||||
|             je = json_scanf(msg.p, msg.len, "{data: {plist:%Q, filter:%Q, searchstr:%Q}}", &p_charbuf1, &p_charbuf2, &p_charbuf3); |  | ||||||
|             if (je == 3) { |  | ||||||
|                 n = mympd_search_add_plist(p_charbuf1, p_charbuf2, p_charbuf3); |  | ||||||
|                 free(p_charbuf1); |  | ||||||
|                 free(p_charbuf2); |  | ||||||
|                 free(p_charbuf3); |  | ||||||
|                 if (n == 0) |  | ||||||
|                     n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}"); |  | ||||||
|             } |  | ||||||
|             break;             |  | ||||||
|         case MPD_API_DATABASE_SEARCH: |         case MPD_API_DATABASE_SEARCH: | ||||||
|             je = json_scanf(msg.p, msg.len, "{data: {offset:%u, mpdtag:%Q, searchstr:%Q}}", &uint_buf1, &p_charbuf1, &p_charbuf2); |             je = json_scanf(msg.p, msg.len, "{data: {searchstr:%Q, filter:%Q, plist:%Q, offset:%u}}", &p_charbuf1, &p_charbuf2, &p_charbuf3, &uint_buf1); | ||||||
|             if (je == 3) { |             if (je == 4) { | ||||||
|                 n = mympd_search(mpd.buf, p_charbuf1, uint_buf1, p_charbuf2); |                 n = mympd_search(mpd.buf, p_charbuf1, p_charbuf2, p_charbuf3, uint_buf1); | ||||||
|                 free(p_charbuf1); |                 free(p_charbuf1); | ||||||
|                 free(p_charbuf2); |                 free(p_charbuf2); | ||||||
|             } |             } | ||||||
| @@ -598,6 +580,81 @@ void mympd_parse_idle(struct mg_mgr *s, int idle_bitmask) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void mympd_mpd_features() { | ||||||
|  |     struct mpd_pair *pair; | ||||||
|  |      | ||||||
|  |     mpd.protocol = mpd_connection_get_server_version(mpd.conn); | ||||||
|  |  | ||||||
|  |     // Defaults | ||||||
|  |     mpd.feat_sticker = false; | ||||||
|  |     mpd.tag_artist = false; | ||||||
|  |     mpd.tag_album = false; | ||||||
|  |     mpd.tag_album_artist = false; | ||||||
|  |     mpd.tag_title = false; | ||||||
|  |     mpd.tag_track = false; | ||||||
|  |     mpd.tag_genre = false; | ||||||
|  |     mpd.tag_date = false; | ||||||
|  |     mpd.tag_composer = false; | ||||||
|  |     mpd.tag_performer = false; | ||||||
|  |  | ||||||
|  |     mpd_send_allowed_commands(mpd.conn); | ||||||
|  |     while ((pair = mpd_recv_command_pair(mpd.conn)) != NULL) { | ||||||
|  |         if (strcmp(pair->value, "sticker") == 0) | ||||||
|  |             mpd.feat_sticker = true; | ||||||
|  |         mpd_return_pair(mpd.conn, pair); | ||||||
|  |     } | ||||||
|  |     mpd_response_finish(mpd.conn); | ||||||
|  |     printf("MPD protocoll version: %i.%i.%i\n", mpd.protocol[0], mpd.protocol[1], mpd.protocol[2]); | ||||||
|  |     if (mpd.feat_sticker == false && config.stickers == true) { | ||||||
|  |         printf("MPD don't support stickers, disabling myMPD feature\n"); | ||||||
|  |         config.stickers = false; | ||||||
|  |     } | ||||||
|  |   | ||||||
|  |     printf("MPD supported tags: "); | ||||||
|  |     mpd_send_list_tag_types(mpd.conn); | ||||||
|  |     while ((pair = mpd_recv_tag_type_pair(mpd.conn)) != NULL) { | ||||||
|  |         printf("%s ", pair->value); | ||||||
|  |         if (strcmp(pair->value, "Artist") == 0) | ||||||
|  |             mpd.tag_artist = true; | ||||||
|  |         else if (strcmp(pair->value, "Album") == 0) | ||||||
|  |             mpd.tag_album = true; | ||||||
|  |         else if (strcmp(pair->value, "AlbumArtist") == 0) | ||||||
|  |             mpd.tag_album_artist = true; | ||||||
|  |         else if (strcmp(pair->value, "Title") == 0) | ||||||
|  |             mpd.tag_title = true; | ||||||
|  |         else if (strcmp(pair->value, "Track") == 0) | ||||||
|  |             mpd.tag_track = true; | ||||||
|  |         else if (strcmp(pair->value, "Genre") == 0) | ||||||
|  |             mpd.tag_genre = true; | ||||||
|  |         else if (strcmp(pair->value, "Date") == 0) | ||||||
|  |             mpd.tag_date = true; | ||||||
|  |         else if (strcmp(pair->value, "Composer") == 0) | ||||||
|  |             mpd.tag_composer = true; | ||||||
|  |         else if (strcmp(pair->value, "Performer") == 0) | ||||||
|  |             mpd.tag_performer = true; | ||||||
|  |         mpd_return_pair(mpd.conn, pair); | ||||||
|  |     } | ||||||
|  |     mpd_response_finish(mpd.conn); | ||||||
|  |     printf("\n"); | ||||||
|  |     if (mpd.tag_artist == false) | ||||||
|  |         printf("WARNING: Artist tag not enabled in mpd\n"); | ||||||
|  |     if (mpd.tag_album == false) | ||||||
|  |         printf("WARNING: Album tag not enabled in mpd\n"); | ||||||
|  |     if (mpd.tag_album_artist == false) | ||||||
|  |         printf("WARNING: AlbumArtist tag not enabled in mpd\n"); | ||||||
|  |     if (mpd.tag_title == false) | ||||||
|  |         printf("WARNING: Title tag not enabled in mpd\n"); | ||||||
|  |     if (mpd.tag_track == false) | ||||||
|  |         printf("WARNING: Track tag not enabled in mpd\n"); | ||||||
|  |     if (mpd.tag_genre == false) | ||||||
|  |         printf("WARNING: Genre tag not enabled in mpd\n"); | ||||||
|  |     if (mpd.tag_date == false) | ||||||
|  |         printf("WARNING: Date tag not enabled in mpd\n"); | ||||||
|  |     if (mpd.tag_composer == false) | ||||||
|  |         printf("WARNING: Composer tag not enabled in mpd\n"); | ||||||
|  |     if (mpd.tag_performer == false) | ||||||
|  |         printf("WARNING: Performer tag not enabled in mpd\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
| void mympd_idle(struct mg_mgr *s, int timeout) { | void mympd_idle(struct mg_mgr *s, int timeout) { | ||||||
|     struct pollfd fds[1]; |     struct pollfd fds[1]; | ||||||
| @@ -635,6 +692,7 @@ void mympd_idle(struct mg_mgr *s, int timeout) { | |||||||
|             printf("MPD connected.\n"); |             printf("MPD connected.\n"); | ||||||
|             mpd_connection_set_timeout(mpd.conn, mpd.timeout); |             mpd_connection_set_timeout(mpd.conn, mpd.timeout); | ||||||
|             mpd.conn_state = MPD_CONNECTED; |             mpd.conn_state = MPD_CONNECTED; | ||||||
|  |             mympd_mpd_features(); | ||||||
|             mpd_send_idle(mpd.conn); |             mpd_send_idle(mpd.conn); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
| @@ -815,6 +873,8 @@ char* mympd_get_tag(struct mpd_song const *song, enum mpd_tag_type tag) { | |||||||
|     if (str == NULL) { |     if (str == NULL) { | ||||||
|         if (tag == MPD_TAG_TITLE) |         if (tag == MPD_TAG_TITLE) | ||||||
|             str = basename((char *)mpd_song_get_uri(song)); |             str = basename((char *)mpd_song_get_uri(song)); | ||||||
|  |         else if (tag == MPD_TAG_ALBUM_ARTIST) | ||||||
|  |             str = (char *)mpd_song_get_tag(song, MPD_TAG_ARTIST, 0); | ||||||
|         else |         else | ||||||
|             str = "-"; |             str = "-"; | ||||||
|     } |     } | ||||||
| @@ -923,8 +983,9 @@ int mympd_put_settings(char *buffer) { | |||||||
|         "repeat: %d, single: %d, crossfade: %d, consume: %d, random: %d, " |         "repeat: %d, single: %d, crossfade: %d, consume: %d, random: %d, " | ||||||
|         "mixrampdb: %f, mixrampdelay: %f, mpdhost: %Q, mpdport: %d, passwort_set: %B, " |         "mixrampdb: %f, mixrampdelay: %f, mpdhost: %Q, mpdport: %d, passwort_set: %B, " | ||||||
|         "streamport: %d, coverimage: %Q, stickers: %B, mixramp: %B, " |         "streamport: %d, coverimage: %Q, stickers: %B, mixramp: %B, " | ||||||
|         "maxElementsPerPage: %d, replaygain: %Q," |         "maxElementsPerPage: %d, replaygain: %Q, notificationWeb: %d, notificationPage: %d, " | ||||||
|         "notificationWeb: %d, notificationPage: %d" |         "tags: { Artist: %B, Album: %B, AlbumArtist: %B, Title: %B, Track: %B, Genre: %B, Date: %B," | ||||||
|  |         "Composer: %B, Performer: %B }" | ||||||
|         "}}",  |         "}}",  | ||||||
|         mpd_status_get_repeat(status), |         mpd_status_get_repeat(status), | ||||||
|         mpd_status_get_single(status), |         mpd_status_get_single(status), | ||||||
| @@ -943,7 +1004,16 @@ int mympd_put_settings(char *buffer) { | |||||||
|         MAX_ELEMENTS_PER_PAGE, |         MAX_ELEMENTS_PER_PAGE, | ||||||
|         replaygain, |         replaygain, | ||||||
|         state.a, |         state.a, | ||||||
|         state.b |         state.b, | ||||||
|  |         mpd.tag_artist, | ||||||
|  |         mpd.tag_album, | ||||||
|  |         mpd.tag_album_artist, | ||||||
|  |         mpd.tag_title, | ||||||
|  |         mpd.tag_track, | ||||||
|  |         mpd.tag_genre, | ||||||
|  |         mpd.tag_date, | ||||||
|  |         mpd.tag_composer, | ||||||
|  |         mpd.tag_performer | ||||||
|     ); |     ); | ||||||
|     mpd_status_free(status); |     mpd_status_free(status); | ||||||
|     free(replaygain); |     free(replaygain); | ||||||
| @@ -1091,7 +1161,7 @@ int mympd_put_songdetails(char *buffer, char *uri) { | |||||||
|          |          | ||||||
|         mympd_get_cover(uri, cover, 500); |         mympd_get_cover(uri, cover, 500); | ||||||
|         len += json_printf(&out, "duration: %d, artist: %Q, album: %Q, title: %Q, albumartist: %Q, cover: %Q, uri: %Q, " |         len += json_printf(&out, "duration: %d, artist: %Q, album: %Q, title: %Q, albumartist: %Q, cover: %Q, uri: %Q, " | ||||||
|             "genre: %Q, track: %Q, date: %Q", |             "genre: %Q, track: %Q, date: %Q, composer: %Q, performer: %Q", | ||||||
|             mpd_song_get_duration(song), |             mpd_song_get_duration(song), | ||||||
|             mympd_get_tag(song, MPD_TAG_ARTIST), |             mympd_get_tag(song, MPD_TAG_ARTIST), | ||||||
|             mympd_get_tag(song, MPD_TAG_ALBUM), |             mympd_get_tag(song, MPD_TAG_ALBUM), | ||||||
| @@ -1101,7 +1171,9 @@ int mympd_put_songdetails(char *buffer, char *uri) { | |||||||
|             uri, |             uri, | ||||||
|             mympd_get_tag(song, MPD_TAG_GENRE), |             mympd_get_tag(song, MPD_TAG_GENRE), | ||||||
|             mympd_get_tag(song, MPD_TAG_TRACK), |             mympd_get_tag(song, MPD_TAG_TRACK), | ||||||
|             mympd_get_tag(song, MPD_TAG_DATE) |             mympd_get_tag(song, MPD_TAG_DATE), | ||||||
|  |             mympd_get_tag(song, MPD_TAG_COMPOSER), | ||||||
|  |             mympd_get_tag(song, MPD_TAG_PERFORMER) | ||||||
|         ); |         ); | ||||||
|         mpd_entity_free(entity); |         mpd_entity_free(entity); | ||||||
|     } |     } | ||||||
| @@ -1349,18 +1421,19 @@ int mympd_put_db_tag(char *buffer, unsigned int offset, char *mpdtagtype, char * | |||||||
|     return len; |     return len; | ||||||
| } | } | ||||||
|  |  | ||||||
| int mympd_put_songs_in_album(char *buffer, char *albumartist, char *album) { | int mympd_put_songs_in_album(char *buffer, char *album, char *search, char *tag) { | ||||||
|     struct mpd_song *song; |     struct mpd_song *song; | ||||||
|     unsigned long entity_count = 0; |     unsigned long entity_count = 0; | ||||||
|     unsigned long entities_returned = 0; |     unsigned long entities_returned = 0; | ||||||
|     int len; |     int len; | ||||||
|     char cover[500]; |     char cover[500]; | ||||||
|  |     char *albumartist; | ||||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); |     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||||
|  |  | ||||||
|     if (mpd_search_db_songs(mpd.conn, true) == false) |     if (mpd_search_db_songs(mpd.conn, true) == false) | ||||||
|         RETURN_ERROR_AND_RECOVER("mpd_search_db_songs"); |         RETURN_ERROR_AND_RECOVER("mpd_search_db_songs"); | ||||||
|      |      | ||||||
|     if (mpd_search_add_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, MPD_TAG_ALBUM_ARTIST, albumartist) == false) |     if (mpd_search_add_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, mpd_tag_name_parse(tag), search) == false) | ||||||
|         RETURN_ERROR_AND_RECOVER("mpd_search_add_tag_constraint"); |         RETURN_ERROR_AND_RECOVER("mpd_search_add_tag_constraint"); | ||||||
|  |  | ||||||
|     if (mpd_search_add_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, MPD_TAG_ALBUM, album) == false) |     if (mpd_search_add_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, MPD_TAG_ALBUM, album) == false) | ||||||
| @@ -1376,9 +1449,10 @@ int mympd_put_songs_in_album(char *buffer, char *albumartist, char *album) { | |||||||
|             if (entity_count <= MAX_ELEMENTS_PER_PAGE) { |             if (entity_count <= MAX_ELEMENTS_PER_PAGE) { | ||||||
|                 if (entities_returned ++)  |                 if (entities_returned ++)  | ||||||
|                     len += json_printf(&out, ", "); |                     len += json_printf(&out, ", "); | ||||||
|                 else  |                 else { | ||||||
|                     mympd_get_cover(mpd_song_get_uri(song), cover, 500); |                     mympd_get_cover(mpd_song_get_uri(song), cover, 500); | ||||||
|                  |                     albumartist = strdup(mympd_get_tag(song, MPD_TAG_ALBUM_ARTIST)); | ||||||
|  |                 } | ||||||
|                 len += json_printf(&out, "{type: song, uri: %Q, duration: %d, title: %Q, track: %Q}", |                 len += json_printf(&out, "{type: song, uri: %Q, duration: %d, title: %Q, track: %Q}", | ||||||
|                     mpd_song_get_uri(song), |                     mpd_song_get_uri(song), | ||||||
|                     mpd_song_get_duration(song), |                     mpd_song_get_duration(song), | ||||||
| @@ -1389,14 +1463,17 @@ int mympd_put_songs_in_album(char *buffer, char *albumartist, char *album) { | |||||||
|             mpd_song_free(song); |             mpd_song_free(song); | ||||||
|         } |         } | ||||||
|          |          | ||||||
|         len += json_printf(&out, "], totalEntities: %d, returnedEntities: %d, albumartist: %Q, album: %Q, cover: %Q}", |         len += json_printf(&out, "], totalEntities: %d, returnedEntities: %d, album: %Q, search: %Q, tag: %Q, cover: %Q, albumartist: %Q}", | ||||||
|             entity_count, |             entity_count, | ||||||
|             entities_returned, |             entities_returned, | ||||||
|             albumartist, |  | ||||||
|             album, |             album, | ||||||
|             cover |             search, | ||||||
|  |             tag, | ||||||
|  |             cover, | ||||||
|  |             albumartist | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  |     free(albumartist); | ||||||
|  |  | ||||||
|     if (len > MAX_SIZE) |     if (len > MAX_SIZE) | ||||||
|         printf("Buffer truncated\n"); |         printf("Buffer truncated\n"); | ||||||
| @@ -1503,31 +1580,29 @@ int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char * | |||||||
|     return len; |     return len; | ||||||
| } | } | ||||||
|  |  | ||||||
| int mympd_search(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr) { | int mympd_search(char *buffer, char *searchstr, char *filter, char *plist, unsigned int offset) { | ||||||
|     struct mpd_song *song; |     struct mpd_song *song; | ||||||
|     unsigned long entity_count = 0; |     unsigned long entity_count = 0; | ||||||
|     unsigned long entities_returned = 0; |     unsigned long entities_returned = 0; | ||||||
|     int len; |     int len = 0; | ||||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); |     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||||
|  |  | ||||||
|     if (mpd_search_db_songs(mpd.conn, false) == false) |  | ||||||
|         RETURN_ERROR_AND_RECOVER("mpd_search_db_songs"); |  | ||||||
|      |      | ||||||
|     if (mpd_tag_name_parse(mpdtagtype) != MPD_TAG_UNKNOWN) { |     if (strcmp(plist, "") == 0) { | ||||||
|        if (mpd_search_add_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, mpd_tag_name_parse(mpdtagtype), searchstr) == false) |         if (mpd_send_command(mpd.conn, "search", filter, searchstr, NULL) == false) | ||||||
|             RETURN_ERROR_AND_RECOVER("mpd_search_add_tag_constraint"); |             RETURN_ERROR_AND_RECOVER("mpd_search"); | ||||||
|  |         len = json_printf(&out, "{type: search, data: ["); | ||||||
|  |     } | ||||||
|  |     else if (strcmp(plist, "queue") == 0) { | ||||||
|  |         if (mpd_send_command(mpd.conn, "searchadd", filter, searchstr, NULL) == false) | ||||||
|  |             RETURN_ERROR_AND_RECOVER("mpd_searchadd"); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         if (mpd_search_add_any_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, searchstr) == false) |         if (mpd_send_command(mpd.conn, "searchaddpl", plist, filter, searchstr, NULL) == false) | ||||||
|             RETURN_ERROR_AND_RECOVER("mpd_search_add_any_tag_constraint");         |             RETURN_ERROR_AND_RECOVER("mpd_searchaddpl"); | ||||||
|     }     |     } | ||||||
|          |  | ||||||
|     if (mpd_search_commit(mpd.conn) == false) |  | ||||||
|         RETURN_ERROR_AND_RECOVER("mpd_search_commit"); |  | ||||||
|     else { |  | ||||||
|         len = json_printf(&out, "{type: search, data: ["); |  | ||||||
|  |  | ||||||
|         while((song = mpd_recv_song(mpd.conn)) != NULL) { |     if (strcmp(plist, "") == 0) { | ||||||
|  |         while ((song = mpd_recv_song(mpd.conn)) != NULL) { | ||||||
|             entity_count ++; |             entity_count ++; | ||||||
|             if (entity_count > offset && entity_count <= offset + MAX_ELEMENTS_PER_PAGE) { |             if (entity_count > offset && entity_count <= offset + MAX_ELEMENTS_PER_PAGE) { | ||||||
|                 if (entities_returned ++)  |                 if (entities_returned ++)  | ||||||
| @@ -1543,59 +1618,20 @@ int mympd_search(char *buffer, char *mpdtagtype, unsigned int offset, char *sear | |||||||
|             } |             } | ||||||
|             mpd_song_free(song); |             mpd_song_free(song); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |         mpd_response_finish(mpd.conn); | ||||||
|  |  | ||||||
|         len += json_printf(&out, "], totalEntities: %d, offset: %d, returnedEntities: %d, mpdtagtype: %Q}", |     if (strcmp(plist, "") == 0) { | ||||||
|  |         len += json_printf(&out, "], totalEntities: %d, offset: %d, returnedEntities: %d, searchstr: %Q}", | ||||||
|             entity_count, |             entity_count, | ||||||
|             offset, |             offset, | ||||||
|             entities_returned, |             entities_returned, | ||||||
|             mpdtagtype |             searchstr | ||||||
|         ); |         ); | ||||||
|     } |     }  | ||||||
|  |     else | ||||||
|     if (len > MAX_SIZE) |         len = json_printf(&out, "{type: result, data: ok}"); | ||||||
|         printf("Buffer truncated\n"); |  | ||||||
|     return len; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int mympd_search_add(char *buffer, char *mpdtagtype, char *searchstr) { |  | ||||||
|     int len = 0; |  | ||||||
|     struct mpd_song *song; |  | ||||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); |  | ||||||
|  |  | ||||||
|     if (mpd_search_add_db_songs(mpd.conn, false) == false) { |  | ||||||
|         RETURN_ERROR_AND_RECOVER("mpd_search_add_db_songs"); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     if (mpd_tag_name_parse(mpdtagtype) != MPD_TAG_UNKNOWN) { |  | ||||||
|        if (mpd_search_add_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, mpd_tag_name_parse(mpdtagtype), searchstr) == false) |  | ||||||
|             RETURN_ERROR_AND_RECOVER("mpd_search_add_tag_constraint"); |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|         if (mpd_search_add_any_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, searchstr) == false) |  | ||||||
|             RETURN_ERROR_AND_RECOVER("mpd_search_add_any_tag_constraint");         |  | ||||||
|     }     |  | ||||||
|          |  | ||||||
|     if (mpd_search_commit(mpd.conn) == false) |  | ||||||
|         RETURN_ERROR_AND_RECOVER("mpd_search_commit"); |  | ||||||
|      |  | ||||||
|     while((song = mpd_recv_song(mpd.conn)) != NULL) { |  | ||||||
|         mpd_song_free(song); |  | ||||||
|     } |  | ||||||
|          |  | ||||||
|     if (len > MAX_SIZE) |  | ||||||
|         printf("Buffer truncated\n"); |  | ||||||
|     return len; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int mympd_search_add_plist(char *plist, char *mpdtagtype, char *searchstr) { |  | ||||||
|     int len = 0; |  | ||||||
|     struct mpd_pair *pair;     |  | ||||||
|  |  | ||||||
|     mpd_send_command(mpd.conn, "searchaddpl", plist, mpdtagtype, searchstr, NULL); |  | ||||||
|  |  | ||||||
|     while ((pair = mpd_recv_pair(mpd.conn)) != NULL) { |  | ||||||
|         mpd_return_pair(mpd.conn, pair); |  | ||||||
|     }     |  | ||||||
|  |  | ||||||
|     if (len > MAX_SIZE) |     if (len > MAX_SIZE) | ||||||
|         printf("Buffer truncated\n"); |         printf("Buffer truncated\n"); | ||||||
| @@ -1657,20 +1693,20 @@ int mympd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char | |||||||
|         len = json_printf(&out, "{type: queuesearch, data: ["); |         len = json_printf(&out, "{type: queuesearch, data: ["); | ||||||
|  |  | ||||||
|         while((song = mpd_recv_song(mpd.conn)) != NULL) { |         while((song = mpd_recv_song(mpd.conn)) != NULL) { | ||||||
|           entity_count ++; |             entity_count ++; | ||||||
|           if (entity_count > offset && entity_count <= offset + MAX_ELEMENTS_PER_PAGE) { |             if (entity_count > offset && entity_count <= offset + MAX_ELEMENTS_PER_PAGE) { | ||||||
|             if (entities_returned ++) |                 if (entities_returned ++) | ||||||
|                 len += json_printf(&out, ", "); |                     len += json_printf(&out, ", "); | ||||||
|             len += json_printf(&out, "{type: song, id: %d, pos: %d, album: %Q, artist: %Q, duration: %d, title: %Q}", |                 len += json_printf(&out, "{type: song, id: %d, pos: %d, album: %Q, artist: %Q, duration: %d, title: %Q}", | ||||||
|                 mpd_song_get_id(song), |                     mpd_song_get_id(song), | ||||||
|                 mpd_song_get_pos(song), |                     mpd_song_get_pos(song), | ||||||
|                 mympd_get_tag(song, MPD_TAG_ALBUM), |                     mympd_get_tag(song, MPD_TAG_ALBUM), | ||||||
|                 mympd_get_tag(song, MPD_TAG_ARTIST), |                     mympd_get_tag(song, MPD_TAG_ARTIST), | ||||||
|                 mpd_song_get_duration(song), |                     mpd_song_get_duration(song), | ||||||
|                 mympd_get_tag(song, MPD_TAG_TITLE) |                     mympd_get_tag(song, MPD_TAG_TITLE) | ||||||
|             ); |                 ); | ||||||
|             mpd_song_free(song); |                 mpd_song_free(song); | ||||||
|           } |             } | ||||||
|         } |         } | ||||||
|          |          | ||||||
|         len += json_printf(&out, "], totalEntities: %d, offset: %d, returnedEntities: %d, mpdtagtype: %Q}", |         len += json_printf(&out, "], totalEntities: %d, offset: %d, returnedEntities: %d, mpdtagtype: %Q}", | ||||||
|   | |||||||
| @@ -72,14 +72,12 @@ | |||||||
|     X(MPD_API_PLAYLIST_RM_TRACK) \ |     X(MPD_API_PLAYLIST_RM_TRACK) \ | ||||||
|     X(MPD_API_PLAYLIST_LIST) \ |     X(MPD_API_PLAYLIST_LIST) \ | ||||||
|     X(MPD_API_PLAYLIST_CONTENT_LIST) \ |     X(MPD_API_PLAYLIST_CONTENT_LIST) \ | ||||||
|     X(MPD_API_DATABASE_SEARCH_ADD_PLAYLIST) \ |  | ||||||
|     X(MPD_API_DATABASE_SEARCH_ADD_QUEUE) \ |  | ||||||
|     X(MPD_API_DATABASE_SEARCH) \ |     X(MPD_API_DATABASE_SEARCH) \ | ||||||
|     X(MPD_API_DATABASE_UPDATE) \ |     X(MPD_API_DATABASE_UPDATE) \ | ||||||
|     X(MPD_API_DATABASE_FILESYSTEM_LIST) \ |     X(MPD_API_DATABASE_FILESYSTEM_LIST) \ | ||||||
|     X(MPD_API_DATABASE_ARTISTALBUM_LIST) \ |     X(MPD_API_DATABASE_TAG_LIST) \ | ||||||
|     X(MPD_API_DATABASE_ARTISTALBUMTITLE_LIST) \ |     X(MPD_API_DATABASE_TAG_ALBUM_LIST) \ | ||||||
|     X(MPD_API_DATABASE_ARTIST_LIST) \ |     X(MPD_API_DATABASE_TAG_ALBUM_TITLE_LIST) \ | ||||||
|     X(MPD_API_DATABASE_STATS) \ |     X(MPD_API_DATABASE_STATS) \ | ||||||
|     X(MPD_API_DATABASE_SONGDETAILS) \ |     X(MPD_API_DATABASE_SONGDETAILS) \ | ||||||
|     X(MPD_API_PLAYER_PLAY_TRACK) \ |     X(MPD_API_PLAYER_PLAY_TRACK) \ | ||||||
| @@ -114,21 +112,36 @@ enum mpd_conn_states { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| struct t_mpd { | struct t_mpd { | ||||||
|  |     // Connection | ||||||
|     struct mpd_connection *conn; |     struct mpd_connection *conn; | ||||||
|     enum mpd_conn_states conn_state; |     enum mpd_conn_states conn_state; | ||||||
|  |     int timeout; | ||||||
|  |  | ||||||
|     /* Reponse Buffer */ |     // Reponse Buffer | ||||||
|     char buf[MAX_SIZE]; |     char buf[MAX_SIZE]; | ||||||
|     size_t buf_size; |     size_t buf_size; | ||||||
|  |  | ||||||
|  |     // States | ||||||
|     int song_id; |     int song_id; | ||||||
|     int next_song_id; |     int next_song_id; | ||||||
|     int last_song_id; |     int last_song_id; | ||||||
|     unsigned queue_version; |     unsigned queue_version; | ||||||
|     unsigned queue_length; |     unsigned queue_length; | ||||||
|     int timeout; |  | ||||||
|      |  | ||||||
|     int last_update_sticker_song_id; |     int last_update_sticker_song_id; | ||||||
|  |      | ||||||
|  |     // Features | ||||||
|  |     const unsigned* protocol; | ||||||
|  |     // Supported tags | ||||||
|  |     bool feat_sticker; | ||||||
|  |     bool tag_artist; | ||||||
|  |     bool tag_album; | ||||||
|  |     bool tag_album_artist; | ||||||
|  |     bool tag_title; | ||||||
|  |     bool tag_track; | ||||||
|  |     bool tag_genre; | ||||||
|  |     bool tag_date; | ||||||
|  |     bool tag_composer; | ||||||
|  |     bool tag_performer; | ||||||
| } mpd; | } mpd; | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
| @@ -177,15 +190,13 @@ int mympd_put_outputs(char *buffer); | |||||||
| int mympd_put_current_song(char *buffer); | int mympd_put_current_song(char *buffer); | ||||||
| int mympd_put_queue(char *buffer, unsigned int offset, unsigned *queue_version, unsigned *queue_length); | int mympd_put_queue(char *buffer, unsigned int offset, unsigned *queue_version, unsigned *queue_length); | ||||||
| int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter); | int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter); | ||||||
| int mympd_search(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr); | int mympd_search(char *buffer, char *searchstr, char *filter, char *plist, unsigned int offset); | ||||||
| int mympd_search_add(char *buffer, char *mpdtagtype, char *searchstr); |  | ||||||
| int mympd_search_add_plist(char *plist, char *mpdtagtype, char *searchstr); |  | ||||||
| int mympd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr); | int mympd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr); | ||||||
| int mympd_put_welcome(char *buffer); | int mympd_put_welcome(char *buffer); | ||||||
| int mympd_put_stats(char *buffer); | int mympd_put_stats(char *buffer); | ||||||
| int mympd_put_settings(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); | int mympd_put_db_tag(char *buffer, unsigned int offset, char *mpdtagtype, char *mpdsearchtagtype, char *searchstr, char *filter); | ||||||
| int mympd_put_songs_in_album(char *buffer, char *albumartist, char *album); | int mympd_put_songs_in_album(char *buffer, char *album, char *search, char *tag); | ||||||
| int mympd_put_playlists(char *buffer, unsigned int offset, char *filter); | int mympd_put_playlists(char *buffer, unsigned int offset, char *filter); | ||||||
| int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char *filter); | int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char *filter); | ||||||
| int mympd_put_songdetails(char *buffer, char *uri); | int mympd_put_songdetails(char *buffer, char *uri); | ||||||
|   | |||||||
| @@ -229,6 +229,7 @@ int main(int argc, char **argv) { | |||||||
|         nc = mg_bind_opt(&mgr, config.sslport, ev_handler, bind_opts); |         nc = mg_bind_opt(&mgr, config.sslport, ev_handler, bind_opts); | ||||||
|         if (nc == NULL) { |         if (nc == NULL) { | ||||||
|             printf("Error listening on port %s: %s\n", config.sslport, err); |             printf("Error listening on port %s: %s\n", config.sslport, err); | ||||||
|  |             mg_mgr_free(&mgr); | ||||||
|             return EXIT_FAILURE; |             return EXIT_FAILURE; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -236,6 +237,7 @@ int main(int argc, char **argv) { | |||||||
|         nc = mg_bind(&mgr, config.webport, ev_handler); |         nc = mg_bind(&mgr, config.webport, ev_handler); | ||||||
|         if (nc == NULL) { |         if (nc == NULL) { | ||||||
|             printf("Error listening on port %s\n", config.webport); |             printf("Error listening on port %s\n", config.webport); | ||||||
|  |             mg_mgr_free(&mgr); | ||||||
|             return EXIT_FAILURE; |             return EXIT_FAILURE; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jürgen Mang
					Jürgen Mang