mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-31 13:53:00 +00:00 
			
		
		
		
	New layout for browse card
First steps for playlist view
This commit is contained in:
		| @@ -101,7 +101,7 @@ tbody { | ||||
|  float: right !important; | ||||
| } | ||||
|  | ||||
| #queue-buttons { | ||||
| #queue-buttons, #browsePlaylistsButtons { | ||||
|  margin-bottom:20px; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -193,13 +193,74 @@ | ||||
|             <button onclick="gotoPage('next',this,event)" id="queuePaginationBottomNext" title="Next Page" type="button" class="btn btn-secondary input-group-append">»</button> | ||||
|           </div> | ||||
|         </div> | ||||
|          | ||||
|       </div> | ||||
|     </div> | ||||
|      | ||||
|     <div class="card hide" id="cardBrowse"> | ||||
|       <div class="card-header" id="panel-heading-browse">Browse</div> | ||||
|       <div class="card-body"> | ||||
|       <div class="card-header" id="panel-heading-browse"> | ||||
|         <ul class="nav nav-tabs card-header-tabs"> | ||||
|           <li class="nav-item"> | ||||
|             <a class="nav-link text-dark" href="#/browse/filesystem/0/" id="cardBrowseNavFilesystem">Filesystem</a> | ||||
|           </li> | ||||
|           <li class="nav-item"> | ||||
|             <a class="nav-link text-dark" href="#/browse/playlists/0" id="cardBrowseNavPlaylists">Playlists</a> | ||||
|           </li> | ||||
|           <li class="nav-item"> | ||||
|             <a class="nav-link text-dark" href="#/browse/database/0" id="cardBrowseNavDatabase">Database</a> | ||||
|           </li> | ||||
|         </ul> | ||||
|       </div> | ||||
|       <div class="card-body hide" id="cardBrowsePlaylists"> | ||||
|         <div class="btn-toolbar collapse show" id="browsePlaylistsButtons" role="toolbar"> | ||||
|           <div id="browsePlaylistsPaginationTop" class="btn-group mr-2"> | ||||
|             <button onclick="gotoPage('prev',this,event)" id="browsePlaylistsPaginationTopPrev" title="Previous Page" type="button" class="btn btn-secondary">«</button> | ||||
|               <div class="input-group-append"> | ||||
|                 <button id="browsePlaylistsPaginationTopPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Page 1 / 1</button> | ||||
|                 <div class="dropdown-menu bg-dark px-2" id="browsePlaylistsPaginationTopPages"> | ||||
|                 </div> | ||||
|               </div>             | ||||
|             <button onclick="gotoPage('next',this,event)" id="browsePlaylistsPaginationTopNext" title="Next Page" type="button" class="btn btn-secondary input-group-append">»</button> | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="table-responsive-md"> | ||||
|           <table id="browsePlaylistsList" class="table table-hover table-sm"> | ||||
|             <col class="tblnum"/> | ||||
|             <col class="tbltitle"/>   | ||||
|             <col class="tbllastmodified"/>           | ||||
|             <col class="tblaction"/> | ||||
|             <thead> | ||||
|               <tr> | ||||
|                 <th></th> | ||||
|                 <th>Playlist</th> | ||||
|                 <th>Last modified</th> | ||||
|                 <th></th> | ||||
|               </tr> | ||||
|             </thead> | ||||
|             <tbody> | ||||
|             </tbody> | ||||
|           </table> | ||||
|         </div> | ||||
|         <div class="btn-toolbar" id="browsePlaylistsButtonsBottom" role="toolbar"> | ||||
|           <div class="btn-group mr-2"> | ||||
|             <button type="button" class="btn btn-secondary" onclick="scrollToTop()" title="To top"> | ||||
|               <span class="material-icons">keyboard_arrow_up</span> | ||||
|             </button> | ||||
|           </div>         | ||||
|           <div id="browsePlaylistsPaginationBottom" class="btn-group mr-2 dropup"> | ||||
|             <button onclick="gotoPage('prev',this,event)" id="browsePlaylistsPaginationBottomPrev" title="Previous Page" type="button" class="btn btn-secondary">«</button> | ||||
|               <div class="input-group-append"> | ||||
|                 <button id="browsePlaylistsPaginationBottomPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Page 1 / 1</button> | ||||
|                 <div class="dropdown-menu bg-dark px-2" id="browsePlaylistsPaginationBottomPages"> | ||||
|                 </div> | ||||
|               </div>             | ||||
|             <button onclick="gotoPage('next',this,event)" id="browsePlaylistsPaginationBottomNext" title="Next Page" type="button" class="btn btn-secondary input-group-append">»</button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="card-body hide" id="cardBrowseDatabase"> | ||||
|       </div> | ||||
|       <div class="card-body hide" id="cardBrowseFilesystem"> | ||||
|         <ol id="browseBreadcrumb" class="breadcrumb"> | ||||
|         </ol> | ||||
|  | ||||
| @@ -211,7 +272,7 @@ | ||||
|         </div> | ||||
|  | ||||
|         <div class="table-responsive-md"> | ||||
|           <table id="browseList" class="table table-hover table-sm"> | ||||
|           <table id="browseFilesystemList" class="table table-hover table-sm"> | ||||
|             <col class="tblnum"/> | ||||
|             <col class="tbltitle"/>             | ||||
|             <col class="tblartist"/> | ||||
| @@ -240,7 +301,7 @@ | ||||
|     </div>         | ||||
|  | ||||
|     <div class="card hide" id="cardSearch"> | ||||
|       <div class="card-header" id="pnael-heading-search">Search</div> | ||||
|       <div class="card-header" id="panel-heading-search">Search</div> | ||||
|       <div class="card-body"> | ||||
|         <div class="table-responsive-md"> | ||||
|           <table id="searchList" class="table table-hover table-sm"> | ||||
| @@ -272,7 +333,7 @@ | ||||
|       <div class="d-flex flex-fill navbar-nav" id="navbar-bottom"> | ||||
|         <div class="nav-item flex-fill text-center" id="navPlayback"><a class="nav-link" href="#/playing/">Playback</a></div> | ||||
|         <div class="nav-item flex-fill text-center" id="navQueue"><a class="nav-link" href="#/queue/0">Queue</a></div> | ||||
|         <div class="nav-item flex-fill text-center" id="navBrowse"><a class="nav-link" href="#/browse/0/">Browse</a></div> | ||||
|         <div class="nav-item flex-fill text-center" id="navBrowse"><a class="nav-link" href="#/browse/filesystem/0/">Browse</a></div> | ||||
|       </div> | ||||
|     </nav> | ||||
|   </footer> | ||||
| @@ -381,12 +442,12 @@ | ||||
|           </button> | ||||
|         </div> | ||||
|         <div class="modal-body"> | ||||
|           <h4><a style="color:#28a745" href="https://github.com/jcorporation/ympd"><span class="material-icons">play_circle_outline</span> myMPD</a> – <small>MPD Web GUI - written in C, utilizing Websockets and Bootstrap/JS</small></h4> | ||||
|           <h4><a class="text-success" href="https://github.com/jcorporation/ympd"><span class="material-icons">play_circle_outline</span> myMPD</a> – <small>MPD Web GUI - written in C, utilizing Websockets and Bootstrap/JS</small></h4> | ||||
|           <p>myMPD is a lightweight MPD web client that runs without a dedicated webserver or interpreter. It's tuned for minimal resource usage and requires only very litte dependencies. myMPD is a fork of <a style="color:#28a745" href="http://www.ympd.org">ympd</a>.</p> | ||||
|           <ul> | ||||
|             <li>Version: 2.1.1</li> | ||||
|             <li>Homepage: <a style="color:#28a745" target="_blank" href="https://github.com/jcorporation/mympd">https://github.com/jcorporation/mympd</a></li> | ||||
|             <li>Autor: Juergen Mang <<a style="color:#28a745" href="mailto:mail@jcgames.de">mail@jcgames.de</a>></li> | ||||
|             <li>Homepage: <a class="text-success" target="_blank" href="https://github.com/jcorporation/mympd">https://github.com/jcorporation/mympd</a></li> | ||||
|             <li>Autor: Juergen Mang <<a class="text-success" href="mailto:mail@jcgames.de">mail@jcgames.de</a>></li> | ||||
|           </ul> | ||||
|           <hr/> | ||||
|           <h5>Database Statistics</h5> | ||||
|   | ||||
							
								
								
									
										194
									
								
								htdocs/js/mpd.js
									
									
									
									
									
								
							
							
						
						
									
										194
									
								
								htdocs/js/mpd.js
									
									
									
									
									
								
							| @@ -48,6 +48,12 @@ var app = $.sammy(function() { | ||||
|         $('#cardSearch').addClass('hide'); | ||||
|         $('.pagination').addClass('hide'); | ||||
|         $('#searchqueue > input').val(''); | ||||
|         $('#cardBrowsePlaylists').addClass('hide'); | ||||
|         $('#cardBrowseDatabase').addClass('hide'); | ||||
|         $('#cardBrowseFilesystem').addClass('hide'); | ||||
|         $('#cardBrowseNavPlaylists').removeClass('active'); | ||||
|         $('#cardBrowseNavDatabase').removeClass('active'); | ||||
|         $('#cardBrowseNavFilesystem').removeClass('active'); | ||||
|         pagination = 0; | ||||
|         browsepath = ''; | ||||
|     } | ||||
| @@ -70,14 +76,39 @@ var app = $.sammy(function() { | ||||
|         socket.send('MPD_API_GET_QUEUE,'+pagination);         | ||||
|     }); | ||||
|  | ||||
|     this.get(/\#\/browse\/(\d+)\/(.*)/, function() { | ||||
|     this.get(/\#\/browse\/playlists\/(\d+)/, function() { | ||||
|         prepare(); | ||||
|         browsepath = this.params['splat'][1]; | ||||
|         pagination = parseInt(this.params['splat'][0]); | ||||
|         current_app = 'browse'; | ||||
|         current_app = 'browsePlaylists'; | ||||
|         $('#navBrowse').addClass('active'); | ||||
|         $('#cardBrowse').removeClass('hide'); | ||||
|         $('#browseList').find("tr:gt(0)").remove(); | ||||
|         $('#cardBrowsePlaylists').removeClass('hide'); | ||||
|         $('#cardBrowseNavPlaylists').addClass('active'); | ||||
|         socket.send('MPD_API_GET_PLAYLISTS,'+pagination); | ||||
|     }); | ||||
|      | ||||
|     this.get(/\#\/browse\/database\/(\d+)/, function() { | ||||
|         prepare(); | ||||
|         browsepath = this.params['splat'][1]; | ||||
|         pagination = parseInt(this.params['splat'][0]); | ||||
|         current_app = 'browseDatabase'; | ||||
|         $('#navBrowse').addClass('active'); | ||||
|         $('#cardBrowse').removeClass('hide'); | ||||
|         $('#cardBrowseDatabase').removeClass('hide'); | ||||
|         $('#cardBrowseNavDatabase').addClass('active'); | ||||
|     }); | ||||
|  | ||||
|     this.get(/\#\/browse\/filesystem\/(\d+)\/(.*)/, function() { | ||||
|         prepare(); | ||||
|         browsepath = this.params['splat'][1]; | ||||
|         pagination = parseInt(this.params['splat'][0]); | ||||
|         current_app = 'browseFilesystem'; | ||||
|         $('#navBrowse').addClass('active'); | ||||
|         $('#cardBrowse').removeClass('hide'); | ||||
|         $('#cardBrowseFilesystem').removeClass('hide'); | ||||
|         $('#cardBrowseNavFilesystem').addClass('active'); | ||||
|         $('#browseFilesystemList').find("tr:gt(0)").remove(); | ||||
|         $('#browseBreadcrumb').empty().append("<li class=\"breadcrumb-item\"><a uri=\"\" onclick=\"set_filter('')\">root</a></li>"); | ||||
|         socket.send('MPD_API_GET_BROWSE,'+pagination+','+(browsepath ? browsepath : "/")); | ||||
|         // Don't add all songs from root | ||||
| @@ -91,7 +122,7 @@ var app = $.sammy(function() { | ||||
|         } else { | ||||
|             add_all_songs.addClass('hide'); | ||||
|         } | ||||
|         $('#panel-heading-browse').text("Browse database: /"+browsepath); | ||||
|         //$('#panel-heading-browse').text("Browse database: /"+browsepath); | ||||
|  | ||||
|         var path_array = browsepath.split('/'); | ||||
|         var full_path = ""; | ||||
| @@ -243,37 +274,7 @@ function webSocketConnect() { | ||||
|                                "<td></td><td></td></tr>" | ||||
|                         ); | ||||
|                     } | ||||
|                     totalPages=Math.ceil(obj.totalSongs / MAX_ELEMENTS_PER_PAGE); | ||||
|                     if (totalPages==0) { totalPages=1; } | ||||
|                     $('#queuePaginationTopPage').text('Page '+(pagination / MAX_ELEMENTS_PER_PAGE + 1)+' / '+totalPages); | ||||
|                     $('#queuePaginationBottomPage').text('Page '+(pagination / MAX_ELEMENTS_PER_PAGE + 1)+' / '+totalPages); | ||||
|                     if (totalPages > 1) { | ||||
|                         $('#queuePaginationTopPage').removeClass('disabled'); | ||||
|                         $('#queuePaginationBottomPage').removeClass('disabled'); | ||||
|                         $('#queuePaginationTopPages').empty(); | ||||
|                         $('#queuePaginationBottomPages').empty(); | ||||
|                         for (var i=0;i<totalPages;i++) { | ||||
|                             $('#queuePaginationTopPages').append('<button onclick="gotoPage('+(i * MAX_ELEMENTS_PER_PAGE)+',this,event)" type="button" class="mr-1 mb-1 btn btn-secondary">'+(i+1)+'</button>'); | ||||
|                             $('#queuePaginationBottomPages').append('<button onclick="gotoPage('+(i * MAX_ELEMENTS_PER_PAGE)+',this,event)" type="button" class="mr-1 mb-1 btn btn-secondary">'+(i+1)+'</button>'); | ||||
|                         } | ||||
|                     } else { | ||||
|                         $('#queuePaginationTopPage').addClass('disabled'); | ||||
|                         $('#queuePaginationBottomPage').addClass('disabled'); | ||||
|                     } | ||||
|                     if(obj.totalSongs > pagination + MAX_ELEMENTS_PER_PAGE) { | ||||
|                         $('#queuePaginationTopNext').removeClass('disabled'); | ||||
|                         $('#queuePaginationBottomNext').removeClass('disabled'); | ||||
|                     } else { | ||||
|                         $('#queuePaginationTopNext').addClass('disabled'); | ||||
|                         $('#queuePaginationBottomNext').addClass('disabled');                             | ||||
|                     } | ||||
|                     if(pagination > 0) { | ||||
|                         $('#queuePaginationTopPrev').removeClass('disabled'); | ||||
|                         $('#queuePaginationBottomPrev').removeClass('disabled'); | ||||
|                     } else { | ||||
|                         $('#queuePaginationTopPrev').addClass('disabled'); | ||||
|                         $('#queuePaginationBottomPrev').addClass('disabled'); | ||||
|                     } | ||||
|                     setPagination(obj.totalSongs); | ||||
|  | ||||
|                     if ( isTouch ) { | ||||
|                         $('#queueList > tbody > tr > td:last-child').append( | ||||
| @@ -316,10 +317,52 @@ function webSocketConnect() { | ||||
|                         }, | ||||
|                     }); | ||||
|                     break; | ||||
|                 case 'playlists': | ||||
|                     if(current_app !== 'browsePlaylists') | ||||
|                         break; | ||||
|                     var nrItems=0; | ||||
|                     for (var item in obj.data) { | ||||
|                         nrItems++; | ||||
|                         var d = new Date(obj.data[item].last_modified * 1000); | ||||
|                         $('#'+current_app+'List > tbody').append( | ||||
|                                     '<tr uri="' + encodeURI(obj.data[item].plist) + '">' + | ||||
|                                     '<td><span class="material-icons">list</span></td>' + | ||||
|                                     '<td><a>' + basename(obj.data[item].plist) + '</a></td>' + | ||||
|                                     '<td>'+d.toUTCString()+'</td><td></td></tr>' | ||||
|                         ); | ||||
|                     } | ||||
|                     setPagination(obj.totalEntities); | ||||
|                     if ( isTouch ) { | ||||
|                         $('#'+current_app+'List > tbody > tr > td:last-child').append( | ||||
|                                     "<a class=\"pull-right btn-group-hover color-darkgrey\" href=\"#/\" " + | ||||
|                                         "onclick=\"trash($(this).parents('tr'));\">" + | ||||
|                                 "<span class=\"material-icons\">delete</span></a>"); | ||||
|                     } else { | ||||
|                         $('#'+current_app+'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=\"#/\" " + | ||||
|                                             "onclick=\"trash($(this).parents('tr'));\">" + | ||||
|                                     "<span class=\"material-icons\">delete</span></a>"); | ||||
|                             }, | ||||
|                             mouseleave: function(){ | ||||
|                                 var doomed = $(this); | ||||
|                                 $(this).children().last().find("a").stop().remove(); | ||||
|                             } | ||||
|                         }); | ||||
|                     }; | ||||
|                     $('#'+current_app+'List > tbody > tr').on({ | ||||
|                         click: function() { | ||||
|                                     socket.send("MPD_API_ADD_PLAYLIST," + decodeURI($(this).attr("uri"))); | ||||
|                                     showNotification('"' + $('td:nth-last-child(3)', this).text() + '" added','','','success'); | ||||
|                         } | ||||
|                     }); | ||||
|                     break; | ||||
|                 case 'search': | ||||
|                     $('#searchList').find("tr:gt(0)").remove(); | ||||
|                 case 'browse': | ||||
|                     if(current_app !== 'browse' && current_app !== 'search') | ||||
|                     if(current_app !== 'browseFilesystem' && current_app !== 'search') | ||||
|                         break; | ||||
|                      | ||||
|                     /* The use of encodeURI() below might seem useless, but it's not. It prevents | ||||
| @@ -383,7 +426,7 @@ function webSocketConnect() { | ||||
|                                 ); | ||||
|                                 break; | ||||
|                             case 'wrap': | ||||
|                                 if(current_app == 'browse') { | ||||
|                                 if(current_app == 'browseFilesystem') { | ||||
|                                     $('#browseNext').removeClass('disabled'); | ||||
|                                     $('#browsePagination').removeClass('hide'); | ||||
|                                 } else { | ||||
| @@ -445,10 +488,10 @@ function webSocketConnect() { | ||||
|                                 case 'dir': | ||||
|                                     pagination = 0; | ||||
|                                     browsepath = $(this).attr("uri"); | ||||
|                                     $("#browse > a").attr("href", '#/browse/'+pagination+'/'+browsepath); | ||||
| 									$('#filter > a').attr("href", '#/browse/'+pagination+'/'+browsepath); | ||||
|                                     app.setLocation('#/browse/'+pagination+'/'+browsepath); | ||||
| 									set_filter(''); | ||||
|                                     $("#browseFilesystemList > a").attr("href", '#/browse/filesystem/'+pagination+'/'+browsepath); | ||||
|                                     $('#filter > a').attr("href", '#/browse/filesystem/'+pagination+'/'+browsepath); | ||||
|                                     app.setLocation('#/browse/filesystem/'+pagination+'/'+browsepath); | ||||
| 				    set_filter(''); | ||||
|                                     break; | ||||
|                                 case 'song': | ||||
|                                     socket.send("MPD_API_ADD_TRACK," + decodeURI($(this).attr("uri"))); | ||||
| @@ -466,9 +509,9 @@ function webSocketConnect() { | ||||
| 			click: function() { | ||||
| 		        	pagination = 0; | ||||
| 				browsepath = $(this).attr("uri"); | ||||
| 				$("#browse > a").attr("href", '#/browse/'+pagination+'/'+browsepath); | ||||
| 				$('#filter > a').attr("href", '#/browse/'+pagination+'/'+browsepath); | ||||
| 				app.setLocation('#/browse/'+pagination+'/'+browsepath); | ||||
| 				$("#browseFilesystemList > a").attr("href", '#/browse/filesystem/'+pagination+'/'+browsepath); | ||||
| 				$('#filter > a').attr("href", '#/browse/filesystem/'+pagination+'/'+browsepath); | ||||
| 				app.setLocation('#/browse/filesystem/'+pagination+'/'+browsepath); | ||||
| 				set_filter(''); | ||||
| 			} | ||||
|                     }); | ||||
| @@ -671,6 +714,44 @@ function get_appropriate_ws_url() | ||||
|     return pcol + u[0] + separator + "ws"; | ||||
| } | ||||
|  | ||||
| function setPagination(number) { | ||||
|     var totalPages=Math.ceil(number / MAX_ELEMENTS_PER_PAGE); | ||||
|     if (totalPages==0) { totalPages=1; } | ||||
|         $('#'+current_app+'PaginationTopPage').text('Page '+(pagination / MAX_ELEMENTS_PER_PAGE + 1)+' / '+totalPages); | ||||
|         $('#'+current_app+'PaginationBottomPage').text('Page '+(pagination / MAX_ELEMENTS_PER_PAGE + 1)+' / '+totalPages); | ||||
|     if (totalPages > 1) { | ||||
|         $('#'+current_app+'PaginationTopPage').removeClass('disabled'); | ||||
|         $('#'+current_app+'PaginationBottomPage').removeClass('disabled'); | ||||
|         $('#'+current_app+'PaginationTopPages').empty(); | ||||
|         $('#'+current_app+'PaginationBottomPages').empty(); | ||||
|         for (var i=0;i<totalPages;i++) { | ||||
|             $('#'+current_app+'PaginationTopPages').append('<button onclick="gotoPage('+(i * MAX_ELEMENTS_PER_PAGE)+',this,event)" type="button" class="mr-1 mb-1 btn btn-secondary">'+(i+1)+'</button>'); | ||||
|             $('#'+current_app+'PaginationBottomPages').append('<button onclick="gotoPage('+(i * MAX_ELEMENTS_PER_PAGE)+',this,event)" type="button" class="mr-1 mb-1 btn btn-secondary">'+(i+1)+'</button>'); | ||||
|         } | ||||
|     } else { | ||||
|         $('#'+current_app+'PaginationTopPage').addClass('disabled'); | ||||
|         $('#'+current_app+'PaginationBottomPage').addClass('disabled'); | ||||
|     } | ||||
|      | ||||
|     if(number > pagination + MAX_ELEMENTS_PER_PAGE) { | ||||
|         $('#'+current_app+'PaginationTopNext').removeClass('disabled'); | ||||
|         $('#'+current_app+'PaginationBottomNext').removeClass('disabled'); | ||||
|         $('#'+current_app+'ButtonsBottom').removeClass('hide'); | ||||
|     } else { | ||||
|         $('#'+current_app+'PaginationTopNext').addClass('disabled'); | ||||
|         $('#'+current_app+'PaginationBottomNext').addClass('disabled'); | ||||
|         $('#'+current_app+'ButtonsBottom').addClass('hide'); | ||||
|     } | ||||
|      | ||||
|     if(pagination > 0) { | ||||
|         $('#'+current_app+'PaginationTopPrev').removeClass('disabled'); | ||||
|         $('#'+current_app+'PaginationBottomPrev').removeClass('disabled'); | ||||
|     } else { | ||||
|         $('#'+current_app+'PaginationTopPrev').addClass('disabled'); | ||||
|         $('#'+current_app+'PaginationBottomPrev').addClass('disabled'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function updateVolumeIcon(volume) { | ||||
|     if (volume == -1) { | ||||
|       $('#volumePrct').text('Volumecontrol disabled'); | ||||
| @@ -884,11 +965,8 @@ $('.page-link').on('click', function (e) { | ||||
|     } | ||||
|  | ||||
|     switch(current_app) { | ||||
|         case "queue": | ||||
|             app.setLocation('#/queue/'+pagination); | ||||
|             break; | ||||
|         case "browse": | ||||
|             app.setLocation('#/browse/'+pagination+'/'+browsepath); | ||||
|         case "browseFilesystem": | ||||
|             app.setLocation('#/browse/filesystem/'+pagination+'/'+browsepath); | ||||
|             break; | ||||
|     } | ||||
|     e.preventDefault(); | ||||
| @@ -925,8 +1003,14 @@ function gotoPage(x,element,event) { | ||||
|               app.setLocation('#/queue/'+pagination); | ||||
|             } | ||||
|             break; | ||||
|         case "browse": | ||||
|             app.setLocation('#/browse/'+pagination+'/'+browsepath); | ||||
|         case "browseFilesystem": | ||||
|             app.setLocation('#/browse/filesystem/'+pagination+'/'+browsepath); | ||||
|             break; | ||||
|         case "browsePlaylists": | ||||
|             app.setLocation('#/browse/playlists/'+pagination); | ||||
|             break; | ||||
|         case "browseDatabase": | ||||
|             app.setLocation('#/browse/database/'+pagination); | ||||
|             break;             | ||||
|     } | ||||
|     event.preventDefault(); | ||||
| @@ -1071,15 +1155,15 @@ function set_filter (c) { | ||||
| } | ||||
|  | ||||
| function add_filter () { | ||||
|     $('#filter').append('<a class="btn btn-secondary" onclick="set_filter(\'\')" href="#/browse/'+pagination+'/'+browsepath+'">All</a>'); | ||||
|     $('#filter').append('<a class="btn btn-secondary" id="fnum" onclick="set_filter(\'num\')" href="#/browse/'+pagination+'/'+browsepath+'">#</a>'); | ||||
|     $('#filter').append('<a class="btn btn-secondary" onclick="set_filter(\'\')" href="#/browse/filesystem/'+pagination+'/'+browsepath+'">All</a>'); | ||||
|     $('#filter').append('<a class="btn btn-secondary" id="fnum" onclick="set_filter(\'num\')" href="#/browse/filesystem/'+pagination+'/'+browsepath+'">#</a>'); | ||||
|  | ||||
|     for (i = 65; i <= 90; i++) { | ||||
|         var c = String.fromCharCode(i); | ||||
|         $('#filter').append('<a class="btn btn-secondary" id="f' + c + '" onclick="set_filter(\'' + c + '\');" href="#/browse/' + pagination + '/' + browsepath + '">' + c + '</a>'); | ||||
|         $('#filter').append('<a class="btn btn-secondary" id="f' + c + '" onclick="set_filter(\'' + c + '\');" href="#/browse/filesystem/' + pagination + '/' + browsepath + '">' + c + '</a>'); | ||||
|     } | ||||
|  | ||||
|     $('#filter').append('<a class="btn btn-secondary material-icons" id="fplist" onclick="set_filter(\'plist\')" href="#/browse/'+pagination+'/'+browsepath+'">list</a>'); | ||||
|     $('#filter').append('<a class="btn btn-secondary material-icons" id="fplist" onclick="set_filter(\'plist\')" href="#/browse/filesystem/'+pagination+'/'+browsepath+'">list</a>'); | ||||
| } | ||||
|  | ||||
| function chVolume (increment) { | ||||
|   | ||||
| @@ -170,6 +170,10 @@ int callback_mpd(struct mg_connection *c) | ||||
|             if(sscanf(c->content, "MPD_API_GET_QUEUE,%u", &uint_buf)) | ||||
|                 n = mpd_put_queue(mpd.buf, uint_buf); | ||||
|             break; | ||||
|         case MPD_API_GET_PLAYLISTS: | ||||
|             if(sscanf(c->content, "MPD_API_GET_PLAYLISTS,%u", &uint_buf)) | ||||
|                 n = mpd_put_playlists(mpd.buf, uint_buf); | ||||
|             break; | ||||
|         case MPD_API_GET_BROWSE: | ||||
|             p_charbuf = strdup(c->content); | ||||
|             if(strcmp(strtok(p_charbuf, ","), "MPD_API_GET_BROWSE")) | ||||
| @@ -779,6 +783,45 @@ int mpd_put_browse(char *buffer, char *path, unsigned int offset) | ||||
|     return cur - buffer; | ||||
| } | ||||
|  | ||||
| int mpd_put_playlists(char *buffer, unsigned int offset) | ||||
| { | ||||
|     char *cur = buffer; | ||||
|     const char *end = buffer + MAX_SIZE; | ||||
|     struct mpd_playlist *pl; | ||||
|     unsigned int entity_count = 0; | ||||
|  | ||||
|     if (!mpd_send_list_playlists(mpd.conn)) | ||||
|         RETURN_ERROR_AND_RECOVER("mpd_send_lists_playlists"); | ||||
|  | ||||
|     cur += json_emit_raw_str(cur, end  - cur, "{\"type\":\"playlists\",\"data\":[ "); | ||||
|  | ||||
|     while((pl = mpd_recv_playlist(mpd.conn)) != NULL) { | ||||
|         entity_count++; | ||||
|         if(entity_count > offset && entity_count <= offset+MAX_ELEMENTS_PER_PAGE) { | ||||
|             cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"playlist\",\"plist\":"); | ||||
|             cur += json_emit_quoted_str(cur, end - cur, mpd_playlist_get_path(pl)); | ||||
|             cur += json_emit_raw_str(cur, end - cur, ",\"last_modified\":"); | ||||
|             cur += json_emit_int(cur, end - cur, mpd_playlist_get_last_modified(pl)); | ||||
|             cur += json_emit_raw_str(cur, end - cur, "},"); | ||||
|         } | ||||
|         mpd_playlist_free(pl); | ||||
|     } | ||||
|  | ||||
|     if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(mpd.conn)) { | ||||
|         fprintf(stderr, "MPD mpd_send_list_playlists: %s\n", mpd_connection_get_error_message(mpd.conn)); | ||||
|         mpd.conn_state = MPD_FAILURE; | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /* remove last ',' */ | ||||
|     cur--; | ||||
|  | ||||
|     cur += json_emit_raw_str(cur, end - cur, "],\"totalEntities\":"); | ||||
|     cur += json_emit_int(cur, end - cur, entity_count);     | ||||
|     cur += json_emit_raw_str(cur, end - cur, "}"); | ||||
|     return cur - buffer; | ||||
| } | ||||
|  | ||||
| int mpd_search(char *buffer, char *searchstr) | ||||
| { | ||||
|     char *cur = buffer; | ||||
|   | ||||
| @@ -76,7 +76,8 @@ | ||||
|     X(MPD_API_SEND_SHUFFLE) \ | ||||
|     X(MPD_API_GET_STATS) \ | ||||
|     X(MPD_API_SET_MIXRAMPDB) \ | ||||
|     X(MPD_API_SET_MIXRAMPDELAY) | ||||
|     X(MPD_API_SET_MIXRAMPDELAY) \ | ||||
|     X(MPD_API_GET_PLAYLISTS) | ||||
|  | ||||
| enum mpd_cmd_ids { | ||||
|     MPD_CMDS(GEN_ENUM) | ||||
| @@ -125,6 +126,7 @@ int mpd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsigne | ||||
| int mpd_put_outputs(char *buffer, int putnames); | ||||
| int mpd_put_current_song(char *buffer); | ||||
| int mpd_put_queue(char *buffer, unsigned int offset); | ||||
| int mpd_put_playlists(char *buffer, unsigned int offset); | ||||
| int mpd_put_browse(char *buffer, char *path, unsigned int offset); | ||||
| int mpd_search(char *buffer, char *searchstr); | ||||
| int mpd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 jcorporation
					jcorporation