From 70d9a77df3e2b44df6b64f62cee9fa74dbe97fa3 Mon Sep 17 00:00:00 2001
From: Hieromon Ikasamo <hieromon@gmail.com>
Date: Tue, 11 Jun 2019 17:37:32 +0900
Subject: [PATCH] Added the setting page

---
 examples/Update/Update.ino | 138 +++++++++++++++++++++++++++++++++++--
 1 file changed, 131 insertions(+), 7 deletions(-)

diff --git a/examples/Update/Update.ino b/examples/Update/Update.ino
index e0dc158..e37bedb 100644
--- a/examples/Update/Update.ino
+++ b/examples/Update/Update.ino
@@ -19,21 +19,140 @@ using WebServerClass = WebServer;
 #endif
 #include <AutoConnect.h>
 
-#define UPDATESERVER_URL  "192.168.1.9"
-#define UPDATESERVER_PORT 8000
-#define UPDATESERVER_PATH "bin"
+// Update server setting page
+static const char SETUP_PAGE[] PROGMEM = R"(
+{
+  "title": "Update setup",
+  "uri": "/setup",
+  "menu": true,
+  "element": [
+    {
+      "name": "caption",
+      "type": "ACText",
+      "value": "OTA update setup",
+      "style": ""
+    },
+    {
+      "name": "isvalid",
+      "type": "ACText",
+      "style": "color:red"
+    },
+    {
+      "name": "server",
+      "type": "ACInput",
+      "label": "Update server",
+      "pattern": "^((([a-zA-Z]|[a-zA-Z][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z]|[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]))|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})$",
+      "placeholder": "Your update server address"
+    },
+    {
+      "name": "port",
+      "type": "ACInput",
+      "label": "port",
+      "pattern": "[0-9]{1,4}"
+    },
+    {
+      "name": "path",
+      "type": "ACInput",
+      "label": "path"
+    },
+    {
+      "name": "apply",
+      "type": "ACSubmit",
+      "value": "Apply",
+      "uri": "/apply"
+    },
+    {
+      "name": "cancel",
+      "type": "ACSubmit",
+      "value": "Discard",
+      "uri": "/"
+    }
+  ]
+}
+)";
+
+// The /apply handler validates the update server settings entered on
+// the setup page. APPLY_PAGE exists to enable the /apply handler,
+// and its role is a page redirector. If the /apply handler detects some
+// errors, the page will redirect to the /setup page with error message.
+static const char APPLY_PAGE[] PROGMEM = R"(
+{
+  "title": "Update setup",
+  "uri": "/apply",
+  "menu": false,
+  "element": [
+    {
+      "name": "redirect",
+      "type": "ACElement",
+      "value": "<script type=\"text/javascript\">location.href='__REDIRECT__';</script>"
+    }
+  ]
+}
+)";
 
 WebServerClass    server;
 AutoConnect       portal(server);
-AutoConnectUpdate update(UPDATESERVER_URL, UPDATESERVER_PORT, UPDATESERVER_PATH);
-bool  atFirst;
+AutoConnectAux    setupPage;
+AutoConnectAux    applyPage;
+AutoConnectUpdate update;
+
+#define UPDATESERVER_URL  ""    // Define to suit your environment 
+#define UPDATESERVER_PORT 8000
+#define UPDATESERVER_PATH "bin"
+
+void loadAux() {
+  setupPage.load(SETUP_PAGE);
+  setupPage["server"].value = UPDATESERVER_URL;
+  setupPage["port"].value = String(UPDATESERVER_PORT);
+  setupPage["path"].value = UPDATESERVER_PATH;
+  applyPage.load(APPLY_PAGE);
+}
+
+// The onSetup handler clears the error message field of the /setup page.
+// Its field will be cleared after the /setup page generating by the
+// effect of the AC_EXIT_LATER option.
+String onSetup(AutoConnectAux& aux, PageArgument& arg) {
+  setupPage["isvalid"].value = String();
+  return String();
+}
+
+// The onApply handler validates the update server configuration.
+// It does not do any semantic analysis but only verifies that the
+// settings match the pattern defined in each field.
+// The AutoConnectInput isValid function checks if the current value
+// matches the pattern.
+String onApply(AutoConnectAux& aux, PageArgument& arg) {
+  String  returnUri;
+
+  AutoConnectInput& host = setupPage["server"].as<AutoConnectInput>();
+  AutoConnectInput& port = setupPage["port"].as<AutoConnectInput>();
+  AutoConnectInput& path = setupPage["path"].as<AutoConnectInput>();
+
+  Serial.printf("host: %s\n", host.value.c_str());
+  Serial.printf("port: %s\n", port.value.c_str());
+  Serial.printf("uri: %s\n", path.value.c_str());
+
+  if (host.isValid() & port.isValid()) {
+    update.host = host.value;
+    update.port = port.value.toInt();
+    update.uri = path.value;
+    setupPage["isvalid"].value = String();
+    returnUri = "/";
+  }
+  else {
+    setupPage["isvalid"].value = String("Incorrect value specified.");
+    returnUri = "/setup";
+  }
+  applyPage["redirect"].value.replace("__REDIRECT__", returnUri);
+  return String();
+}
 
 void setup() {
   delay(1000);
   Serial.begin(115200);
   Serial.println();
 
-  // Responder of root page handled directly from WebServer class.
+  // Responder of root page and apply page  handled directly from WebServer class.
   server.on("/", []() {
     String content = R"(
 <!DOCTYPE html>
@@ -47,10 +166,15 @@ __AC_LINK__
 </body>
 </html>
     )";
-    content.replace("__AC_LINK__", String(AUTOCONNECT_LINK(COG_24)));
+    content.replace("__AC_LINK__", String(AUTOCONNECT_LINK(COG_16)));
     server.send(200, "text/html", content);
   });
 
+  // AUX page loading
+  loadAux();  
+  setupPage.on(onSetup, AC_EXIT_LATER);
+  applyPage.on(onApply);
+  portal.join({ setupPage, applyPage });
   portal.begin();
   update.attach(portal);
 }