switch layout to purecss

pull/7/head 0.9.3
Thorsten von Eicken 10 years ago
parent 8bb8e1124b
commit 7ade39d986
  1. 29
      Makefile
  2. 25
      html/console.tpl
  3. 16
      html/head.tpl
  4. 40
      html/help.tpl
  5. 27
      html/index.tpl
  6. 25
      html/log.tpl
  7. 11
      html/pure-min.css
  8. 233
      html/style.css
  9. 35
      html/ui.js
  10. 162
      html/wifi/wifi.tpl
  11. 52
      user/cgi.c
  12. 1
      user/cgi.h
  13. 5
      user/cgiwifi.c
  14. 6
      user/console.c
  15. 6
      user/log.c

@ -1,30 +1,33 @@
# --------------- esphttpd config options --------------- # --------------- esphttpd config options ---------------
# If GZIP_COMPRESSION is set to "yes" then the static css, js, and html files will be compressed with gzip before added to the espfs image # If GZIP_COMPRESSION is set to "yes" then the static css, js, and html files will be compressed
# and will be served with gzip Content-Encoding header. # with gzip before added to the espfs image and will be served with gzip Content-Encoding header.
# This could speed up the downloading of these files, but might break compatibility with older web browsers not supporting gzip encoding # This could speed up the downloading of these files, but might break compatibility with older
# because Accept-Encoding is simply ignored. Enable this option if you have large static files to serve (for e.g. JQuery, Twitter bootstrap) # web browsers not supporting gzip encoding because Accept-Encoding is simply ignored.
# By default only js, css and html files are compressed. # Enable this option if you have large static files to serve (for e.g. JQuery, Twitter bootstrap)
# If you have text based static files with different extensions what you want to serve compressed then you will need to add the extension to the following places: # By default only js, css and html files are compressed using heatshrink.
# If you have text based static files with different extensions what you want to serve compressed
# then you will need to add the extension to the following places:
# - Add the extension to this Makefile at the webpages.espfs target to the find command # - Add the extension to this Makefile at the webpages.espfs target to the find command
# - Add the extension to the gzippedFileTypes array in the user/httpd.c file # - Add the extension to the gzippedFileTypes array in the user/httpd.c file
# #
# Adding JPG or PNG files (and any other compressed formats) is not recommended, because GZIP compression does not works effectively on compressed files. # Adding JPG or PNG files (and any other compressed formats) is not recommended, because GZIP
# compression does not work effectively on compressed files.
#Static gzipping is disabled by default. #Static gzipping is disabled by default.
GZIP_COMPRESSION ?= no GZIP_COMPRESSION ?= yes
# If COMPRESS_W_YUI is set to "yes" then the static css and js files will be compressed with yui-compressor # If COMPRESS_W_YUI is set to "yes" then the static css and js files will be compressed with
# This option works only when GZIP_COMPRESSION is set to "yes" # yui-compressor. This option works only when GZIP_COMPRESSION is set to "yes".
# http://yui.github.io/yuicompressor/ # http://yui.github.io/yuicompressor/
#Disabled by default. #Disabled by default.
COMPRESS_W_YUI ?= no COMPRESS_W_YUI ?= no
YUI-COMPRESSOR ?= /usr/bin/yui-compressor YUI-COMPRESSOR ?= /usr/bin/yui-compressor
#If USE_HEATSHRINK is set to "yes" then the espfs files will be compressed with Heatshrink and decompressed # If USE_HEATSHRINK is set to "yes" then the espfs files will be compressed with Heatshrink and
#on the fly while reading the file. Because the decompression is done in the esp8266, it does not require # decompressed on the fly while reading the file.
#any support in the browser. # Because the decompression is done in the esp8266, it does not require any support in the browser.
USE_HEATSHRINK ?= yes USE_HEATSHRINK ?= yes
# -------------- End of esphttpd config options ------------- # -------------- End of esphttpd config options -------------

