Skip to content

Commit 668b33d

Browse files
vdeconinckd-a-vearlephilhowerdevyte
authored
Revamp of the FSBrowser and SDWebServer examples (#7182)
* Minimal file with a few ESP8266-specific keywords - github issue #3701 * Renamed "SDWebServer" to the more universal "WebFileManager" * SD was replaced by SDFS, and sketch now works on either SDFS, SPIFFS or LittleFS based on a #define logic (required adding a second param to open() and replacing 'FILE_WRITE' by "w") + Added size information to file list and a /status request handler to return filesystem status * Tree panel width is now proportional to window. Changed icons (lighter and more neutral), including one for files. Show size of files. Fill "filename" box upon clicking on a file. Sort files alphabetically. * Replaced by a lighter version * Return the filesystem time in the status object + Massive cleanup/merge/align with some code from the FSBrowser example and misc refactorings * Fixed folder handling * Replaced the FILESYSTEM #define by a filesystem variable, and introduced FSConfig to prevent FS formating. Fixed recursive deletion. Got rid of specific isDir() for SPIFFS. * Made 8.3 lowercase filenames formating optional (disabled by default). Refresh only part of the tree when possible. Selecting a file for upload defaults to the same folder as the last clicked file. Removed the Mkdir button on SPIFFS. * Added 'wait' cursor during asynchronous operations. Slight refactoring of XMLHttpRequest completion handling * Removed limitation "files must have an extension, folders may not". Case insensivity of the extension for the editor and preview. * Support Filenames without extension, Dirnames with extension. Added Save/Discard/Help buttons to Editor, discard confirmation on leave, and refresh tree/status upon save. Removed redundant Ctrl-Z + Ctrl-Shift-Z shortcut declarations. Small bug fixes. + some refactoring * Fixed tree refresh on delete in all cases by returning the remaining path as response to the delete request. Refactoring * Changed FS status in text by a percentage graph, with numbers as tooltip. Unsupported files on SPIFFS (files at root not sarting with "/", files with double "/", files ending with "/") are now detected and reported in the page. * Small fix + refactoring * Restrict filename support check to SPIFFS. * Implemented Move/Rename. Added "loading" screen during async operations (dim with spinner and status). Fixed "discard" feature that kept prompting even after an image was loaded. Improved refresh of parts of the tree, with recursive listing. Moved the "path" id attribute to the "li" elements for folders (was already the case for files). Refactoring and cleanup. * Fixed broken spinner * Cosmetic improvements. Removed non-functional Upload context menu. Fixed error in response to move requests. Added minified version. * Added specific icons for text and image files. Fixed incompatibilities with SPIFFS. Fixed a race condition between deletion and reinsertion of nodes when multiple folders are refreshed. Fixed missing URL decoding for files with special chars (e.g. space char). Moved info from source code comment to a readme.md file. Added source PNG to git. Cleanup. * Added favicon.ico. * Renamed project * Small changes * Add a note about the ace.js dependency * Minor changes * Define LittleFS by default. If both uncompressed and gz versions exist, use uncompressed version. Small fixes. * Define LittleFS by default. If both uncompressed and gz versions exist, use uncompressed version. Small fixes. * Restyled version * (dummy edit to retrigger broken CI) * Using unsigned int for comparison with String.length() * Return an error when upload fails (e.g. filesystem full) * Trying to reorder functions to please CI * Reordered functions to please CI. * Moved file * Renamed "SDWebServer" to the more universal "WebFileManager" * SD was replaced by SDFS, and sketch now works on either SDFS, SPIFFS or LittleFS based on a #define logic (required adding a second param to open() and replacing 'FILE_WRITE' by "w") + Added size information to file list and a /status request handler to return filesystem status * Tree panel width is now proportional to window. Changed icons (lighter and more neutral), including one for files. Show size of files. Fill "filename" box upon clicking on a file. Sort files alphabetically. * Replaced by a lighter version * Return the filesystem time in the status object + Massive cleanup/merge/align with some code from the FSBrowser example and misc refactorings * Fixed folder handling * Replaced the FILESYSTEM #define by a filesystem variable, and introduced FSConfig to prevent FS formating. Fixed recursive deletion. Got rid of specific isDir() for SPIFFS. * Made 8.3 lowercase filenames formating optional (disabled by default). Refresh only part of the tree when possible. Selecting a file for upload defaults to the same folder as the last clicked file. Removed the Mkdir button on SPIFFS. * Added 'wait' cursor during asynchronous operations. Slight refactoring of XMLHttpRequest completion handling * Removed limitation "files must have an extension, folders may not". Case insensivity of the extension for the editor and preview. * Support Filenames without extension, Dirnames with extension. Added Save/Discard/Help buttons to Editor, discard confirmation on leave, and refresh tree/status upon save. Removed redundant Ctrl-Z + Ctrl-Shift-Z shortcut declarations. Small bug fixes. + some refactoring * Fixed tree refresh on delete in all cases by returning the remaining path as response to the delete request. Refactoring * Changed FS status in text by a percentage graph, with numbers as tooltip. Unsupported files on SPIFFS (files at root not sarting with "/", files with double "/", files ending with "/") are now detected and reported in the page. * Small fix + refactoring * Restrict filename support check to SPIFFS. * Implemented Move/Rename. Added "loading" screen during async operations (dim with spinner and status). Fixed "discard" feature that kept prompting even after an image was loaded. Improved refresh of parts of the tree, with recursive listing. Moved the "path" id attribute to the "li" elements for folders (was already the case for files). Refactoring and cleanup. * Fixed broken spinner * Cosmetic improvements. Removed non-functional Upload context menu. Fixed error in response to move requests. Added minified version. * Added specific icons for text and image files. Fixed incompatibilities with SPIFFS. Fixed a race condition between deletion and reinsertion of nodes when multiple folders are refreshed. Fixed missing URL decoding for files with special chars (e.g. space char). Moved info from source code comment to a readme.md file. Added source PNG to git. Cleanup. * Added favicon.ico. * Renamed project * Small changes * Add a note about the ace.js dependency * Minor changes * Define LittleFS by default. If both uncompressed and gz versions exist, use uncompressed version. Small fixes. * Define LittleFS by default. If both uncompressed and gz versions exist, use uncompressed version. Small fixes. * Restyled version * (dummy edit to retrigger broken CI) * Using unsigned int for comparison with String.length() * Return an error when upload fails (e.g. filesystem full) * Trying to reorder functions to please CI * Reordered functions to please CI. * Update to use chunked response API * Removed temp files commited by mistake * Avoid using args() as requested * Use html entity for non-breaking space to avoid losing char when minifying * Script to preprocess index.htm * (reformated code) * (comments) * Preprocessed files * Fixed dump to create an actual include file * Optionally embed index.htm in code. (+ documentation and preprocessing script) * (reformated) * If editor cannot be loaded from the web, try a local version, or default to a text viewer if not present * (removed a TODO item :-)) * (forgot to reprocess files after last commit) * (reprocess should be ok this time) * Return error 500 when upload fails immediately (e.g. filesystem full) * Use standard <meter> tag for filesystem use * (updated following changes to index.htm) * Do not include gzipped version in the data folder by default. Leave it in the extras folder and change readme accordingly (plus some reformatingi of the readme file) * Gzipped index file not included in data/edit by default. It is now left in the extras folder. Readme file was updated accordingly (+ some reformating) * Reduce String clutter by reserving and concatenating elements one by one. * Use clear() to reset String. * Avoid comparisons against empty String. * Use char instead of single-char String where possible. * Prefer direct logic over inverted. * Rename returnBlah to replyBlah. * Renamed h2int to hexDigitToInt * Renamed getFileError() to checkForUnsupportedPath(), to avoid confusion with a getter. * Misc improvements. * Added comments about mandatory rebuilding gz and h files in case of update to index.htm. * Addressed a few comments. * Improve replies: bad requests vs server error * (reformated) * Reduce clutter by reserving String size beforehand. * Moved most Strings of more than 10 chars to flash. * Use lib version of urlDecode() instead of a local one, and only call it when required. * Added a comment about the dangers of recursion on embedded devices. * Added a more explicit warning in the .h header comment. * Added a typical set of required files to load ace editor from the ESP. * (reformated) * More explicit warning at the beginning of the .h version. Co-authored-by: david gauchard <[email protected]> Co-authored-by: Earle F. Philhower, III <[email protected]> Co-authored-by: Develo <[email protected]>
1 parent ce200ed commit 668b33d

File tree

15 files changed

+2418
-1287
lines changed

15 files changed

+2418
-1287
lines changed

libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino

+551-184
Large diffs are not rendered by default.
Binary file not shown.

libraries/ESP8266WebServer/examples/FSBrowser/data/edit/index.htm

+1,128
Large diffs are not rendered by default.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,22 @@
1-
<!--
2-
FSWebServer - Example Index Page
3-
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
4-
This file is part of the ESP8266WebServer library for Arduino environment.
5-
6-
This library is free software; you can redistribute it and/or
7-
modify it under the terms of the GNU Lesser General Public
8-
License as published by the Free Software Foundation; either
9-
version 2.1 of the License, or (at your option) any later version.
10-
This library is distributed in the hope that it will be useful,
11-
but WITHOUT ANY WARRANTY; without even the implied warranty of
12-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13-
Lesser General Public License for more details.
14-
You should have received a copy of the GNU Lesser General Public
15-
License along with this library; if not, write to the Free Software
16-
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17-
-->
181
<!DOCTYPE html>
192
<html>
203
<head>
214
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
22-
<title>ESP Monitor</title>
23-
<script type="text/javascript" src="graphs.js"></script>
24-
<script type="text/javascript">
25-
var heap,temp,digi;
26-
var reloadPeriod = 1000;
27-
var running = false;
28-
29-
function loadValues(){
30-
if(!running) return;
31-
var xh = new XMLHttpRequest();
32-
xh.onreadystatechange = function(){
33-
if (xh.readyState == 4){
34-
if(xh.status == 200) {
35-
var res = JSON.parse(xh.responseText);
36-
heap.add(res.heap);
37-
temp.add(res.analog);
38-
digi.add(res.gpio);
39-
if(running) setTimeout(loadValues, reloadPeriod);
40-
} else running = false;
41-
}
42-
};
43-
xh.open("GET", "/all", true);
44-
xh.send(null);
45-
};
46-
47-
function run(){
48-
if(!running){
49-
running = true;
50-
loadValues();
51-
}
5+
<title>ESP Index</title>
6+
<style>
7+
body {
8+
background-color:black;
9+
color:white;
5210
}
53-
11+
</style>
12+
<script type="text/javascript">
5413
function onBodyLoad(){
55-
var refreshInput = document.getElementById("refresh-rate");
56-
refreshInput.value = reloadPeriod;
57-
refreshInput.onchange = function(e){
58-
var value = parseInt(e.target.value);
59-
reloadPeriod = (value > 0)?value:0;
60-
e.target.value = reloadPeriod;
61-
}
62-
var stopButton = document.getElementById("stop-button");
63-
stopButton.onclick = function(e){
64-
running = false;
65-
}
66-
var startButton = document.getElementById("start-button");
67-
startButton.onclick = function(e){
68-
run();
69-
}
70-
71-
// Example with 10K thermistor
72-
//function calcThermistor(v) {
73-
// var t = Math.log(((10230000 / v) - 10000));
74-
// t = (1/(0.001129148+(0.000234125*t)+(0.0000000876741*t*t*t)))-273.15;
75-
// return (t>120)?0:Math.round(t*10)/10;
76-
//}
77-
//temp = createGraph(document.getElementById("analog"), "Temperature", 100, 128, 10, 40, false, "cyan", calcThermistor);
78-
79-
temp = createGraph(document.getElementById("analog"), "Analog Input", 100, 128, 0, 1023, false, "cyan");
80-
heap = createGraph(document.getElementById("heap"), "Current Heap", 100, 125, 0, 30000, true, "orange");
81-
digi = createDigiGraph(document.getElementById("digital"), "GPIO", 100, 146, [0, 4, 5, 16], "gold");
82-
run();
14+
console.log("we are loaded!!");
8315
}
8416
</script>
8517
</head>
86-
<body id="index" style="margin:0; padding:0;" onload="onBodyLoad()">
87-
<div id="controls" style="display: block; border: 1px solid rgb(68, 68, 68); padding: 5px; margin: 5px; width: 362px; background-color: rgb(238, 238, 238);">
88-
<label>Period (ms):</label>
89-
<input type="number" id="refresh-rate"/>
90-
<input type="button" id="start-button" value="Start"/>
91-
<input type="button" id="stop-button" value="Stop"/>
92-
</div>
93-
<div id="heap"></div>
94-
<div id="analog"></div>
95-
<div id="digital"></div>
18+
<body id="index" onload="onBodyLoad()">
19+
<h1>ESP8266 Pin Functions</h1>
20+
<img src="pins.png" />
9621
</body>
97-
</html>
22+
</html>
Loading
Loading
Binary file not shown.

libraries/ESP8266WebServer/examples/FSBrowser/extras/index_htm.h

+529
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#/bin/sh
2+
3+
# Processing script to optionally reduce filesystem use by miniying, gzipping and preparing index.htm for embedding in code.
4+
# Please see readme.md for more information.
5+
6+
# Requires xdd which is part of the VIM package
7+
# Requires npm
8+
# sudo apt install npm
9+
# ln -s /usr/bin/nodejs /usr/bin/node
10+
# Requires html-minifier
11+
# sudo npm install html-minifier -g
12+
13+
html-minifier \
14+
--case-sensitive \
15+
--collapse-boolean-attributes \
16+
--collapse-whitespace \
17+
--minify-css true \
18+
--minify-js true \
19+
--process-conditional-comments \
20+
--remove-attribute-quotes \
21+
--remove-comments \
22+
--remove-empty-attributes \
23+
--remove-optional-tags \
24+
--remove-redundant-attributes \
25+
--remove-script-type-attributes \
26+
--remove-style-link-type-attributes \
27+
-o index.htm \
28+
../data/edit/index.htm
29+
30+
if [ $? -ne 0 ]
31+
then
32+
echo "Error minifying index.htm"
33+
exit -1
34+
fi
35+
36+
if [ -e index.htm.gz ]
37+
then
38+
rm index.htm.gz
39+
fi
40+
41+
gzip index.htm
42+
if [ $? -ne 0 ]
43+
then
44+
echo "Error gzipping minified index.htm"
45+
exit -1
46+
fi
47+
48+
echo '// WARNING: Auto-generated file. Please do not modify by hand.' > index_htm.h
49+
echo '// This file is an embeddable version of the gzipped index.htm file.' >> index_htm.h
50+
echo '// To update it, please rerun the `reduce_index.sh` script located in the `extras` subfolder' >> index_htm.h
51+
echo '// then recompile the sketch after each change to the `index.html` file.' >> index_htm.h
52+
xxd -i index.htm.gz >> index_htm.h
53+
if [ $? -ne 0 ]
54+
then
55+
echo "Error creating include file from index.htm.gz"
56+
exit -1
57+
fi
58+
59+
echo Reduce complete.
60+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# FSBrowser readme
2+
3+
## What is this sketch about ?
4+
5+
This example is a FileSystem Browser for the ESP8266 using http requests and a html/javascript frontend,
6+
working for all of SPIFFS, LittleFS and SDFS.
7+
This unified version is based on the previous examples named FSWebServer, FSBrowser and SDWebServer, Copyright (c) 2015 Hristo Gochkov. All rights reserved.
8+
9+
## How to use it ?
10+
1. Uncomment one of the `#define USE_xxx` directives in the sketch
11+
2. Add the credentials of your WiFi network (search for `STASSID`)
12+
3. Compile and upload the sketch to your ESP8266 device
13+
4. For normal use, copy the contents of the `data` folder to the filesystem. To do so:
14+
- for SDFS, copy that contents (not the data folder itself, just its contents) to the root of a FAT/FAT32-formated SD card connected to the SPI port of the ESP8266
15+
- for SPIFFS or LittleFS, please follow the instructions at https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#uploading-files-to-file-system
16+
5. Once the data and sketch have been uploaded, access the editor by pointing your browser to http://fsbrowser.local/edit
17+
18+
## Options
19+
If you need to free some space on the ESP filesystem, you can delete all the sample files at the root but also replace the `index.htm` file in the `data/edit` subfolder by the `index.htm.gz` file from the `extras` folder. That compressed version is not suited for learning or debugging, but will bring the total FS usage under 7KB.
20+
If you want to use the browser on a an existing filesystem or don't want to perform step 4 above, you have two possibilities :
21+
- either upload the `index.htm` file to the filesystem by opening a command shell in the `data` folder and running the following cURL command:
22+
`curl -F file=@edit/index.htm;filename=/edit/index.htm fsbrowser.local/edit`
23+
- or embed a version of the html page in the source code itself by uncommenting the following line in the sketch and rebuilding:
24+
`#define INCLUDE_FALLBACK_INDEX_HTM`
25+
That embedded version is functionally equivalent and will be returned if no `/edit/index.htm` or `/edit/index.htm.gz` file can be found on the filesystem, at the expense of a higher binary size.
26+
27+
If you use the gzipped or `INCLUDE_FALLBACK_INDEX_HTM` options, please remember to rerun the `reduce_index.sh` script located in the `extras` subfolder and recompile the sketch after each change to the `index.html` file.
28+
29+
## Dependency
30+
The html page uses the [Ace.js](https://ace.c9.io/) (v1.4.9 at the time of writing) text editor which is loaded from a CDN. Consequently, internet access from your web browser is required for the FSBrowser editing feature to work as-is.
31+
32+
If your browser has no web access (e.g. if you are connected to the ESP8266 as an access-point), you can copy the `ace.js` file to the `edit` subfolder of the ESP filesystem, along with optional plugins etc. according to your needs. A typical set might be:
33+
```
34+
ace.js
35+
ext-keybinding_menu.js
36+
ext-searchbox.js
37+
mode-html.js
38+
worker-html.js
39+
worker-css.js
40+
worker-javascript.js
41+
mode-xml.js
42+
worker-xml.js
43+
mode-json.js
44+
worker-json.js
45+
```
46+
(see https://github.com/ajaxorg/ace-builds for a full list).
47+
48+
If `ace.js` cannot be found on the ESP filesystem either, the page will default to a plain text viewer, with a warning message.
49+
50+
## Notes
51+
- See https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html for more information on FileSystems supported by the ESP8266.
52+
- For SDFS, if your card's CS pin is not connected to the default pin (4), uncomment the `fileSystemConfig.setCSPin(chipSelectPin);` line, specifying the GPIO the CS pin is connected to
53+
- `index.htm` is the default index returned if your URL does not end with a filename (works on subfolders as well)
54+
- Filesystem limitations apply. For example, FAT16 is limited to 8.3 filenames - see https://en.wikipedia.org/wiki/8.3_filename - SPIFFS and LittleFS also have limitations, please see https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#spiffs-file-system-limitations
55+
- Directories are supported on SDFS and LittleFS. On SPIFFS, all files are at the root, although their names may contain the "/" character.
56+
- The convention here is that the root of the filesystem is "/". On SPIFFS, paths not started with a slash are not supported
57+
- For creation, the convention is that a path ending with a "/" means create a folder, while without a "/" we create a file. Having an extension or not does not matter.
58+
59+
## Changelog since original FSBrowser
60+
61+
### Fixes to work on LittleFS based on SDFS
62+
- #define logic to select FS
63+
- switched from SD to SDFS
64+
- begin() does not support parameters > removed SS and added optional config
65+
- LittleFS.open() second parametsr is mandatory > specified "r" where needed
66+
- 'FILE_WRITE' was not declared in this scope > replaced by "w"
67+
68+
### UI/usability improvements
69+
- Never format filesystem, just return "FS INIT ERROR" when FS cannot be mounted
70+
- Tree panel width is now proportional (20%) to see long names on big screens
71+
- Added icons for files, and indented them to the same level as folders
72+
- Changed file/folder icon set to use a lighter and more neutral one, and added specific "text" and "image" icons for formats recognized as such
73+
- Items are now sorted (folders first, then plain files, each in alphabetic order)
74+
- Added file size after each file name
75+
- Added FS status information at the top right
76+
- Made clear that an async operation is in progress by dimming screen and showing operation status
77+
- Filled filename box in header with the name of the last clicked file
78+
- Selecting a file for upload defaults to putting it in the same folder as the last clicked file
79+
- Removed limitation to 8.3 lowercase filenames
80+
- Support Filenames without extension, Dirnames with extension
81+
- Improved recursive refresh of parts of the tree (e.g. refresh folder upon file delete, show last folder upon creating nested file)
82+
- Added Save/Discard/Help buttons to ACE editor, discard confirmation on leave, and refresh tree and status upon save
83+
- Removed "Upload" from context menu (which didn't work anyway)
84+
- Added "Rename/Move" feature to context menu
85+
- Sketch can be used on a preexisting filesystem by embedding the index.htm file in the program
86+
87+
## TODO (maybe)
88+
- ? How can we query the fatType of the SDFS (FAT16 or FAT32) to limit filenames to 8.3 on FAT16 ?
89+
- ? Add a visible root node "/" (with no delete option) + add the FS type next to it, like <i>LittleFS</i>
90+
- ? move "Mkdir" and "MkFile" to context menu, with prompt like for Rename/Move
91+
- ? implement drag/drop for move + make "rename" only a local rename operation (no move)
92+
- ? Optionally present SPIFFS as a hierarchical FS too
93+
- ? Optionally mount several filesystems at the same time (SPIFFS + SDFS or LittleFS + SDFS)
94+
95+
## Test suite
96+
These tests are a checklist of operations to verify the FSBrowser behaviour.
97+
### On SPIFFS
98+
#### 8.3 filenames
99+
- At root : MkFile '/1.txt' / List / Edit / Download / Delete / Upload '/1.png' / View image / Delete image
100+
- In subdir : MkFile '/dir/2.txt' / List / Edit / Download / Delete / Upload '/dir/2.png' / View image
101+
- Create nested file '/a/b.txt' and delete it
102+
- Attempt creation of unsupported filenames
103+
#### Long filenames
104+
- At root : MkFile '/My text file 1.txt' / List / Edit / Download / Delete / Upload '/My image file 1.png' / View image / Delete image
105+
- In subdir : MkFile '/My Directory/My text 2.txt' / List / Edit / Download / Delete / Upload '/My Directory/My image 2.png' / View image
106+
- Create nested file '/My folder/My test file.txt' and delete it
107+
108+
### On LittleFS
109+
#### 8.3 filenames
110+
- At root : MkFile '/1.txt' / List / Edit / Download / Delete / Upload '/1.png' / View image / Delete image / Mkdir '/dir'
111+
- In subdir : MkFile '/dir/2.txt' / List / Edit / Download / Delete / Upload '/dir/2.png' / View image / Mkdir '/dir/sub'
112+
- Delete root folder '/dir'
113+
- Create nested file '/a/b.txt' and delete file 'b.txt'
114+
#### Long filenames
115+
- At root : MkFile '/My text file 1.txt' / List / Edit / Download / Delete / Upload '/My image file 1.png' / View image / Delete image / Mkdir '/My Directory'
116+
- In subdir : MkFile '/My Directory/My text file 2.txt' / List / Edit / Download / Delete / Upload '/My Directory/My image file 2.png' / View image / Mkdir '/My Directory/My Subdirectory'
117+
- Delete root folder '/My Directory'
118+
- Create nested file '/My folder/My test file.txt' and delete file 'My test file.txt'
119+
120+
### On SDFS
121+
#### 8.3 filenames
122+
- At root : MkFile '/1.txt' / List / Edit / Download / Delete / Upload '/1.png' / View image / Delete image / Mkdir '/dir'
123+
- In subdir : MkFile '/dir/2.txt' / List / Edit / Download / Delete / Upload '/dir/2.png' / View image / Mkdir '/dir/sub'
124+
- Delete root folder '/dir'
125+
- Create nested file '/a/b.txt' and delete file 'b.txt', then delete '/a'
126+
#### Long filenames
127+
- At root : MkFile '/My text file 1.txt' / List / Edit / Download / Delete / Upload '/My image file 1.png' / View image / Delete image / Mkdir '/My Directory'
128+
- In subdir : MkFile '/My Directory/My text file 2.txt' / List / Edit / Download / Delete / Upload '/My Directory/My image file 2.png' / View image / Mkdir '/My Directory/My Subdirectory'
129+
- Delete root folder '/My Directory'
130+
- Create nested file '/My folder/My test file.txt' and delete file 'My test file.txt'
131+
132+
## Credits
133+
- Original version of FSBrowser written by me-no-dev, contributions over time by various contributors
134+
- Icons are from https://feathericons.com/ . The resulting PNG is passed first through https://compresspng.com/ before being converted to base64 using https://www.base64-image.de/
135+
- The spinner is based on https://github.com/jlong/css-spinners
136+
- Minifiying of index.htm is done using the command line version of https://kangax.github.io/html-minifier/
137+
- Idea of embedding webpage in code borrowed from https://github.com/me-no-dev/ESPAsyncWebServer
138+

0 commit comments

Comments
 (0)