mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-31 13:53:00 +00:00 
			
		
		
		
	Add advanced action menus
This commit is contained in:
		| @@ -5,7 +5,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/") | |||||||
| set(CPACK_PACKAGE_VERSION_MAJOR "3") | set(CPACK_PACKAGE_VERSION_MAJOR "3") | ||||||
| set(CPACK_PACKAGE_VERSION_MINOR "1") | set(CPACK_PACKAGE_VERSION_MINOR "1") | ||||||
| set(CPACK_PACKAGE_VERSION_PATCH "0") | set(CPACK_PACKAGE_VERSION_PATCH "0") | ||||||
| >>>>>>> master |  | ||||||
|  |  | ||||||
| if(CMAKE_BUILD_TYPE MATCHES RELEASE) | if(CMAKE_BUILD_TYPE MATCHES RELEASE) | ||||||
|     set(ASSETS_PATH "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/htdocs") |     set(ASSETS_PATH "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/htdocs") | ||||||
|   | |||||||
							
								
								
									
										714
									
								
								htdocs/js/mpd.js
									
									
									
									
									
								
							
							
						
						
									
										714
									
								
								htdocs/js/mpd.js
									
									
									
									
									
								
							| @@ -34,7 +34,6 @@ var volumeBar; | |||||||
| var settings = {}; | var settings = {}; | ||||||
|  |  | ||||||
| var app = {}; | var app = {}; | ||||||
|  |  | ||||||
| app.apps = { "Playback": { "state": "0/-/" }, | app.apps = { "Playback": { "state": "0/-/" }, | ||||||
|              "Queue": 	 { "state": "0/Any Tag/" }, |              "Queue": 	 { "state": "0/Any Tag/" }, | ||||||
|              "Browse":   {  |              "Browse":   {  | ||||||
| @@ -80,9 +79,11 @@ app.prepare=function() { | |||||||
| app.goto=function(a,t,v,s) { | app.goto=function(a,t,v,s) { | ||||||
|     var hash=''; |     var hash=''; | ||||||
|     if (app.apps[a].tabs) { |     if (app.apps[a].tabs) { | ||||||
|      if (t == undefined) t = app.apps[a].active; |         if (t == undefined)  | ||||||
|  |             t = app.apps[a].active; | ||||||
|         if (app.apps[a].tabs[t].views) { |         if (app.apps[a].tabs[t].views) { | ||||||
|        if (v == undefined) v = app.apps[a].tabs[t].active; |             if (v == undefined)  | ||||||
|  |                 v = app.apps[a].tabs[t].active; | ||||||
|             hash = '/'+a+'/'+t+'/'+v+'!'+ (s == undefined ? app.apps[a].tabs[t].views[v].state : s); |             hash = '/'+a+'/'+t+'/'+v+'!'+ (s == undefined ? app.apps[a].tabs[t].views[v].state : s); | ||||||
|         } else { |         } else { | ||||||
|             hash = '/'+a+'/'+t+'!'+ (s == undefined ? app.apps[a].tabs[t].state : s); |             hash = '/'+a+'/'+t+'!'+ (s == undefined ? app.apps[a].tabs[t].state : s); | ||||||
| @@ -94,9 +95,8 @@ app.goto=function(a,t,v,s) { | |||||||
| } | } | ||||||
|  |  | ||||||
| app.route=function() { | app.route=function() { | ||||||
|     var hash=decodeURI(location.hash); |     var hash = decodeURI(location.hash); | ||||||
|     if (params=hash.match(/^\#\/(\w+)\/?(\w+)?\/?(\w+)?\!((\d+)\/([^\/]+)\/(.*))$/)) |     if (params=hash.match(/^\#\/(\w+)\/?(\w+)?\/?(\w+)?\!((\d+)\/([^\/]+)\/(.*))$/)) { | ||||||
|     { |  | ||||||
|         app.current.app = params[1]; |         app.current.app = params[1]; | ||||||
|         app.current.tab = params[2]; |         app.current.tab = params[2]; | ||||||
|         app.current.view = params[3]; |         app.current.view = params[3]; | ||||||
| @@ -105,12 +105,12 @@ app.route=function() { | |||||||
|         } |         } | ||||||
|         else if (app.apps[app.current.app].tabs[app.current.tab].state) { |         else if (app.apps[app.current.app].tabs[app.current.tab].state) { | ||||||
|             app.apps[app.current.app].tabs[app.current.tab].state = params[4]; |             app.apps[app.current.app].tabs[app.current.tab].state = params[4]; | ||||||
|            app.apps[app.current.app].active=app.current.tab; |             app.apps[app.current.app].active = app.current.tab; | ||||||
|         } |         } | ||||||
|         else if (app.apps[app.current.app].tabs[app.current.tab].views[app.current.view].state) { |         else if (app.apps[app.current.app].tabs[app.current.tab].views[app.current.view].state) { | ||||||
|             app.apps[app.current.app].tabs[app.current.tab].views[app.current.view].state = params[4]; |             app.apps[app.current.app].tabs[app.current.tab].views[app.current.view].state = params[4]; | ||||||
|           app.apps[app.current.app].active=app.current.tab; |             app.apps[app.current.app].active = app.current.tab; | ||||||
|           app.apps[app.current.app].tabs[app.current.tab].active=app.current.view; |             app.apps[app.current.app].tabs[app.current.tab].active = app.current.view; | ||||||
|         } |         } | ||||||
|         app.current.page = parseInt(params[5]); |         app.current.page = parseInt(params[5]); | ||||||
|         app.current.filter = params[6]; |         app.current.filter = params[6]; | ||||||
| @@ -122,84 +122,93 @@ app.route=function() { | |||||||
|  |  | ||||||
|     app.prepare(); |     app.prepare(); | ||||||
|     if (app.current.app == 'Playback') { |     if (app.current.app == 'Playback') { | ||||||
|         sendAPI({"cmd":"MPD_API_GET_CURRENT_SONG"},songChange); |         sendAPI({"cmd":"MPD_API_GET_CURRENT_SONG"}, songChange); | ||||||
|     }     |     }     | ||||||
|     else if (app.current.app == 'Queue' ) { |     else if (app.current.app == 'Queue' ) { | ||||||
|         if (app.last.app != app.current.app) { |         if (app.last.app != app.current.app) { | ||||||
|             if (app.current.search.length < 2) { |             if (app.current.search.length < 2) { | ||||||
|                 setPagination(app.current.page);         |                 setPagination(app.current.page);         | ||||||
|             } |             } | ||||||
|           $('#searchqueuetag > button').each(function() { |  | ||||||
|             $(this).removeClass('active'); |             var btns = document.getElementById('searchqueuetag').getElementsByTagName('button'); | ||||||
|             if ($(this).text() == app.current.filter) {  |             for (var i = 0; i < btns.length; i ++) { | ||||||
|                 $(this).addClass('active'); |                 btns[i].classList.remove('active'); | ||||||
|                 $('#searchqueuetagdesc').text($(this).text()); |                 if (btns[i].innerText == app.current.filter) {  | ||||||
|  |                     btns[i].classList.add('active');  | ||||||
|  |                     document.getElementById('searchqueuetagdesc').innerText = btns[i].innerText; | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|           });  |  | ||||||
|         } |         } | ||||||
|         getQueue(); |         getQueue(); | ||||||
|     } |     } | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Playlists') { |     else if (app.current.app == 'Browse' && app.current.tab == 'Playlists') { | ||||||
|         sendAPI({"cmd":"MPD_API_GET_PLAYLISTS","data": {"offset": app.current.page, "filter": app.current.filter}},parsePlaylists); |         sendAPI({"cmd":"MPD_API_GET_PLAYLISTS","data": {"offset": app.current.page, "filter": app.current.filter}},parsePlaylists); | ||||||
|  |         doSetFilterLetter('#browsePlaylistsFilter'); | ||||||
|     } |     } | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.view == 'Artist') { |     else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.view == 'Artist') { | ||||||
|         sendAPI({"cmd":"MPD_API_GET_ARTISTS","data": {"offset": app.current.page, "filter": app.current.filter}},parseListDBtags); |         sendAPI({"cmd":"MPD_API_GET_ARTISTS","data": {"offset": app.current.page, "filter": app.current.filter}}, parseListDBtags); | ||||||
|  |         doSetFilterLetter('#BrowseDatabaseFilter'); | ||||||
|     } |     } | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.view == 'Album') { |     else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.view == 'Album') { | ||||||
|         sendAPI({"cmd":"MPD_API_GET_ARTISTALBUMS","data": {"offset": app.current.page, "filter": app.current.filter, "albumartist": app.current.search}},parseListDBtags); |         sendAPI({"cmd":"MPD_API_GET_ARTISTALBUMS","data": {"offset": app.current.page, "filter": app.current.filter, "albumartist": app.current.search}}, parseListDBtags); | ||||||
|  |         doSetFilterLetter('#BrowseDatabaseFilter'); | ||||||
|     }     |     }     | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Filesystem') { |     else if (app.current.app == 'Browse' && app.current.tab == 'Filesystem') { | ||||||
|         $('#BrowseBreadcrumb').empty().append('<li class="breadcrumb-item"><a uri="">root</a></li>'); |         sendAPI({"cmd":"MPD_API_GET_FILESYSTEM","data": {"offset": app.current.page, "path": (app.current.search ? app.current.search : "/"), "filter": app.current.filter}}, parseFilesystem); | ||||||
|         sendAPI({"cmd":"MPD_API_GET_FILESYSTEM","data": {"offset": app.current.page,"path":(app.current.search ? app.current.search : "/"),"filter": app.current.filter}},parseFilesystem); |  | ||||||
|         // Don't add all songs from root |         // Don't add all songs from root | ||||||
|         var add_all_songs = $('#browseFilesystemAddAllSongs'); |         if (app.current.search) | ||||||
|         if (app.current.search) { |             document.getElementById('BrowseFilesystemAddAllSongs').removeAttribute('disabled'); | ||||||
|             add_all_songs.off(); // remove previous binds |         else | ||||||
|             add_all_songs.on('click', function() { |             document.getElementById('BrowseFilesystemAddAllSongs').setAttribute('disabled', 'disabled') | ||||||
|                 sendAPI({"cmd":"MPD_API_ADD_TRACK", "data": { "uri": app.current.search}}); |         // Create breadcrumb | ||||||
|             }); |         var breadcrumbs=['<li class="breadcrumb-item"><a uri="">root</a></li>']; | ||||||
|             add_all_songs.removeAttr('disabled').removeClass('disabled'); |  | ||||||
|         } else { |  | ||||||
|             add_all_songs.attr('disabled','disabled').addClass('disabled'); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         var path_array = app.current.search.split('/'); |         var path_array = app.current.search.split('/'); | ||||||
|         var full_path = ""; |         var full_path = ''; | ||||||
|         $.each(path_array, function(index, chunk) { |         for (var index in path_array) { | ||||||
|             if(path_array.length - 1 == index) { |             if (path_array.length - 1 == index) { | ||||||
|                 $('#BrowseBreadcrumb').append("<li class=\"breadcrumb-item active\">"+ chunk + "</li>"); |                 breadcrumbs.push('<li class="breadcrumb-item active">' + path_array[index] + '</li>'); | ||||||
|                 return; |                 break; | ||||||
|             } |             } | ||||||
|             full_path = full_path + chunk; |             full_path = full_path + path_array[index]; | ||||||
|             $('#BrowseBreadcrumb').append("<li class=\"breadcrumb-item\"><a uri=\"" + full_path + "\">"+chunk+"</a></li>"); |             breadcrumbs.push('<li class="breadcrumb-item"><a uri="' + full_path + '">' + path_array[index] + '</a></li>'); | ||||||
|             full_path += "/"; |             full_path += '/'; | ||||||
|         }); |         } | ||||||
|  |         var elBrowseBreadcrumb=document.getElementById('BrowseBreadcrumb'); | ||||||
|  |         elBrowseBreadcrumb.innerHTML = breadcrumbs.join(''); | ||||||
|  |         var breadcrumbItems = elBrowseBreadcrumb.getElementsByTagName('a'); | ||||||
|  |         for (var i = 0; i < breadcrumbItems.length; i ++) { | ||||||
|  |             breadcrumbItems[index].addEventListener('click',function() { | ||||||
|  | 	        app.goto('Browse', 'Filesystem', undefined, '0/'+app.current.filter+'/'+$(this).attr('uri')); | ||||||
|  |             }, false); | ||||||
|  |         } | ||||||
|  |         doSetFilterLetter('#BrowseFilesystemFilter'); | ||||||
|     } |     } | ||||||
|     else if (app.current.app == 'Search') { |     else if (app.current.app == 'Search') { | ||||||
|         if (app.last.app != app.current.app) { |         if (app.last.app != app.current.app) { | ||||||
|           if (app.current.search != '') { |             if (app.current.search != '') | ||||||
|             $('#SearchList > tbody').append( |                 document.getElementById('SearchList').getElementsByTagName('tbody')[0].innerHTML= | ||||||
|                 "<tr><td><span class=\"material-icons\">search</span></td>" + |                     '<tr><td><span class="material-icons">search</span></td>' + | ||||||
|                 "<td colspan=\"3\">Searching</td>" + |                     '<td colspan="5">Searching...</td></tr>'; | ||||||
|                 "<td></td><td></td></tr>"); |             else | ||||||
|           } |  | ||||||
|           else { |  | ||||||
|                 setPagination(app.current.page);         |                 setPagination(app.current.page);         | ||||||
|  |                  | ||||||
|  |             document.getElementById('searchstr2').value=app.current.search; | ||||||
|         } |         } | ||||||
|           $('#searchstr2').val(app.current.search); |  | ||||||
|         } |  | ||||||
|         $('#searchtags2 > button').each(function() { |  | ||||||
|               $(this).removeClass('active'); |  | ||||||
|           if ($(this).text() == app.current.filter) {  |  | ||||||
|               $(this).addClass('active');  |  | ||||||
|               $('#searchtags2desc').text($(this).text()); |  | ||||||
|           } |  | ||||||
|         }); |  | ||||||
|         if (app.current.search.length >= 2) { |         if (app.current.search.length >= 2) { | ||||||
|            sendAPI({"cmd":"MPD_API_SEARCH", "data": { "mpdtag": app.current.filter,"offset":app.current.page,"searchstr":app.current.search}},parseSearch); |            sendAPI({"cmd":"MPD_API_SEARCH", "data": { "mpdtag": app.current.filter, "offset": app.current.page, "searchstr": app.current.search}}, parseSearch); | ||||||
|         } else { |         } else { | ||||||
|           $('#SearchList > tbody').empty(); |           document.getElementById('SearchList').getElementsByTagName('tbody')[0].innerHTML = ''; | ||||||
|           $('#searchAddAllSongs').attr('disabled','disabled').addClass('disabled');   |           document.getElementById('searchAddAllSongs').setAttribute('disabled','disabled');   | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         var btns = document.getElementById('searchtags2').getElementsByTagName('button'); | ||||||
|  |         for (var i = 0; i < btns.length; i ++) { | ||||||
|  |             btns[i].classList.remove('active'); | ||||||
|  |             if (btns[i].innerText == app.current.filter) {  | ||||||
|  |                 btns[i].classList.add('active');  | ||||||
|  |                 document.getElementById('searchtags2desc').innerText = btns[i].innerText; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
| @@ -262,6 +271,55 @@ $(document).ready(function(){ | |||||||
|     add_filter('#BrowseDatabaseFilterLetters'); |     add_filter('#BrowseDatabaseFilterLetters'); | ||||||
|     add_filter('#BrowsePlaylistsFilterLetters'); |     add_filter('#BrowsePlaylistsFilterLetters'); | ||||||
|  |  | ||||||
|  |     document.getElementById('BrowseFilesystemAddAllSongs').addEventListener('click',function() { | ||||||
|  |         sendAPI({"cmd":"MPD_API_ADD_TRACK", "data": { "uri": app.current.search}}); | ||||||
|  |     },false); | ||||||
|  |      | ||||||
|  |     $('#cardBrowseNavFilesystem').on('click', function (e) { | ||||||
|  |         app.goto('Browse','Filesystem'); | ||||||
|  |         e.preventDefault(); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     $('#cardBrowseNavDatabase').on('click', function (e) { | ||||||
|  |         app.goto('Browse','Database'); | ||||||
|  |         e.preventDefault(); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     $('#btnBrowseDatabaseArtist').on('click', function (e) { | ||||||
|  |         app.goto('Browse','Database','Artist'); | ||||||
|  |         e.preventDefault(); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     $('#cardBrowseNavPlaylists').on('click', function (e) { | ||||||
|  |         app.goto('Browse','Playlists'); | ||||||
|  |         e.preventDefault(); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     $('#cardBrowseNavFilesystem').on('click', function (e) { | ||||||
|  |         app.goto('Browse','Filesystem'); | ||||||
|  |         e.preventDefault(); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     $('#navPlayback').on('click', function (e) { | ||||||
|  |         app.goto('Playback'); | ||||||
|  |         e.preventDefault(); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     $('#navQueue').on('click', function (e) { | ||||||
|  |         app.goto('Queue'); | ||||||
|  |         e.preventDefault(); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     $('#navBrowse').on('click', function (e) { | ||||||
|  |         app.goto('Browse'); | ||||||
|  |         e.preventDefault(); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     $('#navSearch').on('click', function (e) { | ||||||
|  |         app.goto('Search'); | ||||||
|  |         e.preventDefault(); | ||||||
|  |     }); | ||||||
|  |      | ||||||
|     window.addEventListener("hashchange", app.route, false); |     window.addEventListener("hashchange", app.route, false); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| @@ -350,16 +408,16 @@ function get_appropriate_ws_url() | |||||||
| } | } | ||||||
|  |  | ||||||
| function parseStats(obj) { | function parseStats(obj) { | ||||||
|   $('#mpdstats_artists').text(obj.data.artists); |     document.getElementById('mpdstats_artists').innerText =  obj.data.artists; | ||||||
|   $('#mpdstats_albums').text(obj.data.albums); |     document.getElementById('mpdstats_albums').innerText = obj.data.albums; | ||||||
|   $('#mpdstats_songs').text(obj.data.songs); |     document.getElementById('mpdstats_songs').innerText = obj.data.songs; | ||||||
|   $('#mpdstats_dbplaytime').text(beautifyDuration(obj.data.dbplaytime)); |     document.getElementById('mpdstats_dbplaytime').innerText = beautifyDuration(obj.data.dbplaytime); | ||||||
|   $('#mpdstats_playtime').text(beautifyDuration(obj.data.playtime)); |     document.getElementById('mpdstats_playtime').innerText = beautifyDuration(obj.data.playtime); | ||||||
|   $('#mpdstats_uptime').text(beautifyDuration(obj.data.uptime)); |     document.getElementById('mpdstats_uptime').innerText = beautifyDuration(obj.data.uptime); | ||||||
|     var d = new Date(obj.data.dbupdated * 1000); |     var d = new Date(obj.data.dbupdated * 1000); | ||||||
|   $('#mpdstats_dbupdated').text(d.toUTCString()); |     document.getElementById('mpdstats_dbupdated').innerText = d.toUTCString(); | ||||||
|   $('#mympdVersion').text(obj.data.mympd_version); |     document.getElementById('mympdVersion').innerText = obj.data.mympd_version; | ||||||
|   $('#mpdVersion').text(obj.data.mpd_version); |     document.getElementById('mpdVersion').innerText = obj.data.mpd_version; | ||||||
| } | } | ||||||
|  |  | ||||||
| function parseSettings(obj) { | function parseSettings(obj) { | ||||||
| @@ -461,34 +519,30 @@ function parseState(obj) { | |||||||
|     current_song.currentSongId = obj.data.currentsongid; |     current_song.currentSongId = obj.data.currentsongid; | ||||||
|     var total_minutes = Math.floor(obj.data.totalTime / 60); |     var total_minutes = Math.floor(obj.data.totalTime / 60); | ||||||
|     var total_seconds = obj.data.totalTime - total_minutes * 60; |     var total_seconds = obj.data.totalTime - total_minutes * 60; | ||||||
|  |  | ||||||
|     var elapsed_minutes = Math.floor(obj.data.elapsedTime / 60); |     var elapsed_minutes = Math.floor(obj.data.elapsedTime / 60); | ||||||
|     var elapsed_seconds = obj.data.elapsedTime - elapsed_minutes * 60; |     var elapsed_seconds = obj.data.elapsedTime - elapsed_minutes * 60; | ||||||
|  |  | ||||||
|                     volumeBar.slider('setValue',obj.data.volume); |     volumeBar.slider('setValue', obj.data.volume); | ||||||
|                     var progress = Math.floor(100*obj.data.elapsedTime/obj.data.totalTime); |     var progress = Math.floor(100 * obj.data.elapsedTime / obj.data.totalTime); | ||||||
|                     progressBar.slider('setValue',progress); |     progressBar.slider('setValue', progress); | ||||||
|  |  | ||||||
|                     var counterText=elapsed_minutes + ":" +  |     var counterText = elapsed_minutes + ":" +  | ||||||
|         (elapsed_seconds < 10 ? '0' : '') + elapsed_seconds + " / " + |         (elapsed_seconds < 10 ? '0' : '') + elapsed_seconds + " / " + | ||||||
|         total_minutes + ":" + (total_seconds < 10 ? '0' : '') + total_seconds; |         total_minutes + ":" + (total_seconds < 10 ? '0' : '') + total_seconds; | ||||||
|                          |     document.getElementById('counter').innerText = counterText; | ||||||
|                     $('#counter').text(counterText); |  | ||||||
|  |  | ||||||
|     if (last_state) { |     if (last_state) { | ||||||
|                       $('#QueueList > tbody > tr[trackid='+last_state.data.currentsongid+'] > td').eq(4).text(last_state.data.totalTime); |         $('#QueueList > tbody > tr[trackid=' + last_state.data.currentsongid + '] > td').eq(4).text(last_state.data.totalTime); | ||||||
|                       $('#QueueList > tbody > tr[trackid='+last_state.data.currentsongid+'] > td').eq(0).removeClass('material-icons').text(last_state.data.songpos); |         $('#QueueList > tbody > tr[trackid=' + last_state.data.currentsongid + '] > td').eq(0).removeClass('material-icons').text(last_state.data.songpos); | ||||||
|     } |     } | ||||||
|     $('#QueueList > tbody > tr').removeClass('active').removeClass("font-weight-bold"); |     $('#QueueList > tbody > tr').removeClass('active').removeClass("font-weight-bold"); | ||||||
|                          |  | ||||||
|     $('#QueueList > tbody > tr[trackid='+obj.data.currentsongid+'] > td').eq(4).text(counterText); |     $('#QueueList > tbody > tr[trackid='+obj.data.currentsongid+'] > td').eq(4).text(counterText); | ||||||
|     $('#QueueList > tbody > tr[trackid='+obj.data.currentsongid+'] > td').eq(0).addClass('material-icons').text('play_arrow'); |     $('#QueueList > tbody > tr[trackid='+obj.data.currentsongid+'] > td').eq(0).addClass('material-icons').text('play_arrow'); | ||||||
|     $('#QueueList > tbody > tr[trackid='+obj.data.currentsongid+']').addClass('active').addClass("font-weight-bold"); |     $('#QueueList > tbody > tr[trackid='+obj.data.currentsongid+']').addClass('active').addClass("font-weight-bold"); | ||||||
|                      |                      | ||||||
|     //Get current song on queue change for http streams |     //Get current song on queue change for http streams | ||||||
|                     if (last_state == undefined || obj.data.queue_version != last_state.data.queue_version) { |     if (last_state == undefined || obj.data.queue_version != last_state.data.queue_version) | ||||||
|         sendAPI({"cmd":"MPD_API_GET_CURRENT_SONG"},songChange); |         sendAPI({"cmd":"MPD_API_GET_CURRENT_SONG"},songChange); | ||||||
|                     } |  | ||||||
|                      |                      | ||||||
|     last_state = obj; |     last_state = obj; | ||||||
|                      |                      | ||||||
| @@ -498,6 +552,7 @@ function parseState(obj) { | |||||||
|         else |         else | ||||||
|             $('#btnoutput'+id).removeClass("active"); |             $('#btnoutput'+id).removeClass("active"); | ||||||
|     }); |     }); | ||||||
|  |                      | ||||||
|     last_outputs = obj.data.outputs;                     |     last_outputs = obj.data.outputs;                     | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -593,187 +648,138 @@ function parseQueue(obj) { | |||||||
| function parseSearch(obj) { | function parseSearch(obj) { | ||||||
|     if (app.current.app !== 'Search') |     if (app.current.app !== 'Search') | ||||||
|         return; |         return; | ||||||
|     $('#panel-heading-search').text(obj.totalEntities + ' Songs found'); |     document.getElementById('panel-heading-search').innerHTML=obj.totalEntities + ' Songs found'; | ||||||
|     if (obj.totalEntities > 0) { |     if (obj.totalEntities > 0) | ||||||
|         $('#searchAddAllSongs').removeAttr('disabled').removeClass('disabled'); |         document.getElementById('searchAddAllSongs').removeAttribute('disabled'); | ||||||
|     } else { |     else | ||||||
|         $('#searchAddAllSongs').attr('disabled','disabled').addClass('disabled');                     |         document.getElementById('searchAddAllSongs').setAttribute('disabled','disabled');                     | ||||||
|     } |  | ||||||
|     parseFilesystem(obj); |     parseFilesystem(obj); | ||||||
| } | } | ||||||
|  |  | ||||||
| function parseFilesystem(obj) { | function parseFilesystem(obj) { | ||||||
|                     if(app.current.app !== 'Browse' && app.current.tab !== 'Filesystem' && app.current.app !== 'Search') |     if (app.current.app !== 'Browse' && app.current.tab !== 'Filesystem' && app.current.app !== 'Search') | ||||||
|         return; |         return; | ||||||
|                      |     var nrItems = 0; | ||||||
|                     /* The use of encodeURI() below might seem useless, but it's not. It prevents |     var tbody = document.getElementById(app.current.app + (app.current.tab==undefined ? '' : app.current.tab) + 'List').getElementsByTagName('tbody')[0]; | ||||||
|                      * some browsers, such as Safari, from changing the normalization form of the |     var tr = tbody.getElementsByTagName('tr'); | ||||||
|                      * URI from NFD to NFC, breaking our link with MPD. |  | ||||||
|                      */ |  | ||||||
|                     var nrItems=0; |  | ||||||
|                     var tr=document.getElementById(app.current.app+(app.current.tab==undefined ? '' : app.current.tab)+'List').getElementsByTagName('tbody')[0].getElementsByTagName('tr'); |  | ||||||
|     for (var item in obj.data) { |     for (var item in obj.data) { | ||||||
|                         nrItems++; |         nrItems ++; | ||||||
|                         var row=''; |         var uri = encodeURI(obj.data[item].uri); | ||||||
|                         var uri=''; |         if (tr[nrItems-1]) | ||||||
|  |             if (tr[nrItems-1].getAttribute('data-uri') == uri) | ||||||
|  |                 continue; | ||||||
|  |         var row = document.createElement('tr'); | ||||||
|  |         row.setAttribute('data-type', obj.data[item].type); | ||||||
|  |         row.setAttribute('data-uri', uri); | ||||||
|  |         row.setAttribute('data-name', obj.data[item].name); | ||||||
|  |          | ||||||
|         switch(obj.data[item].type) { |         switch(obj.data[item].type) { | ||||||
|                             case 'directory': |             case 'dir': | ||||||
|                                 uri=encodeURI(obj.data[item].dir); |                 row.innerHTML = '<td><span class="material-icons">folder_open</span></td>' + | ||||||
|                                 row ='<tr uri="' + uri + '" class="dir">' + |                       '<td colspan="4">' + obj.data[item].name + '</td>' + | ||||||
|                                     '<td><span class="material-icons">folder_open</span></td>' + |                       '<td><a href="#" tabindex="0" data-trigger="focus" class="material-icons">playlist_add</a></td>'; | ||||||
|                                     '<td colspan="4"><a>' + basename(obj.data[item].dir) + '</a></td>' + |  | ||||||
|                                     '<td><a class="material-icons">playlist_add</a></td></tr>'; |  | ||||||
|                 break; |                 break; | ||||||
|             case 'song': |             case 'song': | ||||||
|                 var minutes = Math.floor(obj.data[item].duration / 60); |                 var minutes = Math.floor(obj.data[item].duration / 60); | ||||||
|                 var seconds = obj.data[item].duration - minutes * 60; |                 var seconds = obj.data[item].duration - minutes * 60; | ||||||
|                                 uri=encodeURI(obj.data[item].uri); |                 row.innerHTML = '<td><span class="material-icons">music_note</span></td>' +  | ||||||
|                                 row ='<tr uri="' + uri  + '" class="song">' + |  | ||||||
|                                     '<td><span class="material-icons">music_note</span></td>' +  |  | ||||||
|                       '<td>' + obj.data[item].title + '</td>' + |                       '<td>' + obj.data[item].title + '</td>' + | ||||||
|                       '<td>' + obj.data[item].artist + '</td>' +  |                       '<td>' + obj.data[item].artist + '</td>' +  | ||||||
|                       '<td>' + obj.data[item].album  + '</td>' + |                       '<td>' + obj.data[item].album  + '</td>' + | ||||||
|                       '<td>' + minutes + ':' + (seconds < 10 ? '0' : '') + seconds + |                       '<td>' + minutes + ':' + (seconds < 10 ? '0' : '') + seconds + | ||||||
|                                     '</td><td><a tabindex="0" onclick="showMenu(this,event);" data-trigger="focus" class="material-icons">playlist_add</a></td></tr>'; |                       '</td><td><a href="#" tabindex="0" data-trigger="focus" class="material-icons">playlist_add</a></td>'; | ||||||
|                                 break; |  | ||||||
|                             case 'playlist': |  | ||||||
|                                 uri=encodeURI(obj.data[item].plist); |  | ||||||
|                                 row ='<tr uri="' + uri + '" class="plist">' + |  | ||||||
|                                     '<td><span class="material-icons">list</span></td>' + |  | ||||||
|                                     '<td colspan="4"><a>' + basename(obj.data[item].plist) + '</a></td>' + |  | ||||||
|                                     '<td><a class="material-icons">playlist_add</a></td></tr>'; |  | ||||||
|                                 break; |  | ||||||
|                         } |  | ||||||
|                         if (nrItems <= tr.length) { if ($(tr[nrItems-1]).attr('uri') != uri) $(tr[nrItems-1]).replaceWith(row); }  |  | ||||||
|                         else { $('#'+app.current.app+(app.current.tab==undefined ? '' : app.current.tab)+'List > tbody').append(row); } |  | ||||||
|                     } |  | ||||||
|                     for (var i=tr.length;i>nrItems;i--) { |  | ||||||
|                         $(tr[tr.length-1]).remove(); |  | ||||||
|                     } |  | ||||||
|                     setPagination(obj.totalEntities); |  | ||||||
|                      |  | ||||||
|                     if (nrItems == 0) { |  | ||||||
|                        $('#'+app.current.app+app.current.tab+'List > tbody').append( |  | ||||||
|                            '<tr><td><span class="material-icons">error_outline</span></td>' + |  | ||||||
|                            '<td colspan="3">No results</td>' + |  | ||||||
|                            '<td></td><td></td></tr>'); |  | ||||||
|                     } |  | ||||||
|                     $('[data-toggle="popover"]').popover();  |  | ||||||
| /* |  | ||||||
|                     function appendClickableIcon(appendTo, onClickAction, glyphicon) { |  | ||||||
|                         $(appendTo).append( |  | ||||||
|                             '<a role="button" class="pull-right btn-group-hover">' + |  | ||||||
|                             '<span class="material-icons">' + glyphicon + '</span></a>') |  | ||||||
|                             .find('a').click(function(e) { |  | ||||||
|                                 e.stopPropagation(); |  | ||||||
|                                 sendAPI({"cmd":onClickAction,"data":{ "uri":decodeURI($(this).parents("tr").attr("uri"))}}); |  | ||||||
|                                 showNotification('"' + $('td:nth-last-child(3)', $(this).parents('tr')).text() + '" added','','','success'); |  | ||||||
|                             }); |  | ||||||
|                     } |  | ||||||
|  |  | ||||||
|                     if ( isTouch ) { |  | ||||||
|                         appendClickableIcon($('#'+app.current.app+(app.current.tab == undefined ? '' : app.current.tab )+'List > tbody > tr.dir > td:last-child'), 'MPD_API_ADD_TRACK', 'playlist_add'); |  | ||||||
|                         appendClickableIcon($('#'+app.current.app+(app.current.tab == undefined ? '' : app.current.tab )+'List > tbody > tr.song > td:last-child'), 'MPD_API_ADD_TRACK', 'playlist_add'); |  | ||||||
|                     } else { |  | ||||||
|                         $('#'+app.current.app+(app.current.tab == undefined ? '' : app.current.tab )+'List > tbody > tr').on({ |  | ||||||
|                             mouseenter: function() { |  | ||||||
|                                 if($(this).is(".dir"))  |  | ||||||
|                                     appendClickableIcon($(this).children().last(), 'MPD_API_ADD_TRACK', 'playlist_add'); |  | ||||||
|                                 else if($(this).is(".song")) |  | ||||||
|                                     appendClickableIcon($(this).children().last(), 'MPD_API_ADD_TRACK', 'playlist_add'); |  | ||||||
|                             }, |  | ||||||
|                             mouseleave: function(){ |  | ||||||
|                                 $(this).children().last().find("a").stop().remove(); |  | ||||||
|                             } |  | ||||||
|                         }); |  | ||||||
|                     } |  | ||||||
| */ |  | ||||||
|                     $('#'+app.current.app+(app.current.tab == undefined ? '' : app.current.tab )+'List > tbody > tr').on({ |  | ||||||
|                         click: function() { |  | ||||||
|                             switch($(this).attr('class')) { |  | ||||||
|                                 case 'dir': |  | ||||||
|                                     app.current.page = 0; |  | ||||||
|                                     app.current.search = $(this).attr("uri"); |  | ||||||
|                                     $("#BrowseFilesystemList > a").attr("href", '#/Browse/Filesystem!'+app.current.page+'/'+app.current.filter+'/'+app.current.search); |  | ||||||
|                                     app.goto('Browse','Filesystem',undefined,app.current.page+'/'+app.current.filter+'/'+app.current.search); |  | ||||||
|                                     break; |  | ||||||
|                                 case 'song': |  | ||||||
|                                     sendAPI({"cmd":"MPD_API_ADD_TRACK", "data": {"uri": decodeURI($(this).attr("uri"))}}); |  | ||||||
|                                     showNotification('"' + $('td:nth-last-child(5)', this).text() + '" added','','','success'); |  | ||||||
|                 break; |                 break; | ||||||
|             case 'plist': |             case 'plist': | ||||||
|                                     sendAPI({"cmd":"MPD_API_ADD_PLAYLIST", "data": {"plist": decodeURI($(this).attr("uri"))}}); |                 row.innerHTML = '<td><span class="material-icons">list</span></td>' + | ||||||
|                                     showNotification('"' + $('td:nth-last-child(3)', this).text() + '" added','','','success'); |                       '<td colspan="4">' + obj.data[item].name + '</td>' + | ||||||
|  |                       '<td><a href="#" tabindex="0" data-trigger="focus" class="material-icons">playlist_add</a></td>'; | ||||||
|                 break; |                 break; | ||||||
|         } |         } | ||||||
|                         } |         if (nrItems <= tr.length) | ||||||
|                     }); |             tr[nrItems-1].replaceWith(row);  | ||||||
|  |         else  | ||||||
|  |             tbody.append(row); | ||||||
|              |              | ||||||
|                     $('#BrowseBreadcrumb > li > a').on({ |         tr[nrItems-1].getElementsByTagName('a')[0].addEventListener('click', function(event) { | ||||||
| 			click: function() { |           event.stopPropagation(); | ||||||
| 		        	app.current.page = 0; |           event.preventDefault(); | ||||||
| 				app.current.search = $(this).attr("uri"); |           showMenu(this); | ||||||
| 				$("#BrowseFilesystemList > a").attr("href", '#/Browse/Filesystem!'+app.current.page+'/'+app.current.filter+'/'+app.current.search); |         },false); | ||||||
| 				app.goto('Browse','Filesystem',undefined,app.current.page+'/'+app.current.filter+'/'+app.current.search); |              | ||||||
|  |         tr[nrItems-1].addEventListener('click', function() { | ||||||
|  |             switch(this.getAttribute('data-type')) { | ||||||
|  |                 case 'dir': | ||||||
|  |                     app.goto('Browse', 'Filesystem', undefined, '0/' + app.current.filter +'/' + decodeURI(this.getAttribute("data-uri"))); | ||||||
|  |                     break; | ||||||
|  |                 case 'song': | ||||||
|  |                     appendQueue('song', decodeURI(this.getAttribute("data-uri")), this.getAttribute("data-name")); | ||||||
|  |                     break; | ||||||
|  |                 case 'plist': | ||||||
|  |                     appendQueue('plist', decodeURI(this.getAttribute("data-uri")), this.getAttribute("data-name")); | ||||||
|  |                     break; | ||||||
|             } |             } | ||||||
|                     }); |         },false); | ||||||
|     doSetFilterLetter('#BrowseFilesystemFilter'); |     } | ||||||
|  |     var tr_length=tr.length - 1; | ||||||
|  |     for (var i = tr_length; i >= nrItems; i --) { | ||||||
|  |         tr[i].remove(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     setPagination(obj.totalEntities); | ||||||
|  |                      | ||||||
|  |     if (nrItems == 0) | ||||||
|  |         tbody.innerHTML='<tr><td><span class="material-icons">error_outline</span></td>' + | ||||||
|  |             '<td colspan="5">No results</td></tr>'; | ||||||
|  |          | ||||||
| } | } | ||||||
|  |  | ||||||
| function parsePlaylists(obj) { | function parsePlaylists(obj) { | ||||||
|                     if(app.current.app !== 'Browse' && app.current.tab !== 'Playlists') |     if (app.current.app !== 'Browse' && app.current.tab !== 'Playlists') | ||||||
|         return; |         return; | ||||||
|                     var nrItems=0; |     var nrItems = 0; | ||||||
|                     var tr=document.getElementById(app.current.app+app.current.tab+'List').getElementsByTagName('tbody')[0].getElementsByTagName('tr'); |     var tbody = document.getElementById(app.current.app+app.current.tab+'List').getElementsByTagName('tbody')[0]; | ||||||
|  |     var tr = tbody.getElementsByTagName('tr'); | ||||||
|     for (var item in obj.data) { |     for (var item in obj.data) { | ||||||
|         nrItems++; |         nrItems++; | ||||||
|  |         var uri = encodeURI(obj.data[item].uri); | ||||||
|  |         if (tr[nrItems-1]) | ||||||
|  |             if (tr[nrItems-1].getAttribute('data-uri') == uri) | ||||||
|  |                 continue; | ||||||
|         var d = new Date(obj.data[item].last_modified * 1000); |         var d = new Date(obj.data[item].last_modified * 1000); | ||||||
|                         var uri=encodeURI(obj.data[item].plist); |         var row = document.createElement('tr'); | ||||||
|                         var row='<tr uri="' + uri + '">' + |         row.setAttribute('data-uri', uri); | ||||||
|                                 '<td><span class="material-icons">list</span></td>' + |         row.setAttribute('data-type', 'plist'); | ||||||
|                                 '<td><a>' + basename(obj.data[item].plist) + '</a></td>' + |         row.setAttribute('data-name', obj.data[item].name); | ||||||
|                                 '<td>'+d.toUTCString()+'</td><td></td></tr>'; |         row.innerHTML = '<td><span class="material-icons">list</span></td>' + | ||||||
|                         if (nrItems <= tr.length) { if ($(tr[nrItems-1]).attr('uri') != uri) $(tr[nrItems-1]).replaceWith(row); }  |                         '<td>' + obj.data[item].name + '</td>' + | ||||||
|                         else { $('#'+app.current.app+app.current.tab+'List > tbody').append(row); } |                         '<td>'+ d.toUTCString() + '</td>' + | ||||||
|  |                         '<td><a href="#" tabindex="0" data-trigger="focus" class="material-icons">playlist_add</a></td>'; | ||||||
|  |         if (nrItems <= tr.length) | ||||||
|  |             tr[nrItems-1].replaceWith(row);  | ||||||
|  |         else  | ||||||
|  |             tbody.append(row); | ||||||
|  |              | ||||||
|  |         tr[nrItems-1].getElementsByTagName('a')[0].addEventListener('click', function(event) { | ||||||
|  |           event.stopPropagation(); | ||||||
|  |           event.preventDefault(); | ||||||
|  |           showMenu(this); | ||||||
|  |         },false); | ||||||
|  |              | ||||||
|  |         tr[nrItems-1].addEventListener('click', function() { | ||||||
|  |             appendQueue('plist', decodeURI(this.getAttribute("data-uri")), this.getAttribute("data-name")); | ||||||
|  |         },false); | ||||||
|     } |     } | ||||||
|                     for (var i=tr.length;i>nrItems;i--) { |     var tr_length=tr.length - 1; | ||||||
|                          $(tr[tr.length-1]).remove(); |     for (var i = tr_length; i >= nrItems; i --) { | ||||||
|  |         tr[i].remove(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     setPagination(obj.totalEntities); |     setPagination(obj.totalEntities); | ||||||
|                     if ( isTouch ) { |      | ||||||
|                         $('#'+app.current.app+app.current.tab+'List > tbody > tr > td:last-child').append( |     if (nrItems == 0)  | ||||||
|                                 '<a class="pull-right btn-group-hover color-darkgrey" href="#/Browse/Playlists!' + app.current.page + '/'+app.current.filter+'/'+app.current.search+'" '+ |         tbody.innerHTML='<tr><td><span class="material-icons">error_outline</span></td>' + | ||||||
|                                 'onclick="delPlaylist($(this).parents(\'tr\'));">' + |                         '<td colspan="5">No playlists found.</td></tr>' | ||||||
|                                 '<span class="material-icons">delete</span></a>'); |      | ||||||
|                     } else { |  | ||||||
|                         $('#'+app.current.app+app.current.tab+'List > tbody > tr').on({ |  | ||||||
|                             mouseover: function(){ |  | ||||||
|                                 if($(this).children().last().has('a').length == 0) |  | ||||||
|                                     $(this).children().last().append( |  | ||||||
|                                         '<a class="pull-right btn-group-hover color-darkgrey" href="#/Browse/Playlists!' + app.current.page + '/'+app.current.filter+'/'+app.current.search+'" '+ |  | ||||||
|                                         'onclick="delPlaylist($(this).parents(\'tr\'));">' + |  | ||||||
|                                         '<span class="material-icons">delete</span></a>'); |  | ||||||
|                             }, |  | ||||||
|                             mouseleave: function(){ |  | ||||||
|                                 var doomed = $(this); |  | ||||||
|                                 $(this).children().last().find("a").stop().remove(); |  | ||||||
|                             } |  | ||||||
|                         }); |  | ||||||
|                     }; |  | ||||||
|                     $('#'+app.current.app+app.current.tab+'List > tbody > tr').on({ |  | ||||||
|                         click: function() { |  | ||||||
|                                     sendAPI({"cmd":"MPD_API_ADD_PLAYLIST", "data": { "plist": decodeURI($(this).attr('uri'))}}); |  | ||||||
|                                     showNotification('"' + $('td:nth-last-child(3)', this).text() + '" added','','','success'); |  | ||||||
|                         } |  | ||||||
|                     }); |  | ||||||
|                     if (nrItems == 0) { |  | ||||||
|                         $('#'+app.current.app+app.current.tab+'List > tbody').append( |  | ||||||
|                                '<tr><td><span class="material-icons">error_outline</span></td>' + |  | ||||||
|                                '<td colspan="3">No playlists found.</td>' + |  | ||||||
|                                '<td></td><td></td></tr>' |  | ||||||
|                         ); |  | ||||||
|                     } |  | ||||||
|   doSetFilterLetter('#browsePlaylistsFilter'); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function parseListDBtags(obj) { | function parseListDBtags(obj) { | ||||||
| @@ -783,90 +789,130 @@ function parseListDBtags(obj) { | |||||||
|         $('#BrowseDatabaseAlbumCards').addClass('hide'); |         $('#BrowseDatabaseAlbumCards').addClass('hide'); | ||||||
|         $('#BrowseDatabaseArtistList').removeClass('hide'); |         $('#BrowseDatabaseArtistList').removeClass('hide'); | ||||||
|         $('#btnBrowseDatabaseArtist').addClass('hide'); |         $('#btnBrowseDatabaseArtist').addClass('hide'); | ||||||
|                         var nrItems=0; |         var nrItems = 0; | ||||||
|                         var tr=document.getElementById(app.current.app+app.current.tab+app.current.view+'List').getElementsByTagName('tbody')[0].getElementsByTagName('tr'); |         var tbody = document.getElementById(app.current.app+app.current.tab+app.current.view+'List').getElementsByTagName('tbody')[0]; | ||||||
|  |         var tr = tbody.getElementsByTagName('tr'); | ||||||
|         for (var item in obj.data) { |         for (var item in obj.data) { | ||||||
|             nrItems++; |             nrItems++; | ||||||
|                             var uri=encodeURI(obj.data[item].value); |             var uri = encodeURI(obj.data[item].value); | ||||||
|                             var row='<tr uri="' + uri  + '">' + |             if (tr[nrItems-1]) | ||||||
|                                 '<td><span class="material-icons">album</span></td>' + |                 if (tr[nrItems-1].getAttribute('data-uri') == uri) | ||||||
|                                 '<td><a>' + obj.data[item].value + '</a></td></tr>'; |                     continue; | ||||||
|                             if (nrItems <= tr.length) { if ($(tr[nrItems-1]).attr('uri')!=uri) $(tr[nrItems-1]).replaceWith(row); }  |             var row = document.createElement('tr'); | ||||||
|                             else { $('#'+app.current.app+app.current.tab+app.current.view+'List > tbody').append(row); } |             row.setAttribute('data-uri', uri); | ||||||
|  |             row.innerHTML='<td><span class="material-icons">album</span></td>' + | ||||||
|  |                           '<td>' + obj.data[item].value + '</td>' + | ||||||
|  |                           '<!--<td><a href="#" tabindex="0" data-trigger="focus" class="material-icons">playlist_add</a></td>-->' + | ||||||
|  |                           '</tr>'; | ||||||
|  |  | ||||||
|  |             if (nrItems <= tr.length) | ||||||
|  |                 tr[nrItems-1].replaceWith(row);  | ||||||
|  |             else  | ||||||
|  |                 tbody.append(row); | ||||||
|  | /*             | ||||||
|  |             tr[nrItems-1].getElementsByTagName('a')[0].addEventListener('click', function(event) { | ||||||
|  |                 event.stopPropagation(); | ||||||
|  |                 event.preventDefault(); | ||||||
|  |                 showMenu(this); | ||||||
|  |             },false); | ||||||
|  | */             | ||||||
|  |             tr[nrItems-1].addEventListener('click', function() { | ||||||
|  |                 app.goto('Browse','Database','Album','0/-/'+this.getAttribute('data-uri')); | ||||||
|  |             },false); | ||||||
|         } |         } | ||||||
|                         for (var i=tr.length;i>nrItems;i--) { |         var tr_length=tr.length - 1; | ||||||
|                             $(tr[tr.length-1]).remove(); |         for (var i = tr_length; i >= nrItems; i --) { | ||||||
|  |             tr[i].remove(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         setPagination(obj.totalEntities); |         setPagination(obj.totalEntities); | ||||||
|                         $('#'+app.current.app+app.current.tab+app.current.view+'List > tbody > tr').on({ |  | ||||||
|                             click: function() { |         if (nrItems == 0)  | ||||||
|                                 app.goto('Browse','Database','Album','0/-/'+$(this).attr('uri')); |             tbody.innerHTML='<tr><td><span class="material-icons">error_outline</span></td>' + | ||||||
|                             } |                             '<td colspan="5">No entries found.</td></tr>' | ||||||
|                         }); |                                 | ||||||
|                         if (nrItems == 0) { |  | ||||||
|                             $('#'+app.current.app+app.current.tab+app.current.view+'List > tbody').append( |  | ||||||
|                                '<tr><td><span class="material-icons">error_outline</span></td>' + |  | ||||||
|                                '<td colspan="3">No entries found.</td>' + |  | ||||||
|                                '<td></td><td></td></tr>' |  | ||||||
|                             ); |  | ||||||
|                         } |  | ||||||
|     } else if (obj.tagtype == 'Album') { |     } else if (obj.tagtype == 'Album') { | ||||||
|         $('#BrowseDatabaseArtistList').addClass('hide'); |         $('#BrowseDatabaseArtistList').addClass('hide'); | ||||||
|         $('#BrowseDatabaseAlbumCards').removeClass('hide'); |         $('#BrowseDatabaseAlbumCards').removeClass('hide'); | ||||||
|         $('#btnBrowseDatabaseArtist').removeClass('hide'); |         $('#btnBrowseDatabaseArtist').removeClass('hide'); | ||||||
|         var nrItems=0; |         var nrItems=0; | ||||||
|                         var cards=document.getElementById('BrowseDatabaseAlbumCards').querySelectorAll('.col-md'); |         var cardContainer=document.getElementById('BrowseDatabaseAlbumCards') | ||||||
|  |         var cards=cardContainer.querySelectorAll('.col-md'); | ||||||
|         for (var item in obj.data) { |         for (var item in obj.data) { | ||||||
|             nrItems++; |             nrItems++; | ||||||
|             var id=genId(obj.data[item].value); |             var id=genId(obj.data[item].value); | ||||||
|                           var card='<div class="col-md mr-0" id="'+id+'"><div class="card mb-4" id="card'+id+'">'+ |             if (cards[nrItems-1]) | ||||||
|                                    ' <img class="card-img-top" src="" alt="">'+ |                 if (cards[nrItems-1].getAttribute('id') == id) | ||||||
|  |                     continue;               | ||||||
|  |             var card=document.createElement('div'); | ||||||
|  |             card.classList.add('col-md'); | ||||||
|  |             card.classList.add('mr-0'); | ||||||
|  |             card.setAttribute('id', id); | ||||||
|  |             card.innerHTML='<div class="card mb-4" id="card'+id+'">'+ | ||||||
|  |                            ' <img class="card-img-top" src="" tabindex="0" data-trigger="focus">'+ | ||||||
|                            ' <div class="card-body">'+ |                            ' <div class="card-body">'+ | ||||||
|                            '  <h5 class="card-title">'+obj.searchstr+'</h5>'+ |                            '  <h5 class="card-title">'+obj.searchstr+'</h5>'+ | ||||||
|                            '  <h4 class="card-title">'+obj.data[item].value+'</h4>'+ |                            '  <h4 class="card-title">'+obj.data[item].value+'</h4>'+ | ||||||
|                            '  <table class="table table-sm table-hover" id="tbl'+id+'"><tbody></tbody></table'+ |                            '  <table class="table table-sm table-hover" id="tbl'+id+'"><tbody></tbody></table'+ | ||||||
|                            ' </div>'+ |                            ' </div>'+ | ||||||
|                                    '</div></div>'; |                            '</div>'; | ||||||
|                           if (nrItems <= cards.length) { if (cards[nrItems-1].id != id) $(cards[nrItems-1]).replaceWith(card); }  |           | ||||||
|                           else { $('#BrowseDatabaseAlbumCards').append(card); } |             if (nrItems <= cards.length) | ||||||
|                           if (nrItems > cards.length || cards[nrItems-1].id != id) |                 cards[nrItems-1].replaceWith(card);  | ||||||
|  |             else  | ||||||
|  |                 cardContainer.append(card); | ||||||
|  |                  | ||||||
|             sendAPI({"cmd":"MPD_API_GET_ARTISTALBUMTITLES", "data": { "albumartist": obj.searchstr, "album": obj.data[item].value}},parseListTitles); |             sendAPI({"cmd":"MPD_API_GET_ARTISTALBUMTITLES", "data": { "albumartist": obj.searchstr, "album": obj.data[item].value}},parseListTitles); | ||||||
|         } |         } | ||||||
|                         for (var i=cards.length;i>nrItems;i--) { |         var cards_length=cards.length - 1; | ||||||
|                             $(cards[i-1]).remove(); |         for (var i = cards_length; i >= nrItems; i --) { | ||||||
|  |             cards[i].remove(); | ||||||
|         } |         } | ||||||
|         setPagination(obj.totalEntities); |         setPagination(obj.totalEntities); | ||||||
|     } |     } | ||||||
|    doSetFilterLetter('#BrowseDatabaseFilter'); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function parseListTitles(obj) { | function parseListTitles(obj) { | ||||||
|   if(app.current.app !== 'Browse' && app.current.tab !== 'Database' && app.current.view !== 'Album') return; |   if(app.current.app !== 'Browse' && app.current.tab !== 'Database' && app.current.view !== 'Album')  | ||||||
|                     var id=genId(obj.album); |       return; | ||||||
|                     var album=$('#card'+id+' > div > table > tbody'); |  | ||||||
|                     $('#card'+id+' > img').attr('src',obj.cover) |  | ||||||
|                         .attr('uri',obj.data[0].uri.replace(/\/[^\/]+$/,'')) |  | ||||||
|                         .attr('data-album',encodeURI(obj.album)); |  | ||||||
|                     var titleList=''; |  | ||||||
|                     for (var item in obj.data) { |  | ||||||
|                         titleList+='<tr uri="' + encodeURI(obj.data[item].uri) + '" class="song">'+ |  | ||||||
|                             '<td>'+obj.data[item].track+'</td><td>'+obj.data[item].title+'</td></tr>'; |  | ||||||
|                     } |  | ||||||
|                     album.append(titleList); |  | ||||||
|                     $('#card'+id+' > img').on({ |  | ||||||
|                         click: function() { |  | ||||||
|                                     sendAPI({"cmd":"MPD_API_ADD_TRACK", "data": { "track": decodeURI($(this).attr('uri'))}}); |  | ||||||
|                                     showNotification('"'+decodeURI($(this).attr('data-album'))+'" added','','','success'); |  | ||||||
|                         } |  | ||||||
|                     }); |  | ||||||
|    |    | ||||||
|                     $('#tbl'+id+' > tbody > tr').on({ |   var id = genId(obj.album); | ||||||
|                         click: function() { |   var card = document.getElementById('card' + id) | ||||||
|                                     sendAPI({"cmd":"MPD_API_ADD_TRACK", "data": { "track": decodeURI($(this).attr('uri'))}}); |   var tbody = card.getElementsByTagName('tbody')[0]; | ||||||
|                                     showNotification('"' + $('td:nth-last-child(1)', this).text() + '" added','','','success'); |   var img = card.getElementsByTagName('img')[0]; | ||||||
|  |   img.setAttribute('src', obj.cover); | ||||||
|  |   img.setAttribute('data-uri', obj.data[0].uri.replace(/\/[^\/]+$/,'')); | ||||||
|  |   img.setAttribute('data-name', encodeURI(obj.album)); | ||||||
|  |   img.setAttribute('data-type', 'album'); | ||||||
|  |    | ||||||
|  |   var titleList=new Array(); | ||||||
|  |   for (var item in obj.data) { | ||||||
|  |       titleList.push('<tr data-type="song" data-name="' + obj.data[item].title + '" data-uri="' + encodeURI(obj.data[item].uri) + '">' + | ||||||
|  |                  '<td>' + obj.data[item].track + '</td><td>' + obj.data[item].title + '</td>' + | ||||||
|  |                  '<td><a href="#" tabindex="0" data-trigger="focus" class="material-icons">playlist_add</a></td>' +  | ||||||
|  |                  '</tr>'); | ||||||
|  |   } | ||||||
|  |   tbody.innerHTML=titleList.join(''); | ||||||
|  |    | ||||||
|  |   img.addEventListener('click', function() { | ||||||
|  |       //sendAPI({"cmd":"MPD_API_ADD_TRACK", "data": { "uri": decodeURI(this.getAttribute('data-uri'))}}); | ||||||
|  |       //showNotification('"'+ decodeURI(this.getAttribute('data-name')) + '" added', '', '', 'success'); | ||||||
|  |       showMenu(this); | ||||||
|  |   }, false); | ||||||
|  |  | ||||||
|  |   var tr = tbody.getElementsByTagName('tr'); | ||||||
|  |   var tr_length = tr.length; | ||||||
|  |   for (var i = 0; i < tr_length; i ++) { | ||||||
|  |       tr[i].addEventListener('click', function() { | ||||||
|  |           sendAPI({"cmd":"MPD_API_ADD_TRACK", "data": { "uri": decodeURI(this.getAttribute('data-uri'))}}); | ||||||
|  |           showNotification('"' + this.getAttribute('data-name') + '" added','','','success'); | ||||||
|  |       }, false); | ||||||
|  |       tr[i].getElementsByTagName('a')[0].addEventListener('click', function(event) { | ||||||
|  |           event.stopPropagation(); | ||||||
|  |           event.preventDefault(); | ||||||
|  |           showMenu(this); | ||||||
|  |       },false); | ||||||
|   } |   } | ||||||
|                     }); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function setPagination(number) { | function setPagination(number) { | ||||||
| @@ -908,18 +954,43 @@ function setPagination(number) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function showMenu(el,event) { | function appendQueue(type,uri,name) { | ||||||
|   event.stopPropagation(); |     switch(type) { | ||||||
|   $(el).popover({html:true, content:'<a class="dropdown-item" href="#">Append to queue</a>'+ |         case 'song': | ||||||
|     '<a class="dropdown-item" href="#">Add after current playing song</a>'+ |             sendAPI({"cmd":"MPD_API_ADD_TRACK", "data": {"uri": uri}}); | ||||||
|     '<a class="dropdown-item" href="#">Replace queue</a>'+ |             showNotification('"' + name + '" added','','','success'); | ||||||
|     '<div class="dropdown-divider"></div>'+ |             break; | ||||||
|     '<a class="dropdown-item" href="#">Add to playlist</a>'+ |         case 'plist': | ||||||
|     '<div class="dropdown-divider"></div>'+ |             sendAPI({"cmd":"MPD_API_ADD_PLAYLIST", "data": {"plist": uri}}); | ||||||
|     '<a class="dropdown-item" href="#">Details</a>' |             showNotification('"' + name + '" added','','','success'); | ||||||
|     }); |             break; | ||||||
|   $(el).popover('show'); |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function showMenu(el) { | ||||||
|  |     var type = el.parentNode.parentNode.getAttribute('data-type'); | ||||||
|  |     var uri = el.parentNode.parentNode.getAttribute('data-uri'); | ||||||
|  |     if ((app.current.app == 'Browse' && app.current.tab == 'Filesystem') || app.current.app == 'Search' || | ||||||
|  |         (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.view == 'Album')) { | ||||||
|  |         $(el).popover({html:true, content:'<a class="dropdown-item" href="#" onclick="">Append to queue</a>' + | ||||||
|  |             '<a class="dropdown-item" href="#">Add after current playing song</a>' + | ||||||
|  |             '<a class="dropdown-item" href="#">Replace queue</a>' + | ||||||
|  |             ( type != 'plist' ? '<div class="dropdown-divider"></div><a class="dropdown-item" href="#">Add to playlist</a>' : '') + | ||||||
|  |             ( type != 'dir' ? '<div class="dropdown-divider"></div>' : '') + | ||||||
|  |             ( type == 'song' ? '<a class="dropdown-item" href="#">Songdetails</a>' : '') + | ||||||
|  |             ( type == 'plist' ? '<a class="dropdown-item" href="#">Show playlist</a>' : '') | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |     else if (app.current.app == 'Browse' && app.current.tab == 'Playlists') { | ||||||
|  |         $(el).popover({html:true, content:'<a class="dropdown-item" href="#" onclick="">Append to queue</a>' + | ||||||
|  |             '<a class="dropdown-item" href="#">Add after current playing song</a>' + | ||||||
|  |             '<a class="dropdown-item" href="#">Replace queue</a>' + | ||||||
|  |             '<div class="dropdown-divider"></div>' + | ||||||
|  |             '<a class="dropdown-item" href="#">Show playlist</a>' + | ||||||
|  |             '<a class="dropdown-item" href="#">Delete playlist</a>' | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |   $(el).popover('show'); | ||||||
| } | } | ||||||
|  |  | ||||||
| function updateVolumeIcon(volume) { | function updateVolumeIcon(volume) { | ||||||
| @@ -1021,59 +1092,10 @@ function delQueueSong(tr,event) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function delPlaylist(tr) { | function delPlaylist(tr) { | ||||||
|     sendAPI({"cmd":"MPD_API_RM_PLAYLIST","data": {"plist": decodeURI(tr.attr("uri"))}}); |     sendAPI({"cmd":"MPD_API_RM_PLAYLIST","data": {"plist": decodeURI(tr.attr("data-uri"))}}); | ||||||
|     tr.remove(); |     tr.remove(); | ||||||
| } | } | ||||||
|  |  | ||||||
| function basename(path) { |  | ||||||
|     return path.split('/').reverse()[0]; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $('#cardBrowseNavFilesystem').on('click', function (e) { |  | ||||||
|     app.goto('Browse','Filesystem'); |  | ||||||
|     e.preventDefault(); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| $('#cardBrowseNavDatabase').on('click', function (e) { |  | ||||||
|     app.goto('Browse','Database'); |  | ||||||
|     e.preventDefault(); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| $('#btnBrowseDatabaseArtist').on('click', function (e) { |  | ||||||
|     app.goto('Browse','Database','Artist'); |  | ||||||
|     e.preventDefault(); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| $('#cardBrowseNavPlaylists').on('click', function (e) { |  | ||||||
|     app.goto('Browse','Playlists'); |  | ||||||
|     e.preventDefault(); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| $('#cardBrowseNavFilesystem').on('click', function (e) { |  | ||||||
|     app.goto('Browse','Filesystem'); |  | ||||||
|     e.preventDefault(); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| $('#navPlayback').on('click', function (e) { |  | ||||||
|     app.goto('Playback'); |  | ||||||
|     e.preventDefault(); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| $('#navQueue').on('click', function (e) { |  | ||||||
|     app.goto('Queue'); |  | ||||||
|     e.preventDefault(); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| $('#navBrowse').on('click', function (e) { |  | ||||||
|     app.goto('Browse'); |  | ||||||
|     e.preventDefault(); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| $('#navSearch').on('click', function (e) { |  | ||||||
|     app.goto('Search'); |  | ||||||
|     e.preventDefault(); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| function confirmSettings() { | function confirmSettings() { | ||||||
|     var formOK=true; |     var formOK=true; | ||||||
|     if (!$('#inputCrossfade').is(':disabled')) { |     if (!$('#inputCrossfade').is(':disabled')) { | ||||||
|   | |||||||
| @@ -828,11 +828,12 @@ int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter | |||||||
|                         ( strncmp(filter,"0",1) == 0 && isalpha(*entityName) == 0 ) |                         ( strncmp(filter,"0",1) == 0 && isalpha(*entityName) == 0 ) | ||||||
|                     ) { |                     ) { | ||||||
|                         if (entities_returned ++) len += json_printf(&out,","); |                         if (entities_returned ++) len += json_printf(&out,","); | ||||||
|                         len += json_printf(&out, "{type:song, uri: %Q, album: %Q, artist: %Q, duration: %d, title: %Q }", |                         len += json_printf(&out, "{type: song, uri: %Q, album: %Q, artist: %Q, duration: %d, title: %Q, name: %Q }", | ||||||
|                             mpd_song_get_uri(song), |                             mpd_song_get_uri(song), | ||||||
|                             mympd_get_album(song), |                             mympd_get_album(song), | ||||||
|                             mympd_get_artist(song), |                             mympd_get_artist(song), | ||||||
|                             mpd_song_get_duration(song), |                             mpd_song_get_duration(song), | ||||||
|  |                             entityName, | ||||||
|                             entityName |                             entityName | ||||||
|                         ); |                         ); | ||||||
|                     } else { |                     } else { | ||||||
| @@ -853,8 +854,9 @@ int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter | |||||||
|                         ( strncmp(filter,"0",1) == 0 && isalpha(*dirName) == 0 ) |                         ( strncmp(filter,"0",1) == 0 && isalpha(*dirName) == 0 ) | ||||||
|                     ) {                 |                     ) {                 | ||||||
|                         if (entities_returned ++) len += json_printf(&out,","); |                         if (entities_returned ++) len += json_printf(&out,","); | ||||||
|                         len += json_printf(&out, "{type: directory, dir: %Q }", |                         len += json_printf(&out, "{type: dir, uri: %Q, name: %Q }", | ||||||
|                             entityName |                             entityName, | ||||||
|  |                             dirName | ||||||
|                         ); |                         ); | ||||||
|                     } else { |                     } else { | ||||||
|                         entity_count --; |                         entity_count --; | ||||||
| @@ -874,8 +876,9 @@ int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter | |||||||
|                         ( strncmp(filter,"0",1) == 0 && isalpha(*plName) == 0 ) |                         ( strncmp(filter,"0",1) == 0 && isalpha(*plName) == 0 ) | ||||||
|                     ) { |                     ) { | ||||||
|                         if (entities_returned ++) len += json_printf(&out,","); |                         if (entities_returned ++) len += json_printf(&out,","); | ||||||
|                         len += json_printf(&out, "{ type: playlist, plist: %Q }", |                         len += json_printf(&out, "{ type: plist, uri: %Q, name: %Q }", | ||||||
|                             entityName |                             entityName, | ||||||
|  |                             plName | ||||||
|                         ); |                         ); | ||||||
|                     } else { |                     } else { | ||||||
|                         entity_count --; |                         entity_count --; | ||||||
| @@ -1030,7 +1033,8 @@ int mympd_put_playlists(char *buffer, unsigned int offset, char *filter) | |||||||
|                     ( strncmp(filter,"0",1) == 0 && isalpha(*plpath) == 0 ) |                     ( strncmp(filter,"0",1) == 0 && isalpha(*plpath) == 0 ) | ||||||
|             ) { |             ) { | ||||||
|                 if (entities_returned ++) len += json_printf(&out, ", "); |                 if (entities_returned ++) len += json_printf(&out, ", "); | ||||||
|                 len += json_printf(&out, "{ type: playlist, plist: %Q, last_modified: %d }", |                 len += json_printf(&out, "{ type: plist, uri: %Q, name: %Q, last_modified: %d }", | ||||||
|  |                     plpath, | ||||||
|                     plpath, |                     plpath, | ||||||
|                     mpd_playlist_get_last_modified(pl) |                     mpd_playlist_get_last_modified(pl) | ||||||
|                 ); |                 ); | ||||||
| @@ -1084,11 +1088,12 @@ int mympd_search(char *buffer, char *mpdtagtype, unsigned int offset, char *sear | |||||||
|             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 ++) len += json_printf(&out, ", "); |                 if (entities_returned ++) len += json_printf(&out, ", "); | ||||||
|                 len += json_printf(&out, "{ type: song, uri: %Q, album: %Q, artist: %Q, duration: %d, title: %Q }", |                 len += json_printf(&out, "{ type: song, uri: %Q, album: %Q, artist: %Q, duration: %d, title: %Q, name: %Q }", | ||||||
|                     mpd_song_get_uri(song), |                     mpd_song_get_uri(song), | ||||||
|                     mympd_get_album(song), |                     mympd_get_album(song), | ||||||
|                     mympd_get_artist(song), |                     mympd_get_artist(song), | ||||||
|                     mpd_song_get_duration(song), |                     mpd_song_get_duration(song), | ||||||
|  |                     mympd_get_title(song), | ||||||
|                     mympd_get_title(song) |                     mympd_get_title(song) | ||||||
|                 ); |                 ); | ||||||
|             } |             } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 jcorporation
					jcorporation