@ -1,14 +1,19 @@
<html><head><title>MCU Console - ESP Link</title> %head%
<link rel="stylesheet" type="text/css" href="style.css">
</head> <div id="main">
<body> <div class="header">
<div id="main"> <h1><span class="esp">esp</span> link - Microcontroller Console</h1>
<div id="topnav">%topnav%</div> </div>
<h1><span class="esp">esp</span> link - Microcontroller Console</h1>
<p>The Microcontroller console shows the last 1024 characters received from UART0, to which <div class="content">
a microcontroller is tpically attached.</p> <p>The Microcontroller console shows the last 1024 characters received from UART0, to which
<pre class="console"> a microcontroller is typically attached.</p>
<pre class="console">
%console% %console%
</pre> </pre>
</div>
</div>
</div> </div>
<script src="ui.js"></script>
</body></html> </body></html>

@ -0,0 +1,16 @@
<html><head>
<title>ESP Link</title>
<link rel="stylesheet" href="/pure-min.css">
<link rel="stylesheet" href="/style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="layout">
<a href="#menu" id="menuLink" class="menu-link"><span></span></a>
<div id="menu">
<div class="pure-menu">
<a class="pure-menu-heading" href="/">esp-link</a>
<ul class="pure-menu-list">%topnav%</ul>
</div>
</div>

@ -1,13 +1,16 @@
<html> %head%
<head><title>Help - ESP Link</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="main">
<div id="topnav">%topnav%</div>
<h1><span class="esp">esp</span> link - Help</h1>
The ESP Link functions in two wifi modes: Station+AccessPoint (STA+AP) and Station (STA). <div id="main">
<div class="header">
<h1><span class="esp">esp</span> link - Help</h1>
</div>
<div class="content">
<p>This text is somewhat out of date, please refer to
<a href="https://github.com/jeelabs/esp-link/blob/master/README.md">the online README</a>
for the time being.</p>
<p>The ESP Link functions in two wifi modes: Station+AccessPoint (STA+AP) and Station (STA).
In the STA+AP mode it presents a network called esp8266 that you can connect to using the In the STA+AP mode it presents a network called esp8266 that you can connect to using the
password jeelabs8266. This mode is intended for initial configuration, but it is password jeelabs8266. This mode is intended for initial configuration, but it is
fully functional. Typically the easiest way to connect to the esp8266 network is using a phone, fully functional. Typically the easiest way to connect to the esp8266 network is using a phone,
@ -27,23 +30,25 @@ fresh IP the next time it starts up. On many Wifi routers you can enter a fixed
the ESP Link's hardware MAC address to a static IP address so it always gets the same IP the ESP Link's hardware MAC address to a static IP address so it always gets the same IP
address. This is the recommended method of operation.</p> address. This is the recommended method of operation.</p>
<h1>Using your ESP Serial Programmer</h1> <h2 class="content-subhead">Using your esp-link</h2>
The ESP Programmer can used in several distinct ways: <p>
The esp-link can used in several distinct ways:
<ul> <ul>
<li>as a transparent bridge between TCP port 23 and the serial port</li> <li>as a transparent bridge between TCP port 23 and the serial port</li>
<li>as a web console to see input from the serial port</li> <li>as a web console to see input from the serial port</li>
<li>as an Arduino, AVR, or ARM processor programmer using serial-over-TCP</li> <li>as an Arduino, AVR, or ARM processor programmer using serial-over-TCP</li>
<li>as an Arduino, AVR, or ARM processor programmer by uploading HEX files (not yet functional)</li> <li>as an Arduino, AVR, or ARM processor programmer by uploading HEX files (not yet functional)</li>
</ul> </ul>
</p>
<h2>Transparent bridge</h2> <h2 class="content-subhead">Transparent bridge</h2>
<p>The ESP accepts TCP connections to port 23 and "connects" through to the serial port. <p>The ESP accepts TCP connections to port 23 and "connects" through to the serial port.
Up to 5 simultaneous TCP connections are supported and characters coming in on the serial Up to 5 simultaneous TCP connections are supported and characters coming in on the serial
port get passed through to all connections. Characters coming in on a connection get copied port get passed through to all connections. Characters coming in on a connection get copied
through to the serial port.</p> through to the serial port.</p>
<p>When using Linux a simple way to use this is <tt>nc esp8266 23</tt></p> <p>When using Linux a simple way to use this is <tt>nc esp8266 23</tt></p>
<h2>Programmer using serial-over-TCP</h2> <h2 class="content-subhead">Programmer using serial-over-TCP</h2>
<p>By hooking up the ESP's GPIO lines to the reset line of an Arduino (or AVR in general) that is <p>By hooking up the ESP's GPIO lines to the reset line of an Arduino (or AVR in general) that is
preloaded with the Optiboot bootloader/flasher it is possible to reprogram these processors over preloaded with the Optiboot bootloader/flasher it is possible to reprogram these processors over
Wifi. The way is works is that the ESP toggles the reset line each time a connection is established Wifi. The way is works is that the ESP toggles the reset line each time a connection is established
@ -55,16 +60,21 @@ Serial Programmer (an IP address could have been used instead).</p>
ARM's reset and ISP lines. The ESP Serial Programmer issues the correct reset/isp pulses to put ARM's reset and ISP lines. The ESP Serial Programmer issues the correct reset/isp pulses to put
the ARM chip into firmware programming mode.</p> the ARM chip into firmware programming mode.</p>
<h2>Web Console</h2> <h2 class="content-subhead">Web Console</h2>
<p>The output of an attached Arduino/AVR/ARM can also be monitored via the console web page. <p>The output of an attached Arduino/AVR/ARM can also be monitored via the console web page.
When connecting, it shows the most recent 10KB of characters received on the serial port and When connecting, it shows the most recent 10KB of characters received on the serial port and
then continues to print everything that comes in on the serial port. Eventually the page refreshes then continues to print everything that comes in on the serial port. Eventually the page refreshes
when it gets very long. (Yes, this could be improved with some javascript...)</p> when it gets very long. (Yes, this could be improved with some javascript...)</p>
<h2>Programmer using HEX upload</h2> <h2 class="content-subhead">Programmer using HEX upload</h2>
<p><i>(Not yet functional)</i> Instead of using the wifi-to-serial bridge to program <p><i>(Not yet functional)</i> Instead of using the wifi-to-serial bridge to program
microcontrollers it is often faster to upload the HEX file to the ESP Serial Programmer and microcontrollers it is often faster to upload the HEX file to the ESP Serial Programmer and
have it perform the actual programming protocol.</p> have it perform the actual programming protocol.</p>
</div>
</div>
</div> </div>
<script src="ui.js"></script>
</body></html> </body></html>

