mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-31 05:43:01 +00:00 
			
		
		
		
	Feat: startup screen, connect to websocket after getting the settings
This commit is contained in:
		| @@ -91,6 +91,10 @@ small { | |||||||
|   display: none !important; |   display: none !important; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .unvisible { | ||||||
|  |   visibility: hidden; | ||||||
|  | } | ||||||
|  |  | ||||||
| .pull-right { | .pull-right { | ||||||
|   float: right !important; |   float: right !important; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ | |||||||
|   <link rel="apple-touch-icon" href="/assets/appicon-167.png"> |   <link rel="apple-touch-icon" href="/assets/appicon-167.png"> | ||||||
| </head> | </head> | ||||||
| <body> | <body> | ||||||
|   <header> |   <header class="hide"> | ||||||
|     <nav class="navbar navbar-expand navbar-dark fixed-top bg-dark"> |     <nav class="navbar navbar-expand navbar-dark fixed-top bg-dark"> | ||||||
|         <div class="dropdown col-auto mr-auto pl-0"> |         <div class="dropdown col-auto mr-auto pl-0"> | ||||||
|           <a class="dropdown-toggle navbar-brand" href="#" id="mainMenu"> |           <a class="dropdown-toggle navbar-brand" href="#" id="mainMenu"> | ||||||
| @@ -74,7 +74,7 @@ | |||||||
|         </div> |         </div> | ||||||
|     </nav> |     </nav> | ||||||
|   </header> |   </header> | ||||||
|   <main class="container"> |   <main class="container hide"> | ||||||
|     <noscript> |     <noscript> | ||||||
|       <div class="alert alert-danger">JavaScript is disabled!</div> |       <div class="alert alert-danger">JavaScript is disabled!</div> | ||||||
|     </noscript> |     </noscript> | ||||||
| @@ -607,7 +607,7 @@ | |||||||
|     </div>     |     </div>     | ||||||
|   </main>     |   </main>     | ||||||
|    |    | ||||||
|   <footer class="footer"> |   <footer class="footer hide"> | ||||||
|     <nav class="navbar navbar-expand navbar-dark fixed-bottom bg-dark"> |     <nav class="navbar navbar-expand navbar-dark fixed-bottom bg-dark"> | ||||||
|       <div class="d-flex flex-fill navbar-nav" id="navbar-bottom"> |       <div class="d-flex flex-fill navbar-nav" id="navbar-bottom"> | ||||||
|         <div id="navPlayback" class="nav-item flex-fill text-center"><a data-href='{"cmd": "appGoto", "options": ["Playback"]}' class="nav-link" href="#">Playback</a></div> |         <div id="navPlayback" class="nav-item flex-fill text-center"><a data-href='{"cmd": "appGoto", "options": ["Playback"]}' class="nav-link" href="#">Playback</a></div> | ||||||
| @@ -619,6 +619,23 @@ | |||||||
|   </footer> |   </footer> | ||||||
|  |  | ||||||
|   <!-- Modals --> |   <!-- Modals --> | ||||||
|  |   <div class="modal fade" id="modalAppInit" tabindex="-1"> | ||||||
|  |     <div class="modal-dialog"> | ||||||
|  |       <div class="modal-content"> | ||||||
|  |         <div class="modal-header bg-success text-light"> | ||||||
|  |           <h5 class="modal-title"><span class="material-icons title-icon">play_circle_outline</span> Initializing myMPD</h5> | ||||||
|  |         </div> | ||||||
|  |         <div class="modal-body"> | ||||||
|  |           <p>Please wait, myMPD is initializing...</p> | ||||||
|  |           <p><span id="appInitSettings" class="material-icons unvisible">check</span> Fetch settings</p> | ||||||
|  |           <p><span id="appInitWebsocket" class="material-icons unvisible">check</span> Connect to websocket</p> | ||||||
|  |           <p><span id="appInitApply" class="material-icons unvisible">check</span> Applying settings</p> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       </div> | ||||||
|  |   </div>   | ||||||
|  |    | ||||||
|  |    | ||||||
|   <div class="modal fade" id="modalConnectionError" tabindex="-1"> |   <div class="modal fade" id="modalConnectionError" tabindex="-1"> | ||||||
|     <div class="modal-dialog"> |     <div class="modal-dialog"> | ||||||
|       <div class="modal-content"> |       <div class="modal-content"> | ||||||
|   | |||||||
| @@ -29,12 +29,16 @@ var lastSongObj = {}; | |||||||
| var lastState; | var lastState; | ||||||
| var currentSong = new Object(); | var currentSong = new Object(); | ||||||
| var playstate = ''; | var playstate = ''; | ||||||
|  | var settingsLock = false; | ||||||
|  | var settingsParsed = false; | ||||||
|  | var settingsNew = {}; | ||||||
| var settings = {}; | var settings = {}; | ||||||
| var alertTimeout; | var alertTimeout; | ||||||
| var progressTimer; | var progressTimer; | ||||||
| var deferredPrompt; | var deferredPrompt; | ||||||
| var dragEl; | var dragEl; | ||||||
| var playlistEl; | var playlistEl; | ||||||
|  | var websocketConnected = false; | ||||||
|  |  | ||||||
| var app = {}; | var app = {}; | ||||||
| app.apps = { "Playback":   { "state": "0/-/", "scrollPos": 0 }, | app.apps = { "Playback":   { "state": "0/-/", "scrollPos": 0 }, | ||||||
| @@ -104,6 +108,7 @@ var modalUpdateDB = new Modal(document.getElementById('modalUpdateDB')); | |||||||
| var modalSaveSmartPlaylist = new Modal(document.getElementById('modalSaveSmartPlaylist')); | var modalSaveSmartPlaylist = new Modal(document.getElementById('modalSaveSmartPlaylist')); | ||||||
| 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 modalAppInit = new Modal(document.getElementById('modalAppInit')); | ||||||
|  |  | ||||||
| var dropdownMainMenu; | var dropdownMainMenu; | ||||||
| var dropdownVolumeMenu = new Dropdown(document.getElementById('volumeMenu')); | var dropdownVolumeMenu = new Dropdown(document.getElementById('volumeMenu')); | ||||||
| @@ -353,10 +358,37 @@ function appRoute() { | |||||||
|     app.last.view = app.current.view; |     app.last.view = app.current.view; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| function appInit() { | function appInitStart() { | ||||||
|     webSocketConnect(); |     modalAppInit.show(); | ||||||
|     getSettings(); |     getSettings(); | ||||||
|     sendAPI({"cmd": "MPD_API_PLAYER_STATE"}, parseState); |     appInitWait(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function appInitWait() { | ||||||
|  |     setTimeout(function() { | ||||||
|  |         if (settingsParsed == true && websocketConnected == true) { | ||||||
|  |             //app initialized | ||||||
|  |             document.getElementById('appInitWebsocket').classList.remove('unvisible'); | ||||||
|  |             appInit(); | ||||||
|  |             document.getElementById('appInitApply').classList.remove('unvisible'); | ||||||
|  |             document.getElementsByTagName('header')[0].classList.remove('hide'); | ||||||
|  |             document.getElementsByTagName('main')[0].classList.remove('hide'); | ||||||
|  |             document.getElementsByTagName('footer')[0].classList.remove('hide'); | ||||||
|  |             modalAppInit.hide(); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         if (settingsParsed == true) { | ||||||
|  |             //parsed settings, now its save to connect to websocket | ||||||
|  |             document.getElementById('appInitSettings').classList.remove('unvisible'); | ||||||
|  |             webSocketConnect(); | ||||||
|  |         } | ||||||
|  |         appInitWait(); | ||||||
|  |     }, 500); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function appInit() { | ||||||
|  |     //sendAPI({"cmd": "MPD_API_PLAYER_STATE"}, parseState); | ||||||
|  |  | ||||||
|     domCache.volumeBar.value = 0; |     domCache.volumeBar.value = 0; | ||||||
|  |  | ||||||
| @@ -811,6 +843,12 @@ function appInit() { | |||||||
|     window.addEventListener('appinstalled', function(event) { |     window.addEventListener('appinstalled', function(event) { | ||||||
|         console.log('myMPD installed as app'); |         console.log('myMPD installed as app'); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     window.addEventListener('beforeunload', function() { | ||||||
|  |         socket.onclose = function () {}; // disable onclose handler first | ||||||
|  |         socket.close(); | ||||||
|  |         websocketConnected = false; | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function parseCmd(event, href) { | function parseCmd(event, href) { | ||||||
| @@ -1028,6 +1066,9 @@ function webSocketConnect() { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             switch (obj.type) { |             switch (obj.type) { | ||||||
|  |                 case 'welcome': | ||||||
|  |                     websocketConnected = true; | ||||||
|  |                     break; | ||||||
|                 case 'update_state': |                 case 'update_state': | ||||||
|                     parseState(obj); |                     parseState(obj); | ||||||
|                     break; |                     break; | ||||||
| @@ -1070,6 +1111,7 @@ function webSocketConnect() { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         socket.onclose = function(){ |         socket.onclose = function(){ | ||||||
|  |             websocketConnected = false; | ||||||
|             console.log('disconnected'); |             console.log('disconnected'); | ||||||
|             modalConnectionError.show(); |             modalConnectionError.show(); | ||||||
|             setTimeout(function() { |             setTimeout(function() { | ||||||
| @@ -1145,8 +1187,8 @@ function filterCols(x) { | |||||||
|     settings[x] = cols; |     settings[x] = cols; | ||||||
| } | } | ||||||
|  |  | ||||||
| function parseSettings(obj) { | function parseSettings() { | ||||||
|     settings = obj.data; |     settingsParsed = false; | ||||||
|  |  | ||||||
|     toggleBtn('btnRandom', settings.random); |     toggleBtn('btnRandom', settings.random); | ||||||
|     toggleBtn('btnConsume', settings.consume); |     toggleBtn('btnConsume', settings.consume); | ||||||
| @@ -1300,12 +1342,12 @@ function parseSettings(obj) { | |||||||
|     if (settings.featSyscmds) { |     if (settings.featSyscmds) { | ||||||
|         var mainMenuDropdown = document.getElementById('mainMenuDropdown'); |         var mainMenuDropdown = document.getElementById('mainMenuDropdown'); | ||||||
|         var syscmdsList = ''; |         var syscmdsList = ''; | ||||||
|         var syscmdsListLen = settings.syscmds.length; |         var syscmdsListLen = settings.syscmdList.length; | ||||||
|         if (syscmdsListLen > 0) { |         if (syscmdsListLen > 0) { | ||||||
|             syscmdsList = '<div class="dropdown-divider"></div>'; |             syscmdsList = '<div class="dropdown-divider"></div>'; | ||||||
|             for (var i = 0; i < syscmdsListLen; i++) { |             for (var i = 0; i < syscmdsListLen; i++) { | ||||||
|                 syscmdsList += '<a class="dropdown-item text-light bg-dark" href="#" data-href=\'{"cmd": "execSyscmd", "options": ["' +  |                 syscmdsList += '<a class="dropdown-item text-light bg-dark" href="#" data-href=\'{"cmd": "execSyscmd", "options": ["' +  | ||||||
|                     settings.syscmds[i] + '"]}\'>' + settings.syscmds[i] + '</a>'; |                     settings.syscmdList[i] + '"]}\'>' + settings.syscmdList[i] + '</a>'; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         document.getElementById('syscmds').innerHTML = syscmdsList; |         document.getElementById('syscmds').innerHTML = syscmdsList; | ||||||
| @@ -1333,6 +1375,8 @@ function parseSettings(obj) { | |||||||
|         appRoute(); |         appRoute(); | ||||||
|     else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.search != '') |     else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.search != '') | ||||||
|         appRoute(); |         appRoute(); | ||||||
|  |  | ||||||
|  |     settingsParsed = true; | ||||||
| } | } | ||||||
|  |  | ||||||
| function setCols(table, className) { | function setCols(table, className) { | ||||||
| @@ -1404,7 +1448,24 @@ function setCols(table, className) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function getSettings() { | function getSettings() { | ||||||
|     sendAPI({"cmd": "MPD_API_SETTINGS_GET"}, parseSettings); |     if (settingsLock == false) { | ||||||
|  |         settingsLock = true; | ||||||
|  |         sendAPI({"cmd": "MYMPD_API_SETTINGS_GET"}, getMpdSettings); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function getMpdSettings(obj) { | ||||||
|  |     settingsNew = obj.data; | ||||||
|  |     sendAPI({"cmd": "MPD_API_SETTINGS_GET"}, joinSettings); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function joinSettings(obj) { | ||||||
|  |     for (var key in obj.data) { | ||||||
|  |         settingsNew[key] = obj.data[key]; | ||||||
|  |     } | ||||||
|  |     settings = Object.assign({}, settingsNew); | ||||||
|  |     settingsLock = false; | ||||||
|  |     parseSettings(); | ||||||
| } | } | ||||||
|  |  | ||||||
| function saveCols(table, tableEl) { | function saveCols(table, tableEl) { | ||||||
| @@ -1431,7 +1492,7 @@ function saveCols(table, tableEl) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     var cols = {"cmd": "MPD_API_COLS_SAVE", "data": {"table": "cols" + table, "cols": []}}; |     var cols = {"cmd": "MYMPD_API_COLS_SAVE", "data": {"table": "cols" + table, "cols": []}}; | ||||||
|     var ths = header.getElementsByTagName('th'); |     var ths = header.getElementsByTagName('th'); | ||||||
|     for (var i = 0; i < ths.length; i++) { |     for (var i = 0; i < ths.length; i++) { | ||||||
|         var name = ths[i].getAttribute('data-col'); |         var name = ths[i].getAttribute('data-col'); | ||||||
| @@ -1460,7 +1521,7 @@ function saveColsPlayback(table) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     var cols = {"cmd": "MPD_API_COLS_SAVE", "data": {"table": "cols" + table, "cols": []}}; |     var cols = {"cmd": "MYMPD_API_COLS_SAVE", "data": {"table": "cols" + table, "cols": []}}; | ||||||
|     var ths = header.getElementsByTagName('div'); |     var ths = header.getElementsByTagName('div'); | ||||||
|     for (var i = 0; i < ths.length; i++) { |     for (var i = 0; i < ths.length; i++) { | ||||||
|         var name = ths[i].getAttribute('data-tag'); |         var name = ths[i].getAttribute('data-tag'); | ||||||
| @@ -2865,7 +2926,7 @@ function confirmSettings() { | |||||||
|         var selectReplaygain = document.getElementById('selectReplaygain'); |         var selectReplaygain = document.getElementById('selectReplaygain'); | ||||||
|         var selectJukeboxPlaylist = document.getElementById('selectJukeboxPlaylist'); |         var selectJukeboxPlaylist = document.getElementById('selectJukeboxPlaylist'); | ||||||
|         var selectJukeboxMode = document.getElementById('selectJukeboxMode'); |         var selectJukeboxMode = document.getElementById('selectJukeboxMode'); | ||||||
|         sendAPI({"cmd": "MPD_API_SETTINGS_SET", "data": { |         sendAPI({"cmd": "MYMPD_API_SETTINGS_SET", "data": { | ||||||
|             "consume": (document.getElementById('btnConsume').classList.contains('active') ? 1 : 0), |             "consume": (document.getElementById('btnConsume').classList.contains('active') ? 1 : 0), | ||||||
|             "random":  (document.getElementById('btnRandom').classList.contains('active') ? 1 : 0), |             "random":  (document.getElementById('btnRandom').classList.contains('active') ? 1 : 0), | ||||||
|             "single":  (document.getElementById('btnSingle').classList.contains('active') ? 1 : 0), |             "single":  (document.getElementById('btnSingle').classList.contains('active') ? 1 : 0), | ||||||
| @@ -3162,4 +3223,4 @@ function genId(x) { | |||||||
| } | } | ||||||
|  |  | ||||||
| //Init app | //Init app | ||||||
| appInit(); | appInitStart(); | ||||||
|   | |||||||
| @@ -211,6 +211,7 @@ static void mympd_api(t_config *config, t_mympd_state *mympd_state, t_work_reque | |||||||
|         //push settings to mpd_client queue |         //push settings to mpd_client queue | ||||||
|         t_work_request *mpd_client_request = (t_work_request *)malloc(sizeof(t_work_request)); |         t_work_request *mpd_client_request = (t_work_request *)malloc(sizeof(t_work_request)); | ||||||
|         mpd_client_request->conn_id = request->conn_id; |         mpd_client_request->conn_id = request->conn_id; | ||||||
|  |         mpd_client_request->cmd_id = request->cmd_id; | ||||||
|         mpd_client_request->length = copy_string(mpd_client_request->data, request->data, MAX_SIZE, request->length); |         mpd_client_request->length = copy_string(mpd_client_request->data, request->data, MAX_SIZE, request->length); | ||||||
|         tiny_queue_push(mpd_client_queue, mpd_client_request); |         tiny_queue_push(mpd_client_queue, mpd_client_request); | ||||||
|     } |     } | ||||||
| @@ -411,15 +412,13 @@ static int mympd_api_put_settings(t_config *config, t_mympd_state *mympd_state, | |||||||
|     int nr = 0; |     int nr = 0; | ||||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); |     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||||
|      |      | ||||||
|     len = json_printf(&out, "{type: settings, data: {mpdhost: %Q, mpdport: %d, passwort_set: %B, featSyscmds: %B, featStickers: %B, featSmartpls: %B, " |     len = json_printf(&out, "{type: mympdSettings, data: {mpdhost: %Q, mpdport: %d, passwort_set: %B, featSyscmds: %B, " | ||||||
|         "featLocalplayer: %B, streamport: %d, streamurl: %Q, featCoverimage: %B, coverimagename: %Q, coverimagesize: %d, featMixramp: %B, " |         "featLocalplayer: %B, streamport: %d, streamurl: %Q, featCoverimage: %B, coverimagename: %Q, coverimagesize: %d, featMixramp: %B, " | ||||||
|         "maxElementsPerPage: %d, notificationWeb: %B, notificationPage: %B, jukeboxMode: %d, jukeboxPlaylist: %Q, jukeboxQueueLength: %d",  |         "maxElementsPerPage: %d, notificationWeb: %B, notificationPage: %B, jukeboxMode: %d, jukeboxPlaylist: %Q, jukeboxQueueLength: %d",  | ||||||
|         config->mpdhost,  |         config->mpdhost,  | ||||||
|         config->mpdport,  |         config->mpdport,  | ||||||
|         config->mpdpass ? "true" : "false", |         config->mpdpass ? "true" : "false", | ||||||
|         config->syscmds, |         config->syscmds, | ||||||
|         config->stickers, |  | ||||||
|         config->smartpls, |  | ||||||
|         config->localplayer, |         config->localplayer, | ||||||
|         config->streamport, |         config->streamport, | ||||||
|         config->streamurl, |         config->streamurl, | ||||||
| @@ -436,7 +435,7 @@ static int mympd_api_put_settings(t_config *config, t_mympd_state *mympd_state, | |||||||
|     ); |     ); | ||||||
|      |      | ||||||
|     if (config->syscmds == true) { |     if (config->syscmds == true) { | ||||||
|         len += json_printf(&out, ", syscmds: ["); |         len += json_printf(&out, ", syscmdList: ["); | ||||||
|         nr = 0; |         nr = 0; | ||||||
|         struct node *current = mympd_state->syscmd_list.list; |         struct node *current = mympd_state->syscmd_list.list; | ||||||
|         while (current != NULL) { |         while (current != NULL) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 jcorporation
					jcorporation