feat: implement WebSocket for update progress and enhance update response handling
This commit is contained in:
		| @@ -155,17 +155,29 @@ | |||||||
|         const progressContainer = document.querySelector('.progress-container'); |         const progressContainer = document.querySelector('.progress-container'); | ||||||
|         const status = document.querySelector('.status'); |         const status = document.querySelector('.status'); | ||||||
|  |  | ||||||
|  |         // WebSocket für Update-Progress | ||||||
|  |         const ws = new WebSocket('ws://' + window.location.host + '/ws'); | ||||||
|  |         ws.onmessage = function(event) { | ||||||
|  |             try { | ||||||
|  |                 const data = JSON.parse(event.data); | ||||||
|  |                 if (data.type === "updateProgress") { | ||||||
|  |                     progress.style.width = data.progress + '%'; | ||||||
|  |                     progress.textContent = data.progress + '%'; | ||||||
|  |                 } | ||||||
|  |             } catch (e) { | ||||||
|  |                 console.error('WebSocket message error:', e); | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |  | ||||||
|         function handleUpdate(e) { |         function handleUpdate(e) { | ||||||
|             e.preventDefault(); |             e.preventDefault(); | ||||||
|             const form = e.target; |             const form = e.target; | ||||||
|             const file = form.update.files[0]; |             const file = form.update.files[0]; | ||||||
|             const updateType = form.dataset.type; |             const updateType = form.dataset.type; | ||||||
|  |  | ||||||
|             if (!file) { |             if (!file) { | ||||||
|                 alert('Please select a file.'); |                 alert('Please select a file.'); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             // Validate file name pattern |             // Validate file name pattern | ||||||
|             if (updateType === 'firmware' && !file.name.startsWith('upgrade_filaman_firmware_')) { |             if (updateType === 'firmware' && !file.name.startsWith('upgrade_filaman_firmware_')) { | ||||||
|                 alert('Please select a valid firmware file (upgrade_filaman_firmware_*.bin)'); |                 alert('Please select a valid firmware file (upgrade_filaman_firmware_*.bin)'); | ||||||
| @@ -179,56 +191,54 @@ | |||||||
|             progressContainer.style.display = 'block'; |             progressContainer.style.display = 'block'; | ||||||
|             status.style.display = 'none'; |             status.style.display = 'none'; | ||||||
|             status.className = 'status'; |             status.className = 'status'; | ||||||
|  |  | ||||||
|             // Reset progress bar |             // Reset progress bar | ||||||
|             progress.style.width = '0%'; |             progress.style.width = '0%'; | ||||||
|             progress.textContent = '0%'; |             progress.textContent = '0%'; | ||||||
|  |  | ||||||
|             // Disable both forms during update |             // Disable both forms during update | ||||||
|             document.querySelectorAll('form input[type=submit]').forEach(btn => btn.disabled = true); |             document.querySelectorAll('form input[type=submit]').forEach(btn => btn.disabled = true); | ||||||
|  |  | ||||||
|             const xhr = new XMLHttpRequest(); |             const xhr = new XMLHttpRequest(); | ||||||
|             xhr.open('POST', '/update', true); |             xhr.open('POST', '/update', true); | ||||||
|  |              | ||||||
|             xhr.onload = function() { |             xhr.onload = function() { | ||||||
|                 try { |                 if (xhr.status === 200) { | ||||||
|                     let response = this.responseText; |  | ||||||
|                     try { |                     try { | ||||||
|                         const jsonResponse = JSON.parse(response); |                         const response = JSON.parse(xhr.responseText); | ||||||
|                          |                         if (response.success) { | ||||||
|                         // Zeige finale Nachricht |                             status.textContent = "Update successful! Restarting device... The page will reload in 30 seconds."; | ||||||
|                         status.textContent = jsonResponse.message || "Update complete"; |                             status.classList.add('success'); | ||||||
|                         status.classList.add(jsonResponse.success ? 'success' : 'error'); |                             status.style.display = 'block'; | ||||||
|                         status.style.display = 'block'; |                              | ||||||
|                          |                             // Setze Progress auf 100% | ||||||
|                         if (jsonResponse.success) { |  | ||||||
|                             progress.style.width = '100%'; |                             progress.style.width = '100%'; | ||||||
|                             progress.textContent = '100%'; |                             progress.textContent = '100%'; | ||||||
|                              |                              | ||||||
|                             // Automatischer Neustart nach erfolgreicher Aktualisierung |                             // Automatischer Redirect nach 30 Sekunden | ||||||
|                             status.textContent = "Update successful! Restarting device... The page will reload in 30 seconds."; |  | ||||||
|                             setTimeout(() => { |                             setTimeout(() => { | ||||||
|                                 window.location.href = '/'; |                                 window.location.href = '/'; | ||||||
|                             }, 30000); |                             }, 30000); | ||||||
|                         } else { |                         } else { | ||||||
|  |                             status.textContent = response.message || "Update failed"; | ||||||
|  |                             status.classList.add('error'); | ||||||
|  |                             status.style.display = 'block'; | ||||||
|                             document.querySelectorAll('form input[type=submit]').forEach(btn => btn.disabled = false); |                             document.querySelectorAll('form input[type=submit]').forEach(btn => btn.disabled = false); | ||||||
|                         } |                         } | ||||||
|                     } catch (e) { |                     } catch (e) { | ||||||
|                         console.error('JSON parse error:', e); |                         status.textContent = "Error: Invalid server response"; | ||||||
|                         status.textContent = 'Update failed: Invalid response from server'; |  | ||||||
|                         status.classList.add('error'); |                         status.classList.add('error'); | ||||||
|  |                         status.style.display = 'block'; | ||||||
|                         document.querySelectorAll('form input[type=submit]').forEach(btn => btn.disabled = false); |                         document.querySelectorAll('form input[type=submit]').forEach(btn => btn.disabled = false); | ||||||
|                     } |                     } | ||||||
|                 } catch (error) { |                 } else { | ||||||
|                     status.textContent = 'Error: ' + error.message; |                     status.textContent = "Update failed with status: " + xhr.status; | ||||||
|                     status.classList.add('error'); |                     status.classList.add('error'); | ||||||
|                     status.style.display = 'block'; |                     status.style.display = 'block'; | ||||||
|                     document.querySelectorAll('form input[type=submit]').forEach(btn => btn.disabled = false); |                     document.querySelectorAll('form input[type=submit]').forEach(btn => btn.disabled = false); | ||||||
|                 } |                 } | ||||||
|             }; |             }; | ||||||
|  |              | ||||||
|             xhr.onerror = function() { |             xhr.onerror = function() { | ||||||
|                 status.textContent = 'Update failed: Network error'; |                 status.textContent = "Network error during update"; | ||||||
|                 status.classList.add('error'); |                 status.classList.add('error'); | ||||||
|                 status.style.display = 'block'; |                 status.style.display = 'block'; | ||||||
|                 document.querySelectorAll('form input[type=submit]').forEach(btn => btn.disabled = false); |                 document.querySelectorAll('form input[type=submit]').forEach(btn => btn.disabled = false); | ||||||
|   | |||||||
| @@ -375,6 +375,12 @@ void setupWebserver(AsyncWebServer &server) { | |||||||
|         [](AsyncWebServerRequest *request) { |         [](AsyncWebServerRequest *request) { | ||||||
|             // Nach Update-Abschluss |             // Nach Update-Abschluss | ||||||
|             bool success = !Update.hasError(); |             bool success = !Update.hasError(); | ||||||
|  |              | ||||||
|  |             // Bei SPIFFS Update und Erfolg: Restore Configs vor dem Neustart | ||||||
|  |             if (success && Update.command() == U_SPIFFS) { | ||||||
|  |                 restoreJsonConfigs(); | ||||||
|  |             } | ||||||
|  |              | ||||||
|             String message = success ? "Update successful" : String("Update failed: ") + Update.errorString(); |             String message = success ? "Update successful" : String("Update failed: ") + Update.errorString(); | ||||||
|             AsyncWebServerResponse *response = request->beginResponse( |             AsyncWebServerResponse *response = request->beginResponse( | ||||||
|                 success ? 200 : 400, |                 success ? 200 : 400, | ||||||
| @@ -397,8 +403,6 @@ void setupWebserver(AsyncWebServer &server) { | |||||||
|             static size_t updateSize = 0; |             static size_t updateSize = 0; | ||||||
|             static int command = 0; |             static int command = 0; | ||||||
|  |  | ||||||
|             //oledShowMessage("Upgrade please wait"); |  | ||||||
|  |  | ||||||
|             if (!index) { |             if (!index) { | ||||||
|                 updateSize = request->contentLength(); |                 updateSize = request->contentLength(); | ||||||
|                 command = (filename.indexOf("website") > -1) ? U_SPIFFS : U_FLASH; |                 command = (filename.indexOf("website") > -1) ? U_SPIFFS : U_FLASH; | ||||||
| @@ -410,14 +414,12 @@ void setupWebserver(AsyncWebServer &server) { | |||||||
|                     // Get the actual SPIFFS partition size from ESP32 |                     // Get the actual SPIFFS partition size from ESP32 | ||||||
|                     const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, NULL); |                     const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, NULL); | ||||||
|                     if (!partition) { |                     if (!partition) { | ||||||
|                         restoreJsonConfigs(); |  | ||||||
|                         String errorMsg = "SPIFFS partition not found"; |                         String errorMsg = "SPIFFS partition not found"; | ||||||
|                         request->send(400, "application/json", "{\"success\":false,\"message\":\"" + errorMsg + "\"}"); |                         request->send(400, "application/json", "{\"success\":false,\"message\":\"" + errorMsg + "\"}"); | ||||||
|                         return; |                         return; | ||||||
|                     } |                     } | ||||||
|                      |                      | ||||||
|                     if (!Update.begin(partition->size, command)) { |                     if (!Update.begin(partition->size, command)) { | ||||||
|                         restoreJsonConfigs(); |  | ||||||
|                         String errorMsg = String("Update begin failed: ") + Update.errorString(); |                         String errorMsg = String("Update begin failed: ") + Update.errorString(); | ||||||
|                         request->send(400, "application/json", "{\"success\":false,\"message\":\"" + errorMsg + "\"}"); |                         request->send(400, "application/json", "{\"success\":false,\"message\":\"" + errorMsg + "\"}"); | ||||||
|                         return; |                         return; | ||||||
| @@ -434,9 +436,6 @@ void setupWebserver(AsyncWebServer &server) { | |||||||
|  |  | ||||||
|             if (len) { |             if (len) { | ||||||
|                 if (Update.write(data, len) != len) { |                 if (Update.write(data, len) != len) { | ||||||
|                     if (command == U_SPIFFS) { |  | ||||||
|                         restoreJsonConfigs(); |  | ||||||
|                     } |  | ||||||
|                     String errorMsg = String("Write failed: ") + Update.errorString(); |                     String errorMsg = String("Write failed: ") + Update.errorString(); | ||||||
|                     request->send(400, "application/json", "{\"success\":false,\"message\":\"" + errorMsg + "\"}"); |                     request->send(400, "application/json", "{\"success\":false,\"message\":\"" + errorMsg + "\"}"); | ||||||
|                     return; |                     return; | ||||||
| @@ -458,9 +457,6 @@ void setupWebserver(AsyncWebServer &server) { | |||||||
|  |  | ||||||
|             if (final) { |             if (final) { | ||||||
|                 if (!Update.end(true)) { |                 if (!Update.end(true)) { | ||||||
|                     if (command == U_SPIFFS) { |  | ||||||
|                         restoreJsonConfigs(); |  | ||||||
|                     } |  | ||||||
|                     String errorMsg = String("Update end failed: ") + Update.errorString(); |                     String errorMsg = String("Update end failed: ") + Update.errorString(); | ||||||
|                     request->send(400, "application/json", "{\"success\":false,\"message\":\"" + errorMsg + "\"}"); |                     request->send(400, "application/json", "{\"success\":false,\"message\":\"" + errorMsg + "\"}"); | ||||||
|                     return; |                     return; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user