@ -1,14 +1,17 @@
<html> %head%
<head><title>ESP Link</title>
<link rel="stylesheet" type="text/css" href="style.css"> <div id="main">
</head> <div class="header">
<body> <h1><span class="esp">esp</span> link</h1>
<div id="main"> </div>
<div id="topnav">%topnav%</div>
<h1><span class="esp">esp</span> link</h1> <div class="content">
<p> <p>The ESP Link connects the ESP's serial port to Wifi and it can
The ESP Link connects the ESP's serial port to Wifi and it can program microcontrollers over the serial port, in particular Arduinos, AVRs, and
program microcontrollers over the serial port, in particular Arduinos, AVRs, and NXP's LPC800-series ARM processors.</p>
NXP's LPC800-series ARM processors.</p> </div>
</div>
</div> </div>
<script src="ui.js"></script>
</body></html> </body></html>

@ -1,14 +1,19 @@
<html><head><title>Log - ESP Link</title> %head%
<link rel="stylesheet" type="text/css" href="style.css">
</head> <div id="main">
<body> <div class="header">
<div id="main"> <h1><span class="esp">esp</span> link - Debug Log</h1>
<div id="topnav">%topnav%</div> </div>
<h1><span class="esp">esp</span> link - Debug Log</h1>
<p>The debug log shows the 1024 last characters printed by the esp-link software itself to <div class="content">
its own debug log.</p> <p>The debug log shows the 1024 last characters printed by the esp-link software itself to
<pre class="console"> its own debug log.</p>
<pre class="console">
%log% %log%
</pre> </pre>
</div>
</div>
</div> </div>
<script src="ui.js"></script>
</body></html> </body></html>

11
html/pure-min.css vendored

File diff suppressed because one or more lines are too long

