mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-30 21:33:00 +00:00 
			
		
		
		
	Feat: last played songs card
This commit is contained in:
		| @@ -72,6 +72,7 @@ post_upgrade() { | |||||||
|   [ -f /var/lib/mympd/state/colsBrowsePlaylistsDetail ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowsePlaylistsDetail |   [ -f /var/lib/mympd/state/colsBrowsePlaylistsDetail ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowsePlaylistsDetail | ||||||
|   [ -f /var/lib/mympd/state/colsQueue ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsQueue |   [ -f /var/lib/mympd/state/colsQueue ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsQueue | ||||||
|   [ -f /var/lib/mympd/state/colsSearch ] || echo -n '["Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsSearch |   [ -f /var/lib/mympd/state/colsSearch ] || echo -n '["Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsSearch | ||||||
|  |   [ -f /var/lib/mympd/state/colsLastPlayed ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsLastPlayed | ||||||
|  |  | ||||||
|   # fix ownership of /var/lib/mympd |   # fix ownership of /var/lib/mympd | ||||||
|   echo "INFO: Fixing ownership of /var/lib/mympd" |   echo "INFO: Fixing ownership of /var/lib/mympd" | ||||||
|   | |||||||
| @@ -87,6 +87,7 @@ done | |||||||
| [ -f /var/lib/mympd/state/colsBrowsePlaylistsDetail ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowsePlaylistsDetail | [ -f /var/lib/mympd/state/colsBrowsePlaylistsDetail ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowsePlaylistsDetail | ||||||
| [ -f /var/lib/mympd/state/colsQueue ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsQueue | [ -f /var/lib/mympd/state/colsQueue ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsQueue | ||||||
| [ -f /var/lib/mympd/state/colsSearch ] || echo -n '["Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsSearch | [ -f /var/lib/mympd/state/colsSearch ] || echo -n '["Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsSearch | ||||||
|  | [ -f /var/lib/mympd/state/colsLastPlayed ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsLastPlayed | ||||||
|  |  | ||||||
| echo "Fixing ownership of /var/lib/mympd" | echo "Fixing ownership of /var/lib/mympd" | ||||||
| chown -R mympd.mympd /var/lib/mympd | chown -R mympd.mympd /var/lib/mympd | ||||||
|   | |||||||
| @@ -54,3 +54,6 @@ syscmds = false | |||||||
|  |  | ||||||
| #Elements per page for pagination, max: 400 | #Elements per page for pagination, max: 400 | ||||||
| max_elements_per_page = 100 | max_elements_per_page = 100 | ||||||
|  |  | ||||||
|  | #Number of songs keep in last played list | ||||||
|  | last_played_count = 20 | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								debian/postinst
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/postinst
									
									
									
									
										vendored
									
									
								
							| @@ -66,6 +66,7 @@ fi | |||||||
| [ -f /var/lib/mympd/state/colsPlayback ] || echo -n '["Artist","Album","Genre"]' > /var/lib/mympd/state/colsPlayback | [ -f /var/lib/mympd/state/colsPlayback ] || echo -n '["Artist","Album","Genre"]' > /var/lib/mympd/state/colsPlayback | ||||||
| [ -f /var/lib/mympd/state/colsBrowsePlaylistsDetail ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowsePlaylistsDetail | [ -f /var/lib/mympd/state/colsBrowsePlaylistsDetail ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsBrowsePlaylistsDetail | ||||||
| [ -f /var/lib/mympd/state/colsQueue ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsQueue | [ -f /var/lib/mympd/state/colsQueue ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsQueue | ||||||
|  | [ -f /var/lib/mympd/state/colsLastPlayed ] || echo -n '["Pos","Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsLastPlayed | ||||||
| [ -f /var/lib/mympd/state/colsSearch ] || echo -n '["Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsSearch | [ -f /var/lib/mympd/state/colsSearch ] || echo -n '["Title","Artist","Album","Duration"]' > /var/lib/mympd/state/colsSearch | ||||||
|  |  | ||||||
| echo "Fixing ownership of /var/lib/mympd" | echo "Fixing ownership of /var/lib/mympd" | ||||||
|   | |||||||
| @@ -199,6 +199,62 @@ | |||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
|      |      | ||||||
|  |     <div class="card hide" id="cardLastPlayed"> | ||||||
|  |       <div class="card-header">Last Played Songs<span id="panel-heading-last-played" class="text pull-right"></span></div> | ||||||
|  |       <div class="card-body"> | ||||||
|  |         <div class="btn-toolbar card-toolbar"> | ||||||
|  |           <div id="LastPlayedPaginationTop" class="btn-group mr-2 hide"> | ||||||
|  |             <button data-href='{"cmd": "gotoPage", "options": ["prev"]}' id="LastPlayedPaginationTopPrev" title="Previous Page" type="button" class="btn btn-secondary">«</button> | ||||||
|  |               <div class="input-group-append"> | ||||||
|  |                 <button id="LastPlayedPaginationTopPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">1 / 1</button> | ||||||
|  |                 <div class="dropdown-menu bg-dark px-2 pages" id="LastPlayedPaginationTopPages"> | ||||||
|  |                 </div> | ||||||
|  |               </div>             | ||||||
|  |             <button data-href='{"cmd": "gotoPage", "options": ["next"]}' id="LastPlayedPaginationTopNext" title="Next Page" type="button" class="btn btn-secondary input-group-append">»</button> | ||||||
|  |           </div> | ||||||
|  |           <div class="btn-group mr-2 featTags"> | ||||||
|  |             <button id="LastPlayedColsBtn" class="btn btn-secondary dropdown-toggle material-icons" type="button" data-toggle="dropdown">settings</button> | ||||||
|  |             <div class="dropdown-menu bg-dark px-2" id="LastPlayedColsDropdown"><form></form> | ||||||
|  |               <button data-href='{"cmd": "saveCols", "options": ["LastPlayed"]}' class="btn btn-success btn-block btn-sm mt-2">Apply</button> | ||||||
|  |             </div>           | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |  | ||||||
|  |         <div class="table-responsive-md"> | ||||||
|  |           <table id="LastPlayedList" class="table table-hover table-sm"> | ||||||
|  |             <thead> | ||||||
|  |               <tr> | ||||||
|  |                 <th>#</th> | ||||||
|  |                 <th>Title</th>               | ||||||
|  |                 <th>Artist</th> | ||||||
|  |                 <th>Album</th> | ||||||
|  |                 <th>Duration</th> | ||||||
|  |                 <th></th> | ||||||
|  |               </tr> | ||||||
|  |             </thead> | ||||||
|  |             <tbody class="clickable"> | ||||||
|  |             </tbody> | ||||||
|  |           </table> | ||||||
|  |         </div> | ||||||
|  |         <div class="btn-toolbar hide" id="LastPlayedButtonsBottom"> | ||||||
|  |           <div class="btn-group mr-2"> | ||||||
|  |             <button type="button" class="btn btn-secondary material-icons" data-href='{"cmd": "scrollTo", "options: [0]}' title="To top"> | ||||||
|  |               keyboard_arrow_up | ||||||
|  |             </button> | ||||||
|  |           </div>         | ||||||
|  |           <div id="LastPlayedPaginationBottom" class="btn-group mr-2 dropup"> | ||||||
|  |             <button data-href='{"cmd": "gotoPage", "options": ["prev"]}' id="LastPlayedPaginationBottomPrev" title="Previous Page" type="button" class="btn btn-secondary">«</button> | ||||||
|  |               <div class="input-group-append"> | ||||||
|  |                 <button id="LastPlayedPaginationBottomPage" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">1 / 1</button> | ||||||
|  |                 <div class="dropdown-menu bg-dark px-2 pages" id="LastPlayedPaginationBottomPages"> | ||||||
|  |                 </div> | ||||||
|  |               </div>             | ||||||
|  |             <button data-href='{"cmd": "gotoPage", "options": ["next"]}' id="LastPlayedPaginationBottomNext" 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 hide" id="cardBrowse"> | ||||||
|       <div class="card-header" id="panel-heading-browse"> |       <div class="card-header" id="panel-heading-browse"> | ||||||
|         <ul class="nav nav-tabs card-header-tabs"> |         <ul class="nav nav-tabs card-header-tabs"> | ||||||
|   | |||||||
| @@ -39,6 +39,7 @@ var playlistEl; | |||||||
| var app = {}; | var app = {}; | ||||||
| app.apps = { "Playback":   { "state": "0/-/", "scrollPos": 0 }, | app.apps = { "Playback":   { "state": "0/-/", "scrollPos": 0 }, | ||||||
|              "Queue": 	   { "state": "0/any/", "scrollPos": 0 }, |              "Queue": 	   { "state": "0/any/", "scrollPos": 0 }, | ||||||
|  |              "LastPlayed": { "state": "0/any/", "scrollPos": 0 }, | ||||||
|              "Browse":     {  |              "Browse":     {  | ||||||
|                   "active": "Database",  |                   "active": "Database",  | ||||||
|                   "tabs":  { "Filesystem": { "state": "0/-/", "scrollPos": 0 }, |                   "tabs":  { "Filesystem": { "state": "0/-/", "scrollPos": 0 }, | ||||||
| @@ -96,7 +97,7 @@ var modalSaveSmartPlaylist = new Modal(document.getElementById('modalSaveSmartPl | |||||||
| var modalDeletePlaylist = new Modal(document.getElementById('modalDeletePlaylist')); | var modalDeletePlaylist = new Modal(document.getElementById('modalDeletePlaylist')); | ||||||
| var modalHelp = new Modal(document.getElementById('modalHelp')); | var modalHelp = new Modal(document.getElementById('modalHelp')); | ||||||
|  |  | ||||||
| var dropdownMainMenu;// = new Dropdown(document.getElementById('mainMenu')); | var dropdownMainMenu; | ||||||
| var dropdownVolumeMenu = new Dropdown(document.getElementById('volumeMenu')); | var dropdownVolumeMenu = new Dropdown(document.getElementById('volumeMenu')); | ||||||
|  |  | ||||||
| var collapseDBupdate = new Collapse(document.getElementById('navDBupdate')); | var collapseDBupdate = new Collapse(document.getElementById('navDBupdate')); | ||||||
| @@ -111,6 +112,7 @@ function appPrepare(scrollPos) { | |||||||
|         document.getElementById('cardQueue').classList.add('hide'); |         document.getElementById('cardQueue').classList.add('hide'); | ||||||
|         document.getElementById('cardBrowse').classList.add('hide'); |         document.getElementById('cardBrowse').classList.add('hide'); | ||||||
|         document.getElementById('cardSearch').classList.add('hide'); |         document.getElementById('cardSearch').classList.add('hide'); | ||||||
|  |         document.getElementById('cardLastPlayed').classList.add('hide'); | ||||||
|         for (var i = 0; i < domCache.panelHeadingBrowseLen; i++) { |         for (var i = 0; i < domCache.panelHeadingBrowseLen; i++) { | ||||||
|             domCache.panelHeadingBrowse[i].classList.remove('active'); |             domCache.panelHeadingBrowse[i].classList.remove('active'); | ||||||
|         } |         } | ||||||
| @@ -119,6 +121,7 @@ function appPrepare(scrollPos) { | |||||||
|         document.getElementById('cardBrowseFilesystem').classList.add('hide');         |         document.getElementById('cardBrowseFilesystem').classList.add('hide');         | ||||||
|         //show active card + nav |         //show active card + nav | ||||||
|         document.getElementById('card' + app.current.app).classList.remove('hide'); |         document.getElementById('card' + app.current.app).classList.remove('hide'); | ||||||
|  |         if (document.getElementById('nav' + app.current.app)) | ||||||
|             document.getElementById('nav' + app.current.app).classList.add('active'); |             document.getElementById('nav' + app.current.app).classList.add('active'); | ||||||
|         if (app.current.tab != undefined) { |         if (app.current.tab != undefined) { | ||||||
|             document.getElementById('card' + app.current.app + app.current.tab).classList.remove('hide'); |             document.getElementById('card' + app.current.app + app.current.tab).classList.remove('hide'); | ||||||
| @@ -203,6 +206,9 @@ function appRoute() { | |||||||
|         selectTag('searchqueuetags', 'searchqueuetagsdesc', app.current.filter); |         selectTag('searchqueuetags', 'searchqueuetagsdesc', app.current.filter); | ||||||
|         getQueue(); |         getQueue(); | ||||||
|     } |     } | ||||||
|  |     else if (app.current.app == 'LastPlayed') { | ||||||
|  |         sendAPI({"cmd": "MPD_API_QUEUE_LAST_PLAYED", "data": {"offset": app.current.page}}, parseLastPlayed); | ||||||
|  |     } | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'All') { |     else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'All') { | ||||||
|         sendAPI({"cmd": "MPD_API_PLAYLIST_LIST", "data": {"offset": app.current.page, "filter": app.current.filter}}, parsePlaylists); |         sendAPI({"cmd": "MPD_API_PLAYLIST_LIST", "data": {"offset": app.current.page, "filter": app.current.filter}}, parsePlaylists); | ||||||
|         doSetFilterLetter('BrowsePlaylistsFilter'); |         doSetFilterLetter('BrowsePlaylistsFilter'); | ||||||
| @@ -264,10 +270,13 @@ function appRoute() { | |||||||
|         if (searchstrEl.value == '' && app.current.search != '') |         if (searchstrEl.value == '' && app.current.search != '') | ||||||
|             searchstrEl.value = app.current.search; |             searchstrEl.value = app.current.search; | ||||||
|         if (app.last.app != app.current.app) { |         if (app.last.app != app.current.app) { | ||||||
|             if (app.current.search != '') |             if (app.current.search != '') { | ||||||
|  |                 var colspan = settings['cols' + app.current.app].length; | ||||||
|  |                 colspan--; | ||||||
|                 document.getElementById('SearchList').getElementsByTagName('tbody')[0].innerHTML= |                 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="5">Searching...</td></tr>'; |                     '<td colspan="' + colspan + '">Searching...</td></tr>'; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (app.current.search.length >= 2) { |         if (app.current.search.length >= 2) { | ||||||
| @@ -455,9 +464,13 @@ function appInit() { | |||||||
|     document.getElementById('QueueList').addEventListener('click', function(event) { |     document.getElementById('QueueList').addEventListener('click', function(event) { | ||||||
|         if (event.target.nodeName == 'TD')  |         if (event.target.nodeName == 'TD')  | ||||||
|             sendAPI({"cmd": "MPD_API_PLAYER_PLAY_TRACK","data": {"track": event.target.parentNode.getAttribute('data-trackid')}}); |             sendAPI({"cmd": "MPD_API_PLAYER_PLAY_TRACK","data": {"track": event.target.parentNode.getAttribute('data-trackid')}}); | ||||||
|         else if (event.target.nodeName == 'A') { |         else if (event.target.nodeName == 'A') | ||||||
|  |             showMenu(event.target, event); | ||||||
|  |     }, false); | ||||||
|  |      | ||||||
|  |     document.getElementById('LastPlayedList').addEventListener('click', function(event) { | ||||||
|  |         if (event.target.nodeName == 'A') | ||||||
|             showMenu(event.target, event); |             showMenu(event.target, event); | ||||||
|         } |  | ||||||
|     }, false);     |     }, false);     | ||||||
|  |  | ||||||
|     document.getElementById('BrowseFilesystemList').addEventListener('click', function(event) { |     document.getElementById('BrowseFilesystemList').addEventListener('click', function(event) { | ||||||
| @@ -566,7 +579,7 @@ function appInit() { | |||||||
|     }, false); |     }, false); | ||||||
|  |  | ||||||
|     var dropdowns = ['QueueColsDropdown', 'BrowseFilesystemColsDropdown', 'SearchColsDropdown', 'BrowsePlaylistsDetailColsDropdown',  |     var dropdowns = ['QueueColsDropdown', 'BrowseFilesystemColsDropdown', 'SearchColsDropdown', 'BrowsePlaylistsDetailColsDropdown',  | ||||||
|         'BrowseDatabaseColsDropdown', 'PlaybackColsDropdown']; |         'BrowseDatabaseColsDropdown', 'PlaybackColsDropdown', 'LastPlayedColsDropdown']; | ||||||
|     for (var i = 0; i < dropdowns.length; i++) { |     for (var i = 0; i < dropdowns.length; i++) { | ||||||
|         document.getElementById(dropdowns[i]).addEventListener('click', function(event) { |         document.getElementById(dropdowns[i]).addEventListener('click', function(event) { | ||||||
|             if (event.target.nodeName == 'INPUT') |             if (event.target.nodeName == 'INPUT') | ||||||
| @@ -601,6 +614,7 @@ function appInit() { | |||||||
|     dragAndDropTable('QueueList'); |     dragAndDropTable('QueueList'); | ||||||
|     dragAndDropTable('BrowsePlaylistsDetailList'); |     dragAndDropTable('BrowsePlaylistsDetailList'); | ||||||
|     dragAndDropTableHeader('Queue'); |     dragAndDropTableHeader('Queue'); | ||||||
|  |     dragAndDropTableHeader('LastPlayed'); | ||||||
|     dragAndDropTableHeader('Search'); |     dragAndDropTableHeader('Search'); | ||||||
|     dragAndDropTableHeader('BrowseFilesystem'); |     dragAndDropTableHeader('BrowseFilesystem'); | ||||||
|     dragAndDropTableHeader('BrowsePlaylistsDetail'); |     dragAndDropTableHeader('BrowsePlaylistsDetail'); | ||||||
| @@ -964,7 +978,7 @@ function filterCols(x) { | |||||||
|     if (settings.featTags == false) |     if (settings.featTags == false) | ||||||
|         tags.push('Title'); |         tags.push('Title'); | ||||||
|     tags.push('Duration'); |     tags.push('Duration'); | ||||||
|     if (x == 'colsQueue' || x == 'colsBrowsePlaylistsDetail') |     if (x == 'colsQueue' || x == 'colsBrowsePlaylistsDetail' || x == 'colsLastPlayed') | ||||||
|         tags.push('Pos'); |         tags.push('Pos'); | ||||||
|     else if (x == 'colsBrowseFilesystem') |     else if (x == 'colsBrowseFilesystem') | ||||||
|         tags.push('Type'); |         tags.push('Type'); | ||||||
| @@ -1046,6 +1060,7 @@ function parseSettings(obj) { | |||||||
|         app.apps.Search.state = '0/filename/'; |         app.apps.Search.state = '0/filename/'; | ||||||
|         app.apps.Queue.state = '0/filename/'; |         app.apps.Queue.state = '0/filename/'; | ||||||
|         settings.colsQueue = ["Pos", "Title", "Duration"]; |         settings.colsQueue = ["Pos", "Title", "Duration"]; | ||||||
|  |         settings.colsLastPlayed = ["Pos", "Title", "Duration"]; | ||||||
|         settings.colsSearch = ["Title", "Duration"]; |         settings.colsSearch = ["Title", "Duration"]; | ||||||
|         settings.colsBrowseFilesystem = ["Type", "Title", "Duration"]; |         settings.colsBrowseFilesystem = ["Type", "Title", "Duration"]; | ||||||
|         settings.colsBrowseDatabase = ["Track", "Title", "Duration"]; |         settings.colsBrowseDatabase = ["Track", "Title", "Duration"]; | ||||||
| @@ -1100,6 +1115,7 @@ function parseSettings(obj) { | |||||||
|     settings.browsetags.sort(); |     settings.browsetags.sort(); | ||||||
|     filterCols('colsSearch'); |     filterCols('colsSearch'); | ||||||
|     filterCols('colsQueue'); |     filterCols('colsQueue'); | ||||||
|  |     filterCols('colsLastPlayed'); | ||||||
|     filterCols('colsBrowsePlaylistsDetail'); |     filterCols('colsBrowsePlaylistsDetail'); | ||||||
|     filterCols('colsBrowseFilesystem'); |     filterCols('colsBrowseFilesystem'); | ||||||
|     filterCols('colsBrowseDatabase'); |     filterCols('colsBrowseDatabase'); | ||||||
| @@ -1144,12 +1160,15 @@ function parseSettings(obj) { | |||||||
|      |      | ||||||
|     setCols('Queue'); |     setCols('Queue'); | ||||||
|     setCols('Search'); |     setCols('Search'); | ||||||
|  |     setCols('LastPlayed'); | ||||||
|     setCols('BrowseFilesystem'); |     setCols('BrowseFilesystem'); | ||||||
|     setCols('BrowsePlaylistsDetail'); |     setCols('BrowsePlaylistsDetail'); | ||||||
|     setCols('BrowseDatabase', '.tblAlbumTitles'); |     setCols('BrowseDatabase', '.tblAlbumTitles'); | ||||||
|     setCols('Playback'); |     setCols('Playback'); | ||||||
|     if (app.current.app == 'Queue') |     if (app.current.app == 'Queue') | ||||||
|         getQueue(); |         getQueue(); | ||||||
|  |     else if (app.current.app == 'LastPlayed') | ||||||
|  |         appRoute(); | ||||||
|     else if (app.current.app == 'Search') |     else if (app.current.app == 'Search') | ||||||
|         appRoute(); |         appRoute(); | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Filesystem') |     else if (app.current.app == 'Browse' && app.current.tab == 'Filesystem') | ||||||
| @@ -1166,7 +1185,7 @@ function setCols(table, className) { | |||||||
|     if (settings.featTags == false) |     if (settings.featTags == false) | ||||||
|         tags.push('Title'); |         tags.push('Title'); | ||||||
|     tags.push('Duration'); |     tags.push('Duration'); | ||||||
|     if (table == 'Queue' || table == 'BrowsePlaylistsDetail') |     if (table == 'Queue' || table == 'BrowsePlaylistsDetail' || table == 'LastPlayed') | ||||||
|         tags.push('Pos'); |         tags.push('Pos'); | ||||||
|     if (table == 'BrowseFilesystem') |     if (table == 'BrowseFilesystem') | ||||||
|         tags.push('Type'); |         tags.push('Type'); | ||||||
| @@ -1400,6 +1419,9 @@ function parseState(obj) { | |||||||
|             pb[i].innerText = ''; |             pb[i].innerText = ''; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     if (app.current.app == 'LastPlayed') | ||||||
|  |         sendAPI({"cmd": "MPD_API_QUEUE_LAST_PLAYED", "data": {"offset": app.current.page}}, parseLastPlayed); | ||||||
|  |  | ||||||
|     lastState = obj;                     |     lastState = obj;                     | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1475,17 +1497,65 @@ function parseQueue(obj) { | |||||||
|         tr[i].remove(); |         tr[i].remove(); | ||||||
|     }                     |     }                     | ||||||
|  |  | ||||||
|  |     var colspan = settings['cols' + app.current.app].length; | ||||||
|  |     colspan--; | ||||||
|  |  | ||||||
|     if (obj.type == 'queuesearch' && nrItems == 0) |     if (obj.type == 'queuesearch' && nrItems == 0) | ||||||
|         tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + |         tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + | ||||||
|                           '<td colspan="5">No results, please refine your search!</td></tr>'; |                           '<td colspan="' + colspan + '">No results, please refine your search!</td></tr>'; | ||||||
|     else if (obj.type == 'queue' && nrItems == 0) |     else if (obj.type == 'queue' && nrItems == 0) | ||||||
|         tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + |         tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + | ||||||
|                           '<td colspan="5">Empty queue</td></tr>'; |                           '<td colspan="' + colspan + '">Empty queue</td></tr>'; | ||||||
|  |  | ||||||
|     setPagination(obj.totalEntities); |     setPagination(obj.totalEntities); | ||||||
|     document.getElementById('QueueList').classList.remove('opacity05'); |     document.getElementById('QueueList').classList.remove('opacity05'); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function parseLastPlayed(obj) { | ||||||
|  |     if (app.current.app !== 'LastPlayed') | ||||||
|  |         return; | ||||||
|  |      | ||||||
|  |     document.getElementById('panel-heading-last-played').innerText = obj.totalEntities + ' Songs'; | ||||||
|  |  | ||||||
|  |     var nrItems = obj.data.length; | ||||||
|  |     var table = document.getElementById(app.current.app + 'List'); | ||||||
|  |     table.setAttribute('data-version', obj.queueVersion); | ||||||
|  |     var tbody = table.getElementsByTagName('tbody')[0]; | ||||||
|  |     var tr = tbody.getElementsByTagName('tr'); | ||||||
|  |     for (var i = 0; i < nrItems; i++) { | ||||||
|  |         var minutes = Math.floor(obj.data[i].Duration / 60); | ||||||
|  |         var seconds = obj.data[i].Duration - minutes * 60; | ||||||
|  |         obj.data[i].Duration = minutes + ':' + (seconds < 10 ? '0' : '') + seconds; | ||||||
|  |         var row = document.createElement('tr'); | ||||||
|  |         row.setAttribute('data-songpos', (obj.data[i].Pos + 1)); | ||||||
|  |         row.setAttribute('data-uri', obj.data[i].uri); | ||||||
|  |         var tds = ''; | ||||||
|  |         for (var c = 0; c < settings.colsLastPlayed.length; c++) { | ||||||
|  |             tds += '<td data-col="' + settings.colsLastPlayed[c] + '">' + obj.data[i][settings.colsLastPlayed[c]] + '</td>'; | ||||||
|  |         } | ||||||
|  |         tds += '<td data-col="Action"><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>'; | ||||||
|  |         row.innerHTML = tds; | ||||||
|  |         if (i < tr.length) | ||||||
|  |             tr[i].replaceWith(row);  | ||||||
|  |         else  | ||||||
|  |             tbody.append(row);   | ||||||
|  |     } | ||||||
|  |     var trLen = tr.length - 1; | ||||||
|  |     for (var i = trLen; i >= nrItems; i --) { | ||||||
|  |         tr[i].remove(); | ||||||
|  |     }                     | ||||||
|  |  | ||||||
|  |     var colspan = settings['cols' + app.current.app].length; | ||||||
|  |     colspan--; | ||||||
|  |      | ||||||
|  |     if (nrItems == 0) | ||||||
|  |         tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + | ||||||
|  |             '<td colspan="' + colspan + '">Empty list</td></tr>'; | ||||||
|  |  | ||||||
|  |     setPagination(obj.totalEntities); | ||||||
|  |     document.getElementById('LastPlayedList').classList.remove('opacity05'); | ||||||
|  | } | ||||||
|  |  | ||||||
| function parseSearch(obj) { | function parseSearch(obj) { | ||||||
|     if (app.current.app !== 'Search') |     if (app.current.app !== 'Search') | ||||||
|         return; |         return; | ||||||
| @@ -1574,7 +1644,7 @@ function parseFilesystem(obj) { | |||||||
|                      |                      | ||||||
|     if (nrItems == 0) |     if (nrItems == 0) | ||||||
|         tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + |         tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + | ||||||
|                           '<td colspan="5">No results</td></tr>'; |                           '<td colspan="' + colspan + '">No results</td></tr>'; | ||||||
|     document.getElementById(app.current.app + (app.current.tab==undefined ? '' : app.current.tab) + 'List').classList.remove('opacity05'); |     document.getElementById(app.current.app + (app.current.tab==undefined ? '' : app.current.tab) + 'List').classList.remove('opacity05'); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1671,13 +1741,16 @@ function parsePlaylists(obj) { | |||||||
|  |  | ||||||
|     setPagination(obj.totalEntities); |     setPagination(obj.totalEntities); | ||||||
|      |      | ||||||
|     if (nrItems == 0) |     if (nrItems == 0) { | ||||||
|  |         var colspan = settings['cols' + list].length; | ||||||
|  |         colspan--; | ||||||
|         if (app.current.view == 'All') |         if (app.current.view == 'All') | ||||||
|             tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + |             tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + | ||||||
|                               '<td colspan="5">No playlists found.</td></tr>'; |                               '<td colspan="' + colspan + '">No playlists found.</td></tr>'; | ||||||
|         else |         else | ||||||
|             tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + |             tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' + | ||||||
|                               '<td colspan="5">Empty playlist.</td></tr>'; |                               '<td colspan="' + colspan + '">Empty playlist.</td></tr>'; | ||||||
|  |     } | ||||||
|              |              | ||||||
|     document.getElementById(app.current.app + app.current.tab + app.current.view + 'List').classList.remove('opacity05'); |     document.getElementById(app.current.app + app.current.tab + app.current.view + 'List').classList.remove('opacity05'); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								src/list.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								src/list.c
									
									
									
									
									
								
							| @@ -140,6 +140,34 @@ int list_push(struct list *l, const char *data, int value) { | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | struct node *list_node_extract(struct list *l, unsigned idx) { | ||||||
|  |     if (l->list == NULL) { return NULL; } | ||||||
|  |     struct node *current = l->list, **previous = &l->list; | ||||||
|  |     for (; idx > 0; idx--) { | ||||||
|  |         if (current->next == NULL)  | ||||||
|  |             return NULL; | ||||||
|  |         previous = ¤t->next; | ||||||
|  |         current = current->next; | ||||||
|  |     } | ||||||
|  |     /* set the previous node's 'next' value to the current | ||||||
|  |      * nodes next value */ | ||||||
|  |     *previous = current->next; | ||||||
|  |     /* null out this node's next value since it's not part of | ||||||
|  |      * a list anymore */ | ||||||
|  |     current->next = NULL; | ||||||
|  |     l->length--; | ||||||
|  |     return current; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int list_shift(struct list *l, unsigned idx) { | ||||||
|  |     struct node * extracted = list_node_extract(l, idx); | ||||||
|  |     if (extracted == NULL)  | ||||||
|  |         return -1; | ||||||
|  |     free(extracted->data); | ||||||
|  |     free(extracted); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| int list_free(struct list *l) { | int list_free(struct list *l) { | ||||||
|     struct node *current = l->list, *tmp = NULL; |     struct node *current = l->list, *tmp = NULL; | ||||||
|     while (current != NULL) { |     while (current != NULL) { | ||||||
|   | |||||||
| @@ -13,6 +13,8 @@ struct list { | |||||||
|  |  | ||||||
| int list_init(struct list *l); | int list_init(struct list *l); | ||||||
| int list_push(struct list *l, const char *data, int value); | int list_push(struct list *l, const char *data, int value); | ||||||
|  | int list_shift(struct list *l, unsigned idx); | ||||||
|  | struct node *list_node_extract(struct list *l, unsigned idx); | ||||||
| int list_replace(struct list *l, int pos, const char *data, int value); | int list_replace(struct list *l, int pos, const char *data, int value); | ||||||
| int list_free(struct list *l); | int list_free(struct list *l); | ||||||
| int list_get_value(const struct list *l, const char *data); | int list_get_value(const struct list *l, const char *data); | ||||||
|   | |||||||
| @@ -142,6 +142,10 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) { | |||||||
|                     free(mympd_state.colsPlayback); |                     free(mympd_state.colsPlayback); | ||||||
|                     mympd_state.colsPlayback = strdup(cols); |                     mympd_state.colsPlayback = strdup(cols); | ||||||
|                 } |                 } | ||||||
|  |                 else if (strcmp(p_charbuf1,"colsLastPlayed")==0) { | ||||||
|  |                     free(mympd_state.colsLastPlayed); | ||||||
|  |                     mympd_state.colsLastPlayed = strdup(cols); | ||||||
|  |                 } | ||||||
|                 mympd_state_set(p_charbuf1, cols); |                 mympd_state_set(p_charbuf1, cols); | ||||||
|                 free(p_charbuf1); |                 free(p_charbuf1); | ||||||
|             } |             } | ||||||
| @@ -396,6 +400,12 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) { | |||||||
|                 n = mympd_put_queue(mpd.buf, uint_buf1, &mpd.queue_version, &mpd.queue_length); |                 n = mympd_put_queue(mpd.buf, uint_buf1, &mpd.queue_version, &mpd.queue_length); | ||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|  |         case MPD_API_QUEUE_LAST_PLAYED: | ||||||
|  |             je = json_scanf(msg.p, msg.len, "{data: {offset: %u}}", &uint_buf1); | ||||||
|  |             if (je == 1) { | ||||||
|  |                 n = mympd_put_last_played_songs(mpd.buf, uint_buf1); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|         case MPD_API_PLAYER_CURRENT_SONG: |         case MPD_API_PLAYER_CURRENT_SONG: | ||||||
|                 n = mympd_put_current_song(mpd.buf); |                 n = mympd_put_current_song(mpd.buf); | ||||||
|             break; |             break; | ||||||
| @@ -688,11 +698,15 @@ void mympd_parse_idle(struct mg_mgr *s, int idle_bitmask) { | |||||||
|                     break; |                     break; | ||||||
|                 case MPD_IDLE_PLAYER: |                 case MPD_IDLE_PLAYER: | ||||||
|                     len = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.last_song_id, &mpd.queue_version, &mpd.queue_length); |                     len = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.last_song_id, &mpd.queue_version, &mpd.queue_length); | ||||||
|                     if (config.stickers && mpd.song_id != mpd.last_song_id && mpd.last_update_sticker_song_id != mpd.song_id) { |                     if (mpd.song_id != mpd.last_song_id) { | ||||||
|  |                         if (mpd.last_last_played_id != mpd.song_id) | ||||||
|  |                             mympd_last_played_list(mpd.song_id); | ||||||
|  |                         if (config.stickers && mpd.last_update_sticker_song_id != mpd.song_id) { | ||||||
|                             mympd_count_song_id(mpd.song_id, "playCount", 1); |                             mympd_count_song_id(mpd.song_id, "playCount", 1); | ||||||
|                             mympd_last_played_song_id(mpd.song_id); |                             mympd_last_played_song_id(mpd.song_id); | ||||||
|                             mpd.last_update_sticker_song_id = mpd.song_id; |                             mpd.last_update_sticker_song_id = mpd.song_id; | ||||||
|                         } |                         } | ||||||
|  |                     } | ||||||
|                     break; |                     break; | ||||||
|                 case MPD_IDLE_MIXER: |                 case MPD_IDLE_MIXER: | ||||||
|                     len = mympd_put_volume(mpd.buf); |                     len = mympd_put_volume(mpd.buf); | ||||||
| @@ -998,6 +1012,22 @@ void mympd_like_song_uri(const char *uri, int value) { | |||||||
|         LOG_ERROR_AND_RECOVER("mpd_send_sticker_set"); |         LOG_ERROR_AND_RECOVER("mpd_send_sticker_set"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void mympd_last_played_list(int song_id) { | ||||||
|  |     struct mpd_song *song; | ||||||
|  |     if (song_id > -1) { | ||||||
|  |         song = mpd_run_get_queue_song_id(mpd.conn, song_id); | ||||||
|  |         if (song) { | ||||||
|  |             list_push(&last_played, mpd_song_get_uri(song), 1); | ||||||
|  |             mpd.last_last_played_id = song_id; | ||||||
|  |             mpd_song_free(song); | ||||||
|  |             if (last_played.length > config.last_played_count) { | ||||||
|  |                 list_shift(&last_played, 0); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
| void mympd_last_played_song_id(int song_id) { | void mympd_last_played_song_id(int song_id) { | ||||||
|     struct mpd_song *song; |     struct mpd_song *song; | ||||||
|     if (song_id > -1) { |     if (song_id > -1) { | ||||||
| @@ -1441,13 +1471,16 @@ int mympd_put_settings(char *buffer) { | |||||||
|         } |         } | ||||||
|         len += json_printf(&out, "]"); |         len += json_printf(&out, "]"); | ||||||
|     } |     } | ||||||
|     len += json_printf(&out, ", colsQueue: %s", mympd_state.colsQueue); |     len += json_printf(&out, ", colsQueue: %s, colsSearch: %s, colsBrowseDatabase: %s, colsBrowsePlaylistsDetail: %s, " | ||||||
|     len += json_printf(&out, ", colsSearch: %s", mympd_state.colsSearch); |         "colsBrowseFilesystem: %s, colsPlayback: %s, colsLastPlayed: %s}}", | ||||||
|     len += json_printf(&out, ", colsBrowseDatabase: %s", mympd_state.colsBrowseDatabase); |         mympd_state.colsQueue, | ||||||
|     len += json_printf(&out, ", colsBrowsePlaylistsDetail: %s", mympd_state.colsBrowsePlaylistsDetail); |         mympd_state.colsSearch, | ||||||
|     len += json_printf(&out, ", colsBrowseFilesystem: %s", mympd_state.colsBrowseFilesystem); |         mympd_state.colsBrowseDatabase, | ||||||
|     len += json_printf(&out, ", colsPlayback: %s", mympd_state.colsPlayback); |         mympd_state.colsBrowsePlaylistsDetail, | ||||||
|     len += json_printf(&out, "}}");     |         mympd_state.colsBrowseFilesystem, | ||||||
|  |         mympd_state.colsPlayback, | ||||||
|  |         mympd_state.colsLastPlayed | ||||||
|  |     ); | ||||||
|  |  | ||||||
|     CHECK_RETURN_LEN(); |     CHECK_RETURN_LEN(); | ||||||
|     return len; |     return len; | ||||||
| @@ -1616,6 +1649,51 @@ int mympd_put_songdetails(char *buffer, char *uri) { | |||||||
|     return len; |     return len; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int mympd_put_last_played_songs(char *buffer, unsigned int offset) { | ||||||
|  |     const struct mpd_song *song; | ||||||
|  |     struct mpd_entity *entity; | ||||||
|  |     int len; | ||||||
|  |     unsigned int entity_count = 0; | ||||||
|  |     unsigned int entities_returned = 0; | ||||||
|  |     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||||
|  |      | ||||||
|  |     len = json_printf(&out, "{type: last_played_songs, data: ["); | ||||||
|  |      | ||||||
|  |     struct node *current = last_played.list; | ||||||
|  |     while (current != NULL) { | ||||||
|  |         entity_count++; | ||||||
|  |         if (entity_count > offset && entity_count <= offset + config.max_elements_per_page) { | ||||||
|  |             if (entities_returned++)  | ||||||
|  |                 len += json_printf(&out, ","); | ||||||
|  |             len += json_printf(&out, "{Pos: %d, ", entity_count); | ||||||
|  |             if (!mpd_send_list_all_meta(mpd.conn, current->data)) | ||||||
|  |                 RETURN_ERROR_AND_RECOVER("mpd_send_list_all_meta"); | ||||||
|  |             if ((entity = mpd_recv_entity(mpd.conn)) != NULL) { | ||||||
|  |                 song = mpd_entity_get_song(entity); | ||||||
|  |                 if (mpd.feat_tags == true) | ||||||
|  |                     PUT_SONG_TAGS(); | ||||||
|  |                 else | ||||||
|  |                     PUT_MIN_SONG_TAGS(); | ||||||
|  |                 mpd_entity_free(entity); | ||||||
|  |                 mpd_response_finish(mpd.conn); | ||||||
|  |             } | ||||||
|  |             len += json_printf(&out, "}"); | ||||||
|  |         } | ||||||
|  |         current = current->next; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     len += json_printf(&out, "], totalEntities: %d, offset: %d, returnedEntities: %d}", | ||||||
|  |         entity_count, | ||||||
|  |         offset, | ||||||
|  |         entities_returned | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     CHECK_RETURN_LEN(); | ||||||
|  |     return len; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| int mympd_put_queue(char *buffer, unsigned int offset, unsigned *queue_version, unsigned *queue_length) { | int mympd_put_queue(char *buffer, unsigned int offset, unsigned *queue_version, unsigned *queue_length) { | ||||||
|     struct mpd_entity *entity; |     struct mpd_entity *entity; | ||||||
|     unsigned long totalTime = 0; |     unsigned long totalTime = 0; | ||||||
|   | |||||||
| @@ -86,6 +86,7 @@ | |||||||
|     X(MPD_API_QUEUE_ADD_PLAYLIST) \ |     X(MPD_API_QUEUE_ADD_PLAYLIST) \ | ||||||
|     X(MPD_API_QUEUE_REPLACE_PLAYLIST) \ |     X(MPD_API_QUEUE_REPLACE_PLAYLIST) \ | ||||||
|     X(MPD_API_QUEUE_SHUFFLE) \ |     X(MPD_API_QUEUE_SHUFFLE) \ | ||||||
|  |     X(MPD_API_QUEUE_LAST_PLAYED) \ | ||||||
|     X(MPD_API_PLAYLIST_CLEAR) \ |     X(MPD_API_PLAYLIST_CLEAR) \ | ||||||
|     X(MPD_API_PLAYLIST_RENAME) \ |     X(MPD_API_PLAYLIST_RENAME) \ | ||||||
|     X(MPD_API_PLAYLIST_MOVE_TRACK) \ |     X(MPD_API_PLAYLIST_MOVE_TRACK) \ | ||||||
| @@ -157,6 +158,7 @@ struct t_mpd { | |||||||
|     unsigned queue_version; |     unsigned queue_version; | ||||||
|     unsigned queue_length; |     unsigned queue_length; | ||||||
|     int last_update_sticker_song_id; |     int last_update_sticker_song_id; | ||||||
|  |     int last_last_played_id; | ||||||
|      |      | ||||||
|     // Features |     // Features | ||||||
|     const unsigned* protocol; |     const unsigned* protocol; | ||||||
| @@ -171,7 +173,7 @@ struct list mpd_tags; | |||||||
| struct list mympd_tags; | struct list mympd_tags; | ||||||
| struct list mympd_searchtags; | struct list mympd_searchtags; | ||||||
| struct list mympd_browsetags; | struct list mympd_browsetags; | ||||||
|  | struct list last_played; | ||||||
| struct list syscmds; | struct list syscmds; | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
| @@ -199,6 +201,7 @@ typedef struct { | |||||||
|     bool localplayer; |     bool localplayer; | ||||||
|     long streamport; |     long streamport; | ||||||
|     const char *streamurl; |     const char *streamurl; | ||||||
|  |     unsigned long last_played_count; | ||||||
| } t_config; | } t_config; | ||||||
|  |  | ||||||
| t_config config; | t_config config; | ||||||
| @@ -222,6 +225,7 @@ typedef struct { | |||||||
|     char *colsBrowsePlaylistsDetail; |     char *colsBrowsePlaylistsDetail; | ||||||
|     char *colsBrowseFilesystem; |     char *colsBrowseFilesystem; | ||||||
|     char *colsPlayback; |     char *colsPlayback; | ||||||
|  |     char *colsLastPlayed; | ||||||
| } t_mympd_state; | } t_mympd_state; | ||||||
|  |  | ||||||
| t_mympd_state mympd_state; | t_mympd_state mympd_state; | ||||||
| @@ -241,6 +245,7 @@ void mympd_like_song_uri(const char *uri, int value); | |||||||
| void mympd_last_played_song_uri(const char *uri); | void mympd_last_played_song_uri(const char *uri); | ||||||
| void mympd_last_played_song_id(int song_id); | void mympd_last_played_song_id(int song_id); | ||||||
| void mympd_get_sticker(const char *uri, t_sticker *sticker); | void mympd_get_sticker(const char *uri, t_sticker *sticker); | ||||||
|  | void mympd_last_played_list(int song_id); | ||||||
| void mympd_jukebox(); | void mympd_jukebox(); | ||||||
| bool mympd_state_get(char *name, char *value); | bool mympd_state_get(char *name, char *value); | ||||||
| bool mympd_state_set(const char *name, const char *value); | bool mympd_state_set(const char *name, const char *value); | ||||||
| @@ -270,6 +275,7 @@ int mympd_put_songs_in_album(char *buffer, char *album, char *search, char *tag) | |||||||
| int mympd_put_playlists(char *buffer, unsigned int offset, char *filter); | int mympd_put_playlists(char *buffer, unsigned int offset, char *filter); | ||||||
| int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char *filter); | int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char *filter); | ||||||
| int mympd_put_songdetails(char *buffer, char *uri); | int mympd_put_songdetails(char *buffer, char *uri); | ||||||
|  | int mympd_put_last_played_songs(char *buffer, unsigned int offset); | ||||||
| int mympd_queue_crop(char *buffer); | int mympd_queue_crop(char *buffer); | ||||||
| void mympd_disconnect(); | void mympd_disconnect(); | ||||||
| #endif | #endif | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								src/mympd.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/mympd.c
									
									
									
									
									
								
							| @@ -199,6 +199,8 @@ static int inihandler(void* user, const char* section, const char* name, const c | |||||||
|             p_config->localplayer = false; |             p_config->localplayer = false; | ||||||
|     else if (MATCH("streamurl")) |     else if (MATCH("streamurl")) | ||||||
|         p_config->streamurl = strdup(value); |         p_config->streamurl = strdup(value); | ||||||
|  |     else if (MATCH("last_played_count")) | ||||||
|  |         p_config->last_played_count = strtol(value, &crap, 10); | ||||||
|     else |     else | ||||||
|         return 0;  /* unknown section/name, error */ |         return 0;  /* unknown section/name, error */ | ||||||
|  |  | ||||||
| @@ -318,6 +320,13 @@ void read_statefiles() { | |||||||
|         mympd_state.colsPlayback = strdup("[\"Artist\",\"Album\",\"Genre\"]"); |         mympd_state.colsPlayback = strdup("[\"Artist\",\"Album\",\"Genre\"]"); | ||||||
|         mympd_state_set("colsPlayback", mympd_state.colsPlayback); |         mympd_state_set("colsPlayback", mympd_state.colsPlayback); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (mympd_state_get("colsLastPlayed", value)) | ||||||
|  |         mympd_state.colsLastPlayed = strdup(value); | ||||||
|  |     else { | ||||||
|  |         mympd_state.colsLastPlayed = strdup("[\"Pos\",\"Title\",\"Artist\",\"Album\",\"Duration\"]"); | ||||||
|  |         mympd_state_set("colsLastPlayed", mympd_state.colsLastPlayed); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| bool testdir(char *name, char *dirname) { | bool testdir(char *name, char *dirname) { | ||||||
| @@ -363,6 +372,7 @@ int main(int argc, char **argv) { | |||||||
|     config.browsetaglist = "Artist,Album,AlbumArtist,Genre,Composer,Performer"; |     config.browsetaglist = "Artist,Album,AlbumArtist,Genre,Composer,Performer"; | ||||||
|     config.smartpls = true; |     config.smartpls = true; | ||||||
|     config.max_elements_per_page = 100; |     config.max_elements_per_page = 100; | ||||||
|  |     config.last_played_count = 20; | ||||||
|     char *etcdir = strdup(argv[1]); |     char *etcdir = strdup(argv[1]); | ||||||
|     config.etcdir = dirname(etcdir); |     config.etcdir = dirname(etcdir); | ||||||
|     config.syscmds = false; |     config.syscmds = false; | ||||||
| @@ -371,6 +381,7 @@ int main(int argc, char **argv) { | |||||||
|     mpd.timeout = 3000; |     mpd.timeout = 3000; | ||||||
|     mpd.last_update_sticker_song_id = -1; |     mpd.last_update_sticker_song_id = -1; | ||||||
|     mpd.last_song_id = -1; |     mpd.last_song_id = -1; | ||||||
|  |     mpd.last_last_played_id = -1; | ||||||
|     mpd.feat_library = false; |     mpd.feat_library = false; | ||||||
|      |      | ||||||
|     if (argc == 2) { |     if (argc == 2) { | ||||||
| @@ -487,6 +498,7 @@ int main(int argc, char **argv) { | |||||||
|  |  | ||||||
|     list_init(&mpd_tags); |     list_init(&mpd_tags); | ||||||
|     list_init(&mympd_tags); |     list_init(&mympd_tags); | ||||||
|  |     list_init(&last_played); | ||||||
|      |      | ||||||
|     if (config.ssl == true) |     if (config.ssl == true) | ||||||
|         mg_set_protocol_http_websocket(nc_http); |         mg_set_protocol_http_websocket(nc_http); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 jcorporation
					jcorporation