mirror of
https://github.com/SuperBFG7/ympd
synced 2024-12-26 02:50:26 +00:00
Merge pull request #63 from jcorporation/devel
Merge devel into master for 4.3.0 release
This commit is contained in:
commit
044eaa2ad4
@ -3,8 +3,8 @@ 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 "2")
|
set(CPACK_PACKAGE_VERSION_MINOR "3")
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH "1")
|
set(CPACK_PACKAGE_VERSION_PATCH "0")
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES RELEASE)
|
if(CMAKE_BUILD_TYPE MATCHES RELEASE)
|
||||||
set(ASSETS_PATH "/usr/share/${PROJECT_NAME}/htdocs")
|
set(ASSETS_PATH "/usr/share/${PROJECT_NAME}/htdocs")
|
||||||
@ -55,3 +55,6 @@ 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 ../var/lib/${PROJECT_NAME}/pics)
|
install(DIRECTORY DESTINATION ../var/lib/${PROJECT_NAME}/pics)
|
||||||
|
install(DIRECTORY DESTINATION ../var/lib/${PROJECT_NAME}/tmp)
|
||||||
|
install(DIRECTORY DESTINATION ../var/lib/${PROJECT_NAME}/state)
|
||||||
|
install(DIRECTORY dist/smartpls DESTINATION ../var/lib/${PROJECT_NAME})
|
||||||
|
2
PKGBUILD
2
PKGBUILD
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
pkgname=mympd
|
pkgname=mympd
|
||||||
_pkgname=myMPD
|
_pkgname=myMPD
|
||||||
pkgver=4.2.1
|
pkgver=4.3.0
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="A standalone MPD Web GUI based on YMPD - Default port set to 80"
|
pkgdesc="A standalone MPD Web GUI based on YMPD - Default port set to 80"
|
||||||
arch=('x86_64' 'armv7h' 'aarch64')
|
arch=('x86_64' 'armv7h' 'aarch64')
|
||||||
|
@ -21,13 +21,14 @@ This fork provides a reworked ui based on Bootstrap 4, a modernized backend and
|
|||||||
- Queue management
|
- Queue management
|
||||||
- Playlist management
|
- Playlist management
|
||||||
- Advanced search
|
- Advanced search
|
||||||
- Progressiv Web App enabled
|
- Jukebox mode (add's random songs / albums from database or playlists to queue)
|
||||||
|
- Smart playlists and saved searches
|
||||||
|
- Play statistics and song voting (uses mpd stickers)
|
||||||
- Local coverart support (Albums and Streams)
|
- Local coverart support (Albums and Streams)
|
||||||
- HTTP stream support
|
- HTTP stream support
|
||||||
- Local playback of mpd http stream (html5 audio api)
|
- Local playback of mpd http stream (html5 audio api)
|
||||||
- Play statistics and song voting (uses mpd stickers)
|
- Progressiv Web App enabled
|
||||||
- Embedded Webserver (mongoose)
|
- Embedded Webserver (mongoose)
|
||||||
- Jukebox mode (add's random songs from database or playlists to queue)
|
|
||||||
|
|
||||||
myMPD is work in progress. Bugreportes and feature requests are very welcome.
|
myMPD is work in progress. Bugreportes and feature requests are very welcome.
|
||||||
- https://github.com/jcorporation/myMPD/issues
|
- https://github.com/jcorporation/myMPD/issues
|
||||||
|
@ -11,11 +11,8 @@ post_upgrade() {
|
|||||||
[ "$?" = "2" ] && useradd --system -d /var/lib/mympd -s /usr/sbin/nologin -g mympd mympd
|
[ "$?" = "2" ] && useradd --system -d /var/lib/mympd -s /usr/sbin/nologin -g mympd mympd
|
||||||
|
|
||||||
# fix ownership of /var/lib/mympd
|
# fix ownership of /var/lib/mympd
|
||||||
if ! [ $(stat -c '%U:%G' /var/lib/mympd/) = 'mympd:mympd' ]
|
echo "INFO: Fixing ownership of /var/lib/mympd"
|
||||||
then
|
chown -R mympd.mympd /var/lib/mympd
|
||||||
echo "INFO: Fixing ownership of /var/lib/mympd"
|
|
||||||
chown -R mympd.mympd /var/lib/mympd
|
|
||||||
fi
|
|
||||||
|
|
||||||
# link music directory to mympd if not already exising
|
# link music directory to mympd if not already exising
|
||||||
echo "INFO: Trying to link musicdir to library"
|
echo "INFO: Trying to link musicdir to library"
|
||||||
@ -52,6 +49,18 @@ post_upgrade() {
|
|||||||
/usr/share/mympd/crcert.sh
|
/usr/share/mympd/crcert.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# move smartpls into place unless already existing
|
||||||
|
for PLDIST in /var/lib/mympd/smartpls/*.dist
|
||||||
|
do
|
||||||
|
PLS=$(basename $PLDIST .dist)
|
||||||
|
if [ -f /var/lib/mympd/smartpls/$PLS ]
|
||||||
|
then
|
||||||
|
rm $PLDIST
|
||||||
|
else
|
||||||
|
mv $PLDIST /var/lib/mympd/smartpls/$PLS
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# move config into place unless already existing
|
# move config into place unless already existing
|
||||||
if [ ! -f /etc/mympd/mympd.conf ]
|
if [ ! -f /etc/mympd/mympd.conf ]
|
||||||
then
|
then
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
# (c) 2018 Juergen Mang <mail@jcgames.de>
|
# (c) 2018 Juergen Mang <mail@jcgames.de>
|
||||||
|
|
||||||
Name: myMPD
|
Name: myMPD
|
||||||
Version: 4.2.1
|
Version: 4.3.0
|
||||||
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/v4.2.1.zip
|
Source: https://github.com/jcorporation/myMPD/archive/v4.3.0.zip
|
||||||
BuildRequires: gcc
|
BuildRequires: gcc
|
||||||
BuildRequires: cmake
|
BuildRequires: cmake
|
||||||
BuildRequires: unzip
|
BuildRequires: unzip
|
||||||
@ -44,15 +44,12 @@ getent group mympd > /dev/null
|
|||||||
getent passwd mympd > /dev/null
|
getent passwd mympd > /dev/null
|
||||||
[ "$?" = "2" ] && useradd -r mympd -g mympd -d /var/lib/mympd -s /usr/sbin/nologin
|
[ "$?" = "2" ] && useradd -r mympd -g mympd -d /var/lib/mympd -s /usr/sbin/nologin
|
||||||
|
|
||||||
if ! [ $(stat -c '%U:%G' /var/lib/mympd/) = 'mympd:mympd' ]
|
echo "Fixing ownership of /var/lib/mympd"
|
||||||
then
|
chown -R mympd.mympd /var/lib/mympd
|
||||||
echo "Fixing ownership of /var/lib/mympd"
|
|
||||||
chown -R mympd.mympd /var/lib/mympd
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -d /etc/systemd ]
|
if [ -d /etc/systemd ]
|
||||||
then
|
then
|
||||||
[ -d /usr/lib/systemd/system ] || sudo mkdir -p /usr/lib/systemd/system
|
[ -d /usr/lib/systemd/system ] || mkdir -p /usr/lib/systemd/system
|
||||||
cp /usr/share/mympd/mympd.service /usr/lib/systemd/system/
|
cp /usr/share/mympd/mympd.service /usr/lib/systemd/system/
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl enable mympd
|
systemctl enable mympd
|
||||||
@ -66,6 +63,19 @@ fi
|
|||||||
|
|
||||||
[ -e /usr/share/mympd/htdocs/pics ] || ln -s /var/lib/mympd/pics /usr/share/mympd/htdocs/
|
[ -e /usr/share/mympd/htdocs/pics ] || ln -s /var/lib/mympd/pics /usr/share/mympd/htdocs/
|
||||||
|
|
||||||
|
# move smartpls into place unless already existing
|
||||||
|
for PLDIST in /var/lib/mympd/smartpls/*.dist
|
||||||
|
do
|
||||||
|
PLS=$(basename $PLDIST .dist)
|
||||||
|
if [ -f /var/lib/mympd/smartpls/$PLS ]
|
||||||
|
then
|
||||||
|
rm $PLDIST
|
||||||
|
else
|
||||||
|
mv $PLDIST /var/lib/mympd/smartpls/$PLS
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# move config into place unless already existing
|
||||||
if [ ! -f /etc/mympd/mympd.conf ]
|
if [ ! -f /etc/mympd/mympd.conf ]
|
||||||
then
|
then
|
||||||
mv /etc/mympd/mympd.conf.dist /etc/mympd/mympd.conf
|
mv /etc/mympd/mympd.conf.dist /etc/mympd/mympd.conf
|
||||||
|
@ -23,8 +23,8 @@ streamport = 8000
|
|||||||
#Name for coverimages
|
#Name for coverimages
|
||||||
coverimage = folder.jpg
|
coverimage = folder.jpg
|
||||||
|
|
||||||
#myMPD statefile
|
#myMPD state directory
|
||||||
statefile = /var/lib/mympd/mympd.state
|
varlibdir = /var/lib/mympd
|
||||||
|
|
||||||
#Enable mixramp settings
|
#Enable mixramp settings
|
||||||
mixramp = false
|
mixramp = false
|
||||||
@ -35,3 +35,6 @@ stickers = true
|
|||||||
#List of tags in myMPD gui
|
#List of tags in myMPD gui
|
||||||
#Supported tags: Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer
|
#Supported tags: Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer
|
||||||
taglist = Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer
|
taglist = Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer
|
||||||
|
|
||||||
|
#Enable smart playlists
|
||||||
|
smartpls = true
|
||||||
|
4
debian/changelog
vendored
4
debian/changelog
vendored
@ -1,5 +1,5 @@
|
|||||||
mympd (4.2.1-1) stable; urgency=medium
|
mympd (4.3.0-1) stable; urgency=medium
|
||||||
|
|
||||||
* Release from master
|
* Release from master
|
||||||
|
|
||||||
-- Juergen Mang <mail@jcgames.de> Thu, 20 Sep 2018 19:32:00 +0200
|
-- Juergen Mang <mail@jcgames.de> Tue, 25 Sep 2018 00:35:00 +0200
|
||||||
|
21
debian/postinst
vendored
21
debian/postinst
vendored
@ -6,11 +6,8 @@ getent group mympd > /dev/null
|
|||||||
getent passwd mympd > /dev/null
|
getent passwd mympd > /dev/null
|
||||||
[ "$?" = "2" ] && useradd -r mympd -g mympd -d /var/lib/mympd -s /usr/sbin/nologin
|
[ "$?" = "2" ] && useradd -r mympd -g mympd -d /var/lib/mympd -s /usr/sbin/nologin
|
||||||
|
|
||||||
if ! [ $(stat -c '%U:%G' /var/lib/mympd/) = 'mympd:mympd' ]
|
echo "Fixing ownership of /var/lib/mympd"
|
||||||
then
|
chown -R mympd.mympd /var/lib/mympd
|
||||||
echo "Fixing ownership of /var/lib/mympd"
|
|
||||||
chown -R mympd.mympd /var/lib/mympd
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Trying to link musicdir to library"
|
echo "Trying to link musicdir to library"
|
||||||
if [ -f /etc/mpd.conf ]
|
if [ -f /etc/mpd.conf ]
|
||||||
@ -36,6 +33,18 @@ then
|
|||||||
systemctl enable mympd
|
systemctl enable mympd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# move smartpls into place unless already existing
|
||||||
|
for PLDIST in /var/lib/mympd/smartpls/*.dist
|
||||||
|
do
|
||||||
|
PLS=$(basename $PLDIST .dist)
|
||||||
|
if [ -f /var/lib/mympd/smartpls/$PLS ]
|
||||||
|
then
|
||||||
|
rm $PLDIST
|
||||||
|
else
|
||||||
|
mv $PLDIST /var/lib/mympd/smartpls/$PLS
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# move config into place unless already existing
|
# move config into place unless already existing
|
||||||
if [ ! -f /etc/mympd/mympd.conf ]
|
if [ ! -f /etc/mympd/mympd.conf ]
|
||||||
then
|
then
|
||||||
@ -49,7 +58,7 @@ then
|
|||||||
echo "Certificates already created"
|
echo "Certificates already created"
|
||||||
else
|
else
|
||||||
echo "Creating certificates"
|
echo "Creating certificates"
|
||||||
sudo /usr/share/mympd/crcert.sh
|
/usr/share/mympd/crcert.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "myMPD installed"
|
echo "myMPD installed"
|
||||||
|
2
dist/htdocs/index.html
vendored
2
dist/htdocs/index.html
vendored
File diff suppressed because one or more lines are too long
14
dist/htdocs/js/bootstrap-native-v4.js
vendored
14
dist/htdocs/js/bootstrap-native-v4.js
vendored
@ -1,4 +1,4 @@
|
|||||||
// Native Javascript for Bootstrap 4 v2.0.23 | © dnp_theme | MIT-License
|
// Native Javascript for Bootstrap 4 v2.0.24 | © dnp_theme | MIT-License
|
||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
if (typeof define === 'function' && define.amd) {
|
if (typeof define === 'function' && define.amd) {
|
||||||
// AMD support:
|
// AMD support:
|
||||||
@ -315,7 +315,7 @@
|
|||||||
arrowLeft && (arrow[style][left] = arrowLeft + 'px');
|
arrowLeft && (arrow[style][left] = arrowLeft + 'px');
|
||||||
};
|
};
|
||||||
|
|
||||||
BSN.version = '2.0.23';
|
BSN.version = '2.0.24';
|
||||||
|
|
||||||
/* Native Javascript for Bootstrap 4 | Alert
|
/* Native Javascript for Bootstrap 4 | Alert
|
||||||
-------------------------------------------*/
|
-------------------------------------------*/
|
||||||
@ -501,7 +501,8 @@
|
|||||||
|
|
||||||
this[interval] = typeof intervalOption === 'number' ? intervalOption
|
this[interval] = typeof intervalOption === 'number' ? intervalOption
|
||||||
: intervalOption === false || intervalData === 0 || intervalData === false ? 0
|
: intervalOption === false || intervalData === 0 || intervalData === false ? 0
|
||||||
: 5000; // bootstrap carousel default interval
|
: isNaN(intervalData) ? 5000 // bootstrap carousel default interval
|
||||||
|
: intervalData;
|
||||||
|
|
||||||
// bind, event targets
|
// bind, event targets
|
||||||
var self = this, index = element.index = 0, timer = element.timer = 0,
|
var self = this, index = element.index = 0, timer = element.timer = 0,
|
||||||
@ -592,8 +593,11 @@
|
|||||||
var activeItem = this.getActiveIndex(), // the current active
|
var activeItem = this.getActiveIndex(), // the current active
|
||||||
orientation;
|
orientation;
|
||||||
|
|
||||||
// determine slideDirection first
|
// first return if we're on the same item #227
|
||||||
if ( (activeItem < next ) || (activeItem === 0 && next === total -1 ) ) {
|
if ( activeItem === next ) {
|
||||||
|
return;
|
||||||
|
// or determine slideDirection
|
||||||
|
} else if ( (activeItem < next ) || (activeItem === 0 && next === total -1 ) ) {
|
||||||
slideDirection = self[direction] = left; // next
|
slideDirection = self[direction] = left; // next
|
||||||
} else if ( (activeItem > next) || (activeItem === total - 1 && next === 0 ) ) {
|
} else if ( (activeItem > next) || (activeItem === total - 1 && next === 0 ) ) {
|
||||||
slideDirection = self[direction] = right; // prev
|
slideDirection = self[direction] = right; // prev
|
||||||
|
44
dist/htdocs/js/bootstrap-native-v4.min.js
vendored
44
dist/htdocs/js/bootstrap-native-v4.min.js
vendored
File diff suppressed because one or more lines are too long
137
dist/htdocs/js/mympd.min.js
vendored
137
dist/htdocs/js/mympd.min.js
vendored
@ -10,7 +10,8 @@ scrollPos:0},Composer:{state:"0/-/",scrollPos:0},Performer:{state:"0/-/",scrollP
|
|||||||
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.panelHeadingBrowse=document.getElementById("panel-heading-browse").getElementsByTagName("a");domCache.panelHeadingBrowseLen=domCache.panelHeadingBrowse.length;domCache.counter=document.getElementById("counter");domCache.volumePrct=document.getElementById("volumePrct");domCache.volumeControl=document.getElementById("volumeControl");domCache.volumeIcon=document.getElementById("volumeIcon");domCache.btnsPlay=document.getElementsByClassName("btnPlay");domCache.btnsPlayLen=domCache.btnsPlay.length;
|
||||||
domCache.btnPrev=document.getElementById("btnPrev");domCache.btnNext=document.getElementById("btnNext");domCache.progressBar=document.getElementById("progressBar");domCache.volumeBar=document.getElementById("volumeBar");domCache.outputs=document.getElementById("outputs");domCache.btnAdd=document.getElementById("nav-add2homescreen");domCache.currentTrack=document.getElementById("currentTrack");domCache.currentArtist=document.getElementById("currentArtist");domCache.currentAlbum=document.getElementById("currentAlbum");
|
domCache.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");
|
domCache.currentCover=document.getElementById("currentCover");domCache.btnVoteUp=document.getElementById("btnVoteUp");domCache.btnVoteDown=document.getElementById("btnVoteDown");
|
||||||
var modalConnectionError=new Modal(document.getElementById("modalConnectionError"),{backdrop:"static",keyboard:!1}),modalSettings=new Modal(document.getElementById("modalSettings")),modalSavequeue=new Modal(document.getElementById("modalSaveQueue")),modalSongDetails=new Modal(document.getElementById("modalSongDetails")),modalAddToPlaylist=new Modal(document.getElementById("modalAddToPlaylist")),modalRenamePlaylist=new Modal(document.getElementById("modalRenamePlaylist")),modalUpdateDB=new Modal(document.getElementById("modalUpdateDB"));
|
var modalConnectionError=new Modal(document.getElementById("modalConnectionError"),{backdrop:"static",keyboard:!1}),modalSettings=new Modal(document.getElementById("modalSettings")),modalSavequeue=new Modal(document.getElementById("modalSaveQueue")),modalSongDetails=new Modal(document.getElementById("modalSongDetails")),modalAddToPlaylist=new Modal(document.getElementById("modalAddToPlaylist")),modalRenamePlaylist=new Modal(document.getElementById("modalRenamePlaylist")),modalUpdateDB=new Modal(document.getElementById("modalUpdateDB")),
|
||||||
|
modalSaveSmartPlaylist=new Modal(document.getElementById("modalSaveSmartPlaylist"));
|
||||||
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")}
|
||||||
@ -22,42 +23,44 @@ if("Playback"==app.current.app)sendAPI({cmd:"MPD_API_PLAYER_CURRENT_SONG"},songC
|
|||||||
"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")):
|
"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")):
|
||||||
(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?
|
(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?
|
||||||
(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+=
|
(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 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(),
|
'<li class="breadcrumb-item active">'+c[a]+"</li>";break}e+=c[a];b+='<li class="breadcrumb-item"><a data-uri="'+e+'">'+c[a]+"</a></li>";e+="/"}a=document.getElementById("BrowseBreadcrumb");a.innerHTML=b;b=a.getElementsByTagName("a");c=b.length;for(a=0;a<c;a++)b[a].addEventListener("click",function(){appGoto("Browse","Filesystem",void 0,"0/"+app.current.filter+"/"+this.getAttribute("data-uri"))},!1);doSetFilterLetter("BrowseFilesystemFilter")}else"Search"==app.current.app?(a=document.getElementById("searchstr"),
|
||||||
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",
|
a.focus(),""==a.value&&""!=app.current.search&&(a.value=app.current.search),app.last.app!=app.current.app&&""!=app.current.search&&(document.getElementById("SearchList").getElementsByTagName("tbody")[0].innerHTML='<tr><td><span class="material-icons">search</span></td><td colspan="5">Searching...</td></tr>'),2<=app.current.search.length?sendAPI({cmd:"MPD_API_DATABASE_SEARCH",data:{plist:"",offset:app.current.page,filter:app.current.filter,searchstr:app.current.search}},parseSearch):(document.getElementById("SearchList").getElementsByTagName("tbody")[0].innerHTML=
|
||||||
"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")}
|
"",document.getElementById("searchAddAllSongs").setAttribute("disabled","disabled"),document.getElementById("searchAddAllSongsBtn").setAttribute("disabled","disabled"),document.getElementById("panel-heading-search").innerText="",document.getElementById("SearchList").classList.remove("opacity05"),setPagination(0)),selectTag("searchtags","searchtagsdesc",app.current.filter)):appGoto("Playback");app.last.app=app.current.app;app.last.tab=app.current.tab;app.last.view=app.current.view}else appGoto("Playback")}
|
||||||
function appInit(){getSettings();sendAPI({cmd:"MPD_API_PLAYER_STATE"},parseState);webSocketConnect();domCache.volumeBar.value=0;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;document.getElementById("btnChVolumeDown").addEventListener("click",function(a){a.stopPropagation()},!1);document.getElementById("btnChVolumeUp").addEventListener("click",function(a){a.stopPropagation()},!1);domCache.volumeBar.addEventListener("click",function(a){a.stopPropagation()},!1);domCache.volumeBar.addEventListener("change",function(a){sendAPI({cmd:"MPD_API_PLAYER_VOLUME",
|
||||||
data:{songid:currentSong.currentSongId,seek:Math.ceil(domCache.progressBar.value/100*currentSong.totalTime)}})},!1);document.getElementById("navDBupdate").addEventListener("click",function(a){a.stopPropagation();a.preventDefault();a=this.getElementsByTagName("span")[0];a.innerText="keyboard_arrow_right"==a.innerText?"keyboard_arrow_down":"keyboard_arrow_right"},!1);document.getElementById("volumeIcon").parentNode.addEventListener("show.bs.dropdown",function(){sendAPI({cmd:"MPD_API_PLAYER_OUTPUT_LIST"},
|
data:{volume:domCache.volumeBar.value}})},!1);domCache.progressBar.value=0;domCache.progressBar.addEventListener("change",function(a){currentSong&&0<=currentSong.currentSongId&&sendAPI({cmd:"MPD_API_PLAYER_SEEK",data:{songid:currentSong.currentSongId,seek:Math.ceil(domCache.progressBar.value/100*currentSong.totalTime)}})},!1);document.getElementById("navDBupdate").addEventListener("click",function(a){a.stopPropagation();a.preventDefault();a=this.getElementsByTagName("span")[0];a.innerText="keyboard_arrow_right"==
|
||||||
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");
|
a.innerText?"keyboard_arrow_down":"keyboard_arrow_right"},!1);document.getElementById("volumeIcon").parentNode.addEventListener("show.bs.dropdown",function(){sendAPI({cmd:"MPD_API_PLAYER_OUTPUT_LIST"},parseOutputs)});document.getElementById("modalAbout").addEventListener("shown.bs.modal",function(){sendAPI({cmd:"MPD_API_DATABASE_STATS"},parseStats)});document.getElementById("modalUpdateDB").addEventListener("hidden.bs.modal",function(){document.getElementById("updateDBprogress").classList.remove("updateDBprogressAnimate")});
|
||||||
document.getElementById("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",
|
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");
|
||||||
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<
|
document.getElementById("inputMixrampdb").classList.remove("is-invalid");document.getElementById("inputMixrampdelay").classList.remove("is-invalid")});document.getElementById("selectJukeboxMode").addEventListener("change",function(){var a=this.options[this.selectedIndex].value;0==a||2==a?(document.getElementById("inputJukeboxQueueLength").setAttribute("disabled","disabled"),document.getElementById("selectJukeboxPlaylist").setAttribute("disabled","disabled")):1==a&&(document.getElementById("inputJukeboxQueueLength").removeAttribute("disabled"),
|
||||||
b;c++)a[c].classList.add("clickable"),a[c].addEventListener("click",function(a){a.preventDefault();a=JSON.parse(this.getAttribute("data-href"));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"))},
|
document.getElementById("selectJukeboxPlaylist").removeAttribute("disabled"))});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");
|
||||||
!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")}}):
|
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"));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");
|
||||||
"A"==a.target.nodeName&&showMenu(a.target,a)},!1);document.getElementById("BrowseFilesystemList").addEventListener("click",function(a){if("TD"==a.target.nodeName)switch(a.target.parentNode.getAttribute("data-type")){case "dir":appGoto("Browse","Filesystem",void 0,"0/"+app.current.filter+"/"+decodeURI(a.target.parentNode.getAttribute("data-uri")));break;case "song":appendQueue("song",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name"));break;case "plist":appendQueue("plist",
|
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",
|
||||||
decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name"))}else"A"==a.target.nodeName&&showMenu(a.target,a)},!1);document.getElementById("BrowsePlaylistsAllList").addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("plist",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&showMenu(a.target,a)},!1);document.getElementById("BrowsePlaylistsDetailList").addEventListener("click",
|
function(a){"TD"==a.target.nodeName?sendAPI({cmd:"MPD_API_PLAYER_PLAY_TRACK",data:{track:a.target.parentNode.getAttribute("data-trackid")}}):"A"==a.target.nodeName&&showMenu(a.target,a)},!1);document.getElementById("BrowseFilesystemList").addEventListener("click",function(a){if("TD"==a.target.nodeName)switch(a.target.parentNode.getAttribute("data-type")){case "dir":appGoto("Browse","Filesystem",void 0,"0/"+app.current.filter+"/"+decodeURI(a.target.parentNode.getAttribute("data-uri")));break;case "song":appendQueue("song",
|
||||||
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",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"==
|
decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name"));break;case "plist":appendQueue("plist",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name"))}else"A"==a.target.nodeName&&showMenu(a.target,a)},!1);document.getElementById("BrowsePlaylistsAllList").addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("plist",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):
|
||||||
a.target.nodeName?appendQueue("song",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&showMenu(a.target,a)},!1);document.getElementById("BrowseFilesystemAddAllSongsDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&("Add all to queue"==a.target.innerText?addAllFromBrowse():"Add all to playlist"==a.target.innerText&&showAddToPlaylist(app.current.search))},!1);document.getElementById("searchAddAllSongsDropdown").addEventListener("click",
|
"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",function(a){"TD"==a.target.nodeName&&appGoto("Browse","Database",app.current.view,"0/-/"+a.target.parentNode.getAttribute("data-uri"))},
|
||||||
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",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",
|
!1);document.getElementById("SearchList").addEventListener("click",function(a){"TD"==a.target.nodeName?appendQueue("song",decodeURI(a.target.parentNode.getAttribute("data-uri")),a.target.parentNode.getAttribute("data-name")):"A"==a.target.nodeName&&showMenu(a.target,a)},!1);document.getElementById("BrowseFilesystemAddAllSongsDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&("Add all to queue"==a.target.innerText?addAllFromBrowse():"Add all to playlist"==a.target.innerText&&
|
||||||
function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,"0/"+a.target.getAttribute("data-tag")+"/"+app.current.search)},!1);document.getElementById("searchqueuestr").addEventListener("keyup",function(a){appGoto(app.current.app,app.current.tab,app.current.view,"0/"+app.current.filter+"/"+this.value)},!1);document.getElementById("searchqueuetag").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,
|
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"):"Save as smart playlist"==a.target.innerText&&saveSearchAsSmartPlaylist())},!1);document.getElementById("BrowseDatabaseAddAllSongsDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&
|
||||||
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);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"==
|
("Add all to queue"==a.target.innerText?addAllFromBrowseDatabasePlist("queue"):"Add all to playlist"==a.target.innerText&&showAddToPlaylist("DATABASE"))},!1);document.getElementById("searchtags").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,"0/"+a.target.getAttribute("data-tag")+"/"+app.current.search)},!1);document.getElementById("searchqueuestr").addEventListener("keyup",function(a){appGoto(app.current.app,app.current.tab,
|
||||||
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");for(var b=0;b<a.length;b++)a[b].remove()},!1);dragAndDropTable("QueueList");dragAndDropTable("BrowsePlaylistsDetailList");window.addEventListener("hashchange",appRoute,!1);window.addEventListener("focus",function(){sendAPI({cmd:"MPD_API_PLAYER_STATE"},
|
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);document.getElementById("searchstr").addEventListener("keyup",
|
||||||
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",{scope:"/"}).then(function(a){console.log("ServiceWorker registration successful with scope: ",a.scope);a.update()},function(a){console.log("ServiceWorker registration failed: ",
|
function(a){appGoto("Search",void 0,void 0,"0/"+app.current.filter+"/"+this.value)},!1);document.getElementById("BrowseDatabaseByTagDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,a.target.getAttribute("data-tag"),"0/"+app.current.filter+"/"+app.current.search)},!1);document.getElementsByTagName("body")[0].addEventListener("click",function(a){hideMenu()},!1);dragAndDropTable("QueueList");dragAndDropTable("BrowsePlaylistsDetailList");
|
||||||
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");
|
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",
|
||||||
deferredPrompt=null})});window.addEventListener("appinstalled",function(a){console.log("myMPD installed as app")})}
|
{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"),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");
|
b.nodeName&&b.classList.remove("dragover")},!1);b.addEventListener("dragover",function(a){a.preventDefault();for(var c=b.getElementsByClassName("dragover"),e=c.length,f=0;f<e;f++)c[f].classList.remove("dragover");c=a.target;"TD"==a.target.nodeName&&(c=a.target.parentNode);"TR"==c.nodeName&&c.classList.add("dragover");a.dataTransfer.dropEffect="move"},!1);b.addEventListener("dragend",function(a){for(var c=b.getElementsByClassName("dragover"),e=c.length,f=0;f<e;f++)c[f].classList.remove("dragover");
|
||||||
document.getElementById(a.dataTransfer.getData("Text"))&&document.getElementById(a.dataTransfer.getData("Text")).classList.remove("opacity05")},!1);b.addEventListener("drop",function(c){c.stopPropagation();c.preventDefault();var d=c.target;"TD"==c.target.nodeName&&(d=c.target.parentNode);var e=document.getElementById(c.dataTransfer.getData("Text")).getAttribute("data-songpos"),f=d.getAttribute("data-songpos");document.getElementById(c.dataTransfer.getData("Text")).remove();dragEl.classList.remove("opacity05");
|
document.getElementById(a.dataTransfer.getData("Text"))&&document.getElementById(a.dataTransfer.getData("Text")).classList.remove("opacity05")},!1);b.addEventListener("drop",function(c){c.stopPropagation();c.preventDefault();var d=c.target;"TD"==c.target.nodeName&&(d=c.target.parentNode);var e=document.getElementById(c.dataTransfer.getData("Text")).getAttribute("data-songpos"),f=d.getAttribute("data-songpos");document.getElementById(c.dataTransfer.getData("Text")).remove();dragEl.classList.remove("opacity05");
|
||||||
b.insertBefore(dragEl,d);c=b.getElementsByClassName("dragover");d=c.length;for(var g=0;g<d;g++)c[g].classList.remove("dragover");document.getElementById(a).classList.add("opacity05");"Queue"==app.current.app?sendAPI({cmd:"MPD_API_QUEUE_MOVE_TRACK",data:{from:e,to:f}}):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view&&playlistMoveTrack(e,f)},!1)}
|
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(){var a=getWsUrl();socket=new WebSocket(a);try{socket.onopen=function(){console.log("connected");showNotification("Connected to myMPD: "+a,"","","success");modalConnectionError.hide();appRoute();sendAPI({cmd:"MPD_API_PLAYER_STATE"},parseState)},socket.onmessage=function(b){if(b.data!==lastState&&0!=b.data.length){try{var c=JSON.parse(b.data)}catch(d){console.log("Invalid JSON data received: "+b.data)}switch(c.type){case "update_state":parseState(c);break;case "disconnected":showNotification("Lost connection to myMPD: "+
|
||||||
"","","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();
|
a,"","","danger");break;case "update_queue":"Queue"===app.current.app&&getQueue();sendAPI({cmd:"MPD_API_PLAYER_STATE"},parseState);break;case "update_options":getSettings();break;case "update_outputs":sendAPI({cmd:"MPD_API_PLAYER_OUTPUT_LIST"},parseOutputs);break;case "update_started":updateDBstarted(!1);break;case "update_database":case "update_finished":updateDBfinished(c.type);break;case "error":showNotification(c.data,"","","danger")}}},socket.onclose=function(){console.log("disconnected");modalConnectionError.show();
|
||||||
setTimeout(function(){console.log("reconnect");webSocketConnect()},3E3)}}catch(a){alert("Error: "+a)}}function getWsUrl(){var a=document.URL;if("https"==a.substring(0,5)){var b="wss://";a=a.substr(8)}else b="ws://","http"==a.substring(0,4)&&(a=a.substr(7));a=a.split("#");var c=/\/$/.test(a[0])?"":"/";return b+a[0]+c+"ws"}
|
setTimeout(function(){console.log("reconnect");webSocketConnect()},3E3)}}catch(b){alert("Error: "+b)}}function getWsUrl(){var a=window.location.hostname,b=window.location.protocol,c=window.location.port;a=("https:"==b?"wss://":"ws://")+a+(""!=c?":"+c:"")+"/ws";return document.getElementById("wsUrl").innerText=a}
|
||||||
function parseStats(a){document.getElementById("mpdstats_artists").innerText=a.data.artists;document.getElementById("mpdstats_albums").innerText=a.data.albums;document.getElementById("mpdstats_songs").innerText=a.data.songs;document.getElementById("mpdstats_dbPlaytime").innerText=beautifyDuration(a.data.dbPlaytime);document.getElementById("mpdstats_playtime").innerText=beautifyDuration(a.data.playtime);document.getElementById("mpdstats_uptime").innerText=beautifyDuration(a.data.uptime);var b=new Date(1E3*
|
function parseStats(a){document.getElementById("mpdstats_artists").innerText=a.data.artists;document.getElementById("mpdstats_albums").innerText=a.data.albums;document.getElementById("mpdstats_songs").innerText=a.data.songs;document.getElementById("mpdstats_dbPlaytime").innerText=beautifyDuration(a.data.dbPlaytime);document.getElementById("mpdstats_playtime").innerText=beautifyDuration(a.data.playtime);document.getElementById("mpdstats_uptime").innerText=beautifyDuration(a.data.uptime);var b=new Date(1E3*
|
||||||
a.data.dbUpdated);document.getElementById("mpdstats_dbUpdated").innerText=b.toUTCString();document.getElementById("mympdVersion").innerText=a.data.mympdVersion;document.getElementById("mpdVersion").innerText=a.data.mpdVersion}function toggleBtn(a,b){if(a=document.getElementById(a))void 0==b&&(b=a.classList.contains("active")?0:1),1==b||1==b?a.classList.add("active"):a.classList.remove("active")}
|
a.data.dbUpdated);document.getElementById("mpdstats_dbUpdated").innerText=b.toUTCString();document.getElementById("mympdVersion").innerText=a.data.mympdVersion;document.getElementById("mpdVersion").innerText=a.data.mpdVersion}function toggleBtn(a,b){if(a=document.getElementById(a))void 0==b&&(b=a.classList.contains("active")?0:1),1==b||1==b?a.classList.add("active"):a.classList.remove("active")}
|
||||||
function parseSettings(a){toggleBtn("btnRandom",a.data.random);toggleBtn("btnConsume",a.data.consume);toggleBtn("btnSingle",a.data.single);toggleBtn("btnRepeat",a.data.repeat);toggleBtn("btnJukebox",a.data.jukeboxMode);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);var c=document.getElementsByClassName("stickers"),d=c.length,
|
||||||
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;playlistEl="jukeboxPlaylist";sendAPI({cmd:"MPD_API_PLAYLIST_LIST",data:{offset:0,filter:"-"}},getAllPlaylists);settings.mpdstream="http://";settings.mpdstream="127.0.0.1"==settings.mpdhost||"localhost"==settings.mpdhost?settings.mpdstream+window.location.hostname:
|
e=1==a.data.stickers?"":"none";for(b=0;b<d;b++)c[b].style.display=e;c=document.getElementsByClassName("smartpls");d=c.length;e=1==a.data.smartpls?"":"none";for(b=0;b<d;b++)c[b].style.display=e;1==a.data.mixramp?document.getElementsByClassName("mixramp")[0].style.display="":document.getElementsByClassName("mixramp")[0].style.display="none";document.getElementById("selectJukeboxMode").value=a.data.jukeboxMode;document.getElementById("inputJukeboxQueueLength").value=a.data.jukeboxQueueLength;0==a.data.jukeboxMode||
|
||||||
settings.mpdstream+settings.mpdhost;settings.mpdstream+=":"+settings.streamport+"/";addTagList("BrowseDatabaseByTagDropdown",!1);addTagList("searchqueuetag",!0);addTagList("searchtags",!0)}function getSettings(){sendAPI({cmd:"MPD_API_SETTINGS_GET"},parseSettings)}
|
2==a.data.jukeboxMode?(document.getElementById("inputJukeboxQueueLength").setAttribute("disabled","disabled"),document.getElementById("selectJukeboxPlaylist").setAttribute("disabled","disabled")):1==a.data.jukeboxMode&&(document.getElementById("inputJukeboxQueueLength").removeAttribute("disabled"),document.getElementById("selectJukeboxPlaylist").removeAttribute("disabled"));settings=a.data;playlistEl="selectJukeboxPlaylist";sendAPI({cmd:"MPD_API_PLAYLIST_LIST",data:{offset:0,filter:"-"}},getAllPlaylists);
|
||||||
|
settings.mpdstream="http://";settings.mpdstream="127.0.0.1"==settings.mpdhost||"localhost"==settings.mpdhost?settings.mpdstream+window.location.hostname:settings.mpdstream+settings.mpdhost;settings.mpdstream+=":"+settings.streamport+"/";addTagList("BrowseDatabaseByTagDropdown",!1);addTagList("searchqueuetag",!0);addTagList("searchtags",!0)}function getSettings(){sendAPI({cmd:"MPD_API_SETTINGS_GET"},parseSettings)}
|
||||||
function parseOutputs(a){for(var b="",c=a.data.outputs.length,d=0;d<c;d++)b+='<button id="btnOutput'+a.data.outputs[d].id+'" data-output-id="'+a.data.outputs[d].id+'" class="btn btn-secondary btn-block',1==a.data.outputs[d].state&&(b+=" active"),b+='"><span class="material-icons float-left">volume_up</span> '+a.data.outputs[d].name+"</button>";domCache.outputs.innerHTML=b}
|
function parseOutputs(a){for(var b="",c=a.data.outputs.length,d=0;d<c;d++)b+='<button id="btnOutput'+a.data.outputs[d].id+'" data-output-id="'+a.data.outputs[d].id+'" class="btn btn-secondary btn-block',1==a.data.outputs[d].state&&(b+=" active"),b+='"><span class="material-icons float-left">volume_up</span> '+a.data.outputs[d].name+"</button>";domCache.outputs.innerHTML=b}
|
||||||
function setCounter(a,b,c){currentSong.totalTime=b;currentSong.elapsedTime=c;currentSong.currentSongId=a;var d=Math.floor(b/60),e=b-60*d,f=Math.floor(c/60),g=c-60*f;domCache.progressBar.value=Math.floor(100*c/b);b=f+":"+(10>g?"0":"")+g+" / "+d+":"+(10>e?"0":"")+e;domCache.counter.innerText=b;lastState&&(c=document.getElementById("queueTrackId"+lastState.data.currentSongId))&&(d=c.getElementsByTagName("td"),d[4].innerText=c.getAttribute("data-duration"),d[0].classList.remove("material-icons"),d[0].innerText=
|
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))}
|
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))}
|
||||||
@ -65,21 +68,22 @@ function parseState(a){if(JSON.stringify(a)!==JSON.stringify(lastState)){if(1==a
|
|||||||
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.btnNext.removeAttribute("disabled");0>=a.data.songPos?domCache.btnPrev.setAttribute("disabled","disabled"):domCache.btnPrev.removeAttribute("disabled");if(0==a.data.queueLength)for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].setAttribute("disabled","disabled");else for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].removeAttribute("disabled");-1==a.data.volume?(domCache.volumePrct.innerText="Volumecontrol disabled",domCache.volumeControl.classList.add("hide")):(domCache.volumeControl.classList.remove("hide"),
|
||||||
domCache.volumePrct.innerText=a.data.volume+" %",domCache.volumeIcon.innerText=0==a.data.volume?"volume_off":50>a.data.volume?"volume_down":"volume_up");domCache.volumeBar.value=a.data.volume;setCounter(a.data.currentSongId,a.data.totalTime,a.data.elapsedTime);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=
|
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}}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)}
|
"");lastState=a}}function getQueue(){2<=app.current.search.length?sendAPI({cmd:"MPD_API_QUEUE_SEARCH",data:{filter:app.current.filter,offset:app.current.page,searchstr:app.current.search}},parseQueue):sendAPI({cmd:"MPD_API_QUEUE_LIST",data:{offset:app.current.page}},parseQueue)}
|
||||||
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+" "+(1<a.totalEntities?"Songs":"Song")+" \u2013 "+beautifyDuration(a.totalTime):0<a.totalEntities?document.getElementById("panel-heading-queue").innerText=a.totalEntities+" "+(1<a.totalEntities?"Songs":"Song"):document.getElementById("panel-heading-queue").innerText="";var b=a.data.length,c=document.getElementById(app.current.app+
|
||||||
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",
|
"List");c.setAttribute("data-version",a.queueVersion);c=c.getElementsByTagName("tbody")[0];for(var d=c.getElementsByTagName("tr"),e=0;e<b;e++)if(!d[e]||d[e].getAttribute("data-trackid")!=a.data[e].id||d[e].getAttribute("data-songpos")!=a.data[e].pos+1){var f=Math.floor(a.data[e].duration/60),g=a.data[e].duration-60*f;f=f+":"+(10>g?"0":"")+g;g=document.createElement("tr");g.setAttribute("draggable","true");g.setAttribute("data-trackid",a.data[e].id);g.setAttribute("id","queueTrackId"+a.data[e].id);
|
||||||
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>':
|
g.setAttribute("data-songpos",a.data[e].pos+1);g.setAttribute("data-duration",f);g.setAttribute("data-uri",a.data[e].uri);g.innerHTML="<td>"+(a.data[e].pos+1)+"</td><td>"+a.data[e].title+"</td><td>"+a.data[e].artist+"</td><td>"+a.data[e].album+"</td><td>"+f+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';e<d.length?d[e].replaceWith(g):c.append(g)}for(e=d.length-1;e>=b;e--)d[e].remove();"queuesearch"==a.type&&0==b?c.innerHTML='<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">No results, please refine your search!</td></tr>':
|
||||||
"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],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",
|
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[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>';
|
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[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?"":
|
break;case "smartpls":case "plist":g.innerHTML='<td><span class="material-icons">list</span></td><td colspan="4">'+a.data[e].name+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>'}e<d.length?d[e].replaceWith(g):c.append(g)}}for(e=d.length-1;e>=b;e--)d[e].remove();setPagination(a.totalEntities);0==b&&(c.innerHTML='<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">No results</td></tr>');document.getElementById(app.current.app+(void 0==app.current.tab?
|
||||||
app.current.tab)+"List").classList.remove("opacity05")}}
|
"":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(".")||1==a.smartpls?(document.getElementById("BrowsePlaylistsDetailList").setAttribute("data-ro",
|
||||||
"true"),document.getElementById("btnPlaylistClear").parentNode.classList.add("hide")):(document.getElementById("BrowsePlaylistsDetailList").setAttribute("data-ro","false"),document.getElementById("btnPlaylistClear").parentNode.classList.remove("hide")),document.getElementById("BrowsePlaylistsDetailList").setAttribute("data-uri",a.uri),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),1==a.smartpls?document.getElementById("BrowsePlaylistsDetailList").getElementsByTagName("caption")[0].innerText="Smart playlist: "+a.uri:document.getElementById("BrowsePlaylistsDetailList").getElementsByTagName("caption")[0].innerText=
|
||||||
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");
|
"Playlist: "+a.uri,document.getElementById("BrowsePlaylistsDetailList").classList.remove("hide"),document.getElementById("BrowsePlaylistsAllList").classList.add("hide"),document.getElementById("btnBrowsePlaylistsAll").parentNode.classList.remove("hide"));var b=a.data.length,c=document.getElementById(app.current.app+app.current.tab+app.current.view+"List").getElementsByTagName("tbody")[0],d=c.getElementsByTagName("tr");if("All"==app.current.view)for(var e=0;e<b;e++){var f=encodeURI(a.data[e].uri);
|
||||||
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")!=
|
if(!d[e]||d[e].getAttribute("data-uri")!=f){var g=new Date(1E3*a.data[e].last_modified),h=document.createElement("tr");h.setAttribute("data-uri",f);h.setAttribute("data-type",a.data[e].type);h.setAttribute("data-name",a.data[e].name);h.innerHTML='<td><span class="material-icons">list</span></td><td>'+a.data[e].name+"</td><td>"+g.toUTCString()+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';e<d.length?d[e].replaceWith(h):c.append(h)}}else if("Detail"==app.current.view)for(e=
|
||||||
"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>';
|
0;e<b;e++)if(f=encodeURI(a.data[e].uri),g=a.offset+e+1,!d[e]||d[e].getAttribute("data-uri")!=f||d[e].getAttribute("id")!="playlistTrackId"+g){h=document.createElement("tr");0==a.smartpls&&h.setAttribute("draggable","true");h.setAttribute("id","playlistTrackId"+g);h.setAttribute("data-type",a.data[e].type);h.setAttribute("data-uri",f);h.setAttribute("data-name",a.data[e].name);h.setAttribute("data-songpos",g);f=Math.floor(a.data[e].duration/60);var k=a.data[e].duration-60*f;h.innerHTML="<td>"+g+"</td><td>"+
|
||||||
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")}}
|
a.data[e].title+"</td><td>"+a.data[e].artist+"</td><td>"+a.data[e].album+"</td><td>"+f+":"+(10>k?"0":"")+k+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';e<d.length?d[e].replaceWith(h):c.append(h)}for(e=d.length-1;e>=b;e--)d[e].remove();setPagination(a.totalEntities);0==b&&(c.innerHTML="All"==app.current.view?'<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">No playlists found.</td></tr>':'<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">Empty playlist.</td></tr>');
|
||||||
|
document.getElementById(app.current.app+app.current.tab+app.current.view+"List").classList.remove("opacity05")}}
|
||||||
function parseListDBtags(a){if(""!=app.current.search){document.getElementById("BrowseDatabaseAlbumList").classList.remove("hide");document.getElementById("BrowseDatabaseTagList").classList.add("hide");document.getElementById("btnBrowseDatabaseByTag").parentNode.classList.add("hide");document.getElementById("btnBrowseDatabaseTag").parentNode.classList.remove("hide");document.getElementById("BrowseDatabaseAddAllSongs").parentNode.parentNode.classList.remove("hide");document.getElementById("btnBrowseDatabaseTag").innerHTML=
|
function parseListDBtags(a){if(""!=app.current.search){document.getElementById("BrowseDatabaseAlbumList").classList.remove("hide");document.getElementById("BrowseDatabaseTagList").classList.add("hide");document.getElementById("btnBrowseDatabaseByTag").parentNode.classList.add("hide");document.getElementById("btnBrowseDatabaseTag").parentNode.classList.remove("hide");document.getElementById("BrowseDatabaseAddAllSongs").parentNode.parentNode.classList.remove("hide");document.getElementById("btnBrowseDatabaseTag").innerHTML=
|
||||||
"« "+app.current.view;document.getElementById("BrowseDatabaseAlbumListCaption").innerText=a.searchtagtype+": "+a.searchstr;for(var b=a.data.length,c=document.getElementById("BrowseDatabaseAlbumList"),d=c.getElementsByClassName("col-md"),e=0;e<b;e++){var f=genId(a.data[e].value);if(!d[e]||d[e].getAttribute("id")!=f){var g=document.createElement("div");g.classList.add("col-md");g.classList.add("mr-0");g.setAttribute("id",f);g.innerHTML='<div class="card mb-4" id="card'+f+'"> <a href="#" class="card-img-top"><img class="card-img-top" src="" ></a> <div class="card-body"> <h5 class="card-title" id="albumartist'+
|
"« "+app.current.view;document.getElementById("BrowseDatabaseAlbumListCaption").innerText=a.searchtagtype+": "+a.searchstr;for(var b=a.data.length,c=document.getElementById("BrowseDatabaseAlbumList"),d=c.getElementsByClassName("col-md"),e=0;e<b;e++){var f=genId(a.data[e].value);if(!d[e]||d[e].getAttribute("id")!=f){var g=document.createElement("div");g.classList.add("col-md");g.classList.add("mr-0");g.setAttribute("id",f);g.innerHTML='<div class="card mb-4" id="card'+f+'"> <a href="#" class="card-img-top"><img class="card-img-top" src="" ></a> <div class="card-body"> <h5 class="card-title" id="albumartist'+
|
||||||
f+'"></h5> <h4 class="card-title">'+a.data[e].value+'</h4> <table class="table table-sm table-hover" id="tbl'+f+'"><tbody></tbody></table </div></div>';e<d.length?d[e].replaceWith(g):c.append(g);sendAPI({cmd:"MPD_API_DATABASE_TAG_ALBUM_TITLE_LIST",data:{album:a.data[e].value,search:app.current.search,tag:app.current.view}},parseListTitles)}}for(e=d.length-1;e>=b;e--)d[e].remove();setPagination(a.totalEntities);document.getElementById("BrowseDatabaseAlbumList").classList.remove("opacity05")}else{document.getElementById("BrowseDatabaseAlbumList").classList.add("hide");
|
f+'"></h5> <h4 class="card-title">'+a.data[e].value+'</h4> <table class="table table-sm table-hover" id="tbl'+f+'"><tbody></tbody></table </div></div>';e<d.length?d[e].replaceWith(g):c.append(g);sendAPI({cmd:"MPD_API_DATABASE_TAG_ALBUM_TITLE_LIST",data:{album:a.data[e].value,search:app.current.search,tag:app.current.view}},parseListTitles)}}for(e=d.length-1;e>=b;e--)d[e].remove();setPagination(a.totalEntities);document.getElementById("BrowseDatabaseAlbumList").classList.remove("opacity05")}else{document.getElementById("BrowseDatabaseAlbumList").classList.add("hide");
|
||||||
@ -95,45 +99,56 @@ function replaceQueue(a,b,c){switch(a){case "song":case "dir":sendAPI({cmd:"MPD_
|
|||||||
function artistClick(){var a=domCache.currentArtist.getAttribute("data-albumartist");""!=a&&appGoto("Browse","Database","AlbumArtist","0/-/"+a)}function albumClick(){var a=domCache.currentAlbum.getAttribute("data-album");""!=a&&appGoto("Browse","Database","Album","0/-/"+a)}function songDetails(a){sendAPI({cmd:"MPD_API_DATABASE_SONGDETAILS",data:{uri:a}},parseSongDetails);modalSongDetails.show()}
|
function 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;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+
|
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+
|
||||||
'">'+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*a.data.lastPlayed)).toUTCString())+"</td></tr><tr><th>Like</th><td>"+
|
'">'+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*a.data.lastPlayed)).toUTCString())+"</td></tr><tr><th>Like</th><td>"+
|
||||||
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)}
|
f+"</td></tr>"}b.getElementsByTagName("tbody")[0].innerHTML=c}function playlistDetails(a){document.getElementById("BrowsePlaylistsAllList").classList.add("opacity05");appGoto("Browse","Playlists","Detail","0/-/"+a)}
|
||||||
|
function removeFromPlaylist(a,b){b--;sendAPI({cmd:"MPD_API_PLAYLIST_RM_TRACK",data:{uri:a,track:b}});document.getElementById("BrowsePlaylistsDetailList").classList.add("opacity05");sendAPI({cmd:"MPD_API_PLAYLIST_CONTENT_LIST",data:{offset:app.current.page,filter:app.current.filter,uri:app.current.search}},parsePlaylists)}
|
||||||
function playlistClear(){var a=document.getElementById("BrowsePlaylistsDetailList").getAttribute("data-uri");sendAPI({cmd:"MPD_API_PLAYLIST_CLEAR",data:{uri:a}});document.getElementById("BrowsePlaylistsDetailList").classList.add("opacity05");sendAPI({cmd:"MPD_API_PLAYLIST_CONTENT_LIST",data:{offset:app.current.page,filter:app.current.filter,uri:app.current.search}},parsePlaylists)}
|
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){var b=a.data.length,c="";0==a.offset&&("addToPlaylistPlaylist"==playlistEl?c="<option></option><option>New Playlist</option>":"jukeboxPlaylist"==playlistEl&&(c="<option>Database</option>"));for(var d=0;d<b;d++)c+="<option","jukeboxPlaylist"==playlistEl&&a.data[d].uri==settings.jukeboxPlaylist&&(c+=" selected"),c+=">"+a.data[d].uri+"</option>";0==a.offset?document.getElementById(playlistEl).innerHTML=c:document.getElementById(playlistEl).innerHTML+=c;a.totalEntities>a.returnedEntities&&
|
function getAllPlaylists(a){var b=a.data.length,c="";0==a.offset&&("addToPlaylistPlaylist"==playlistEl?c="<option></option><option>New Playlist</option>":"selectJukeboxPlaylist"==playlistEl&&(c="<option>Database</option>"));for(var d=0;d<b;d++)c+="<option","selectJukeboxPlaylist"==playlistEl&&a.data[d].uri==settings.jukeboxPlaylist&&(c+=" selected"),c+=">"+a.data[d].uri+"</option>";0==a.offset?document.getElementById(playlistEl).innerHTML=c:document.getElementById(playlistEl).innerHTML+=c;a.totalEntities>
|
||||||
(a.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))}
|
a.returnedEntities&&(a.offset+=settings.maxElementsPerPage,sendAPI({cmd:"MPD_API_PLAYLIST_LIST",data:{offset:a.offset,filter:"-"}},getAllPlaylists))}function updateSmartPlaylists(){sendAPI({cmd:"MPD_API_SMARTPLS_UPDATE_ALL"})}
|
||||||
|
function voteSong(a){var b=domCache.currentTrack.getAttribute("data-uri");""!=b&&(2==a&&domCache.btnVoteUp.classList.contains("active-fg-green")?a=1:0==a&&domCache.btnVoteDown.classList.contains("active-fg-red")&&(a=1),sendAPI({cmd:"MPD_API_LIKE",data:{uri:b,like:a}}),setVoteSongBtns(a,b))}
|
||||||
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"))}
|
||||||
function toggleAddToPlaylistFrm(){var a=document.getElementById("toggleAddToPlaylistBtn");toggleBtn("toggleAddToPlaylistBtn");a.classList.contains("active")?(document.getElementById("addToPlaylistFrm").classList.remove("hide"),document.getElementById("addStreamFooter").classList.add("hide"),document.getElementById("addToPlaylistFooter").classList.remove("hide")):(document.getElementById("addToPlaylistFrm").classList.add("hide"),document.getElementById("addStreamFooter").classList.remove("hide"),document.getElementById("addToPlaylistFooter").classList.add("hide"))}
|
function toggleAddToPlaylistFrm(){var a=document.getElementById("toggleAddToPlaylistBtn");toggleBtn("toggleAddToPlaylistBtn");a.classList.contains("active")?(document.getElementById("addToPlaylistFrm").classList.remove("hide"),document.getElementById("addStreamFooter").classList.add("hide"),document.getElementById("addToPlaylistFooter").classList.remove("hide")):(document.getElementById("addToPlaylistFrm").classList.add("hide"),document.getElementById("addStreamFooter").classList.remove("hide"),document.getElementById("addToPlaylistFooter").classList.add("hide"))}
|
||||||
|
function saveSearchAsSmartPlaylist(){parseSmartPlaylist({type:"smartpls",data:{playlist:"",type:"search",tag:app.current.filter,searchstr:app.current.search}})}
|
||||||
|
function parseSmartPlaylist(a){var b=document.getElementById("saveSmartPlaylistName");b.value=a.data.playlist;b.classList.remove("is-invalid");document.getElementById("saveSmartPlaylistType").value=a.data.type;document.getElementById("saveSmartPlaylistFrm").classList.remove("was-validated");document.getElementById("saveSmartPlaylistSearch").classList.add("hide");document.getElementById("saveSmartPlaylistSticker").classList.add("hide");document.getElementById("saveSmartPlaylistNewest").classList.add("hide");
|
||||||
|
var c='<option value="any">Any Tag</option>',d;for(d in settings.tags)1==settings.tags[d]&&"Track"!=d&&(c+='<option value="'+d+'">'+d+"</option>");document.getElementById("selectSaveSmartPlaylistTag").innerHTML=c;"search"==a.data.type?(document.getElementById("saveSmartPlaylistSearch").classList.remove("hide"),document.getElementById("selectSaveSmartPlaylistTag").value=a.data.tag,document.getElementById("inputSaveSmartPlaylistSearchstr").value=a.data.searchstr):"sticker"==a.data.type?(document.getElementById("saveSmartPlaylistSticker").classList.remove("hide"),
|
||||||
|
document.getElementById("selectSaveSmartPlaylistSticker").value=a.data.sticker,document.getElementById("inputSaveSmartPlaylistStickerMaxentries").value=a.data.maxentries):"newest"==a.data.type&&(document.getElementById("saveSmartPlaylistNewest").classList.remove("hide"),c=a.data.timerange/24/60/60,document.getElementById("inputSaveSmartPlaylistNewestTimerange").value=c,document.getElementById("inputSaveSmartPlaylistNewestMaxentries").value=a.data.maxentries);modalSaveSmartPlaylist.show();b.focus()}
|
||||||
|
function chkInt(a,b){if(""!=a.value.replace(/\d/g,""))return a.classList.add("is-invalid"),b.classList.add("was-validated"),!1;a.classList.remove("is-invalid");return!0}
|
||||||
|
function saveSmartPlaylist(){var a=document.getElementById("saveSmartPlaylistName").value,b=document.getElementById("saveSmartPlaylistType").value,c=a.replace(/[\w\-]/g,""),d=document.getElementById("saveSmartPlaylistFrm");if(""!=a&&""==c){if("search"==b)d=document.getElementById("selectSaveSmartPlaylistTag"),d=d.options[d.selectedIndex].value,c=document.getElementById("inputSaveSmartPlaylistSearchstr").value,sendAPI({cmd:"MPD_API_SMARTPLS_SAVE",data:{type:b,playlist:a,tag:d,searchstr:c}});else if("sticker"==
|
||||||
|
b){c=document.getElementById("selectSaveSmartPlaylistSticker");c=c.options[c.selectedIndex].value;var e=document.getElementById("inputSaveSmartPlaylistStickerMaxentries");if(!chkInt(e,d))return;d=e.value;sendAPI({cmd:"MPD_API_SMARTPLS_SAVE",data:{type:b,playlist:a,sticker:c,maxentries:d}})}else if("newest"==b){c=document.getElementById("inputSaveSmartPlaylistNewestTimerange");if(!chkInt(c,d))return;c=86400*parseInt(c.value);e=document.getElementById("inputSaveSmartPlaylistNewestMaxentries");if(!chkInt(e,
|
||||||
|
d))return;d=e.value;sendAPI({cmd:"MPD_API_SMARTPLS_SAVE",data:{type:b,playlist:a,timerange:c,maxentries:d}})}else{document.getElementById("saveSmartPlaylistType").classList.add("is-invalid");return}modalSaveSmartPlaylist.hide();showNotification("Saved smart playlist "+a,"","","success")}else document.getElementById("saveSmartPlaylistName").classList.add("is-invalid"),d.classList.add("was-validated")}
|
||||||
function showAddToPlaylist(a){document.getElementById("addToPlaylistUri").value=a;document.getElementById("addToPlaylistPlaylist").innerHTML="";document.getElementById("addToPlaylistNewPlaylist").value="";document.getElementById("addToPlaylistNewPlaylistDiv").classList.add("hide");document.getElementById("addToPlaylistFrm").classList.remove("was-validated");document.getElementById("addToPlaylistNewPlaylist").classList.remove("is-invalid");toggleBtn("toggleAddToPlaylistBtn",0);var b=document.getElementById("streamUrl");
|
function showAddToPlaylist(a){document.getElementById("addToPlaylistUri").value=a;document.getElementById("addToPlaylistPlaylist").innerHTML="";document.getElementById("addToPlaylistNewPlaylist").value="";document.getElementById("addToPlaylistNewPlaylistDiv").classList.add("hide");document.getElementById("addToPlaylistFrm").classList.remove("was-validated");document.getElementById("addToPlaylistNewPlaylist").classList.remove("is-invalid");toggleBtn("toggleAddToPlaylistBtn",0);var b=document.getElementById("streamUrl");
|
||||||
b.focus();b.value="";b.classList.remove("is-invalid");document.getElementById("addStreamFrm").classList.remove("was-validated");"stream"!=a?(document.getElementById("addStreamFooter").classList.add("hide"),document.getElementById("addStreamFrm").classList.add("hide"),document.getElementById("addToPlaylistFooter").classList.remove("hide"),document.getElementById("addToPlaylistFrm").classList.remove("hide"),document.getElementById("addToPlaylistLabel").innerText="Add to playlist"):(document.getElementById("addStreamFooter").classList.remove("hide"),
|
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();playlistEl="addToPlaylistPlaylist";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();playlistEl="addToPlaylistPlaylist";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?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"))}
|
"");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 dirname(a){return a.replace(/\/[^\/]*$/,"")}function addMenuItem(a,b){return'<a class="dropdown-item" href="#" data-href=\''+btoa(JSON.stringify(a))+"'>"+b+"</a>"}
|
function showSmartPlaylist(a){sendAPI({cmd:"MPD_API_SMARTPLS_GET",data:{playlist:a}},parseSmartPlaylist)}function dirname(a){return a.replace(/\/[^\/]*$/,"")}function b64EncodeUnicode(a){return btoa(encodeURIComponent(a).replace(/%([0-9A-F]{2})/g,function(a,c){return String.fromCharCode("0x"+c)}))}function b64DecodeUnicode(a){return decodeURIComponent(atob(a).split("").map(function(a){return"%"+("00"+a.charCodeAt(0).toString(16)).slice(-2)}).join(""))}
|
||||||
function showMenu(a,b){b.preventDefault();b.stopPropagation();b=document.getElementsByClassName("popover");for(var c=0;c<b.length;c++)b[c].remove();b=a.getAttribute("data-type");var d=decodeURI(a.getAttribute("data-uri"));c=a.getAttribute("data-name");var e=0;if(null==b||null==d)b=a.parentNode.parentNode.getAttribute("data-type"),d=decodeURI(a.parentNode.parentNode.getAttribute("data-uri")),c=a.parentNode.parentNode.getAttribute("data-name");lastState&&(e=lastState.data.nextSongPos);var f="";"Browse"==
|
function addMenuItem(a,b){return'<a class="dropdown-item" href="#" data-href=\''+b64EncodeUnicode(JSON.stringify(a))+"'>"+b+"</a>"}function hideMenu(){var a=document.querySelector("[data-popover]");a&&(new Popover(a,{}),a.Popover.hide(),a.removeAttribute("data-popover"))}
|
||||||
app.current.app&&"Filesystem"==app.current.tab||"Search"==app.current.app||"Browse"==app.current.app&&"Database"==app.current.tab?(f+=addMenuItem({cmd:"appendQueue",options:[b,d,c]},"Append to queue")+("song"==b?addMenuItem({cmd:"appendAfterQueue",options:[b,d,e,c]},"Add after current playing song"):"")+addMenuItem({cmd:"replaceQueue",options:[b,d,c]},"Replace queue")+("plist"!=b?addMenuItem({cmd:"showAddToPlaylist",options:[d]},"Add to playlist"):"")+("song"==b?addMenuItem({cmd:"songDetails",options:[d]},
|
function showMenu(a,b){b.preventDefault();b.stopPropagation();if(!a.getAttribute("data-init")){hideMenu();b=a.getAttribute("data-type");var c=decodeURI(a.getAttribute("data-uri")),d=a.getAttribute("data-name"),e=0;if(null==b||null==c)b=a.parentNode.parentNode.getAttribute("data-type"),c=decodeURI(a.parentNode.parentNode.getAttribute("data-uri")),d=a.parentNode.parentNode.getAttribute("data-name");lastState&&(e=lastState.data.nextSongPos);var f="";"Browse"==app.current.app&&"Filesystem"==app.current.tab||
|
||||||
"Songdetails"):"")+("plist"==b?addMenuItem({cmd:"playlistDetails",options:[d]},"Show playlist"):""),"Search"==app.current.app&&(d=dirname(d),f+='<div class="dropdown-divider"></div><a class="dropdown-item" id="advancedMenuLink" data-toggle="collapse" href="#advancedMenu"><span class="material-icons material-icons-small-left">keyboard_arrow_right</span>Album actions</a><div class="collapse" id="advancedMenu">'+addMenuItem({cmd:"appendQueue",options:[b,d,c]},"Append to queue")+addMenuItem({cmd:"appendAfterQueue",
|
"Search"==app.current.app||"Browse"==app.current.app&&"Database"==app.current.tab?(f+=addMenuItem({cmd:"appendQueue",options:[b,c,d]},"Append to queue")+("song"==b?addMenuItem({cmd:"appendAfterQueue",options:[b,c,e,d]},"Add after current playing song"):"")+addMenuItem({cmd:"replaceQueue",options:[b,c,d]},"Replace queue")+("plist"!=b&&"smartpls"!=b?addMenuItem({cmd:"showAddToPlaylist",options:[c]},"Add to playlist"):"")+("song"==b?addMenuItem({cmd:"songDetails",options:[c]},"Songdetails"):"")+("plist"==
|
||||||
options:[b,d,e,c]},"Add after current playing song")+addMenuItem({cmd:"replaceQueue",options:[b,d,c]},"Replace queue")+addMenuItem({cmd:"showAddToPlaylist",options:[d]},"Add to playlist")+"</div>")):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"All"==app.current.view?f+=addMenuItem({cmd:"appendQueue",options:[b,d,c]},"Append to queue")+addMenuItem({cmd:"replaceQueue",options:[b,d,c]},"Replace queue")+addMenuItem({cmd:"playlistDetails",options:[d]},"Edit playlist")+addMenuItem({cmd:"showRenamePlaylist",
|
b||"smartpls"==b?addMenuItem({cmd:"playlistDetails",options:[c]},"View playlist"):""),"Search"==app.current.app&&(c=dirname(c),f+='<div class="dropdown-divider"></div><a class="dropdown-item" id="advancedMenuLink" data-toggle="collapse" href="#advancedMenu"><span class="material-icons material-icons-small-left">keyboard_arrow_right</span>Album actions</a><div class="collapse" id="advancedMenu">'+addMenuItem({cmd:"appendQueue",options:[b,c,d]},"Append to queue")+addMenuItem({cmd:"appendAfterQueue",
|
||||||
options:[d]},"Rename playlist")+addMenuItem({cmd:"delPlaylist",options:[d]},"Delete playlist"):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view?(e=document.getElementById("BrowsePlaylistsDetailList"),f+=addMenuItem({cmd:"appendQueue",options:[b,d,c]},"Append to queue")+addMenuItem({cmd:"replaceQueue",options:[b,d,c]},"Replace queue")+("false"==e.getAttribute("data-ro")?addMenuItem({cmd:"removeFromPlaylist",options:[e.getAttribute("data-uri"),a.parentNode.parentNode.getAttribute("data-songpos")]},
|
options:[b,c,e,d]},"Add after current playing song")+addMenuItem({cmd:"replaceQueue",options:[b,c,d]},"Replace queue")+addMenuItem({cmd:"showAddToPlaylist",options:[c]},"Add to playlist")+"</div>")):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"All"==app.current.view?f+=addMenuItem({cmd:"appendQueue",options:[b,c,d]},"Append to queue")+addMenuItem({cmd:"replaceQueue",options:[b,c,d]},"Replace queue")+("smartpls"==b?addMenuItem({cmd:"playlistDetails",options:[c]},"View playlist"):addMenuItem({cmd:"playlistDetails",
|
||||||
"Remove"):"")+("plist"!=b?addMenuItem({cmd:"showAddToPlaylist",options:[d]},"Add to playlist"):"")):"Queue"==app.current.app&&(f+=addMenuItem({cmd:"delQueueSong",options:["single",a.parentNode.parentNode.getAttribute("data-trackid")]},"Remove")+addMenuItem({cmd:"delQueueSong",options:["range",0,a.parentNode.parentNode.getAttribute("data-songpos")]},"Remove all upwards")+addMenuItem({cmd:"delQueueSong",options:["range",parseInt(a.parentNode.parentNode.getAttribute("data-songpos"))-1,-1]},"Remove all downwards")+
|
options:[c]},"Edit playlist"))+("smartpls"==b?addMenuItem({cmd:"showSmartPlaylist",options:[c]},"Edit smart playlist"):"")+(0!=c.indexOf("myMPDsmart")?addMenuItem({cmd:"showRenamePlaylist",options:[c]},"Rename playlist")+addMenuItem({cmd:"delPlaylist",options:[c]},"Delete playlist"):""):"Browse"==app.current.app&&"Playlists"==app.current.tab&&"Detail"==app.current.view?(e=document.getElementById("BrowsePlaylistsDetailList"),f+=addMenuItem({cmd:"appendQueue",options:[b,c,d]},"Append to queue")+addMenuItem({cmd:"replaceQueue",
|
||||||
(-1==d.indexOf("http")?addMenuItem({cmd:"songDetails",options:[d]},"Songdetails"):""));new Popover(a,{trigger:"click",delay:0,dismissible:!0,template:'<div class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content">'+f+"</div></div>"});var g=a.Popover;a.getAttribute("data-init")||(a.setAttribute("data-init","true"),a.addEventListener("shown.bs.popover",function(a){document.getElementsByClassName("popover-content")[0].addEventListener("click",function(a){a.preventDefault();
|
options:[b,c,d]},"Replace queue")+("false"==e.getAttribute("data-ro")?addMenuItem({cmd:"removeFromPlaylist",options:[e.getAttribute("data-uri"),a.parentNode.parentNode.getAttribute("data-songpos")]},"Remove"):"")+addMenuItem({cmd:"showAddToPlaylist",options:[c]},"Add to playlist")+(-1==c.indexOf("http")?addMenuItem({cmd:"songDetails",options:[c]},"Songdetails"):"")):"Queue"==app.current.app&&(f+=addMenuItem({cmd:"delQueueSong",options:["single",a.parentNode.parentNode.getAttribute("data-trackid")]},
|
||||||
a.stopPropagation();if("A"==a.target.nodeName&&(a=a.target.getAttribute("data-href"))){a=JSON.parse(atob(a));if("function"===typeof window[a.cmd])switch(a.cmd){case "sendAPI":sendAPI.apply(null,$jscomp.arrayFromIterable(a.options));break;default:window[a.cmd].apply(null,$jscomp.arrayFromIterable(a.options))}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":
|
"Remove")+addMenuItem({cmd:"delQueueSong",options:["range",0,a.parentNode.parentNode.getAttribute("data-songpos")]},"Remove all upwards")+addMenuItem({cmd:"delQueueSong",options:["range",parseInt(a.parentNode.parentNode.getAttribute("data-songpos"))-1,-1]},"Remove all downwards")+(-1==c.indexOf("http")?addMenuItem({cmd:"songDetails",options:[c]},"Songdetails"):""));new Popover(a,{trigger:"click",delay:0,dismissible:!0,template:'<div class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content">'+
|
||||||
"keyboard_arrow_right"},!1),new Collapse(a)},!1));g.show()}
|
f+"</div></div>"});b=a.Popover;a.setAttribute("data-init","true");a.addEventListener("shown.bs.popover",function(a){a.target.setAttribute("data-popover","true");document.getElementsByClassName("popover-content")[0].addEventListener("click",function(a){a.preventDefault();a.stopPropagation();if("A"==a.target.nodeName&&(a=a.target.getAttribute("data-href"))){a=JSON.parse(b64DecodeUnicode(a));if("function"===typeof window[a.cmd])switch(a.cmd){case "sendAPI":sendAPI.apply(null,$jscomp.arrayFromIterable(a.options));
|
||||||
|
break;default:window[a.cmd].apply(null,$jscomp.arrayFromIterable(a.options))}hideMenu()}},!1);if(a=document.getElementById("advancedMenuLink"))a.addEventListener("click",function(a){a=this.getElementsByTagName("span")[0];a.innerText="keyboard_arrow_right"==a.innerText?"keyboard_arrow_down":"keyboard_arrow_right"},!1),new Collapse(a)},!1);b.show()}}
|
||||||
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))};
|
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)}function rescanDB(){sendAPI({cmd:"MPD_API_DATABASE_RESCAN"});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 rescanDB(){sendAPI({cmd:"MPD_API_DATABASE_RESCAN"});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")):
|
||||||
"update_database"==a?showNotification("Database successfully updated.","","","success"):"update_finished"==a&&showNotification("Database update finished.","","","success")}function clickPlay(){"play"!=playstate?sendAPI({cmd:"MPD_API_PLAYER_PLAY"}):sendAPI({cmd:"MPD_API_PLAYER_PAUSE"})}function clickStop(){sendAPI({cmd:"MPD_API_PLAYER_STOP"})}function clickPrev(){sendAPI({cmd:"MPD_API_PLAYER_PREV"})}function clickNext(){sendAPI({cmd:"MPD_API_PLAYER_NEXT"})}
|
"update_database"==a?showNotification("Database successfully updated.","","","success"):"update_finished"==a&&showNotification("Database update finished.","","","success")}function clickPlay(){"play"!=playstate?sendAPI({cmd:"MPD_API_PLAYER_PLAY"}):sendAPI({cmd:"MPD_API_PLAYER_PAUSE"})}function clickStop(){sendAPI({cmd:"MPD_API_PLAYER_STOP"})}function clickPrev(){sendAPI({cmd:"MPD_API_PLAYER_PREV"})}function clickNext(){sendAPI({cmd:"MPD_API_PLAYER_NEXT"})}
|
||||||
function delQueueSong(a,b,c){"range"==a?sendAPI({cmd:"MPD_API_QUEUE_RM_RANGE",data:{start:b,end:c}}):"single"==a&&sendAPI({cmd:"MPD_API_QUEUE_RM_TRACK",data:{track:b}})}function delPlaylist(a){sendAPI({cmd:"MPD_API_PLAYLIST_RM",data:{uri:a}});sendAPI({cmd:"MPD_API_PLAYLIST_LIST",data:{offset:app.current.page,filter:app.current.filter}},parsePlaylists)}
|
function delQueueSong(a,b,c){"range"==a?sendAPI({cmd:"MPD_API_QUEUE_RM_RANGE",data:{start:b,end:c}}):"single"==a&&sendAPI({cmd:"MPD_API_QUEUE_RM_TRACK",data:{track:b}})}function delPlaylist(a){sendAPI({cmd:"MPD_API_PLAYLIST_RM",data:{uri:a}});sendAPI({cmd:"MPD_API_PLAYLIST_LIST",data:{offset:app.current.page,filter:app.current.filter}},parsePlaylists)}
|
||||||
function 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}b=document.getElementById("inputJukeboxQueueLength");c=parseInt(b.value);isNaN(c)?(b.classList.add("is-invalid"),a=!1):0<c?b.value=c:(b.classList.add("is-invalid"),a=!1);settings.mixramp&&(b=document.getElementById("inputMixrampdb"),b.getAttribute("disabled")||(c=parseFloat(b.value),isNaN(c)?(b.classList.add("is-invalid"),
|
||||||
(b.classList.add("is-invalid"),a=!1):b.value=c));1==a?(a=document.getElementById("selectReplaygain"),c=document.getElementById("jukeboxPlaylist"),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,
|
a=!1):b.value=c),b=document.getElementById("inputMixrampdelay"),b.getAttribute("disabled")||("nan"==b.value&&(b.value="-1"),c=parseFloat(b.value),isNaN(c)?(b.classList.add("is-invalid"),a=!1):b.value=c));1==a?(a=document.getElementById("selectReplaygain"),c=document.getElementById("selectJukeboxPlaylist"),b=document.getElementById("selectJukeboxMode"),sendAPI({cmd:"MPD_API_SETTINGS_SET",data:{consume:document.getElementById("btnConsume").classList.contains("active")?1:0,random:document.getElementById("btnRandom").classList.contains("active")?
|
||||||
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")?!0:!1,notificationPage:document.getElementById("btnnotifyPage").classList.contains("active")?!0:!1,jukeboxMode:document.getElementById("btnJukebox").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")?
|
||||||
!0:!1,jukeboxPlaylist:c.options[c.selectedIndex].value}},getSettings),modalSettings.hide()):document.getElementById("settingsFrm").classList.add("was-validated")}function addAllFromBrowseFilesystem(){sendAPI({cmd:"MPD_API_QUEUE_ADD_TRACK",data:{uri:app.current.search}});showNotification("Added all songs","","","success")}
|
!0:!1,notificationPage:document.getElementById("btnnotifyPage").classList.contains("active")?!0:!1,jukeboxMode:b.options[b.selectedIndex].value,jukeboxPlaylist:c.options[c.selectedIndex].value,jukeboxQueueLength:document.getElementById("inputJukeboxQueueLength").value}},getSettings),modalSettings.hide()):document.getElementById("settingsFrm").classList.add("was-validated")}
|
||||||
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 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 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 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()):(alert(b),document.getElementById("saveQueueName").classList.add("is-invalid"),document.getElementById("saveQueueFrm").classList.add("was-validated"))}
|
||||||
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>"+
|
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}
|
||||||
|
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.2.1",urlsToCache="/ /player.html /css/bootstrap.min.css /css/mympd.min.css /js/bootstrap-native-v4.min.js /js/mympd.min.js /js/player.min.js /assets/appicon-167.png /assets/appicon-192.png /assets/appicon-512.png /assets/coverimage-httpstream.png /assets/coverimage-notavailable.png /assets/favicon.ico /assets/MaterialIcons-Regular.eot /assets/MaterialIcons-Regular.ttf /assets/MaterialIcons-Regular.woff /assets/MaterialIcons-Regular.woff2".split(" ");
|
c){for(var d=$jscomp.makeIterator(a),e=d.next();!e.done;e=d.next())f(e.value).callWhenSettled_(b,c)})};c.all=function(a){var b=$jscomp.makeIterator(a),d=b.next();return d.done?f([]):new c(function(a,c){function e(b){return function(c){g[b]=c;h--;0==h&&a(g)}}var g=[],h=0;do g.push(void 0),h++,f(d.value).callWhenSettled_(e(g.length-1),c),d=b.next();while(!d.done)})};return c},"es6","es3");var CACHE="myMPD-cache-v4.3.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){if(a.request.url.match("^http://"))return!1;a.respondWith(caches.match(a.request).then(function(b){return b?b:fetch(a.request)}))});self.addEventListener("activate",function(a){a.waitUntil(caches.keys().then(function(a){return Promise.all(a.map(function(a){if(a!=CACHE)return caches.delete(a)}))}))});
|
self.addEventListener("install",function(a){a.waitUntil(caches.open(CACHE).then(function(a){return a.addAll(urlsToCache)}))});self.addEventListener("fetch",function(a){if(a.request.url.match("^http://"))return!1;a.respondWith(caches.match(a.request).then(function(b){return b?b:fetch(a.request)}))});self.addEventListener("activate",function(a){a.waitUntil(caches.keys().then(function(a){return Promise.all(a.map(function(a){if(a!=CACHE)return caches.delete(a)}))}))});
|
||||||
|
1
dist/smartpls/myMPDsmart-bestRated.dist
vendored
Normal file
1
dist/smartpls/myMPDsmart-bestRated.dist
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"type": "sticker", "sticker": "like", "maxentries": 200}
|
1
dist/smartpls/myMPDsmart-mostPlayed.dist
vendored
Normal file
1
dist/smartpls/myMPDsmart-mostPlayed.dist
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"type": "sticker", "sticker": "playCount", "maxentries": 200}
|
1
dist/smartpls/myMPDsmart-newestSongs.dist
vendored
Normal file
1
dist/smartpls/myMPDsmart-newestSongs.dist
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"type": "newest", "timerange": 604800 , "maxentries": 200}
|
@ -24,10 +24,11 @@
|
|||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu bg-dark">
|
<div class="dropdown-menu bg-dark">
|
||||||
<a class="dropdown-item text-light bg-dark" href="#" data-href='{"cmd": "showAddToPlaylist", "options": ["stream"]}'>Add Stream</a>
|
<a class="dropdown-item text-light bg-dark" href="#" data-href='{"cmd": "showAddToPlaylist", "options": ["stream"]}'>Add Stream</a>
|
||||||
<a id="navDBupdate" class="dropdown-item text-light bg-dark" data-toggle="collapse" href="#menu-dbupdate"><span class="material-icons material-icons-left">keyboard_arrow_right</span>Database</a>
|
<a id="navDBupdate" class="dropdown-item text-light bg-dark" data-toggle="collapse" href="#menu-dbupdate"><span class="material-icons material-icons-left">keyboard_arrow_right</span>Update</a>
|
||||||
<div class="collapse" id="menu-dbupdate">
|
<div class="collapse" id="menu-dbupdate">
|
||||||
<a class="dropdown-item text-light bg-dark" href="#" data-href='{"cmd": "updateDB", "options": []}'>Update</a>
|
<a class="dropdown-item text-light bg-dark" href="#" data-href='{"cmd": "updateDB", "options": []}'>Update Database</a>
|
||||||
<a class="dropdown-item text-light bg-dark" href="#" data-href='{"cmd": "rescanDB", "options": []}'>Rescan</a>
|
<a class="dropdown-item text-light bg-dark" href="#" data-href='{"cmd": "rescanDB", "options": []}'>Rescan Database</a>
|
||||||
|
<a class="dropdown-item text-light bg-dark" href="#" data-href='{"cmd": "updateSmartPlaylists", "options": []}'>Update Smart Playlists</a>
|
||||||
</div>
|
</div>
|
||||||
<a class="dropdown-item text-light bg-dark" href="#" data-href='{"cmd": "openLocalPlayer", "options": []}'>Local Player</a>
|
<a class="dropdown-item text-light bg-dark" href="#" data-href='{"cmd": "openLocalPlayer", "options": []}'>Local Player</a>
|
||||||
<a class="dropdown-item text-light bg-dark" href="#" data-toggle="modal" data-target="#modalSettings">Settings</a>
|
<a class="dropdown-item text-light bg-dark" href="#" data-toggle="modal" data-target="#modalSettings">Settings</a>
|
||||||
@ -58,11 +59,11 @@
|
|||||||
<h2 class="dropdown-header text-light">Volume: <span id="volumePrct"></span></h2>
|
<h2 class="dropdown-header text-light">Volume: <span id="volumePrct"></span></h2>
|
||||||
<form class="px-4 py-0 pb-3" id="volumeControl">
|
<form class="px-4 py-0 pb-3" id="volumeControl">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button data-href='{"cmd": "chVolume", "options": [-5]}' class="btn btn-secondary">−</button>
|
<button id="btnChVolumeDown" data-href='{"cmd": "chVolume", "options": [-5]}' class="btn btn-secondary">−</button>
|
||||||
<div class="btn btn-secondary">
|
<div class="btn btn-secondary">
|
||||||
<input type="range" min="0" max="100" step="1" class="form-control-range" id="volumeBar">
|
<input type="range" min="0" max="100" step="1" class="form-control-range" id="volumeBar">
|
||||||
</div>
|
</div>
|
||||||
<button data-href='{"cmd": "chVolume", "options": [5]}' class="btn btn-secondary">+</button>
|
<button id="btnChVolumeUp" data-href='{"cmd": "chVolume", "options": [5]}' class="btn btn-secondary">+</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
@ -466,6 +467,7 @@
|
|||||||
<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-sm 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-sm btn-block">Add all to playlist</button>
|
<button type="button" class="btn btn-secondary btn-sm btn-block">Add all to playlist</button>
|
||||||
|
<button type="button" class="btn btn-secondary btn-sm btn-block smartpls">Save as smart playlist</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -540,7 +542,7 @@
|
|||||||
<h5 class="modal-title"><span class="material-icons title-icon">error</span> Connection Error</h5>
|
<h5 class="modal-title"><span class="material-icons title-icon">error</span> Connection Error</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>Connection to myMPD failed. Trying to reconnect.</p>
|
<p>Connection to myMPD failed. Trying to reconnect to <span id="wsUrl"></span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -644,6 +646,74 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="modalSaveSmartPlaylist" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title"><span class="material-icons title-icon">playlist_add</span>Save smart playlist</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form class="needs-validation" id="saveSmartPlaylistFrm" novalidate>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="saveSmartPlaylistName">Name</label>
|
||||||
|
<input type="text" class="form-control" id="saveSmartPlaylistName"/>
|
||||||
|
<div class="invalid-feedback">Invalid filename.</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="saveSmartPlaylistType">Type</label>
|
||||||
|
<input type="text" class="form-control" id="saveSmartPlaylistType" readonly/>
|
||||||
|
<div class="invalid-feedback">Invalid type.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
<div class="row" id="saveSmartPlaylistSearch" class="hide">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="selectSaveSmartPlaylistTag">Tag</label>
|
||||||
|
<select id="selectSaveSmartPlaylistTag" class="form-control custom-select"></select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="inputSaveSmartPlaylistSearchstr">Search</label>
|
||||||
|
<input type="text" class="form-control" id="inputSaveSmartPlaylistSearchstr"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" id="saveSmartPlaylistSticker" class="hide">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="selectSaveSmartPlaylistSticker">Sticker</label>
|
||||||
|
<select id="selectSaveSmartPlaylistSticker" class="form-control custom-select">
|
||||||
|
<option value="like">Like</option>
|
||||||
|
<option value="playCount">playCount</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="inputSaveSmartPlaylistStickerMaxentries">Max. entries</label>
|
||||||
|
<input type="text" class="form-control" id="inputSaveSmartPlaylistStickerMaxentries"/>
|
||||||
|
<div class="invalid-feedback">Must be a number.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" id="saveSmartPlaylistNewest" class="hide">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="inputSaveSmartPlaylistNewestTimerange">Timerange (days)</label>
|
||||||
|
<input type="text" class="form-control" id="inputSaveSmartPlaylistNewestTimerange"/>
|
||||||
|
<div class="invalid-feedback">Must be a number.</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="inputSaveSmartPlaylistNewestMaxentries">Max. entries</label>
|
||||||
|
<input type="text" class="form-control" id="inputSaveSmartPlaylistNewestMaxentries"/>
|
||||||
|
<div class="invalid-feedback">Must be a number.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-success" data-href='{"cmd": "saveSmartPlaylist", "options": []}'>Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="modal fade" id="modalSettings" tabindex="-1">
|
<div class="modal fade" id="modalSettings" tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
@ -717,16 +787,30 @@
|
|||||||
<hr/>
|
<hr/>
|
||||||
<h4>Jukebox</h4>
|
<h4>Jukebox</h4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="form-group col-md-6" data-toggle="buttons">
|
<div class="form-group input-group col-md-6 border-secondary">
|
||||||
<button data-href='{"cmd": "toggleBtn", "options": ["btnJukebox"]}' id="btnJukebox" type="button" class="btn btn-secondary btn-block" title="Jukebox">
|
<div class="input-group-prepend">
|
||||||
Jukebox
|
<div class="input-group-text bg-secondary text-light border-secondary">Mode</div>
|
||||||
</button>
|
</div>
|
||||||
|
<select id="selectJukeboxMode" class="form-control custom-select border-secondary">
|
||||||
|
<option value="0">Off</option>
|
||||||
|
<option value="1">Track</option>
|
||||||
|
<option value="2">Album</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group input-group col-md-6 border-secondary">
|
<div class="form-group input-group col-md-6 border-secondary">
|
||||||
<select id="jukeboxPlaylist" class="form-control custom-select border-secondary">
|
<select id="selectJukeboxPlaylist" class="form-control custom-select border-secondary">
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group input-group col-md-6 border-secondary">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<div class="input-group-text bg-secondary text-light border-secondary">Min. queue length</div>
|
||||||
|
</div>
|
||||||
|
<input id="inputJukeboxQueueLength" type="text" class="form-control border-secondary" value="1">
|
||||||
|
<div class="invalid-feedback">Must be a number and > 0</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<hr/>
|
<hr/>
|
||||||
<h4>Notifications</h4>
|
<h4>Notifications</h4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -97,6 +97,7 @@ var modalSongDetails = new Modal(document.getElementById('modalSongDetails'));
|
|||||||
var modalAddToPlaylist = new Modal(document.getElementById('modalAddToPlaylist'));
|
var modalAddToPlaylist = new Modal(document.getElementById('modalAddToPlaylist'));
|
||||||
var modalRenamePlaylist = new Modal(document.getElementById('modalRenamePlaylist'));
|
var modalRenamePlaylist = new Modal(document.getElementById('modalRenamePlaylist'));
|
||||||
var modalUpdateDB = new Modal(document.getElementById('modalUpdateDB'));
|
var modalUpdateDB = new Modal(document.getElementById('modalUpdateDB'));
|
||||||
|
var modalSaveSmartPlaylist = new Modal(document.getElementById('modalSaveSmartPlaylist'));
|
||||||
//var mainMenu = new Dropdown(document.getElementById('mainMenu'));
|
//var mainMenu = new Dropdown(document.getElementById('mainMenu'));
|
||||||
//var volumeMenu = new Dropdown(document.getElementById('volumeIcon'));
|
//var volumeMenu = new Dropdown(document.getElementById('volumeIcon'));
|
||||||
|
|
||||||
@ -259,7 +260,10 @@ function appRoute() {
|
|||||||
doSetFilterLetter('BrowseFilesystemFilter');
|
doSetFilterLetter('BrowseFilesystemFilter');
|
||||||
}
|
}
|
||||||
else if (app.current.app == 'Search') {
|
else if (app.current.app == 'Search') {
|
||||||
document.getElementById('searchstr').focus();
|
var searchstrEl = document.getElementById('searchstr');
|
||||||
|
searchstrEl.focus();
|
||||||
|
if (searchstrEl.value == '' && app.current.search != '')
|
||||||
|
searchstrEl.value = app.current.search;
|
||||||
if (app.last.app != app.current.app) {
|
if (app.last.app != app.current.app) {
|
||||||
if (app.current.search != '')
|
if (app.current.search != '')
|
||||||
document.getElementById('SearchList').getElementsByTagName('tbody')[0].innerHTML=
|
document.getElementById('SearchList').getElementsByTagName('tbody')[0].innerHTML=
|
||||||
@ -295,6 +299,14 @@ function appInit() {
|
|||||||
webSocketConnect();
|
webSocketConnect();
|
||||||
|
|
||||||
domCache.volumeBar.value = 0;
|
domCache.volumeBar.value = 0;
|
||||||
|
|
||||||
|
document.getElementById('btnChVolumeDown').addEventListener('click', function(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}, false);
|
||||||
|
document.getElementById('btnChVolumeUp').addEventListener('click', function(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}, false);
|
||||||
|
|
||||||
domCache.volumeBar.addEventListener('click', function(event) {
|
domCache.volumeBar.addEventListener('click', function(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}, false);
|
}, false);
|
||||||
@ -348,8 +360,19 @@ function appInit() {
|
|||||||
document.getElementById('inputMixrampdelay').classList.remove('is-invalid');
|
document.getElementById('inputMixrampdelay').classList.remove('is-invalid');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.getElementById('selectJukeboxMode').addEventListener('change', function () {
|
||||||
|
var value = this.options[this.selectedIndex].value;
|
||||||
|
if (value == 0 || value == 2) {
|
||||||
|
document.getElementById('inputJukeboxQueueLength').setAttribute('disabled', 'disabled');
|
||||||
|
document.getElementById('selectJukeboxPlaylist').setAttribute('disabled', 'disabled');
|
||||||
|
}
|
||||||
|
else if (value == 1) {
|
||||||
|
document.getElementById('inputJukeboxQueueLength').removeAttribute('disabled');
|
||||||
|
document.getElementById('selectJukeboxPlaylist').removeAttribute('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
document.getElementById('addToPlaylistPlaylist').addEventListener('change',function(event) {
|
document.getElementById('addToPlaylistPlaylist').addEventListener('change', function (event) {
|
||||||
if (this.options[this.selectedIndex].text == 'New Playlist') {
|
if (this.options[this.selectedIndex].text == 'New Playlist') {
|
||||||
document.getElementById('addToPlaylistNewPlaylistDiv').classList.remove('hide');
|
document.getElementById('addToPlaylistNewPlaylistDiv').classList.remove('hide');
|
||||||
document.getElementById('addToPlaylistNewPlaylist').focus();
|
document.getElementById('addToPlaylistNewPlaylist').focus();
|
||||||
@ -479,6 +502,9 @@ function appInit() {
|
|||||||
else if (event.target.innerText == 'Add all to playlist') {
|
else if (event.target.innerText == 'Add all to playlist') {
|
||||||
showAddToPlaylist('SEARCH');
|
showAddToPlaylist('SEARCH');
|
||||||
}
|
}
|
||||||
|
else if (event.target.innerText == 'Save as smart playlist') {
|
||||||
|
saveSearchAsSmartPlaylist();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
@ -525,9 +551,10 @@ function appInit() {
|
|||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
document.getElementsByTagName('body')[0].addEventListener('click', function(event) {
|
document.getElementsByTagName('body')[0].addEventListener('click', function(event) {
|
||||||
var oldPopover = document.getElementsByClassName('popover');
|
// var oldPopover = document.getElementsByClassName('popover');
|
||||||
for (var i = 0; i < oldPopover.length; i++)
|
// for (var i = 0; i < oldPopover.length; i++)
|
||||||
oldPopover[i].remove();
|
// oldPopover[i].remove();
|
||||||
|
hideMenu();
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
dragAndDropTable('QueueList');
|
dragAndDropTable('QueueList');
|
||||||
@ -677,12 +704,13 @@ function playlistMoveTrack(from, to) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function webSocketConnect() {
|
function webSocketConnect() {
|
||||||
socket = new WebSocket(getWsUrl());
|
var wsUrl = getWsUrl();
|
||||||
|
socket = new WebSocket(wsUrl);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
socket.onopen = function() {
|
socket.onopen = function() {
|
||||||
console.log('connected');
|
console.log('connected');
|
||||||
showNotification('Connected to myMPD', '', '', 'success');
|
showNotification('Connected to myMPD: ' + wsUrl, '', '', 'success');
|
||||||
modalConnectionError.hide();
|
modalConnectionError.hide();
|
||||||
appRoute();
|
appRoute();
|
||||||
sendAPI({"cmd": "MPD_API_PLAYER_STATE"}, parseState);
|
sendAPI({"cmd": "MPD_API_PLAYER_STATE"}, parseState);
|
||||||
@ -703,7 +731,7 @@ function webSocketConnect() {
|
|||||||
parseState(obj);
|
parseState(obj);
|
||||||
break;
|
break;
|
||||||
case 'disconnected':
|
case 'disconnected':
|
||||||
showNotification('myMPD lost connection to MPD', '', '', 'danger');
|
showNotification('Lost connection to myMPD: ' + wsUrl, '', '', 'danger');
|
||||||
break;
|
break;
|
||||||
case 'update_queue':
|
case 'update_queue':
|
||||||
if (app.current.app === 'Queue')
|
if (app.current.app === 'Queue')
|
||||||
@ -746,26 +774,18 @@ function webSocketConnect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getWsUrl() {
|
function getWsUrl() {
|
||||||
var pcol;
|
var hostname = window.location.hostname;
|
||||||
var u = document.URL;
|
var protocol = window.location.protocol;
|
||||||
var separator;
|
var port = window.location.port;
|
||||||
|
|
||||||
if (u.substring(0, 5) == 'https') {
|
if (protocol == 'https:')
|
||||||
pcol = 'wss://';
|
protocol = 'wss://';
|
||||||
u = u.substr(8);
|
|
||||||
} else {
|
|
||||||
pcol = 'ws://';
|
|
||||||
if (u.substring(0, 4) == 'http')
|
|
||||||
u = u.substr(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
u = u.split('#');
|
|
||||||
if (/\/$/.test(u[0]))
|
|
||||||
separator = '';
|
|
||||||
else
|
else
|
||||||
separator = '/';
|
protocol = 'ws://';
|
||||||
|
|
||||||
return pcol + u[0] + separator + 'ws';
|
var wsUrl = protocol + hostname + (port != '' ? ':' + port : '') + '/ws';
|
||||||
|
document.getElementById('wsUrl').innerText = wsUrl;
|
||||||
|
return wsUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseStats(obj) {
|
function parseStats(obj) {
|
||||||
@ -799,7 +819,6 @@ function parseSettings(obj) {
|
|||||||
toggleBtn('btnConsume', obj.data.consume);
|
toggleBtn('btnConsume', obj.data.consume);
|
||||||
toggleBtn('btnSingle', obj.data.single);
|
toggleBtn('btnSingle', obj.data.single);
|
||||||
toggleBtn('btnRepeat', obj.data.repeat);
|
toggleBtn('btnRepeat', obj.data.repeat);
|
||||||
toggleBtn('btnJukebox', obj.data.jukeboxMode);
|
|
||||||
|
|
||||||
if (obj.data.crossfade != undefined) {
|
if (obj.data.crossfade != undefined) {
|
||||||
document.getElementById('inputCrossfade').removeAttribute('disabled');
|
document.getElementById('inputCrossfade').removeAttribute('disabled');
|
||||||
@ -850,19 +869,34 @@ function parseSettings(obj) {
|
|||||||
var stickerEls = document.getElementsByClassName('stickers');
|
var stickerEls = document.getElementsByClassName('stickers');
|
||||||
var stickerElsLen = stickerEls.length;
|
var stickerElsLen = stickerEls.length;
|
||||||
var displayStickers = obj.data.stickers == true ? '' : 'none';
|
var displayStickers = obj.data.stickers == true ? '' : 'none';
|
||||||
for (var i = 0; i < stickerElsLen; i++) {
|
for (var i = 0; i < stickerElsLen; i++)
|
||||||
stickerEls[i].style.display = displayStickers;
|
stickerEls[i].style.display = displayStickers;
|
||||||
}
|
|
||||||
|
var smartplsEls = document.getElementsByClassName('smartpls');
|
||||||
|
var smartplsElsLen = smartplsEls.length;
|
||||||
|
var displaySmartpls = obj.data.smartpls == true ? '' : 'none';
|
||||||
|
for (var i = 0; i < smartplsElsLen; i++)
|
||||||
|
smartplsEls[i].style.display = displaySmartpls;
|
||||||
|
|
||||||
if (obj.data.mixramp == true) {
|
if (obj.data.mixramp == true)
|
||||||
document.getElementsByClassName('mixramp')[0].style.display = '';
|
document.getElementsByClassName('mixramp')[0].style.display = '';
|
||||||
} else {
|
else
|
||||||
document.getElementsByClassName('mixramp')[0].style.display = 'none';
|
document.getElementsByClassName('mixramp')[0].style.display = 'none';
|
||||||
|
|
||||||
|
document.getElementById('selectJukeboxMode').value = obj.data.jukeboxMode;
|
||||||
|
document.getElementById('inputJukeboxQueueLength').value = obj.data.jukeboxQueueLength;
|
||||||
|
if (obj.data.jukeboxMode == 0 || obj.data.jukeboxMode == 2) {
|
||||||
|
document.getElementById('inputJukeboxQueueLength').setAttribute('disabled', 'disabled');
|
||||||
|
document.getElementById('selectJukeboxPlaylist').setAttribute('disabled', 'disabled');
|
||||||
|
}
|
||||||
|
else if (obj.data.jukeboxMode == 1) {
|
||||||
|
document.getElementById('inputJukeboxQueueLength').removeAttribute('disabled');
|
||||||
|
document.getElementById('selectJukeboxPlaylist').removeAttribute('disabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
settings = obj.data;
|
settings = obj.data;
|
||||||
|
|
||||||
playlistEl = 'jukeboxPlaylist';
|
playlistEl = 'selectJukeboxPlaylist';
|
||||||
sendAPI({"cmd": "MPD_API_PLAYLIST_LIST", "data": {"offset": 0, "filter": "-"}}, getAllPlaylists);
|
sendAPI({"cmd": "MPD_API_PLAYLIST_LIST", "data": {"offset": 0, "filter": "-"}}, getAllPlaylists);
|
||||||
|
|
||||||
settings.mpdstream = 'http://';
|
settings.mpdstream = 'http://';
|
||||||
@ -1020,9 +1054,9 @@ function parseQueue(obj) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (typeof(obj.totalTime) != undefined && obj.totalTime > 0 && obj.totalEntities <= settings.maxElementsPerPage )
|
if (typeof(obj.totalTime) != undefined && obj.totalTime > 0 && obj.totalEntities <= settings.maxElementsPerPage )
|
||||||
document.getElementById('panel-heading-queue').innerText = obj.totalEntities + ' Songs – ' + beautifyDuration(obj.totalTime);
|
document.getElementById('panel-heading-queue').innerText = obj.totalEntities + ' ' + (obj.totalEntities > 1 ? 'Songs' : 'Song') + ' – ' + beautifyDuration(obj.totalTime);
|
||||||
else if (obj.totalEntities > 0)
|
else if (obj.totalEntities > 0)
|
||||||
document.getElementById('panel-heading-queue').innerText = obj.totalEntities + ' Songs';
|
document.getElementById('panel-heading-queue').innerText = obj.totalEntities + ' ' + (obj.totalEntities > 1 ? 'Songs' : 'Song');
|
||||||
else
|
else
|
||||||
document.getElementById('panel-heading-queue').innerText = '';
|
document.getElementById('panel-heading-queue').innerText = '';
|
||||||
|
|
||||||
@ -1120,6 +1154,7 @@ function parseFilesystem(obj) {
|
|||||||
'<td>' + minutes + ':' + (seconds < 10 ? '0' : '') + seconds +
|
'<td>' + minutes + ':' + (seconds < 10 ? '0' : '') + seconds +
|
||||||
'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';
|
'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';
|
||||||
break;
|
break;
|
||||||
|
case 'smartpls':
|
||||||
case 'plist':
|
case 'plist':
|
||||||
row.innerHTML = '<td><span class="material-icons">list</span></td>' +
|
row.innerHTML = '<td><span class="material-icons">list</span></td>' +
|
||||||
'<td colspan="4">' + obj.data[i].name + '</td>' +
|
'<td colspan="4">' + obj.data[i].name + '</td>' +
|
||||||
@ -1153,7 +1188,7 @@ function parsePlaylists(obj) {
|
|||||||
document.getElementById('btnBrowsePlaylistsAll').parentNode.classList.add('hide');
|
document.getElementById('btnBrowsePlaylistsAll').parentNode.classList.add('hide');
|
||||||
document.getElementById('btnPlaylistClear').parentNode.classList.add('hide');
|
document.getElementById('btnPlaylistClear').parentNode.classList.add('hide');
|
||||||
} else {
|
} else {
|
||||||
if (obj.uri.indexOf('.') > -1) {
|
if (obj.uri.indexOf('.') > -1 || obj.smartpls == true) {
|
||||||
document.getElementById('BrowsePlaylistsDetailList').setAttribute('data-ro', 'true')
|
document.getElementById('BrowsePlaylistsDetailList').setAttribute('data-ro', 'true')
|
||||||
document.getElementById('btnPlaylistClear').parentNode.classList.add('hide');
|
document.getElementById('btnPlaylistClear').parentNode.classList.add('hide');
|
||||||
}
|
}
|
||||||
@ -1162,7 +1197,10 @@ function parsePlaylists(obj) {
|
|||||||
document.getElementById('btnPlaylistClear').parentNode.classList.remove('hide');
|
document.getElementById('btnPlaylistClear').parentNode.classList.remove('hide');
|
||||||
}
|
}
|
||||||
document.getElementById('BrowsePlaylistsDetailList').setAttribute('data-uri', obj.uri);
|
document.getElementById('BrowsePlaylistsDetailList').setAttribute('data-uri', obj.uri);
|
||||||
document.getElementById('BrowsePlaylistsDetailList').getElementsByTagName('caption')[0].innerText = 'Playlist: ' + obj.uri;
|
if (obj.smartpls == true)
|
||||||
|
document.getElementById('BrowsePlaylistsDetailList').getElementsByTagName('caption')[0].innerText = 'Smart playlist: ' + obj.uri;
|
||||||
|
else
|
||||||
|
document.getElementById('BrowsePlaylistsDetailList').getElementsByTagName('caption')[0].innerText = 'Playlist: ' + obj.uri;
|
||||||
document.getElementById('BrowsePlaylistsDetailList').classList.remove('hide');
|
document.getElementById('BrowsePlaylistsDetailList').classList.remove('hide');
|
||||||
document.getElementById('BrowsePlaylistsAllList').classList.add('hide');
|
document.getElementById('BrowsePlaylistsAllList').classList.add('hide');
|
||||||
document.getElementById('btnBrowsePlaylistsAll').parentNode.classList.remove('hide');
|
document.getElementById('btnBrowsePlaylistsAll').parentNode.classList.remove('hide');
|
||||||
@ -1180,7 +1218,7 @@ function parsePlaylists(obj) {
|
|||||||
var d = new Date(obj.data[i].last_modified * 1000);
|
var d = new Date(obj.data[i].last_modified * 1000);
|
||||||
var row = document.createElement('tr');
|
var row = document.createElement('tr');
|
||||||
row.setAttribute('data-uri', uri);
|
row.setAttribute('data-uri', uri);
|
||||||
row.setAttribute('data-type', 'plist');
|
row.setAttribute('data-type', obj.data[i].type);
|
||||||
row.setAttribute('data-name', obj.data[i].name);
|
row.setAttribute('data-name', obj.data[i].name);
|
||||||
row.innerHTML = '<td><span class="material-icons">list</span></td>' +
|
row.innerHTML = '<td><span class="material-icons">list</span></td>' +
|
||||||
'<td>' + obj.data[i].name + '</td>' +
|
'<td>' + obj.data[i].name + '</td>' +
|
||||||
@ -1200,7 +1238,8 @@ function parsePlaylists(obj) {
|
|||||||
if (tr[i].getAttribute('data-uri') == uri && tr[i].getAttribute('id') == 'playlistTrackId' + songpos)
|
if (tr[i].getAttribute('data-uri') == uri && tr[i].getAttribute('id') == 'playlistTrackId' + songpos)
|
||||||
continue;
|
continue;
|
||||||
var row = document.createElement('tr');
|
var row = document.createElement('tr');
|
||||||
row.setAttribute('draggable','true');
|
if (obj.smartpls == false)
|
||||||
|
row.setAttribute('draggable','true');
|
||||||
row.setAttribute('id','playlistTrackId' + songpos);
|
row.setAttribute('id','playlistTrackId' + songpos);
|
||||||
row.setAttribute('data-type', obj.data[i].type);
|
row.setAttribute('data-type', obj.data[i].type);
|
||||||
row.setAttribute('data-uri', uri);
|
row.setAttribute('data-uri', uri);
|
||||||
@ -1500,6 +1539,7 @@ function parseSongDetails(obj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function playlistDetails(uri) {
|
function playlistDetails(uri) {
|
||||||
|
document.getElementById('BrowsePlaylistsAllList').classList.add('opacity05');
|
||||||
appGoto('Browse', 'Playlists', 'Detail', '0/-/' + uri);
|
appGoto('Browse', 'Playlists', 'Detail', '0/-/' + uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1523,12 +1563,12 @@ function getAllPlaylists(obj) {
|
|||||||
if (obj.offset == 0) {
|
if (obj.offset == 0) {
|
||||||
if (playlistEl == 'addToPlaylistPlaylist')
|
if (playlistEl == 'addToPlaylistPlaylist')
|
||||||
playlists = '<option></option><option>New Playlist</option>';
|
playlists = '<option></option><option>New Playlist</option>';
|
||||||
else if (playlistEl == 'jukeboxPlaylist')
|
else if (playlistEl == 'selectJukeboxPlaylist')
|
||||||
playlists = '<option>Database</option>';
|
playlists = '<option>Database</option>';
|
||||||
}
|
}
|
||||||
for (var i = 0; i < nrItems; i++) {
|
for (var i = 0; i < nrItems; i++) {
|
||||||
playlists += '<option';
|
playlists += '<option';
|
||||||
if (playlistEl == 'jukeboxPlaylist' && obj.data[i].uri == settings.jukeboxPlaylist)
|
if (playlistEl == 'selectJukeboxPlaylist' && obj.data[i].uri == settings.jukeboxPlaylist)
|
||||||
playlists += ' selected';
|
playlists += ' selected';
|
||||||
playlists += '>' + obj.data[i].uri + '</option>';
|
playlists += '>' + obj.data[i].uri + '</option>';
|
||||||
}
|
}
|
||||||
@ -1542,6 +1582,10 @@ function getAllPlaylists(obj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateSmartPlaylists() {
|
||||||
|
sendAPI({"cmd": "MPD_API_SMARTPLS_UPDATE_ALL"});
|
||||||
|
}
|
||||||
|
|
||||||
function voteSong(vote) {
|
function voteSong(vote) {
|
||||||
var uri = domCache.currentTrack.getAttribute('data-uri');
|
var uri = domCache.currentTrack.getAttribute('data-uri');
|
||||||
if (uri == '')
|
if (uri == '')
|
||||||
@ -1591,6 +1635,101 @@ function toggleAddToPlaylistFrm() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveSearchAsSmartPlaylist() {
|
||||||
|
parseSmartPlaylist({"type": "smartpls", "data": {"playlist": "", "type": "search", "tag": app.current.filter, "searchstr": app.current.search}});
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseSmartPlaylist(obj) {
|
||||||
|
var nameEl = document.getElementById('saveSmartPlaylistName');
|
||||||
|
nameEl.value = obj.data.playlist;
|
||||||
|
nameEl.classList.remove('is-invalid');
|
||||||
|
document.getElementById('saveSmartPlaylistType').value = obj.data.type;
|
||||||
|
document.getElementById('saveSmartPlaylistFrm').classList.remove('was-validated');
|
||||||
|
document.getElementById('saveSmartPlaylistSearch').classList.add('hide');
|
||||||
|
document.getElementById('saveSmartPlaylistSticker').classList.add('hide');
|
||||||
|
document.getElementById('saveSmartPlaylistNewest').classList.add('hide');
|
||||||
|
var tagList = '<option value="any">Any Tag</option>';
|
||||||
|
for (var key in settings.tags) {
|
||||||
|
if (settings.tags[key] == true && key != 'Track') {
|
||||||
|
tagList += '<option value="' + key + '">' + key + '</option>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.getElementById('selectSaveSmartPlaylistTag').innerHTML = tagList;
|
||||||
|
if (obj.data.type == 'search') {
|
||||||
|
document.getElementById('saveSmartPlaylistSearch').classList.remove('hide');
|
||||||
|
document.getElementById('selectSaveSmartPlaylistTag').value = obj.data.tag;
|
||||||
|
document.getElementById('inputSaveSmartPlaylistSearchstr').value = obj.data.searchstr;
|
||||||
|
}
|
||||||
|
else if (obj.data.type == 'sticker') {
|
||||||
|
document.getElementById('saveSmartPlaylistSticker').classList.remove('hide');
|
||||||
|
document.getElementById('selectSaveSmartPlaylistSticker').value = obj.data.sticker;
|
||||||
|
document.getElementById('inputSaveSmartPlaylistStickerMaxentries').value = obj.data.maxentries;
|
||||||
|
}
|
||||||
|
else if (obj.data.type == 'newest') {
|
||||||
|
document.getElementById('saveSmartPlaylistNewest').classList.remove('hide');
|
||||||
|
var timerange = obj.data.timerange / 24 / 60 / 60;
|
||||||
|
document.getElementById('inputSaveSmartPlaylistNewestTimerange').value = timerange;
|
||||||
|
document.getElementById('inputSaveSmartPlaylistNewestMaxentries').value = obj.data.maxentries;
|
||||||
|
}
|
||||||
|
modalSaveSmartPlaylist.show();
|
||||||
|
nameEl.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function chkInt(el, frm) {
|
||||||
|
var value = el.value.replace(/\d/g,'');
|
||||||
|
if (value != '') {
|
||||||
|
el.classList.add('is-invalid');
|
||||||
|
frm.classList.add('was-validated');
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
el.classList.remove('is-invalid');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveSmartPlaylist() {
|
||||||
|
var name = document.getElementById('saveSmartPlaylistName').value;
|
||||||
|
var type = document.getElementById('saveSmartPlaylistType').value;
|
||||||
|
var valid = name.replace(/[\w\-]/g, '');
|
||||||
|
var frm = document.getElementById('saveSmartPlaylistFrm');
|
||||||
|
if (name != '' && valid == '') {
|
||||||
|
if (type == 'search') {
|
||||||
|
var tagEl = document.getElementById('selectSaveSmartPlaylistTag');
|
||||||
|
var tag = tagEl.options[tagEl.selectedIndex].value;
|
||||||
|
var searchstr = document.getElementById('inputSaveSmartPlaylistSearchstr').value;
|
||||||
|
sendAPI({"cmd": "MPD_API_SMARTPLS_SAVE", "data": {"type": type, "playlist": name, "tag": tag, "searchstr": searchstr}});
|
||||||
|
} else if (type == 'sticker') {
|
||||||
|
var stickerEl = document.getElementById('selectSaveSmartPlaylistSticker');
|
||||||
|
var sticker = stickerEl.options[stickerEl.selectedIndex].value;
|
||||||
|
var maxentriesEl = document.getElementById('inputSaveSmartPlaylistStickerMaxentries');
|
||||||
|
if (!chkInt(maxentriesEl, frm))
|
||||||
|
return;
|
||||||
|
var maxentries = maxentriesEl.value;
|
||||||
|
sendAPI({"cmd": "MPD_API_SMARTPLS_SAVE", "data": {"type": type, "playlist": name, "sticker": sticker, "maxentries": maxentries}});
|
||||||
|
} else if (type == 'newest') {
|
||||||
|
var timerangeEl = document.getElementById('inputSaveSmartPlaylistNewestTimerange');
|
||||||
|
if (!chkInt(timerangeEl, frm))
|
||||||
|
return;
|
||||||
|
var timerange = parseInt(timerangeEl.value) * 60 * 60 * 24;
|
||||||
|
var maxentriesEl = document.getElementById('inputSaveSmartPlaylistNewestMaxentries');
|
||||||
|
if (!chkInt(maxentriesEl, frm))
|
||||||
|
return;
|
||||||
|
var maxentries = maxentriesEl.value;
|
||||||
|
sendAPI({"cmd": "MPD_API_SMARTPLS_SAVE", "data": {"type": type, "playlist": name, "timerange": timerange, "maxentries": maxentries}});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.getElementById('saveSmartPlaylistType').classList.add('is-invalid');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
modalSaveSmartPlaylist.hide();
|
||||||
|
showNotification('Saved smart playlist ' + name, '', '', 'success');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.getElementById('saveSmartPlaylistName').classList.add('is-invalid');
|
||||||
|
frm.classList.add('was-validated');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showAddToPlaylist(uri) {
|
function showAddToPlaylist(uri) {
|
||||||
document.getElementById('addToPlaylistUri').value = uri;
|
document.getElementById('addToPlaylistUri').value = uri;
|
||||||
document.getElementById('addToPlaylistPlaylist').innerHTML = '';
|
document.getElementById('addToPlaylistPlaylist').innerHTML = '';
|
||||||
@ -1636,7 +1775,7 @@ function addToPlaylist() {
|
|||||||
var plist = plistEl.options[plistEl.selectedIndex].text;
|
var plist = plistEl.options[plistEl.selectedIndex].text;
|
||||||
if (plist == 'New Playlist') {
|
if (plist == 'New Playlist') {
|
||||||
var newPl = document.getElementById('addToPlaylistNewPlaylist').value;
|
var newPl = document.getElementById('addToPlaylistNewPlaylist').value;
|
||||||
var valid = newPl.replace(/\w\-/g, '');
|
var valid = newPl.replace(/[\w\-]/g, '');
|
||||||
if (newPl != '' && valid == '') {
|
if (newPl != '' && valid == '') {
|
||||||
plist = newPl;
|
plist = newPl;
|
||||||
} else {
|
} else {
|
||||||
@ -1684,7 +1823,7 @@ function showRenamePlaylist(from) {
|
|||||||
function renamePlaylist() {
|
function renamePlaylist() {
|
||||||
var from = document.getElementById('renamePlaylistFrom').value;
|
var from = document.getElementById('renamePlaylistFrom').value;
|
||||||
var to = document.getElementById('renamePlaylistTo').value;
|
var to = document.getElementById('renamePlaylistTo').value;
|
||||||
var valid = to.replace(/\w\-/g, '');
|
var valid = to.replace(/[\w\-]/g, '');
|
||||||
if (to != '' && to != from && valid == '') {
|
if (to != '' && to != from && valid == '') {
|
||||||
sendAPI({"cmd": "MPD_API_PLAYLIST_RENAME", "data": {"from": from, "to": to}});
|
sendAPI({"cmd": "MPD_API_PLAYLIST_RENAME", "data": {"from": from, "to": to}});
|
||||||
modalRenamePlaylist.hide();
|
modalRenamePlaylist.hide();
|
||||||
@ -1696,21 +1835,48 @@ function renamePlaylist() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showSmartPlaylist(playlist) {
|
||||||
|
sendAPI({"cmd": "MPD_API_SMARTPLS_GET", "data": {"playlist": playlist}}, parseSmartPlaylist);
|
||||||
|
}
|
||||||
|
|
||||||
function dirname(uri) {
|
function dirname(uri) {
|
||||||
return uri.replace(/\/[^\/]*$/, '');
|
return uri.replace(/\/[^\/]*$/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function b64EncodeUnicode(str) {
|
||||||
|
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
|
||||||
|
function toSolidBytes(match, p1) {
|
||||||
|
return String.fromCharCode('0x' + p1);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function b64DecodeUnicode(str) {
|
||||||
|
return decodeURIComponent(atob(str).split('').map(function(c) {
|
||||||
|
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||||
|
}).join(''));
|
||||||
|
}
|
||||||
|
|
||||||
function addMenuItem(href, text) {
|
function addMenuItem(href, text) {
|
||||||
return '<a class="dropdown-item" href="#" data-href=\'' + btoa(JSON.stringify(href)) + '\'>' + text +'</a>';
|
return '<a class="dropdown-item" href="#" data-href=\'' + b64EncodeUnicode(JSON.stringify(href)) + '\'>' + text +'</a>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideMenu() {
|
||||||
|
var menuEl = document.querySelector('[data-popover]');
|
||||||
|
if (menuEl) {
|
||||||
|
new Popover(menuEl, {});
|
||||||
|
menuEl.Popover.hide();
|
||||||
|
menuEl.removeAttribute('data-popover');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showMenu(el, event) {
|
function showMenu(el, event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
var oldPopover = document.getElementsByClassName('popover');
|
if (el.getAttribute('data-init'))
|
||||||
for (var i = 0; i < oldPopover.length; i++)
|
return;
|
||||||
oldPopover[i].remove();
|
|
||||||
|
hideMenu();
|
||||||
|
|
||||||
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'));
|
||||||
@ -1731,9 +1897,9 @@ function showMenu(el, event) {
|
|||||||
menu += addMenuItem({"cmd": "appendQueue", "options": [type, uri, name]}, 'Append to queue') +
|
menu += addMenuItem({"cmd": "appendQueue", "options": [type, uri, name]}, 'Append to queue') +
|
||||||
(type == 'song' ? addMenuItem({"cmd": "appendAfterQueue", "options": [type, uri, nextsongpos, name]}, 'Add after current playing song') : '') +
|
(type == 'song' ? addMenuItem({"cmd": "appendAfterQueue", "options": [type, uri, nextsongpos, name]}, 'Add after current playing song') : '') +
|
||||||
addMenuItem({"cmd": "replaceQueue", "options": [type, uri, name]}, 'Replace queue') +
|
addMenuItem({"cmd": "replaceQueue", "options": [type, uri, name]}, 'Replace queue') +
|
||||||
(type != 'plist' ? addMenuItem({"cmd": "showAddToPlaylist", "options": [uri]}, 'Add to playlist') : '') +
|
(type != 'plist' && type != 'smartpls' ? addMenuItem({"cmd": "showAddToPlaylist", "options": [uri]}, 'Add to playlist') : '') +
|
||||||
(type == 'song' ? addMenuItem({"cmd": "songDetails", "options": [uri]}, 'Songdetails') : '') +
|
(type == 'song' ? addMenuItem({"cmd": "songDetails", "options": [uri]}, 'Songdetails') : '') +
|
||||||
(type == 'plist' ? addMenuItem({"cmd": "playlistDetails", "options": [uri]}, 'Show playlist') : '');
|
(type == 'plist' || type == 'smartpls' ? addMenuItem({"cmd": "playlistDetails", "options": [uri]}, 'View playlist') : '');
|
||||||
if (app.current.app == 'Search') {
|
if (app.current.app == 'Search') {
|
||||||
var baseuri = dirname(uri);
|
var baseuri = dirname(uri);
|
||||||
menu += '<div class="dropdown-divider"></div>' +
|
menu += '<div class="dropdown-divider"></div>' +
|
||||||
@ -1749,9 +1915,11 @@ function showMenu(el, event) {
|
|||||||
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 += addMenuItem({"cmd": "appendQueue", "options": [type, uri, name]}, 'Append to queue') +
|
menu += addMenuItem({"cmd": "appendQueue", "options": [type, uri, name]}, 'Append to queue') +
|
||||||
addMenuItem({"cmd": "replaceQueue", "options": [type, uri, name]},'Replace queue') +
|
addMenuItem({"cmd": "replaceQueue", "options": [type, uri, name]},'Replace queue') +
|
||||||
addMenuItem({"cmd": "playlistDetails", "options": [uri]}, 'Edit playlist') +
|
(type == 'smartpls' ? addMenuItem({"cmd": "playlistDetails", "options": [uri]}, 'View playlist') : addMenuItem({"cmd": "playlistDetails", "options": [uri]}, 'Edit playlist'))+
|
||||||
addMenuItem({"cmd": "showRenamePlaylist", "options": [uri]}, 'Rename playlist') +
|
(type == 'smartpls' ? addMenuItem({"cmd": "showSmartPlaylist", "options": [uri]}, 'Edit smart playlist') : '') +
|
||||||
addMenuItem({"cmd": "delPlaylist", "options": [uri]}, 'Delete playlist');
|
(uri.indexOf('myMPDsmart') != 0 ?
|
||||||
|
addMenuItem({"cmd": "showRenamePlaylist", "options": [uri]}, 'Rename playlist') +
|
||||||
|
addMenuItem({"cmd": "delPlaylist", "options": [uri]}, 'Delete playlist') : '');
|
||||||
}
|
}
|
||||||
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'Detail') {
|
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'Detail') {
|
||||||
var x = document.getElementById('BrowsePlaylistsDetailList');
|
var x = document.getElementById('BrowsePlaylistsDetailList');
|
||||||
@ -1759,7 +1927,8 @@ function showMenu(el, event) {
|
|||||||
addMenuItem({"cmd": "replaceQueue", "options": [type, uri, name]}, 'Replace queue') +
|
addMenuItem({"cmd": "replaceQueue", "options": [type, uri, name]}, 'Replace queue') +
|
||||||
(x.getAttribute('data-ro') == 'false' ? addMenuItem({"cmd": "removeFromPlaylist", "options": [x.getAttribute('data-uri'),
|
(x.getAttribute('data-ro') == 'false' ? addMenuItem({"cmd": "removeFromPlaylist", "options": [x.getAttribute('data-uri'),
|
||||||
el.parentNode.parentNode.getAttribute('data-songpos')]}, 'Remove') : '') +
|
el.parentNode.parentNode.getAttribute('data-songpos')]}, 'Remove') : '') +
|
||||||
(type != 'plist' ? addMenuItem({"cmd": "showAddToPlaylist", "options": [uri]}, 'Add to playlist') : '');
|
addMenuItem({"cmd": "showAddToPlaylist", "options": [uri]}, 'Add to playlist') +
|
||||||
|
(uri.indexOf('http') == -1 ? addMenuItem({"cmd": "songDetails", "options": [uri]}, 'Songdetails') : '');
|
||||||
}
|
}
|
||||||
else if (app.current.app == 'Queue') {
|
else if (app.current.app == 'Queue') {
|
||||||
menu += addMenuItem({"cmd": "delQueueSong", "options": ["single", el.parentNode.parentNode.getAttribute('data-trackid')]}, 'Remove') +
|
menu += addMenuItem({"cmd": "delQueueSong", "options": ["single", el.parentNode.parentNode.getAttribute('data-trackid')]}, 'Remove') +
|
||||||
@ -1767,27 +1936,22 @@ function showMenu(el, event) {
|
|||||||
addMenuItem({"cmd": "delQueueSong", "options": ["range", (parseInt(el.parentNode.parentNode.getAttribute('data-songpos'))-1), -1]}, 'Remove all downwards') +
|
addMenuItem({"cmd": "delQueueSong", "options": ["range", (parseInt(el.parentNode.parentNode.getAttribute('data-songpos'))-1), -1]}, 'Remove all downwards') +
|
||||||
(uri.indexOf('http') == -1 ? addMenuItem({"cmd": "songDetails", "options": [uri]}, 'Songdetails') : '');
|
(uri.indexOf('http') == -1 ? addMenuItem({"cmd": "songDetails", "options": [uri]}, 'Songdetails') : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
new Popover(el, { trigger: 'click', delay: 0, dismissible: true, template: '<div class="popover" role="tooltip">' +
|
new Popover(el, { trigger: 'click', delay: 0, dismissible: true, 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;
|
||||||
|
|
||||||
if (el.getAttribute('data-init')) {
|
|
||||||
popoverInit.show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
el.setAttribute('data-init', 'true');
|
el.setAttribute('data-init', 'true');
|
||||||
el.addEventListener('shown.bs.popover', function(event) {
|
el.addEventListener('shown.bs.popover', function(event) {
|
||||||
|
event.target.setAttribute('data-popover', 'true');
|
||||||
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 dh = event.target.getAttribute('data-href');
|
||||||
if (dh) {
|
if (dh) {
|
||||||
var cmd = JSON.parse(atob(dh));
|
var cmd = JSON.parse(b64DecodeUnicode(dh));
|
||||||
if (typeof window[cmd.cmd] === 'function') {
|
if (typeof window[cmd.cmd] === 'function') {
|
||||||
switch(cmd.cmd) {
|
switch(cmd.cmd) {
|
||||||
case 'sendAPI':
|
case 'sendAPI':
|
||||||
@ -1797,7 +1961,7 @@ function showMenu(el, event) {
|
|||||||
window[cmd.cmd](... cmd.options);
|
window[cmd.cmd](... cmd.options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
popoverInit.hide();
|
hideMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
@ -1932,6 +2096,20 @@ function confirmSettings() {
|
|||||||
formOK = false;
|
formOK = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var inputJukeboxQueueLength = document.getElementById('inputJukeboxQueueLength');
|
||||||
|
var value = parseInt(inputJukeboxQueueLength.value);
|
||||||
|
if (!isNaN(value)) {
|
||||||
|
if (value > 0) {
|
||||||
|
inputJukeboxQueueLength.value = value;
|
||||||
|
} else {
|
||||||
|
inputJukeboxQueueLength.classList.add('is-invalid');
|
||||||
|
formOK = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
inputJukeboxQueueLength.classList.add('is-invalid');
|
||||||
|
formOK = false;
|
||||||
|
}
|
||||||
if (settings.mixramp) {
|
if (settings.mixramp) {
|
||||||
var inputMixrampdb = document.getElementById('inputMixrampdb');
|
var inputMixrampdb = document.getElementById('inputMixrampdb');
|
||||||
if (!inputMixrampdb.getAttribute('disabled')) {
|
if (!inputMixrampdb.getAttribute('disabled')) {
|
||||||
@ -1959,7 +2137,8 @@ function confirmSettings() {
|
|||||||
|
|
||||||
if (formOK == true) {
|
if (formOK == true) {
|
||||||
var selectReplaygain = document.getElementById('selectReplaygain');
|
var selectReplaygain = document.getElementById('selectReplaygain');
|
||||||
var selectJukeboxPlaylist = document.getElementById('jukeboxPlaylist');
|
var selectJukeboxPlaylist = document.getElementById('selectJukeboxPlaylist');
|
||||||
|
var selectJukeboxMode = document.getElementById('selectJukeboxMode');
|
||||||
sendAPI({"cmd": "MPD_API_SETTINGS_SET", "data": {
|
sendAPI({"cmd": "MPD_API_SETTINGS_SET", "data": {
|
||||||
"consume": (document.getElementById('btnConsume').classList.contains('active') ? 1 : 0),
|
"consume": (document.getElementById('btnConsume').classList.contains('active') ? 1 : 0),
|
||||||
"random": (document.getElementById('btnRandom').classList.contains('active') ? 1 : 0),
|
"random": (document.getElementById('btnRandom').classList.contains('active') ? 1 : 0),
|
||||||
@ -1971,8 +2150,9 @@ function confirmSettings() {
|
|||||||
"mixrampdelay": (settings.mixramp == true ? document.getElementById('inputMixrampdelay').value : settings.mixrampdelay),
|
"mixrampdelay": (settings.mixramp == true ? document.getElementById('inputMixrampdelay').value : settings.mixrampdelay),
|
||||||
"notificationWeb": (document.getElementById('btnnotifyWeb').classList.contains('active') ? true : false),
|
"notificationWeb": (document.getElementById('btnnotifyWeb').classList.contains('active') ? true : false),
|
||||||
"notificationPage": (document.getElementById('btnnotifyPage').classList.contains('active') ? true : false),
|
"notificationPage": (document.getElementById('btnnotifyPage').classList.contains('active') ? true : false),
|
||||||
"jukeboxMode": (document.getElementById('btnJukebox').classList.contains('active') ? true : false),
|
"jukeboxMode": selectJukeboxMode.options[selectJukeboxMode.selectedIndex].value,
|
||||||
"jukeboxPlaylist": selectJukeboxPlaylist.options[selectJukeboxPlaylist.selectedIndex].value
|
"jukeboxPlaylist": selectJukeboxPlaylist.options[selectJukeboxPlaylist.selectedIndex].value,
|
||||||
|
"jukeboxQueueLength": document.getElementById('inputJukeboxQueueLength').value
|
||||||
}}, getSettings);
|
}}, getSettings);
|
||||||
modalSettings.hide();
|
modalSettings.hide();
|
||||||
} else
|
} else
|
||||||
@ -2021,12 +2201,13 @@ function gotoPage(x) {
|
|||||||
|
|
||||||
function saveQueue() {
|
function saveQueue() {
|
||||||
var plName = document.getElementById('saveQueueName').value;
|
var plName = document.getElementById('saveQueueName').value;
|
||||||
var valid = plName.replace(/\w\-/g, '');
|
var valid = plName.replace(/[\w\-]/g, '');
|
||||||
if (plName != '' && valid == '') {
|
if (plName != '' && valid == '') {
|
||||||
sendAPI({"cmd": "MPD_API_QUEUE_SAVE", "data": {"plist": plName}});
|
sendAPI({"cmd": "MPD_API_QUEUE_SAVE", "data": {"plist": plName}});
|
||||||
modalSavequeue.hide();
|
modalSavequeue.hide();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
alert(valid);
|
||||||
document.getElementById('saveQueueName').classList.add('is-invalid');
|
document.getElementById('saveQueueName').classList.add('is-invalid');
|
||||||
document.getElementById('saveQueueFrm').classList.add('was-validated');
|
document.getElementById('saveQueueFrm').classList.add('was-validated');
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
var CACHE = 'myMPD-cache-v4.2.1';
|
var CACHE = 'myMPD-cache-v4.3.0';
|
||||||
var urlsToCache = [
|
var urlsToCache = [
|
||||||
'/',
|
'/',
|
||||||
'/player.html',
|
'/player.html',
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
./mkclean.sh
|
./mkclean.sh
|
||||||
tar -czvf ../mympd_4.2.1.orig.tar.gz *
|
tar -czvf ../mympd_4.3.0.orig.tar.gz *
|
||||||
dpkg-buildpackage -rfakeroot
|
dpkg-buildpackage -rfakeroot
|
||||||
|
@ -46,7 +46,10 @@ make
|
|||||||
sudo make install
|
sudo make install
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
debian/postinst
|
sudo debian/postinst
|
||||||
|
|
||||||
echo "Running cppcheck"
|
if [ -x /usr/bin/cppcheck ]
|
||||||
[ -x /usr/bin/cppcheck ] && cppcheck --enable=warning --inconclusive --force --inline-suppr src/*.c src/*.h
|
then
|
||||||
|
echo "Running cppcheck"
|
||||||
|
cppcheck --enable=warning --inconclusive --force --inline-suppr src/*.c src/*.h
|
||||||
|
fi
|
||||||
|
681
src/mpd_client.c
681
src/mpd_client.c
@ -54,9 +54,10 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
|||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
char *cmd;
|
char *cmd;
|
||||||
unsigned int uint_buf1, uint_buf2, uint_rc;
|
unsigned int uint_buf1, uint_buf2, uint_rc;
|
||||||
int je, int_buf, int_rc;
|
int je, int_buf1, int_buf2, int_rc;
|
||||||
float float_buf;
|
float float_buf;
|
||||||
char *p_charbuf1, *p_charbuf2, *p_charbuf3;
|
char *p_charbuf1, *p_charbuf2, *p_charbuf3, *p_charbuf4;
|
||||||
|
char p_char[4];
|
||||||
enum mpd_cmd_ids cmd_id;
|
enum mpd_cmd_ids cmd_id;
|
||||||
struct pollfd fds[1];
|
struct pollfd fds[1];
|
||||||
int pollrc;
|
int pollrc;
|
||||||
@ -112,24 +113,30 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
|||||||
n = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.last_song_id, &mpd.queue_version, &mpd.queue_length);
|
n = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.last_song_id, &mpd.queue_version, &mpd.queue_length);
|
||||||
break;
|
break;
|
||||||
case MPD_API_SETTINGS_SET:
|
case MPD_API_SETTINGS_SET:
|
||||||
je = json_scanf(msg.p, msg.len, "{data: {notificationWeb: %B, notificationPage: %B, jukeboxMode: %B, jukeboxPlaylist: %Q}}",
|
je = json_scanf(msg.p, msg.len, "{data: {notificationWeb: %B}}", &mympd_state.notificationWeb);
|
||||||
&mympd_state.notificationWeb,
|
if (je == 1)
|
||||||
&mympd_state.notificationPage,
|
mympd_state_set("notificationWeb", (mympd_state.notificationWeb == true ? "true" : "false"));
|
||||||
&mympd_state.jukeboxMode,
|
|
||||||
&mympd_state.jukeboxPlaylist);
|
|
||||||
if (je == 4) {
|
|
||||||
char tmp_file[200];
|
|
||||||
snprintf(tmp_file, 200, "%s.tmp", config.statefile);
|
|
||||||
json_fprintf(tmp_file, "{notificationWeb: %B, notificationPage: %B, jukeboxMode: %B, jukeboxPlaylist: %Q}",
|
|
||||||
mympd_state.notificationWeb,
|
|
||||||
mympd_state.notificationPage,
|
|
||||||
mympd_state.jukeboxMode,
|
|
||||||
mympd_state.jukeboxPlaylist);
|
|
||||||
rename(tmp_file, config.statefile);
|
|
||||||
if (mympd_state.jukeboxMode == true)
|
|
||||||
mympd_jukebox();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
je = json_scanf(msg.p, msg.len, "{data: {notificationPage: %B}}", &mympd_state.notificationPage);
|
||||||
|
if (je == 1)
|
||||||
|
mympd_state_set("notificationPage", (mympd_state.notificationPage == true ? "true" : "false"));
|
||||||
|
|
||||||
|
je = json_scanf(msg.p, msg.len, "{data: {jukeboxMode: %d}}", &mympd_state.jukeboxMode);
|
||||||
|
if (je == 1) {
|
||||||
|
snprintf(p_char, 4, "%d", mympd_state.jukeboxMode);
|
||||||
|
mympd_state_set("jukeboxMode", p_char);
|
||||||
|
}
|
||||||
|
|
||||||
|
je = json_scanf(msg.p, msg.len, "{data: {jukeboxPlaylist: %Q}}", &mympd_state.jukeboxPlaylist);
|
||||||
|
if (je == 1)
|
||||||
|
mympd_state_set("jukeboxPlaylist", mympd_state.jukeboxPlaylist);
|
||||||
|
|
||||||
|
je = json_scanf(msg.p, msg.len, "{data: {jukeboxQueueLength: %d}}", &mympd_state.jukeboxQueueLength);
|
||||||
|
if (je == 1) {
|
||||||
|
snprintf(p_char, 4, "%d", mympd_state.jukeboxQueueLength);
|
||||||
|
mympd_state_set("jukeboxQueueLength", p_char);
|
||||||
|
}
|
||||||
|
|
||||||
je = json_scanf(msg.p, msg.len, "{data: {random: %u}}", &uint_buf1);
|
je = json_scanf(msg.p, msg.len, "{data: {random: %u}}", &uint_buf1);
|
||||||
if (je == 1)
|
if (je == 1)
|
||||||
mpd_run_random(mpd.conn, uint_buf1);
|
mpd_run_random(mpd.conn, uint_buf1);
|
||||||
@ -160,7 +167,7 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
|||||||
mpd_run_mixrampdelay(mpd.conn, float_buf);
|
mpd_run_mixrampdelay(mpd.conn, float_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
je = json_scanf(msg.p, msg.len, "{data: {replaygain:%Q}}", &p_charbuf1);
|
je = json_scanf(msg.p, msg.len, "{data: {replaygain: %Q}}", &p_charbuf1);
|
||||||
if (je == 1) {
|
if (je == 1) {
|
||||||
mpd_send_command(mpd.conn, "replay_gain_mode", p_charbuf1, NULL);
|
mpd_send_command(mpd.conn, "replay_gain_mode", p_charbuf1, NULL);
|
||||||
struct mpd_pair *pair;
|
struct mpd_pair *pair;
|
||||||
@ -169,6 +176,8 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
|||||||
}
|
}
|
||||||
free(p_charbuf1);
|
free(p_charbuf1);
|
||||||
}
|
}
|
||||||
|
if (mympd_state.jukeboxMode > 0)
|
||||||
|
mympd_jukebox();
|
||||||
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_WELCOME:
|
case MPD_API_WELCOME:
|
||||||
@ -183,7 +192,49 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
|||||||
uint_rc = mpd_run_rescan(mpd.conn, NULL);
|
uint_rc = mpd_run_rescan(mpd.conn, NULL);
|
||||||
if (uint_rc > 0)
|
if (uint_rc > 0)
|
||||||
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_SMARTPLS_UPDATE_ALL:
|
||||||
|
uint_rc = mympd_smartpls_update_all();
|
||||||
|
if (uint_rc == 0)
|
||||||
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"Smart Playlists updated\"}");
|
||||||
|
else
|
||||||
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Smart Playlists update failed\"}");
|
||||||
|
break;
|
||||||
|
case MPD_API_SMARTPLS_SAVE:
|
||||||
|
je = json_scanf(msg.p, msg.len, "{data: {type: %Q}}", &p_charbuf1);
|
||||||
|
if (je == 1) {
|
||||||
|
if (strcmp(p_charbuf1, "sticker") == 0) {
|
||||||
|
je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q, sticker: %Q, maxentries: %d}}", &p_charbuf2, &p_charbuf3, &int_buf1);
|
||||||
|
n = mympd_smartpls_save(p_charbuf1, p_charbuf2, p_charbuf3, NULL, int_buf1, 0);
|
||||||
|
free(p_charbuf2);
|
||||||
|
free(p_charbuf3);
|
||||||
|
}
|
||||||
|
else if (strcmp(p_charbuf1, "newest") == 0) {
|
||||||
|
je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q, timerange: %d, maxentries: %d}}", &p_charbuf2, &int_buf1, &int_buf2);
|
||||||
|
n = mympd_smartpls_save(p_charbuf1, p_charbuf2, NULL, NULL, int_buf2, int_buf1);
|
||||||
|
free(p_charbuf2);
|
||||||
|
}
|
||||||
|
else if (strcmp(p_charbuf1, "search") == 0) {
|
||||||
|
je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q, tag: %Q, searchstr: %Q}}", &p_charbuf2, &p_charbuf3, &p_charbuf4);
|
||||||
|
n = mympd_smartpls_save(p_charbuf1, p_charbuf2, p_charbuf3, p_charbuf4, 0, 0);
|
||||||
|
free(p_charbuf2);
|
||||||
|
free(p_charbuf3);
|
||||||
|
free(p_charbuf4);
|
||||||
|
}
|
||||||
|
free(p_charbuf1);
|
||||||
|
}
|
||||||
|
if (n == 0)
|
||||||
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||||
|
else
|
||||||
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Error saving playlist\"}");
|
||||||
|
break;
|
||||||
|
case MPD_API_SMARTPLS_GET:
|
||||||
|
je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q}}", &p_charbuf1);
|
||||||
|
if (je == 1) {
|
||||||
|
n = mympd_smartpls_put(mpd.buf, p_charbuf1);
|
||||||
|
free(p_charbuf1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MPD_API_PLAYER_PAUSE:
|
case MPD_API_PLAYER_PAUSE:
|
||||||
mpd_run_toggle_pause(mpd.conn);
|
mpd_run_toggle_pause(mpd.conn);
|
||||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||||
@ -330,8 +381,24 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
|||||||
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) {
|
||||||
mpd_run_rename(mpd.conn, p_charbuf1, p_charbuf2);
|
//rename smart playlist
|
||||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"Renamed playlist %s to %s\"}", p_charbuf1, p_charbuf2);
|
char old_pl_file[400];
|
||||||
|
char new_pl_file[400];
|
||||||
|
snprintf(old_pl_file, 400, "%s/smartpls/%s", config.varlibdir, p_charbuf1);
|
||||||
|
snprintf(new_pl_file, 400, "%s/smartpls/%s", config.varlibdir, p_charbuf2);
|
||||||
|
if (access(old_pl_file, F_OK ) != -1) {
|
||||||
|
if (access(new_pl_file, F_OK ) == -1) {
|
||||||
|
rename(old_pl_file, new_pl_file);
|
||||||
|
//rename mpd playlist
|
||||||
|
mpd_run_rename(mpd.conn, p_charbuf1, p_charbuf2);
|
||||||
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"Renamed playlist %s to %s\"}", p_charbuf1, p_charbuf2);
|
||||||
|
} else
|
||||||
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Renamed playlist %s already exists\"}", p_charbuf2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mpd_run_rename(mpd.conn, p_charbuf1, p_charbuf2);
|
||||||
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"Renamed playlist %s to %s\"}", p_charbuf1, p_charbuf2);
|
||||||
|
}
|
||||||
free(p_charbuf1);
|
free(p_charbuf1);
|
||||||
free(p_charbuf2);
|
free(p_charbuf2);
|
||||||
}
|
}
|
||||||
@ -385,9 +452,9 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MPD_API_QUEUE_ADD_TRACK_AFTER:
|
case MPD_API_QUEUE_ADD_TRACK_AFTER:
|
||||||
je = json_scanf(msg.p, msg.len, "{data: {uri:%Q, to:%d}}", &p_charbuf1, &int_buf);
|
je = json_scanf(msg.p, msg.len, "{data: {uri:%Q, to:%d}}", &p_charbuf1, &int_buf1);
|
||||||
if (je == 2) {
|
if (je == 2) {
|
||||||
int_rc = mpd_run_add_id_to(mpd.conn, p_charbuf1, int_buf);
|
int_rc = mpd_run_add_id_to(mpd.conn, p_charbuf1, int_buf1);
|
||||||
if (int_rc > -1 )
|
if (int_rc > -1 )
|
||||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||||
free(p_charbuf1);
|
free(p_charbuf1);
|
||||||
@ -414,9 +481,9 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
|||||||
case MPD_API_QUEUE_ADD_PLAY_TRACK:
|
case MPD_API_QUEUE_ADD_PLAY_TRACK:
|
||||||
je = json_scanf(msg.p, msg.len, "{data: {uri:%Q}}", &p_charbuf1);
|
je = json_scanf(msg.p, msg.len, "{data: {uri:%Q}}", &p_charbuf1);
|
||||||
if (je == 1) {
|
if (je == 1) {
|
||||||
int_buf = mpd_run_add_id(mpd.conn, p_charbuf1);
|
int_buf1 = mpd_run_add_id(mpd.conn, p_charbuf1);
|
||||||
if (int_buf != -1)
|
if (int_buf1 != -1)
|
||||||
mpd_run_play_id(mpd.conn, int_buf);
|
mpd_run_play_id(mpd.conn, int_buf1);
|
||||||
free(p_charbuf1);
|
free(p_charbuf1);
|
||||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||||
}
|
}
|
||||||
@ -479,6 +546,12 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
|||||||
case MPD_API_PLAYLIST_RM:
|
case MPD_API_PLAYLIST_RM:
|
||||||
je = json_scanf(msg.p, msg.len, "{data: {uri:%Q}}", &p_charbuf1);
|
je = json_scanf(msg.p, msg.len, "{data: {uri:%Q}}", &p_charbuf1);
|
||||||
if (je == 1) {
|
if (je == 1) {
|
||||||
|
//remove smart playlist
|
||||||
|
char pl_file[400];
|
||||||
|
snprintf(pl_file, 400, "%s/smartpls/%s", config.varlibdir, p_charbuf1);
|
||||||
|
if (access(pl_file, F_OK ) != -1 )
|
||||||
|
unlink(pl_file);
|
||||||
|
//remove mpd playlist
|
||||||
mpd_run_rm(mpd.conn, p_charbuf1);
|
mpd_run_rm(mpd.conn, p_charbuf1);
|
||||||
free(p_charbuf1);
|
free(p_charbuf1);
|
||||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||||
@ -549,13 +622,14 @@ void mympd_parse_idle(struct mg_mgr *s, int idle_bitmask) {
|
|||||||
switch(idle_event) {
|
switch(idle_event) {
|
||||||
case MPD_IDLE_DATABASE:
|
case MPD_IDLE_DATABASE:
|
||||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_database\"}");
|
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_database\"}");
|
||||||
|
mympd_smartpls_update_all();
|
||||||
break;
|
break;
|
||||||
case MPD_IDLE_STORED_PLAYLIST:
|
case MPD_IDLE_STORED_PLAYLIST:
|
||||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_stored_playlist\"}");
|
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_stored_playlist\"}");
|
||||||
break;
|
break;
|
||||||
case MPD_IDLE_QUEUE:
|
case MPD_IDLE_QUEUE:
|
||||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_queue\"}");
|
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_queue\"}");
|
||||||
if (mympd_state.jukeboxMode == true)
|
if (mympd_state.jukeboxMode > 0)
|
||||||
mympd_jukebox();
|
mympd_jukebox();
|
||||||
break;
|
break;
|
||||||
case MPD_IDLE_PLAYER:
|
case MPD_IDLE_PLAYER:
|
||||||
@ -628,6 +702,10 @@ void mympd_mpd_features() {
|
|||||||
printf("MPD don't support stickers, disabling myMPD feature\n");
|
printf("MPD don't support stickers, disabling myMPD feature\n");
|
||||||
config.stickers = false;
|
config.stickers = false;
|
||||||
}
|
}
|
||||||
|
if (config.stickers == false && config.smartpls == true) {
|
||||||
|
printf("Stickers are disabled, disabling smartplaylists\n");
|
||||||
|
config.smartpls = false;
|
||||||
|
}
|
||||||
|
|
||||||
printf("MPD supported tags: ");
|
printf("MPD supported tags: ");
|
||||||
mpd_send_list_tag_types(mpd.conn);
|
mpd_send_list_tag_types(mpd.conn);
|
||||||
@ -736,8 +814,9 @@ void mympd_idle(struct mg_mgr *s, int timeout) {
|
|||||||
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();
|
mympd_mpd_features();
|
||||||
if (mympd_state.jukeboxMode == true)
|
mympd_smartpls_update_all();
|
||||||
mympd_jukebox();
|
if (mympd_state.jukeboxMode > 0)
|
||||||
|
mympd_jukebox();
|
||||||
mpd_send_idle(mpd.conn);
|
mpd_send_idle(mpd.conn);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -929,76 +1008,129 @@ char* mympd_get_tag(struct mpd_song const *song, enum mpd_tag_type tag) {
|
|||||||
void mympd_jukebox() {
|
void mympd_jukebox() {
|
||||||
struct mpd_status *status;
|
struct mpd_status *status;
|
||||||
status = mpd_run_status(mpd.conn);
|
status = mpd_run_status(mpd.conn);
|
||||||
int queue_length, num_songs, rand_song, i;
|
int queue_length, num_songs, rand_song, i, j, addSongs;
|
||||||
struct mpd_entity *entity;
|
struct mpd_entity *entity;
|
||||||
const struct mpd_song *song;
|
const struct mpd_song *song;
|
||||||
|
struct mpd_pair *pair;
|
||||||
|
char *album;
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
printf("MPD mpd_run_status: %s\n", mpd_connection_get_error_message(mpd.conn));
|
LOG_ERROR_AND_RECOVER("mpd_run_status");
|
||||||
mpd.conn_state = MPD_FAILURE;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
queue_length = mpd_status_get_queue_length(status);
|
queue_length = mpd_status_get_queue_length(status);
|
||||||
mpd_status_free(status);
|
mpd_status_free(status);
|
||||||
if (queue_length > 0)
|
if (queue_length > mympd_state.jukeboxQueueLength)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
srand((unsigned int)time(NULL));
|
srand((unsigned int)time(NULL));
|
||||||
|
num_songs = 0;
|
||||||
if (strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) {
|
|
||||||
|
if (mympd_state.jukeboxMode == 1 && strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) {
|
||||||
struct mpd_stats *stats = mpd_run_stats(mpd.conn);
|
struct mpd_stats *stats = mpd_run_stats(mpd.conn);
|
||||||
|
if (stats == NULL) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_run_stats");
|
||||||
|
return;
|
||||||
|
}
|
||||||
num_songs = mpd_stats_get_number_of_songs(stats);
|
num_songs = mpd_stats_get_number_of_songs(stats);
|
||||||
mpd_stats_free(stats);
|
mpd_stats_free(stats);
|
||||||
num_songs--;
|
|
||||||
if (num_songs > 0) {
|
|
||||||
rand_song = rand() % num_songs;
|
|
||||||
mpd_send_list_all(mpd.conn, "/");
|
|
||||||
i = 0;
|
|
||||||
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
|
||||||
if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) {
|
|
||||||
if (i == rand_song)
|
|
||||||
break;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
mpd_entity_free(entity);
|
|
||||||
}
|
|
||||||
mpd_response_finish(mpd.conn);
|
|
||||||
song = mpd_entity_get_song(entity);
|
|
||||||
if (song != NULL) {
|
|
||||||
printf("Jukebox enabled, playing random song from database: %d/%d\n", rand_song, num_songs);
|
|
||||||
mpd_run_add(mpd.conn, mpd_song_get_uri(song));
|
|
||||||
mpd_run_play(mpd.conn);
|
|
||||||
}
|
|
||||||
mpd_entity_free(entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else if (mympd_state.jukeboxMode == 1) {
|
||||||
mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist);
|
if (!mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist)) {
|
||||||
num_songs = 0;
|
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
||||||
num_songs++;
|
num_songs++;
|
||||||
mpd_entity_free(entity);
|
mpd_entity_free(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mympd_state.jukeboxMode == 2) {
|
||||||
|
if (!mpd_search_db_tags(mpd.conn, MPD_TAG_ALBUM)) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
num_songs--;
|
if (!mpd_search_commit(mpd.conn)) {
|
||||||
if (num_songs > 0) {
|
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while ((pair = mpd_recv_pair_tag(mpd.conn, MPD_TAG_ALBUM)) != NULL) {
|
||||||
|
num_songs++;
|
||||||
|
mpd_return_pair(mpd.conn, pair);
|
||||||
|
}
|
||||||
|
mpd_response_finish(mpd.conn);
|
||||||
|
}
|
||||||
|
num_songs--;
|
||||||
|
if (mympd_state.jukeboxMode == 1)
|
||||||
|
addSongs = mympd_state.jukeboxQueueLength - queue_length;
|
||||||
|
else
|
||||||
|
addSongs = 1;
|
||||||
|
if (num_songs > 0) {
|
||||||
|
for (j = 0; j < addSongs; j++) {
|
||||||
rand_song = rand() % num_songs;
|
rand_song = rand() % num_songs;
|
||||||
mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist);
|
if (mympd_state.jukeboxMode == 1) {
|
||||||
i = 0;
|
//add songs
|
||||||
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
if (strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) {
|
||||||
if (i == rand_song)
|
if (!mpd_send_list_all(mpd.conn, "/")) {
|
||||||
break;
|
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
|
||||||
i++;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist)) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
||||||
|
if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) {
|
||||||
|
if (i == rand_song)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
mpd_entity_free(entity);
|
||||||
|
}
|
||||||
|
mpd_response_finish(mpd.conn);
|
||||||
|
song = mpd_entity_get_song(entity);
|
||||||
|
if (song != NULL) {
|
||||||
|
printf("Jukebox enabled, adding random song: %d/%d\n", rand_song, num_songs);
|
||||||
|
if (!mpd_run_add(mpd.conn, mpd_song_get_uri(song))) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
|
||||||
|
}
|
||||||
|
}
|
||||||
mpd_entity_free(entity);
|
mpd_entity_free(entity);
|
||||||
}
|
}
|
||||||
mpd_response_finish(mpd.conn);
|
else if (mympd_state.jukeboxMode == 2) {
|
||||||
song = mpd_entity_get_song(entity);
|
//add album
|
||||||
if (song != NULL) {
|
if (!mpd_search_db_tags(mpd.conn, MPD_TAG_ALBUM)) {
|
||||||
printf("Jukebox enabled, playing random song from %s: %d/%d\n", mympd_state.jukeboxPlaylist, rand_song, num_songs);
|
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
|
||||||
mpd_run_add(mpd.conn, mpd_song_get_uri(song));
|
return;
|
||||||
mpd_run_play(mpd.conn);
|
}
|
||||||
|
if (!mpd_search_commit(mpd.conn)) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while ((pair = mpd_recv_pair_tag(mpd.conn, MPD_TAG_ALBUM )) != NULL) {
|
||||||
|
if (i == rand_song) {
|
||||||
|
album = strdup(pair->value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
mpd_return_pair(mpd.conn, pair);
|
||||||
|
}
|
||||||
|
mpd_return_pair(mpd.conn, pair);
|
||||||
|
mpd_response_finish(mpd.conn);
|
||||||
|
printf("Jukebox enabled, adding random album %s: %d/%d\n", album, rand_song, num_songs);
|
||||||
|
if (!mpd_send_command(mpd.conn, "searchadd", "Album", album, NULL)) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mpd_response_finish(mpd.conn);
|
||||||
}
|
}
|
||||||
mpd_entity_free(entity);
|
|
||||||
}
|
}
|
||||||
|
mpd_run_play(mpd.conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1066,6 +1198,47 @@ int mympd_put_welcome(char *buffer) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mympd_state_get(char *name, char *value) {
|
||||||
|
char cfgfile[400];
|
||||||
|
char *line;
|
||||||
|
size_t n = 0;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
snprintf(cfgfile, 400, "%s/state/%s", config.varlibdir, name);
|
||||||
|
FILE *fp = fopen(cfgfile, "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
printf("Error opening %s", cfgfile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
read = getline(&line, &n, fp);
|
||||||
|
snprintf(value, 400, "%s", line);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("State %s: %s\n", name, value);
|
||||||
|
#endif
|
||||||
|
fclose(fp);
|
||||||
|
if (read > 0)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mympd_state_set(char *name, char *value) {
|
||||||
|
char tmpfile[400];
|
||||||
|
char cfgfile[400];
|
||||||
|
snprintf(cfgfile, 400, "%s/state/%s", config.varlibdir, name);
|
||||||
|
snprintf(tmpfile, 400, "%s/tmp/%s", config.varlibdir, name);
|
||||||
|
|
||||||
|
FILE *fp = fopen(tmpfile, "w");
|
||||||
|
if (fp == NULL) {
|
||||||
|
printf("Error opening %s", tmpfile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fprintf(fp, value);
|
||||||
|
fclose(fp);
|
||||||
|
rename(tmpfile, cfgfile);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int mympd_put_settings(char *buffer) {
|
int mympd_put_settings(char *buffer) {
|
||||||
struct mpd_status *status;
|
struct mpd_status *status;
|
||||||
char *replaygain = strdup("");
|
char *replaygain = strdup("");
|
||||||
@ -1090,8 +1263,8 @@ int mympd_put_settings(char *buffer) {
|
|||||||
len = json_printf(&out, "{type: settings, data: {"
|
len = json_printf(&out, "{type: settings, data: {"
|
||||||
"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, maxElementsPerPage: %d, "
|
"streamport: %d, coverimage: %Q, stickers: %B, mixramp: %B, smartpls: %B, maxElementsPerPage: %d, "
|
||||||
"replaygain: %Q, notificationWeb: %B, notificationPage: %B, jukeboxMode: %B, jukeboxPlaylist: %Q, "
|
"replaygain: %Q, notificationWeb: %B, notificationPage: %B, jukeboxMode: %d, jukeboxPlaylist: %Q, jukeboxQueueLength: %d, "
|
||||||
"tags: { Artist: %B, Album: %B, AlbumArtist: %B, Title: %B, Track: %B, Genre: %B, Date: %B,"
|
"tags: { Artist: %B, Album: %B, AlbumArtist: %B, Title: %B, Track: %B, Genre: %B, Date: %B,"
|
||||||
"Composer: %B, Performer: %B }"
|
"Composer: %B, Performer: %B }"
|
||||||
"}}",
|
"}}",
|
||||||
@ -1109,12 +1282,14 @@ int mympd_put_settings(char *buffer) {
|
|||||||
config.coverimage,
|
config.coverimage,
|
||||||
config.stickers,
|
config.stickers,
|
||||||
config.mixramp,
|
config.mixramp,
|
||||||
|
config.smartpls,
|
||||||
MAX_ELEMENTS_PER_PAGE,
|
MAX_ELEMENTS_PER_PAGE,
|
||||||
replaygain,
|
replaygain,
|
||||||
mympd_state.notificationWeb,
|
mympd_state.notificationWeb,
|
||||||
mympd_state.notificationPage,
|
mympd_state.notificationPage,
|
||||||
mympd_state.jukeboxMode,
|
mympd_state.jukeboxMode,
|
||||||
mympd_state.jukeboxPlaylist,
|
mympd_state.jukeboxPlaylist,
|
||||||
|
mympd_state.jukeboxQueueLength,
|
||||||
mpd.tag_artist,
|
mpd.tag_artist,
|
||||||
mpd.tag_album,
|
mpd.tag_album,
|
||||||
mpd.tag_album_artist,
|
mpd.tag_album_artist,
|
||||||
@ -1187,7 +1362,7 @@ int mympd_get_cover(const char *uri, char *cover, int cover_len) {
|
|||||||
replacechar(path, '/', '_');
|
replacechar(path, '/', '_');
|
||||||
replacechar(path, '.', '_');
|
replacechar(path, '.', '_');
|
||||||
snprintf(cover, cover_len, "%s/pics/%s.png", SRC_PATH, path);
|
snprintf(cover, cover_len, "%s/pics/%s.png", SRC_PATH, path);
|
||||||
if ( access(cover, F_OK ) == -1 ) {
|
if (access(cover, F_OK ) == -1 ) {
|
||||||
len = snprintf(cover, cover_len, "/assets/coverimage-httpstream.png");
|
len = snprintf(cover, cover_len, "/assets/coverimage-httpstream.png");
|
||||||
} else {
|
} else {
|
||||||
len = snprintf(cover, cover_len, "/pics/%s.png", path);
|
len = snprintf(cover, cover_len, "/pics/%s.png", path);
|
||||||
@ -1199,7 +1374,7 @@ int mympd_get_cover(const char *uri, char *cover, int cover_len) {
|
|||||||
else {
|
else {
|
||||||
dirname(path);
|
dirname(path);
|
||||||
snprintf(cover, cover_len, "%s/library/%s/%s", SRC_PATH, path, config.coverimage);
|
snprintf(cover, cover_len, "%s/library/%s/%s", SRC_PATH, path, config.coverimage);
|
||||||
if ( access(cover, F_OK ) == -1 ) {
|
if (access(cover, F_OK ) == -1 ) {
|
||||||
len = snprintf(cover, cover_len, "/assets/coverimage-notavailable.png");
|
len = snprintf(cover, cover_len, "/assets/coverimage-notavailable.png");
|
||||||
} else {
|
} else {
|
||||||
len = snprintf(cover, cover_len, "/library/%s/%s", path, config.coverimage);
|
len = snprintf(cover, cover_len, "/library/%s/%s", path, config.coverimage);
|
||||||
@ -1370,6 +1545,8 @@ int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter
|
|||||||
unsigned int entity_count = 0;
|
unsigned int entity_count = 0;
|
||||||
unsigned int entities_returned = 0;
|
unsigned int entities_returned = 0;
|
||||||
const char *entityName;
|
const char *entityName;
|
||||||
|
char smartpls_file[400];
|
||||||
|
bool smartpls;
|
||||||
int len;
|
int len;
|
||||||
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
||||||
|
|
||||||
@ -1446,7 +1623,13 @@ int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter
|
|||||||
) {
|
) {
|
||||||
if (entities_returned ++)
|
if (entities_returned ++)
|
||||||
len += json_printf(&out, ",");
|
len += json_printf(&out, ",");
|
||||||
len += json_printf(&out, "{type: plist, uri: %Q, name: %Q}",
|
snprintf(smartpls_file, 400, "%s/smartpls/%s", config.varlibdir, plName);
|
||||||
|
if (access(smartpls_file, F_OK ) != -1)
|
||||||
|
smartpls = true;
|
||||||
|
else
|
||||||
|
smartpls = false;
|
||||||
|
len += json_printf(&out, "{type: %Q, uri: %Q, name: %Q}",
|
||||||
|
(smartpls == true ? "smartpls" : "plist"),
|
||||||
entityName,
|
entityName,
|
||||||
plName
|
plName
|
||||||
);
|
);
|
||||||
@ -1599,6 +1782,8 @@ int mympd_put_playlists(char *buffer, unsigned int offset, char *filter) {
|
|||||||
unsigned int entities_returned = 0;
|
unsigned int entities_returned = 0;
|
||||||
const char *plpath;
|
const char *plpath;
|
||||||
int len;
|
int len;
|
||||||
|
bool smartpls;
|
||||||
|
char smartpls_file[400];
|
||||||
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
||||||
|
|
||||||
if (!mpd_send_list_playlists(mpd.conn))
|
if (!mpd_send_list_playlists(mpd.conn))
|
||||||
@ -1615,7 +1800,13 @@ int mympd_put_playlists(char *buffer, unsigned int offset, char *filter) {
|
|||||||
) {
|
) {
|
||||||
if (entities_returned ++)
|
if (entities_returned ++)
|
||||||
len += json_printf(&out, ", ");
|
len += json_printf(&out, ", ");
|
||||||
len += json_printf(&out, "{type: plist, uri: %Q, name: %Q, last_modified: %d}",
|
snprintf(smartpls_file, 400, "%s/smartpls/%s", config.varlibdir, plpath);
|
||||||
|
if (access(smartpls_file, F_OK ) != -1)
|
||||||
|
smartpls = true;
|
||||||
|
else
|
||||||
|
smartpls = false;
|
||||||
|
len += json_printf(&out, "{type: %Q, uri: %Q, name: %Q, last_modified: %d}",
|
||||||
|
(smartpls == true ? "smartpls" : "plist"),
|
||||||
plpath,
|
plpath,
|
||||||
plpath,
|
plpath,
|
||||||
mpd_playlist_get_last_modified(pl)
|
mpd_playlist_get_last_modified(pl)
|
||||||
@ -1646,6 +1837,8 @@ int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char *
|
|||||||
unsigned int entity_count = 0;
|
unsigned int entity_count = 0;
|
||||||
unsigned int entities_returned = 0;
|
unsigned int entities_returned = 0;
|
||||||
const char *entityName;
|
const char *entityName;
|
||||||
|
char smartpls_file[400];
|
||||||
|
bool smartpls;
|
||||||
int len;
|
int len;
|
||||||
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
||||||
|
|
||||||
@ -1679,13 +1872,18 @@ int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char *
|
|||||||
}
|
}
|
||||||
mpd_entity_free(entity);
|
mpd_entity_free(entity);
|
||||||
}
|
}
|
||||||
|
snprintf(smartpls_file, 400, "%s/smartpls/%s", config.varlibdir, uri);
|
||||||
len += json_printf(&out, "], totalEntities: %d, offset: %d, returnedEntities: %d, filter: %Q, uri: %Q}",
|
if (access(smartpls_file, F_OK ) != -1)
|
||||||
|
smartpls = true;
|
||||||
|
else
|
||||||
|
smartpls = false;
|
||||||
|
len += json_printf(&out, "], totalEntities: %d, offset: %d, returnedEntities: %d, filter: %Q, uri: %Q, smartpls: %B}",
|
||||||
entity_count,
|
entity_count,
|
||||||
offset,
|
offset,
|
||||||
entities_returned,
|
entities_returned,
|
||||||
filter,
|
filter,
|
||||||
uri
|
uri,
|
||||||
|
smartpls
|
||||||
);
|
);
|
||||||
|
|
||||||
if (len > MAX_SIZE)
|
if (len > MAX_SIZE)
|
||||||
@ -1805,7 +2003,7 @@ int mympd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char
|
|||||||
else {
|
else {
|
||||||
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 ++)
|
||||||
@ -1868,3 +2066,310 @@ void mympd_disconnect() {
|
|||||||
mpd.conn_state = MPD_DISCONNECT;
|
mpd.conn_state = MPD_DISCONNECT;
|
||||||
mympd_idle(NULL, 0);
|
mympd_idle(NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mympd_smartpls_put(char *buffer, char *playlist) {
|
||||||
|
char pl_file[400];
|
||||||
|
char *smartpltype;
|
||||||
|
char *p_charbuf1, *p_charbuf2;
|
||||||
|
int je, int_buf1, int_buf2;
|
||||||
|
int len = 0;
|
||||||
|
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
||||||
|
|
||||||
|
snprintf(pl_file, 400, "%s/smartpls/%s", config.varlibdir, playlist);
|
||||||
|
char *content = json_fread(pl_file);
|
||||||
|
je = json_scanf(content, strlen(content), "{type: %Q }", &smartpltype);
|
||||||
|
if (je == 1) {
|
||||||
|
if (strcmp(smartpltype, "sticker") == 0) {
|
||||||
|
je = json_scanf(content, strlen(content), "{sticker: %Q, maxentries: %d}", &p_charbuf1, &int_buf1);
|
||||||
|
if (je == 2) {
|
||||||
|
len = json_printf(&out, "{type: smartpls, data: {playlist: %Q, type: %Q, sticker: %Q, maxentries: %d}}",
|
||||||
|
playlist,
|
||||||
|
smartpltype,
|
||||||
|
p_charbuf1,
|
||||||
|
int_buf1);
|
||||||
|
free(p_charbuf1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(smartpltype, "newest") == 0) {
|
||||||
|
je = json_scanf(content, strlen(content), "{timerange: %d, maxentries: %d}", &int_buf1, &int_buf2);
|
||||||
|
if (je == 2) {
|
||||||
|
len = json_printf(&out, "{type: smartpls, data: {playlist: %Q, type: %Q, timerange: %d, maxentries: %d}}",
|
||||||
|
playlist,
|
||||||
|
smartpltype,
|
||||||
|
int_buf1,
|
||||||
|
int_buf2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(smartpltype, "search") == 0) {
|
||||||
|
je = json_scanf(content, strlen(content), "{tag: %Q, searchstr: %Q}", &p_charbuf1, &p_charbuf2);
|
||||||
|
if (je == 2) {
|
||||||
|
len = json_printf(&out, "{type: smartpls, data: {playlist: %Q, type: %Q, tag: %Q, searchstr: %Q}}",
|
||||||
|
playlist,
|
||||||
|
smartpltype,
|
||||||
|
p_charbuf1,
|
||||||
|
p_charbuf2);
|
||||||
|
free(p_charbuf1);
|
||||||
|
free(p_charbuf2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(smartpltype);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mympd_smartpls_save(char *smartpltype, char *playlist, char *tag, char *searchstr, int maxentries, int timerange) {
|
||||||
|
char tmp_file[400];
|
||||||
|
char pl_file[400];
|
||||||
|
snprintf(tmp_file, 400, "%s/tmp/%s", config.varlibdir, playlist);
|
||||||
|
snprintf(pl_file, 400, "%s/smartpls/%s", config.varlibdir, playlist);
|
||||||
|
if (strcmp(smartpltype, "sticker") == 0) {
|
||||||
|
json_fprintf(tmp_file, "{type: %Q, sticker: %Q, maxentries: %d}", smartpltype, tag, maxentries);
|
||||||
|
rename(tmp_file, pl_file);
|
||||||
|
mympd_smartpls_update(playlist, tag, maxentries);
|
||||||
|
}
|
||||||
|
else if (strcmp(smartpltype, "newest") == 0) {
|
||||||
|
json_fprintf(tmp_file, "{type: %Q, timerange: %d, maxentries: %d}", smartpltype, timerange, maxentries);
|
||||||
|
rename(tmp_file, pl_file);
|
||||||
|
mympd_smartpls_update_newest(playlist, timerange, maxentries);
|
||||||
|
}
|
||||||
|
else if (strcmp(smartpltype, "search") == 0) {
|
||||||
|
json_fprintf(tmp_file, "{type: %Q, tag: %Q, searchstr: %Q}", smartpltype, tag, searchstr);
|
||||||
|
rename(tmp_file, pl_file);
|
||||||
|
mympd_smartpls_update_search(playlist, tag, searchstr);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mympd_smartpls_update_all() {
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *ent;
|
||||||
|
char *smartpltype;
|
||||||
|
char filename[400];
|
||||||
|
char dirname[400];
|
||||||
|
int je;
|
||||||
|
char *p_charbuf1, *p_charbuf2;
|
||||||
|
int int_buf1, int_buf2;
|
||||||
|
|
||||||
|
if (!config.smartpls)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snprintf(dirname, 400, "%s/smartpls", config.varlibdir);
|
||||||
|
if ((dir = opendir (dirname)) != NULL) {
|
||||||
|
while ((ent = readdir(dir)) != NULL) {
|
||||||
|
if (strncmp(ent->d_name, ".", 1) == 0)
|
||||||
|
continue;
|
||||||
|
snprintf(filename, 400, "%s/smartpls/%s", config.varlibdir, ent->d_name);
|
||||||
|
char *content = json_fread(filename);
|
||||||
|
je = json_scanf(content, strlen(content), "{type: %Q }", &smartpltype);
|
||||||
|
if (je != 1)
|
||||||
|
continue;
|
||||||
|
if (strcmp(smartpltype, "sticker") == 0) {
|
||||||
|
je = json_scanf(content, strlen(content), "{sticker: %Q, maxentries: %d}", &p_charbuf1, &int_buf1);
|
||||||
|
if (je == 2) {
|
||||||
|
mympd_smartpls_update(ent->d_name, p_charbuf1, int_buf1);
|
||||||
|
free(p_charbuf1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("Can't parse file %s\n", filename);
|
||||||
|
}
|
||||||
|
else if (strcmp(smartpltype, "newest") == 0) {
|
||||||
|
je = json_scanf(content, strlen(content), "{timerange: %d, maxentries: %d}", &int_buf1, &int_buf2);
|
||||||
|
if (je == 2) {
|
||||||
|
mympd_smartpls_update_newest(ent->d_name, int_buf1, int_buf2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("Can't parse file %s\n", filename);
|
||||||
|
}
|
||||||
|
else if (strcmp(smartpltype, "search") == 0) {
|
||||||
|
je = json_scanf(content, strlen(content), "{tag: %Q, searchstr: %Q}", &p_charbuf1, &p_charbuf2);
|
||||||
|
if (je == 2) {
|
||||||
|
mympd_smartpls_update_search(ent->d_name, p_charbuf1, p_charbuf2);
|
||||||
|
free(p_charbuf1);
|
||||||
|
free(p_charbuf2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("Can't parse file %s\n", filename);
|
||||||
|
}
|
||||||
|
free(smartpltype);
|
||||||
|
}
|
||||||
|
closedir (dir);
|
||||||
|
} else {
|
||||||
|
printf("Can't open dir %s\n", dirname);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mympd_smartpls_clear(char *playlist) {
|
||||||
|
struct mpd_playlist *pl;
|
||||||
|
const char *plpath;
|
||||||
|
bool exists = false;
|
||||||
|
if (!mpd_send_list_playlists(mpd.conn)) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_send_list_playlists");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
while((pl = mpd_recv_playlist(mpd.conn)) != NULL) {
|
||||||
|
plpath = mpd_playlist_get_path(pl);
|
||||||
|
if (strcmp(playlist, plpath) == 0)
|
||||||
|
exists = true;
|
||||||
|
mpd_playlist_free(pl);
|
||||||
|
if (exists)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mpd_response_finish(mpd.conn);
|
||||||
|
|
||||||
|
if (exists) {
|
||||||
|
if (!mpd_run_rm(mpd.conn, playlist)) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_run_rm");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mympd_smartpls_update_search(char *playlist, char *tag, char *searchstr) {
|
||||||
|
mympd_smartpls_clear(playlist);
|
||||||
|
mympd_search(mpd.buf, searchstr, tag, playlist, 0);
|
||||||
|
printf("Updated %s\n", playlist);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mympd_smartpls_update(char *playlist, char *sticker, int maxentries) {
|
||||||
|
struct mpd_pair *pair;
|
||||||
|
char *uri = NULL;
|
||||||
|
char *name;
|
||||||
|
char *p_value;
|
||||||
|
char *crap;
|
||||||
|
char tmpfile[400];
|
||||||
|
long value;
|
||||||
|
long value_max = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
ssize_t read;
|
||||||
|
long i = 0;
|
||||||
|
|
||||||
|
if (!mpd_send_sticker_find(mpd.conn, "song", "", sticker)) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_send_sticker_find");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
snprintf(tmpfile, 400, "%s/tmp/playlist.tmp", config.varlibdir);
|
||||||
|
FILE *fp = fopen(tmpfile, "w");
|
||||||
|
if (fp == NULL) {
|
||||||
|
printf("Error opening %s", tmpfile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
while ((pair = mpd_recv_pair(mpd.conn)) != NULL) {
|
||||||
|
if (strcmp(pair->name, "file") == 0) {
|
||||||
|
uri = strdup(pair->value);
|
||||||
|
}
|
||||||
|
else if (strcmp(pair->name, "sticker") == 0) {
|
||||||
|
name = strtok(strdup(pair->value), "=");
|
||||||
|
p_value = strtok(NULL, "=");
|
||||||
|
value = strtol(p_value, &crap, 10);
|
||||||
|
if (value > 1)
|
||||||
|
fprintf(fp, "%s::%ld\n", uri, value);
|
||||||
|
if (value > value_max)
|
||||||
|
value_max = value;
|
||||||
|
}
|
||||||
|
mpd_return_pair(mpd.conn, pair);
|
||||||
|
}
|
||||||
|
mpd_response_finish(mpd.conn);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
mympd_smartpls_clear(playlist);
|
||||||
|
|
||||||
|
if (value_max > 2)
|
||||||
|
value_max = value_max / 2;
|
||||||
|
fp = fopen(tmpfile, "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
printf("Error opening %s", tmpfile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
while ((read = getline(&uri, &len, fp)) != -1) {
|
||||||
|
name = strtok(uri, "::");
|
||||||
|
p_value = strtok(NULL, "::");
|
||||||
|
value = strtol(p_value, &crap, 10);
|
||||||
|
if (value < value_max)
|
||||||
|
continue;
|
||||||
|
if (!mpd_run_playlist_add(mpd.conn, playlist, name)) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_run_playlist_add");
|
||||||
|
fclose(fp);
|
||||||
|
free(uri);
|
||||||
|
unlink(tmpfile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if (i >= maxentries)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
free(uri);
|
||||||
|
unlink(tmpfile);
|
||||||
|
printf("Updated %s with %ld songs, minValue: %ld\n", playlist, i, value_max);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mympd_smartpls_update_newest(char *playlist, int timerange, int maxentries) {
|
||||||
|
struct mpd_song *song;
|
||||||
|
char *uri;
|
||||||
|
char *p_value;
|
||||||
|
char *name;
|
||||||
|
char *crap;
|
||||||
|
char tmpfile[400];
|
||||||
|
time_t value;
|
||||||
|
time_t value_max = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
ssize_t read;
|
||||||
|
long i = 0;
|
||||||
|
|
||||||
|
if (!mpd_send_list_all_meta(mpd.conn, "/")) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_send_list_all_meta");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
snprintf(tmpfile, 400, "%s/tmp/playlist.tmp", config.varlibdir);
|
||||||
|
FILE *fp = fopen(tmpfile, "w");
|
||||||
|
if (fp == NULL) {
|
||||||
|
printf("Error opening %s", tmpfile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
while ((song = mpd_recv_song(mpd.conn)) != NULL) {
|
||||||
|
value = mpd_song_get_last_modified(song);
|
||||||
|
if (value > value_max)
|
||||||
|
value_max = value;
|
||||||
|
fprintf(fp, "%s::%ld\n", mpd_song_get_uri(song), value);
|
||||||
|
mpd_song_free(song);
|
||||||
|
}
|
||||||
|
mpd_response_finish(mpd.conn);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
mympd_smartpls_clear(playlist);
|
||||||
|
|
||||||
|
value_max -= timerange;
|
||||||
|
|
||||||
|
fp = fopen(tmpfile, "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
printf("Error opening %s", tmpfile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
while ((read = getline(&uri, &len, fp)) != -1) {
|
||||||
|
name = strtok(uri, "::");
|
||||||
|
p_value = strtok(NULL, "::");
|
||||||
|
value = strtol(p_value, &crap, 10);
|
||||||
|
if (value >= value_max)
|
||||||
|
continue;
|
||||||
|
if (!mpd_run_playlist_add(mpd.conn, playlist, name)) {
|
||||||
|
LOG_ERROR_AND_RECOVER("mpd_run_playlist_add");
|
||||||
|
fclose(fp);
|
||||||
|
unlink(tmpfile);
|
||||||
|
free(uri);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if (i >= maxentries)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
free(uri);
|
||||||
|
unlink(tmpfile);
|
||||||
|
printf("Updated %s with %ld songs, minValue: %ld\n", playlist, i, value_max);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include "../dist/src/mongoose/mongoose.h"
|
#include "../dist/src/mongoose/mongoose.h"
|
||||||
|
|
||||||
#define RETURN_ERROR_AND_RECOVER(X) do { \
|
#define RETURN_ERROR_AND_RECOVER(X) do { \
|
||||||
fprintf(stderr, "MPD X: %s\n", mpd_connection_get_error_message(mpd.conn)); \
|
printf("MPD X: %s\n", mpd_connection_get_error_message(mpd.conn)); \
|
||||||
len = json_printf(&out, "{ type:error, data : %Q }", \
|
len = json_printf(&out, "{ type:error, data : %Q }", \
|
||||||
mpd_connection_get_error_message(mpd.conn) \
|
mpd_connection_get_error_message(mpd.conn) \
|
||||||
); \
|
); \
|
||||||
@ -38,7 +38,7 @@
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LOG_ERROR_AND_RECOVER(X) do { \
|
#define LOG_ERROR_AND_RECOVER(X) do { \
|
||||||
fprintf(stderr, "MPD X: %s\n", mpd_connection_get_error_message(mpd.conn)); \
|
printf("MPD X: %s\n", mpd_connection_get_error_message(mpd.conn)); \
|
||||||
if (!mpd_connection_clear_error(mpd.conn)) \
|
if (!mpd_connection_clear_error(mpd.conn)) \
|
||||||
mpd.conn_state = MPD_FAILURE; \
|
mpd.conn_state = MPD_FAILURE; \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -72,6 +72,9 @@
|
|||||||
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_SMARTPLS_UPDATE_ALL) \
|
||||||
|
X(MPD_API_SMARTPLS_SAVE) \
|
||||||
|
X(MPD_API_SMARTPLS_GET) \
|
||||||
X(MPD_API_DATABASE_SEARCH) \
|
X(MPD_API_DATABASE_SEARCH) \
|
||||||
X(MPD_API_DATABASE_UPDATE) \
|
X(MPD_API_DATABASE_UPDATE) \
|
||||||
X(MPD_API_DATABASE_RESCAN) \
|
X(MPD_API_DATABASE_RESCAN) \
|
||||||
@ -157,10 +160,11 @@ typedef struct {
|
|||||||
const char* user;
|
const char* user;
|
||||||
long streamport;
|
long streamport;
|
||||||
const char* coverimage;
|
const char* coverimage;
|
||||||
const char* statefile;
|
|
||||||
bool stickers;
|
bool stickers;
|
||||||
bool mixramp;
|
bool mixramp;
|
||||||
const char* taglist;
|
const char* taglist;
|
||||||
|
bool smartpls;
|
||||||
|
const char* varlibdir;
|
||||||
} t_config;
|
} t_config;
|
||||||
|
|
||||||
t_config config;
|
t_config config;
|
||||||
@ -175,8 +179,9 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
bool notificationWeb;
|
bool notificationWeb;
|
||||||
bool notificationPage;
|
bool notificationPage;
|
||||||
bool jukeboxMode;
|
int jukeboxMode;
|
||||||
const char* jukeboxPlaylist;
|
const char* jukeboxPlaylist;
|
||||||
|
int jukeboxQueueLength;
|
||||||
} t_mympd_state;
|
} t_mympd_state;
|
||||||
|
|
||||||
t_mympd_state mympd_state;
|
t_mympd_state mympd_state;
|
||||||
@ -196,6 +201,15 @@ void mympd_last_played_song_uri(const char *uri);
|
|||||||
void mympd_last_played_song_id(int song_id);
|
void mympd_last_played_song_id(int song_id);
|
||||||
void mympd_get_sticker(const char *uri, t_sticker *sticker);
|
void mympd_get_sticker(const char *uri, t_sticker *sticker);
|
||||||
void mympd_jukebox();
|
void mympd_jukebox();
|
||||||
|
bool mympd_state_get(char *name, char *value);
|
||||||
|
bool mympd_state_set(char *name, char *value);
|
||||||
|
int mympd_smartpls_save(char *smartpltype, char *playlist, char *tag, char *searchstr, int maxentries, int timerange);
|
||||||
|
int mympd_smartpls_put(char *buffer, char *playlist);
|
||||||
|
int mympd_smartpls_update_all();
|
||||||
|
int mympd_smartpls_clear(char *playlist);
|
||||||
|
int mympd_smartpls_update(char *sticker, char *playlist, int maxentries);
|
||||||
|
int mympd_smartpls_update_newest(char *playlist, int timerange, int maxentries);
|
||||||
|
int mympd_smartpls_update_search(char *playlist, char *tag, char *searchstr);
|
||||||
int mympd_get_updatedb_state(char *buffer);
|
int mympd_get_updatedb_state(char *buffer);
|
||||||
int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length);
|
int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length);
|
||||||
int mympd_put_outputs(char *buffer);
|
int mympd_put_outputs(char *buffer);
|
||||||
|
70
src/mympd.c
70
src/mympd.c
@ -155,13 +155,18 @@ static int inihandler(void* user, const char* section, const char* name, const c
|
|||||||
p_config->streamport = strtol(value, &crap, 10);
|
p_config->streamport = strtol(value, &crap, 10);
|
||||||
else if (MATCH("coverimage"))
|
else if (MATCH("coverimage"))
|
||||||
p_config->coverimage = strdup(value);
|
p_config->coverimage = strdup(value);
|
||||||
else if (MATCH("statefile"))
|
else if (MATCH("varlibdir"))
|
||||||
p_config->statefile = strdup(value);
|
p_config->varlibdir = strdup(value);
|
||||||
else if (MATCH("stickers"))
|
else if (MATCH("stickers"))
|
||||||
if (strcmp(value, "true") == 0)
|
if (strcmp(value, "true") == 0)
|
||||||
p_config->stickers = true;
|
p_config->stickers = true;
|
||||||
else
|
else
|
||||||
p_config->stickers = false;
|
p_config->stickers = false;
|
||||||
|
else if (MATCH("smartpls"))
|
||||||
|
if (strcmp(value, "true") == 0)
|
||||||
|
p_config->smartpls = true;
|
||||||
|
else
|
||||||
|
p_config->smartpls = false;
|
||||||
else if (MATCH("mixramp"))
|
else if (MATCH("mixramp"))
|
||||||
if (strcmp(value, "true") == 0)
|
if (strcmp(value, "true") == 0)
|
||||||
p_config->mixramp = true;
|
p_config->mixramp = true;
|
||||||
@ -175,6 +180,44 @@ static int inihandler(void* user, const char* section, const char* name, const c
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void read_statefiles() {
|
||||||
|
char *crap;
|
||||||
|
char value[400];
|
||||||
|
if (mympd_state_get("notificationWeb", value)) {
|
||||||
|
if (strcmp(value, "true") == 0)
|
||||||
|
mympd_state.notificationWeb = true;
|
||||||
|
else
|
||||||
|
mympd_state.notificationWeb = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mympd_state.notificationWeb = false;
|
||||||
|
|
||||||
|
if (mympd_state_get("notificationPage", value)) {
|
||||||
|
if (strcmp(value, "true") == 0)
|
||||||
|
mympd_state.notificationPage = true;
|
||||||
|
else
|
||||||
|
mympd_state.notificationPage = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mympd_state.notificationPage = true;
|
||||||
|
|
||||||
|
|
||||||
|
if (mympd_state_get("jukeboxMode", value))
|
||||||
|
mympd_state.jukeboxMode = strtol(value, &crap, 10);
|
||||||
|
else
|
||||||
|
mympd_state.jukeboxMode = 0;
|
||||||
|
|
||||||
|
if (mympd_state_get("jukeboxPlaylist", value))
|
||||||
|
mympd_state.jukeboxPlaylist = strdup(value);
|
||||||
|
else
|
||||||
|
mympd_state.jukeboxPlaylist = "Database";
|
||||||
|
|
||||||
|
if (mympd_state_get("jukeboxQueueLength", value))
|
||||||
|
mympd_state.jukeboxQueueLength = strtol(value, &crap, 10);
|
||||||
|
else
|
||||||
|
mympd_state.jukeboxQueueLength = 1;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
struct mg_mgr mgr;
|
struct mg_mgr mgr;
|
||||||
struct mg_connection *nc;
|
struct mg_connection *nc;
|
||||||
@ -194,10 +237,11 @@ int main(int argc, char **argv) {
|
|||||||
config.user = "nobody";
|
config.user = "nobody";
|
||||||
config.streamport = 8000;
|
config.streamport = 8000;
|
||||||
config.coverimage = "folder.jpg";
|
config.coverimage = "folder.jpg";
|
||||||
config.statefile = "/var/lib/mympd/mympd.state";
|
config.varlibdir = "/var/lib/mympd";
|
||||||
config.stickers = true;
|
config.stickers = true;
|
||||||
config.mixramp = true;
|
config.mixramp = true;
|
||||||
config.taglist = "Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer";
|
config.taglist = "Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer";
|
||||||
|
config.smartpls = true;
|
||||||
|
|
||||||
mpd.timeout = 3000;
|
mpd.timeout = 3000;
|
||||||
mpd.last_update_sticker_song_id = -1;
|
mpd.last_update_sticker_song_id = -1;
|
||||||
@ -234,25 +278,7 @@ int main(int argc, char **argv) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (access( config.statefile, F_OK ) != -1 ) {
|
read_statefiles();
|
||||||
char *content = json_fread(config.statefile);
|
|
||||||
int je = json_scanf(content, strlen(content), "{notificationWeb: %B, notificationPage: %B, jukeboxMode: %B, jukeboxPlaylist: %Q}",
|
|
||||||
&mympd_state.notificationWeb,
|
|
||||||
&mympd_state.notificationPage,
|
|
||||||
&mympd_state.jukeboxMode,
|
|
||||||
&mympd_state.jukeboxPlaylist);
|
|
||||||
if (je != 4) {
|
|
||||||
mympd_state.notificationWeb = false;
|
|
||||||
mympd_state.notificationPage = true;
|
|
||||||
mympd_state.jukeboxMode = false;
|
|
||||||
mympd_state.jukeboxPlaylist = "Database";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mympd_state.notificationWeb = false;
|
|
||||||
mympd_state.notificationPage = true;
|
|
||||||
mympd_state.jukeboxMode = false;
|
|
||||||
mympd_state.jukeboxPlaylist = "Database";
|
|
||||||
}
|
|
||||||
|
|
||||||
signal(SIGTERM, signal_handler);
|
signal(SIGTERM, signal_handler);
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
Loading…
Reference in New Issue
Block a user