@ -1,46 +1,74 @@
/* All fonts */
html, button, input, select, textarea, .pure-g [class *= "pure-u"] {
font-family: sans-serif;
}
body { body {
background-color: #404040; color: #777;
font-family: sans-serif;
font-color: #663300;
} }
#main { /* make images size-up */
background-color: #FFFFCC; .xx-pure-img-responsive {
-moz-border-radius: 10px; max-width: 100%;
-webkit-border-radius: 10px; height: auto;
border-radius: 10px;
border: 2px solid #000000;
width: 800px;
margin: 0 auto;
padding: 20px
} }
h1 { /* Add transition to containers so they can push in and out */
margin-top: 0; #layout, #menu, .menu-link {
font-size: 36pt; -webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
} }
h1 .esp {
font-size: 48pt; /* This is the parent `<div>` that contains the menu and the content area */
#layout {
position: relative;
padding-left: 0;
}
#layout.active #menu {
left: 150px;
width: 150px;
} }
#topnav { #layout.active .menu-link {
background-color: #CC9966; left: 150px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
border: 0px solid #000000;
padding: 10px;
margin-left: auto;
margin-right: auto;
color: #ffff99;
} }
#topnav a {
color: #ffff99; /* The content `<div>` */
font-weight: bold; .content {
font-stretch: expanded; margin: 0 auto;
padding: 0 2em;
max-width: 800px;
margin-bottom: 50px;
line-height: 1.6em;
} }
.header {
margin: 0;
color: #333;
text-align: center;
padding: 2.5em 2em 0;
border-bottom: 1px solid #eee;
background-color: #fc0;
}
.header h1 {
margin: 0.2em 0;
font-size: 3em;
font-weight: 300;
}
.header h1 .esp {
font-size: 1.25em;
}
.content-subhead {
margin: 50px 0 20px 0;
font-weight: 300;
color: #888;
}
/* Text console */
pre.console { pre.console {
background-color: #663300; background-color: #663300;
-moz-border-radius: 5px; -moz-border-radius: 5px;
@ -62,3 +90,146 @@ pre.console a {
height: 32px; height: 32px;
display: inline-block; display: inline-block;
} }
/* The `#menu` `<div>` is the parent `<div>` that contains the `.pure-menu` that
* appears on the left side of the page */
#menu {
margin-left: -150px; /* "#menu" width */
width: 150px;
position: fixed;
top: 0;
left: 0;
bottom: 0;
z-index: 1000; /* so the menu or its navicon stays above all content */
background: #191818;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
/* All anchors inside the menu should be styled like this */
#menu a {
color: #999;
border: none;
padding: 0.6em 0 0.6em 0.6em;
}
/* Remove all background/borders, since we are applying them to #menu */
#menu .pure-menu, #menu .pure-menu ul {
border: none;
background: transparent;
}
/* Add that light border to separate items into groups */
#menu .pure-menu ul, #menu .pure-menu .menu-item-divided {
border-top: 1px solid #333;
}
/* Change color of the anchor links on hover/focus */
#menu .pure-menu li a:hover, #menu .pure-menu li a:focus {
background: #333;
}
/* This styles the selected menu item `<li>` */
#menu .pure-menu-selected, #menu .pure-menu-heading {
background: #c60;
}
/* This styles a link within a selected menu item `<li>` */
#menu .pure-menu-selected a {
color: #fff;
}
/* This styles the menu heading */
#menu .pure-menu-heading {
font-size: 110%;
color: #fff;
margin: 0;
}
#menu .pure-menu-item {
height:2em;
}
/* -- Dynamic Button For Responsive Menu -------------------------------------*/
/* `.menu-link` represents the responsive menu toggle that shows/hides on small screens */
.menu-link {
position: fixed;
display: block; /* show this only on small screens */
top: 0;
left: 0; /* "#menu width" */
background: #000;
background: rgba(0,0,0,0.7);
font-size: 10px; /* change this value to increase/decrease button size */
z-index: 10;
width: 2em;
height: auto;
padding: 2.1em 1.6em;
}
.menu-link:hover, .menu-link:focus {
background: #000;
}
.menu-link span {
position: relative;
display: block;
}
.menu-link span, .menu-link span:before, .menu-link span:after {
background-color: #fff;
width: 100%;
height: 0.2em;
}
.menu-link span:before, .menu-link span:after {
position: absolute;
margin-top: -0.6em;
content: " ";
}
.menu-link span:after {
margin-top: 0.6em;
}
/* -- Responsive Styles (Media Queries) ------------------------------------- */
/* Hides the menu at `48em`, but modify this based on your app's needs */
@media (min-width: 48em) {
.header, .content {
padding-left: 2em;
padding-right: 2em;
}
#layout {
padding-left: 150px; /* left col width "#menu" */
left: 0;
}
#menu {
left: 150px;
}
.menu-link {
position: fixed;
left: 150px;
display: none;
}
#layout.active .menu-link {
left: 150px;
}
}
@media (max-width: 48em) {
/* Only apply this when the window is small. Otherwise, the following
case results in extra padding on the left:
* Make the window small.
* Tap the menu to trigger the active state.
* Make the window large again.
*/
#layout.active {
position: relative;
left: 150px;
}
}

