Repository navigation
Conversation
Implement zip extraction dialog and functionality.
Added ZIP extraction support and improved upload handling.
Added ZIP extraction support function to web interface.
…rmio.ini Increased CONFIG_ASYNC_TCP_STACK_SIZE from 4096 to 20480 to allocate more memory for Async TCP and add miniz to lib deps.
Added Miniz buffer flags for configuration.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a proper ZIP workflow to the WebUI file browser. Previously, uploading a .zip just wrote the archive as a regular file into the current folder — no extraction, no handling of the archive as a package. The new flow detects .zip uploads, stages them in a temp folder, and offers the user a choice: extract here, extract to a chosen folder, or just keep the file.
What's new
· ZIP detection on upload. When the uploaded file's name ends in .zip, the backend writes it to /.bruce_tmp/ (SD if available, LittleFS otherwise) instead of the current folder. This keeps the archive out of the user's way and makes the "keep the file" case a clean move rather than a re-upload.
· State endpoint. A new GET /upload_state reports whether the most recent upload was a ZIP and, if so, where it landed. The frontend queries this after each successful upload instead of relying on the multipart response body — that response goes through the AsyncWebServer's request pipeline and isn't reliable for structured data.
· Dialog with three actions. After a ZIP upload, the user sees a dialog offering:
· Extract here — extracts into the current folder
· Extract to… — opens a folder picker to choose a destination
· Just keep the file — moves the ZIP from temp to the current folder without extracting
· Extraction via miniz. Uses miniz-esp32 (added to lib_deps). Entry names are sanitized before writing (rejects .., strips leading /, rejects :), so an archive can't escape the target folder.
· Stack-safe extraction. extractZipTo tries the fast path first (mz_zip_reader_init_file), then falls back to loading the archive into a heap buffer if the path can't be resolved through miniz's own file layer. The archive-size cap on the fallback (ZIP_MEM_FALLBACK_LIMIT = 2 MB) prevents OOM on oversized zips. Structs are hoisted out of the extraction loop to keep the WebUI task stack bounded, and a vTaskDelay between entries feeds the RTOS watchdog.
· Serialization guard. A single g_longOpInProgress flag ensures only one long operation (extract or zip upload) runs at a time. Two concurrent requests would otherwise corrupt shared miniz globals or the FS handles.
· Frontend concurrency. _zipBusy prevents double-clicks; all zip dialog buttons are disabled during a request; and a short delay after the response before follow-up requests gives the device time to finish cleanup.
Files changed
· src/core/wifi/webInterface.cpp
· New handleUpload logic for .zip detection, temp staging, and original-name preservation
· New GET /upload_state endpoint
· New POST /extract endpoint (extract or move-only), guarded by g_longOpInProgress
· New extractZipTo() helper
· src/core/wifi/webInterface.h — declares extractZipTo()
· embedded_resources/web_interface/index.html — new .dialog.zip-extract block
· embedded_resources/web_interface/index.js — zip flow (dialog handlers, _zipBusy guard, uploadFile state query, _finishZipFlow)
· platformio.ini — miniz-esp32 added to lib_deps; CONFIG_ASYNC_TCP_STACK_SIZE raised from 4096 to 20480 to accommodate the extraction path
Types of Changes
· New feature (zip install workflow)
· Bugfix (frontend can now safely serialize long operations)
Verification
Built and tested on Cardputer Adv (SD card). Manually verified:
· Upload a .zip → dialog appears with three options
· Extract here → archive contents land in the current folder, count matches
· Extract to… → folder picker shows current path and subfolders; selected folder receives the files
· Just keep the file → the .zip moves from /.bruce_tmp/ to the current folder with its original name
· Cancel (dialog X or ESC) → archive remains in temp, cleaned up on next WebUI restart
· Concurrent requests (double-click, or upload while extracting) → refused with 409, no crash
· Non-zip uploads → unchanged behaviour
User-Facing Change
Uploading a .zip through the WebUI now presents a choice of extraction or keeping the file, rather than dropping the archive into the current folder. Existing file browser behaviour for non-zip uploads is unchanged.
Notes
· miniz-esp32 is used (ROM's rom/miniz.h isn't exposed in Bruce's build). Pinned via lib_deps.
· Small archives extract via the fast path with no extra RAM; the heap-buffer fallback exists for filesystem-setup variations where miniz's internal file layer can't see the same mounts as the Arduino FS object.
· ZIP_MEM_FALLBACK_LIMIT can be raised on PSRAM-equipped boards if larger archives need to be handled.
· Anything left over on the /.bruce_tmp/ folder is cleaned at the next WebUI startup.