diff --git a/.gitignore b/.gitignore index 25b36fb..bae255e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .DS_Store .vscode lib/EpdFont/fontsrc +*.generated.h diff --git a/platformio.ini b/platformio.ini index eb839e2..5150c08 100644 --- a/platformio.ini +++ b/platformio.ini @@ -31,6 +31,9 @@ board_build.flash_mode = dio board_build.flash_size = 16MB board_build.partitions = partitions.csv +extra_scripts = + pre:scripts/build_html.py + ; Libraries lib_deps = BatteryMonitor=symlink://open-x4-sdk/libs/hardware/BatteryMonitor diff --git a/scripts/build_html.py b/scripts/build_html.py new file mode 100644 index 0000000..3b3ac57 --- /dev/null +++ b/scripts/build_html.py @@ -0,0 +1,51 @@ +import os +import re + +SRC_DIR = "src" + +def minify_html(html: str) -> str: + # Tags where whitespace should be preserved + preserve_tags = ['pre', 'code', 'textarea'] + preserve_regex = '|'.join(preserve_tags) + + # Protect preserve blocks with placeholders + preserve_blocks = [] + def preserve(match): + preserve_blocks.append(match.group(0)) + return f"__PRESERVE_BLOCK_{len(preserve_blocks)-1}__" + + html = re.sub(rf'<({preserve_regex})[\s\S]*?', preserve, html, flags=re.IGNORECASE) + + # Remove HTML comments + html = re.sub(r'', '', html, flags=re.DOTALL) + + # Collapse all whitespace between tags + html = re.sub(r'>\s+<', '><', html) + + # Collapse multiple spaces inside tags + html = re.sub(r'\s+', ' ', html) + + # Restore preserved blocks + for i, block in enumerate(preserve_blocks): + html = html.replace(f"__PRESERVE_BLOCK_{i}__", block) + + return html.strip() + +for root, _, files in os.walk(SRC_DIR): + for file in files: + if file.endswith(".html"): + html_path = os.path.join(root, file) + with open(html_path, "r", encoding="utf-8") as f: + html_content = f.read() + + # minified = regex.sub("\g<1>", html_content) + minified = minify_html(html_content) + base_name = f"{os.path.splitext(file)[0]}Html" + header_path = os.path.join(root, f"{base_name}.generated.h") + + with open(header_path, "w", encoding="utf-8") as h: + h.write(f"// THIS FILE IS AUTOGENERATED, DO NOT EDIT MANUALLY\n\n") + h.write(f"#pragma once\n") + h.write(f'constexpr char {base_name}[] PROGMEM = R"rawliteral({minified})rawliteral";\n') + + print(f"Generated: {header_path}") diff --git a/src/CrossPointWebServer.cpp b/src/CrossPointWebServer.cpp index daa6c30..ad70f62 100644 --- a/src/CrossPointWebServer.cpp +++ b/src/CrossPointWebServer.cpp @@ -6,6 +6,9 @@ #include #include "config.h" +#include "html/HomePageHtml.generated.h" +#include "html/FilesPageHeaderHtml.generated.h" +#include "html/FilesPageFooterHtml.generated.h" // Global instance CrossPointWebServer crossPointWebServer; @@ -46,817 +49,10 @@ static String escapeHtml(const String& input) { return output; } -// HTML page template -static const char* HTML_PAGE = R"rawliteral( - - - - - - CrossPoint Reader - - - -

📚 CrossPoint Reader

- - - -
-

Device Status

-
- Version - %VERSION% -
-
- WiFi Status - Connected -
-
- IP Address - %IP_ADDRESS% -
-
- Free Memory - %FREE_HEAP% bytes -
-
- -
-

- CrossPoint E-Reader • Open Source -

-
- - -)rawliteral"; - -// File listing page template -static const char* FILES_PAGE_HEADER = R"rawliteral( - - - - - - CrossPoint Reader - Files - - - - -)rawliteral"; - -static const char* FILES_PAGE_FOOTER = R"rawliteral( -
-

- CrossPoint E-Reader • Open Source -

-
- - - - - - - - - - - - - -)rawliteral"; - +// File listing page template - now using generated headers: +// - HomePageHtml (from html/HomePage.html) +// - FilesPageHeaderHtml (from html/FilesPageHeader.html) +// - FilesPageFooterHtml (from html/FilesPageFooter.html) CrossPointWebServer::CrossPointWebServer() {} CrossPointWebServer::~CrossPointWebServer() { stop(); } @@ -930,7 +126,7 @@ void CrossPointWebServer::handleClient() { } void CrossPointWebServer::handleRoot() { - String html = HTML_PAGE; + String html = HomePageHtml; // Replace placeholders with actual values html.replace("%VERSION%", CROSSPOINT_VERSION); @@ -1035,7 +231,7 @@ bool CrossPointWebServer::isEpubFile(const String& filename) { } void CrossPointWebServer::handleFileList() { - String html = FILES_PAGE_HEADER; + String html = FilesPageHeaderHtml; // Get current path from query string (default to root) String currentPath = "/"; @@ -1230,7 +426,7 @@ void CrossPointWebServer::handleFileList() { html += ""; - html += FILES_PAGE_FOOTER; + html += FilesPageFooterHtml; server->send(200, "text/html", html); Serial.printf("[%lu] [WEB] Served file listing page for path: %s\n", millis(), currentPath.c_str()); diff --git a/src/activities/network/WifiScreen.h b/src/activities/network/WifiScreen.h index a0a607c..a57c793 100644 --- a/src/activities/network/WifiScreen.h +++ b/src/activities/network/WifiScreen.h @@ -9,8 +9,8 @@ #include #include -#include "OnScreenKeyboard.h" #include "../Activity.h" +#include "OnScreenKeyboard.h" // Structure to hold WiFi network information struct WifiNetworkInfo { diff --git a/src/html/FilesPageFooter.html b/src/html/FilesPageFooter.html new file mode 100644 index 0000000..e74e4bf --- /dev/null +++ b/src/html/FilesPageFooter.html @@ -0,0 +1,267 @@ +
+

+ CrossPoint E-Reader • Open Source +

+
+ + + + + + + + + + + + + diff --git a/src/html/FilesPageHeader.html b/src/html/FilesPageHeader.html new file mode 100644 index 0000000..380160a --- /dev/null +++ b/src/html/FilesPageHeader.html @@ -0,0 +1,430 @@ + + + + + + CrossPoint Reader - Files + + + + + + diff --git a/src/html/HomePage.html b/src/html/HomePage.html new file mode 100644 index 0000000..024c6a9 --- /dev/null +++ b/src/html/HomePage.html @@ -0,0 +1,108 @@ + + + + + + CrossPoint Reader + + + +

📚 CrossPoint Reader

+ + + +
+

Device Status

+
+ Version + %VERSION% +
+
+ WiFi Status + Connected +
+
+ IP Address + %IP_ADDRESS% +
+
+ Free Memory + %FREE_HEAP% bytes +
+
+ +
+

+ CrossPoint E-Reader • Open Source +

+
+ +