@ -0,0 +1,35 @@
(function (window, document) {
var layout = document.getElementById('layout'),
menu = document.getElementById('menu'),
menuLink = document.getElementById('menuLink');
function toggleClass(element, className) {
var classes = element.className.split(/\s+/),
length = classes.length,
i = 0;
for(; i < length; i++) {
if (classes[i] === className) {
classes.splice(i, 1);
break;
}
}
// The className is not found
if (length === classes.length) {
classes.push(className);
}
element.className = classes.join(' ');
}
menuLink.onclick = function (e) {
var active = 'active';
e.preventDefault();
toggleClass(layout, active);
toggleClass(menu, active);
toggleClass(menuLink, active);
};
}(this, this.document));

@ -1,97 +1,103 @@
<html><head><title>WiFi connection - ESP Link</title> %head%
<link rel="stylesheet" type="text/css" href="/style.css">
<script type="text/javascript" src="140medley.min.js"></script> <div id="main">
<div class="header">
<h1><span class="esp">esp</span> link - Wifi Configuration</h1>
</div>
<div class="content">
<h2 class="content-subhead">Current Wifi State</h2>
<p>
WiFi mode: %WiFiMode%<br>
Configured network: %currSsid% Status: %currStatus% Phy:%currPhy%
</p>
<p>%WiFiapwarn%</p>
<h2 class="content-subhead">Change Wifi association</h2>
<form name="wifiform" action="connect.cgi" method="post">
<p>To connect to a WiFi network, please select one of the detected networks,
enter the password, and hit the connect button...<p>
<div id="aps">Scanning...</div>
<p>WiFi password, if applicable: <br />
<input type="text" name="passwd" val="%WiFiPasswd%">
<input type="submit" name="connect" value="Connect!">
</p>
</form>
</div>
</div>
</div>
<script src="ui.js"></script>
<script src="140medley.min.js"></script>
<script type="text/javascript"> <script type="text/javascript">
var xhr=j(); var xhr=j();
var currAp="%currSsid%"; var currAp="%currSsid%";
function createInputForAp(ap) { function createInputForAp(ap) {
if (ap.essid=="" && ap.rssi==0) return; if (ap.essid=="" && ap.rssi==0) return;
var div=document.createElement("div"); var div=document.createElement("div");
div.id="apdiv"; div.id="apdiv";
var rssi=document.createElement("div"); var rssi=document.createElement("div");
var rssiVal=-Math.floor(ap.rssi/51)*32; var rssiVal=-Math.floor(ap.rssi/51)*32;
rssi.className="lock-icon"; rssi.className="lock-icon";
rssi.style.backgroundPosition="0px "+rssiVal+"px"; rssi.style.backgroundPosition="0px "+rssiVal+"px";
var encrypt=document.createElement("div"); var encrypt=document.createElement("div");
var encVal="-64"; //assume wpa/wpa2 var encVal="-64"; //assume wpa/wpa2
if (ap.enc=="0") encVal="0"; //open if (ap.enc=="0") encVal="0"; //open
if (ap.enc=="1") encVal="-32"; //wep if (ap.enc=="1") encVal="-32"; //wep
encrypt.className="lock-icon"; encrypt.className="lock-icon";
encrypt.style.backgroundPosition="-32px "+encVal+"px"; encrypt.style.backgroundPosition="-32px "+encVal+"px";
var input=document.createElement("input"); var input=document.createElement("input");
input.type="radio"; input.type="radio";
input.name="essid"; input.name="essid";
input.value=ap.essid; input.value=ap.essid;
if (currAp==ap.essid) input.checked="1"; if (currAp==ap.essid) input.checked="1";
input.id="opt-"+ap.essid; input.id="opt-"+ap.essid;
var label=document.createElement("label"); var label=document.createElement("label");
label.htmlFor="opt-"+ap.essid; label.htmlFor="opt-"+ap.essid;
label.textContent=ap.essid+" ("+ap.rssi+")"; label.textContent=ap.essid+" ("+ap.rssi+")";
div.appendChild(input); div.appendChild(input);
div.appendChild(rssi); div.appendChild(rssi);
div.appendChild(encrypt); div.appendChild(encrypt);
div.appendChild(label); div.appendChild(label);
return div; return div;
} }
function getSelectedEssid() { function getSelectedEssid() {
var e=document.forms.wifiform.elements; var e=document.forms.wifiform.elements;
for (var i=0; i<e.length; i++) { for (var i=0; i<e.length; i++) {
if (e[i].type=="radio" && e[i].checked) return e[i].value; if (e[i].type=="radio" && e[i].checked) return e[i].value;
} }
return currAp; return currAp;
} }
function scanAPs() { function scanAPs() {
xhr.open("GET", "wifiscan.cgi"); xhr.open("GET", "wifiscan.cgi");
xhr.onreadystatechange=function() { xhr.onreadystatechange=function() {
if (xhr.readyState==4 && xhr.status>=200 && xhr.status<300) { if (xhr.readyState==4 && xhr.status>=200 && xhr.status<300) {
var data=JSON.parse(xhr.responseText); var data=JSON.parse(xhr.responseText);
currAp=getSelectedEssid(); currAp=getSelectedEssid();
if (data.result.inProgress=="0" && data.result.APs.length>1) { if (data.result.inProgress=="0" && data.result.APs.length>1) {
$("#aps").innerHTML=""; $("#aps").innerHTML="";
for (var i=0; i<data.result.APs.length; i++) { for (var i=0; i<data.result.APs.length; i++) {
if (data.result.APs[i].essid=="" && data.result.APs[i].rssi==0) continue; if (data.result.APs[i].essid=="" && data.result.APs[i].rssi==0) continue;
$("#aps").appendChild(createInputForAp(data.result.APs[i])); $("#aps").appendChild(createInputForAp(data.result.APs[i]));
} }
window.setTimeout(scanAPs, 20000); window.setTimeout(scanAPs, 20000);
} else { } else {
window.setTimeout(scanAPs, 1000); window.setTimeout(scanAPs, 1000);
} }
} }
} }
xhr.send(); xhr.send();
} }
window.onload=function(e) { window.onload=function(e) {
scanAPs(); scanAPs();
}; };
</script> </script>
</head> </body></html>
<body>
<div id="main">
<div id="topnav">%topnav%</div>
<h1><span class="esp">esp</span> link - Wifi Configuration</h1>
<p>
Current WiFi mode: %WiFiMode%<br>
Current network: %currSsid% Status: %currStatus% Phy:%currPhy%
</p>
<p>
Note: %WiFiapwarn%
</p>
<form name="wifiform" action="connect.cgi" method="post">
<p>
To connect to a WiFi network, please select one of the detected networks...<br>
<div id="aps">Scanning...</div>
<br>
WiFi password, if applicable: <br />
<input type="text" name="passwd" val="%WiFiPasswd%"> <br />
<input type="submit" name="connect" value="Connect!">
</p>
</div>
</body>
</html>

@ -15,6 +15,7 @@ flash as a binary. Also handles the hit counter on the main page.
#include <esp8266.h> #include <esp8266.h>
#include "cgi.h" #include "cgi.h"
#include "espfs.h"
//cause I can't be bothered to write an ioGetLed() //cause I can't be bothered to write an ioGetLed()
@ -44,7 +45,7 @@ int ICACHE_FLASH_ATTR cgiLed(HttpdConnData *connData) {
//Template code for the led page. //Template code for the led page.
int ICACHE_FLASH_ATTR tplLed(HttpdConnData *connData, char *token, void **arg) { int ICACHE_FLASH_ATTR tplLed(HttpdConnData *connData, char *token, void **arg) {
char buff[128]; char buff[512];
if (token==NULL) return HTTPD_CGI_DONE; if (token==NULL) return HTTPD_CGI_DONE;
os_strcpy(buff, "Unknown"); os_strcpy(buff, "Unknown");
@ -65,13 +66,14 @@ static long hitCounter=0;
//Template code for the counter on the index page. //Template code for the counter on the index page.
int ICACHE_FLASH_ATTR tplCounter(HttpdConnData *connData, char *token, void **arg) { int ICACHE_FLASH_ATTR tplCounter(HttpdConnData *connData, char *token, void **arg) {
char buff[256]; char buff[64];
if (token==NULL) return HTTPD_CGI_DONE; if (token==NULL) return HTTPD_CGI_DONE;
if (printSysInfo(buff, token) > 0) { if (printSysInfo(buff, token) > 0) {
// awesome... // awesome...
} else if (os_strcmp(token, "topnav")==0) { } else if (os_strcmp(token, "head")==0) {
printNav(buff); printHead(connData);
buff[0] = 0;
} else if (os_strcmp(token, "counter")==0) { } else if (os_strcmp(token, "counter")==0) {
hitCounter++; hitCounter++;
os_sprintf(buff, "%ld", hitCounter); os_sprintf(buff, "%ld", hitCounter);
@ -82,7 +84,7 @@ int ICACHE_FLASH_ATTR tplCounter(HttpdConnData *connData, char *token, void **ar
static char *navLinks[][2] = { static char *navLinks[][2] = {
{ "Home", "/index.tpl" }, { "Wifi", "/wifi/wifi.tpl" }, { "\xC2\xB5""C Console", "/console.tpl" }, { "Home", "/index.tpl" }, { "Wifi", "/wifi/wifi.tpl" }, { "\xC2\xB5""C Console", "/console.tpl" },
{ "Esp log", "/log.tpl" }, { "Help", "/help.tpl" }, { "Debug log", "/log.tpl" }, { "Help", "/help.tpl" },
{ 0, 0 }, { 0, 0 },
}; };
@ -90,14 +92,48 @@ static char *navLinks[][2] = {
int ICACHE_FLASH_ATTR printNav(char *buff) { int ICACHE_FLASH_ATTR printNav(char *buff) {
int len = 0; int len = 0;
for (uint8_t i=0; navLinks[i][0] != NULL; i++) { for (uint8_t i=0; navLinks[i][0] != NULL; i++) {
if (i > 0) buff[len++] = '|';
//os_printf("nav %d: %s -> %s\n", i, navLinks[i][0], navLinks[i][1]); //os_printf("nav %d: %s -> %s\n", i, navLinks[i][0], navLinks[i][1]);
len += os_sprintf(buff+len, " <a href=\"%s\">%s</a> ", navLinks[i][1], navLinks[i][0]); len += os_sprintf(buff+len,
" <li class=\"pure-menu-item\"><a href=\"%s\" class=\"pure-menu-link\">%s</a></li>",
navLinks[i][1], navLinks[i][0]);
} }
//os_printf("nav: %s\n", buff); //os_printf("nav(%d): %s\n", len, buff);
return len; return len;
} }
void ICACHE_FLASH_ATTR printHead(HttpdConnData *connData) {
char buff[1024];
struct EspFsFile *file = espFsOpen("/head.tpl");
if (file == NULL) {
espFsClose(file);
os_printf("Header file 'head.tpl' not found\n");
return;
}
int len = espFsRead(file, buff, 1024);
if (len == 1024) {
os_printf("Header file 'head.tpl' too large!\n");
buff[1023] = 0;
} else {
buff[len] = 0; // ensure null termination
}
if (len > 0) {
char *p = os_strstr(buff, "%topnav%");
if (p != NULL) {
char navBuf[512];
int n = p - buff;
httpdSend(connData, buff, n);
printNav(navBuf);
httpdSend(connData, navBuf, -1);
httpdSend(connData, buff+n+8, len-n-8);
} else {
httpdSend(connData, buff, len);
}
}
}
#define TOKEN(x) (os_strcmp(token, x) == 0) #define TOKEN(x) (os_strcmp(token, x) == 0)
// Handle system information variables and print their value, returns the number of // Handle system information variables and print their value, returns the number of

@ -7,6 +7,7 @@ int cgiLed(HttpdConnData *connData);
int tplLed(HttpdConnData *connData, char *token, void **arg); int tplLed(HttpdConnData *connData, char *token, void **arg);
int tplCounter(HttpdConnData *connData, char *token, void **arg); int tplCounter(HttpdConnData *connData, char *token, void **arg);
int printNav(char *buff); int printNav(char *buff);
void ICACHE_FLASH_ATTR printHead(HttpdConnData *connData);
int ICACHE_FLASH_ATTR printSysInfo(char *buff, char *token); int ICACHE_FLASH_ATTR printSysInfo(char *buff, char *token);
#endif #endif

@ -406,8 +406,9 @@ int ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg)
os_strcpy(buff, "Click <a href=\"setmode.cgi?mode=1\">here</a> to go to STA mode."); os_strcpy(buff, "Click <a href=\"setmode.cgi?mode=1\">here</a> to go to STA mode.");
break; break;
} }
} else if (os_strcmp(token, "topnav")==0) { } else if (os_strcmp(token, "head")==0) {
printNav(buff); printHead(connData);
buff[0] = 0;
} }
httpdSend(connData, buff, -1); httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;

@ -39,7 +39,6 @@ console_write_char(char c) {
int ICACHE_FLASH_ATTR int ICACHE_FLASH_ATTR
tplConsole(HttpdConnData *connData, char *token, void **arg) { tplConsole(HttpdConnData *connData, char *token, void **arg) {
if (token==NULL) return HTTPD_CGI_DONE; if (token==NULL) return HTTPD_CGI_DONE;
char buff[256];
if (os_strcmp(token, "console") == 0) { if (os_strcmp(token, "console") == 0) {
if (console_wr > console_rd) { if (console_wr > console_rd) {
@ -48,9 +47,8 @@ tplConsole(HttpdConnData *connData, char *token, void **arg) {
httpdSend(connData, console_buf+console_rd, BUF_MAX-console_rd); httpdSend(connData, console_buf+console_rd, BUF_MAX-console_rd);
httpdSend(connData, console_buf, console_wr); httpdSend(connData, console_buf, console_wr);
} }
} else if (os_strcmp(token, "topnav")==0) { } else if (os_strcmp(token, "head")==0) {
printNav(buff); printHead(connData);
httpdSend(connData, buff, -1);
} else { } else {
httpdSend(connData, "Unknown\n", -1); httpdSend(connData, "Unknown\n", -1);
} }

@ -67,7 +67,6 @@ log_write_char(char c) {
int ICACHE_FLASH_ATTR int ICACHE_FLASH_ATTR
tplLog(HttpdConnData *connData, char *token, void **arg) { tplLog(HttpdConnData *connData, char *token, void **arg) {
if (token==NULL) return HTTPD_CGI_DONE; if (token==NULL) return HTTPD_CGI_DONE;
char buff[256];
if (os_strcmp(token, "log") == 0) { if (os_strcmp(token, "log") == 0) {
if (log_wr > log_rd) { if (log_wr > log_rd) {
@ -76,9 +75,8 @@ tplLog(HttpdConnData *connData, char *token, void **arg) {
httpdSend(connData, log_buf+log_rd, BUF_MAX-log_rd); httpdSend(connData, log_buf+log_rd, BUF_MAX-log_rd);
httpdSend(connData, log_buf, log_wr); httpdSend(connData, log_buf, log_wr);
} }
} else if (os_strcmp(token, "topnav")==0) { } else if (os_strcmp(token, "head")==0) {
printNav(buff); printHead(connData);
httpdSend(connData, buff, -1);
} else { } else {
httpdSend(connData, "Unknown\n", -1); httpdSend(connData, "Unknown\n", -1);
} }

Loading…
Cancel
Save