almost complete wifi page redesign
This commit is contained in:
@@ -1 +1 @@
|
||||
_test_env.php
|
||||
pages/_test_env.php
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'%term_title%' => 'ESP8266 Wireless Terminal',
|
||||
|
||||
'%b1%' => '1',
|
||||
'%b2%' => '2',
|
||||
'%b3%' => '3',
|
||||
'%b4%' => '4',
|
||||
'%b5%' => '5',
|
||||
'%screenData%' => '{
|
||||
"w": 26, "h": 10,
|
||||
"x": 0, "y": 0,
|
||||
"cv": 1,
|
||||
"screen": "70 t259"
|
||||
}',
|
||||
|
||||
'%ap_enable%' => '1',
|
||||
'%tpw%' => '60',
|
||||
'%ap_channel%' => '7',
|
||||
'%ap_ssid%' => 'ESP-123456',
|
||||
'%ap_password%' => 'Passw0rd!',
|
||||
'%ap_hidden%' => '0',
|
||||
'%sta_ssid%' => 'LibraryFreeWifi',
|
||||
'%sta_password%' => 'windows XP is The Best',
|
||||
'%sta_active_ip%' => '',
|
||||
|
||||
'%sta_enable%' => '0',
|
||||
];
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
define("ESP_IP", "192.168.0.19");
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
$pages = [];
|
||||
|
||||
/** Add a page */
|
||||
function pg($key, $bc, $path) {
|
||||
global $pages;
|
||||
$pages[$key] = (object) [
|
||||
'bodyclass' => $bc,
|
||||
'path' => $path,
|
||||
'label' => tr("menu.$key"),
|
||||
];
|
||||
}
|
||||
|
||||
pg('cfg_wifi', 'cfg', '/cfg/wifi');
|
||||
pg('cfg_network', 'cfg', '/cfg/network');
|
||||
pg('cfg_term', 'cfg', '/cfg/term');
|
||||
pg('about', 'cfg', '/about');
|
||||
pg('help', 'cfg', '/help');
|
||||
pg('term', 'term', '/');
|
||||
|
||||
// technical
|
||||
pg('wifi_set', '', '/cfg/wifi/set');
|
||||
|
||||
return $pages;
|
||||
@@ -1,144 +0,0 @@
|
||||
<?php
|
||||
|
||||
require '_test_env.php';
|
||||
|
||||
$prod = defined('STDIN');
|
||||
$root = $prod ? '' : ('http://' . ESP_IP);
|
||||
|
||||
$menu = [
|
||||
'home' => [ $prod ? '/status' : '/page_status.php', 'Home' ],
|
||||
'wifi' => [ $prod ? '/wifi' : '/page_wifi.php', 'WiFi config' ],
|
||||
'about' => [ $prod ? '/about' : '/page_about.php', 'About' ],
|
||||
];
|
||||
|
||||
$appname = 'Current Analyser';
|
||||
|
||||
function e($s) {
|
||||
return htmlspecialchars($s, ENT_HTML5|ENT_QUOTES);
|
||||
}
|
||||
|
||||
?><!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<title><?= e($menu[$page][1]) ?> - <?= e($appname) ?></title>
|
||||
|
||||
<link href="/css/app.css" rel="stylesheet">
|
||||
<script src="/js/all.js"></script>
|
||||
<script>
|
||||
// server root (or URL) - used for local development with remote AJAX calls
|
||||
// (this needs CORS working on the target - which I added to esp-httpd)
|
||||
var _root = <?= json_encode($root) ?>;
|
||||
</script>
|
||||
</head>
|
||||
<body class="page-<?=$page?>">
|
||||
<div id="outer">
|
||||
<nav id="menu">
|
||||
<div id="brand" onclick="$('#menu').toggleClass('expanded')"><?= e($appname) ?></div>
|
||||
<?php
|
||||
// generate the menu
|
||||
foreach($menu as $k => $m) {
|
||||
$sel = ($page == $k) ? ' class="selected"' : '';
|
||||
$text = e($m[1]);
|
||||
$url = e($m[0]);
|
||||
echo "<a href=\"$url\"$sel>$text</a>";
|
||||
}
|
||||
?>
|
||||
</nav>
|
||||
<div id="content">
|
||||
<img src="/img/loader.gif" alt="Loading…" id="loader">
|
||||
|
||||
|
||||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,shrink-to-fit=no,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
|
||||
|
||||
<title>WiFi Settings - ESP8266 Remote Terminal</title>
|
||||
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
<script src="/js/app.js"></script>
|
||||
</head>
|
||||
<body class="page-wifi">
|
||||
|
||||
<img src="/img/loader.gif" alt="Loading…" id="loader">
|
||||
|
||||
<h1 onclick="location.href='/'">WiFi settings</h1>
|
||||
|
||||
<div class="Box" id="wificonfbox">
|
||||
<table>
|
||||
<tr>
|
||||
<th>WiFi mode</th>
|
||||
<td id="opmodebox">%WiFiMode%</td>
|
||||
</tr>
|
||||
<tr class="x-hide-noip x-hide-2">
|
||||
<th>IP</th>
|
||||
<td>%StaIP%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Switch to</th>
|
||||
<td id="modeswitch"></td>
|
||||
</tr>
|
||||
<tr class="x-hide-1">
|
||||
<th><label for="channel">AP channel</label></th>
|
||||
<td>
|
||||
<form action="/wifi/setchannel" method="GET">
|
||||
<input name="ch" id="channel" type="number" step=1 min=1 max=14 value="%WiFiChannel%"><!--
|
||||
--><input type="submit" value="Set" class="narrow btn-green x-hide-3">
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="x-hide-1">
|
||||
<th><label for="channel">AP name</label></th>
|
||||
<td>
|
||||
<form action="/wifi/setname" method="GET">
|
||||
<input name="name" type="text" value="%APName%"><!--
|
||||
--><input type="submit" value="Set" class="narrow btn-green">
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan=2 style="white-space: normal;">
|
||||
<p>Some changes require a reboot, dropping connection. It can take a while to re-connect.</p>
|
||||
<p>
|
||||
<b>If you lose access</b>, hold the BOOT button for 2 seconds (the Tx LED starts blinking) to re-enable AP mode.
|
||||
If that fails, hold the BOOT button for over 5 seconds (rapid Tx LED flashing) to perform a factory reset.
|
||||
<p>
|
||||
</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="Box" id="ap-box">
|
||||
<h2>Select AP to join</h2>
|
||||
<div id="ap-loader" class="x-hide-2">Scanning<span class="anim-dots">.</span></div>
|
||||
<div id="ap-noscan" class="x-hide-1 x-hide-3">Can't scan in AP-only mode.</div>
|
||||
<div id="ap-list" style="display:none"></div>
|
||||
</div>
|
||||
|
||||
<nav id="botnav">
|
||||
<a href="/">Terminal</a><!--
|
||||
--><a href="/help">Help</a><!--
|
||||
--><a href="/about">About</a>
|
||||
</nav>
|
||||
|
||||
<div class="Modal hidden" id="psk-modal">
|
||||
<div class="Dialog">
|
||||
<form action="/wifi/connect" method="post" id="conn-form">
|
||||
<input type="hidden" id="conn-essid" name="essid"><!--
|
||||
--><label for="conn-passwd">Password:</label><!--
|
||||
--><input type="password" id="conn-passwd" name="passwd"><!--
|
||||
--><input type="submit" value="Connect!">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
_root = window.location.host;
|
||||
wifiInit({staSSID: '%StaSSID%', staIP: '%StaIP%', mode: '%WiFiModeNum%'});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+469
-195
@@ -1,3 +1,4 @@
|
||||
@charset "UTF-8";
|
||||
/* normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
|
||||
/**
|
||||
* 1. Set default font family to sans-serif.
|
||||
@@ -313,12 +314,219 @@ html {
|
||||
*, *::after, *::before {
|
||||
box-sizing: inherit; }
|
||||
|
||||
html {
|
||||
font-family: Arial, sans-serif;
|
||||
color: #D0D0D0;
|
||||
background: #131315; }
|
||||
|
||||
html, body {
|
||||
border: 0 none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden; }
|
||||
|
||||
a, a:visited, a:link {
|
||||
cursor: pointer;
|
||||
color: #5abfff;
|
||||
text-decoration: none; }
|
||||
|
||||
a:hover {
|
||||
color: #5abfff;
|
||||
text-decoration: underline; }
|
||||
|
||||
.hidden {
|
||||
display: none !important; }
|
||||
|
||||
[onclick] {
|
||||
cursor: pointer; }
|
||||
|
||||
/* Main outer container */
|
||||
#outer {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
flex-direction: row; }
|
||||
|
||||
@media screen and (max-width: 544px) {
|
||||
#outer {
|
||||
display: block;
|
||||
overflow-y: scroll; } }
|
||||
#menu {
|
||||
flex: 0 0 15rem;
|
||||
background: #3983CD; }
|
||||
#menu > * {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
padding: 0.61805rem 1rem;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none; }
|
||||
#menu #brand {
|
||||
color: white;
|
||||
background: #2b6aa8;
|
||||
font-size: 120%;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
transition: none;
|
||||
font-weight: bold;
|
||||
margin-bottom: 1rem; }
|
||||
@media screen and (max-width: 544px) {
|
||||
#menu #brand {
|
||||
background: #3983CD;
|
||||
cursor: pointer;
|
||||
margin-bottom: 0.38198rem; }
|
||||
#menu #brand::after {
|
||||
position: absolute;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
right: 1rem;
|
||||
content: '▸';
|
||||
top: 50%;
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
transform: translate(0, -50%) rotate(90deg); } }
|
||||
#menu.expanded #brand {
|
||||
background: #2b6aa8; }
|
||||
@media screen and (max-width: 544px) {
|
||||
#menu.expanded #brand:after {
|
||||
transform: translate(-25%, -50%) rotate(-90deg); } }
|
||||
#menu a {
|
||||
font-size: 130%;
|
||||
color: white;
|
||||
transition: background-color 0.2s;
|
||||
text-shadow: 0 0 5px rgba(0, 0, 0, 0.4); }
|
||||
#menu a:hover, #menu a.selected {
|
||||
background: #5badff;
|
||||
text-shadow: 0 0 5px rgba(0, 0, 0, 0.6); }
|
||||
#menu a.selected {
|
||||
position: relative;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); }
|
||||
#menu a::before {
|
||||
content: "▸";
|
||||
padding-right: .5rem;
|
||||
position: relative;
|
||||
top: -0.1rem; }
|
||||
@media screen and (max-width: 544px) {
|
||||
#menu a {
|
||||
display: none; } }
|
||||
#menu.expanded a {
|
||||
display: block; }
|
||||
@media screen and (min-width: 545px) and (max-width: 1000px) {
|
||||
#menu {
|
||||
flex-basis: 10rem; }
|
||||
#menu #brand {
|
||||
font-size: 95%;
|
||||
margin-bottom: 0.61805rem; }
|
||||
#menu a {
|
||||
font-size: 105%; }
|
||||
#menu > * {
|
||||
padding: 0.38198rem 0.61805rem; } }
|
||||
|
||||
#content {
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
padding: 1rem;
|
||||
overflow-y: auto; }
|
||||
@media screen and (max-width: 544px) {
|
||||
#content {
|
||||
padding: 0.61805rem; } }
|
||||
#content > * {
|
||||
margin-left: auto;
|
||||
margin-right: auto; }
|
||||
#content h1 {
|
||||
text-align: center;
|
||||
font-size: 2.2807em;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem; }
|
||||
@media screen and (max-width: 544px) {
|
||||
#content h1 {
|
||||
font-size: 1.80203em;
|
||||
margin-bottom: 0.61805rem; } }
|
||||
#content h2 {
|
||||
font-size: 1.42383em;
|
||||
margin-bottom: 0.61805rem; }
|
||||
#content td, #content th {
|
||||
padding: 0.38198rem; }
|
||||
#content tbody th {
|
||||
text-align: right;
|
||||
width: 160px;
|
||||
color: white; }
|
||||
|
||||
#loader {
|
||||
position: absolute;
|
||||
right: 1.618rem;
|
||||
top: 1.618rem;
|
||||
transition: opacity .2s;
|
||||
opacity: 0; }
|
||||
@media screen and (max-width: 544px) {
|
||||
#loader {
|
||||
top: 1rem;
|
||||
right: 1rem; } }
|
||||
#loader.show {
|
||||
opacity: 1; }
|
||||
|
||||
.Box {
|
||||
display: block;
|
||||
max-width: 900px;
|
||||
margin-top: 1rem;
|
||||
padding: 0.61805rem 1rem;
|
||||
border-radius: 3px;
|
||||
background-color: rgba(255, 255, 255, 0.07); }
|
||||
@media screen and (max-width: 544px) {
|
||||
.Box {
|
||||
margin-top: 0.61805rem; } }
|
||||
h1 + .Box {
|
||||
margin-top: 0; }
|
||||
.Box h2 {
|
||||
margin-top: 0; }
|
||||
.Box.wide {
|
||||
width: initial;
|
||||
max-width: initial; }
|
||||
.Box.medium {
|
||||
max-width: 1200px; }
|
||||
.Box.str {
|
||||
position: relative; }
|
||||
.Box.str .Row.buttons {
|
||||
position: absolute;
|
||||
right: 1rem;
|
||||
top: 2.7em;
|
||||
margin: 12px auto; }
|
||||
@media screen and (min-width: 545px) {
|
||||
.Box.str .Row.buttons {
|
||||
right: 0;
|
||||
top: 0; } }
|
||||
|
||||
@media screen and (max-width: 544px) {
|
||||
.Box.mobcol h2 {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
margin-bottom: 0 !important; }
|
||||
.Box.mobcol h2::after {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
content: '▸';
|
||||
top: 50%;
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
transform: translate(0, -50%) rotate(90deg); }
|
||||
.Box.mobcol.expanded h2::after {
|
||||
transform: translate(-25%, -50%) rotate(-90deg);
|
||||
margin-bottom: 1rem; }
|
||||
.Box.mobcol .Row {
|
||||
display: none; }
|
||||
.Box.mobcol.expanded .Row {
|
||||
display: flex; } }
|
||||
.Modal {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
@@ -355,161 +563,35 @@ html {
|
||||
.Dialog p:last-child {
|
||||
margin-bottom: 0; }
|
||||
|
||||
/*
|
||||
// "toast"
|
||||
.NotifyMsg {
|
||||
position: fixed;
|
||||
bottom: dist(2);
|
||||
padding: dist(-1) dist(0);
|
||||
|
||||
// center horizontally
|
||||
left: 50%;
|
||||
@include translate(-50%,0);
|
||||
// hack to remove blur in chrome
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
-webkit-transform: translateZ(0) scale(1.0, 1.0);
|
||||
|
||||
background: #37a349;
|
||||
&.error {
|
||||
background: #d03e42;
|
||||
}
|
||||
|
||||
color: white;
|
||||
text-shadow: 0 0 2px black;
|
||||
box-shadow: 0 0 6px 0 rgba(black, .6);
|
||||
border-radius: 5px;
|
||||
|
||||
max-width: 80%;
|
||||
|
||||
@include media($phone) {
|
||||
width: calc(100% - 1rem);
|
||||
}
|
||||
|
||||
transition: opacity .5s;
|
||||
opacity: 0;
|
||||
&.visible { opacity: 1 }
|
||||
&.hidden { display: none }
|
||||
}
|
||||
*/
|
||||
html {
|
||||
font-family: Arial, sans-serif;
|
||||
color: #D0D0D0;
|
||||
background: #131315; }
|
||||
|
||||
html, body {
|
||||
border: 0 none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden; }
|
||||
|
||||
a, a:visited, a:link {
|
||||
cursor: pointer;
|
||||
color: #5abfff;
|
||||
text-decoration: none; }
|
||||
|
||||
a:hover {
|
||||
color: #5abfff;
|
||||
text-decoration: underline; }
|
||||
|
||||
.Box {
|
||||
display: block;
|
||||
max-width: 900px;
|
||||
margin-top: 1rem;
|
||||
position: fixed;
|
||||
bottom: 2.61792rem;
|
||||
padding: 0.61805rem 1rem;
|
||||
border-radius: 3px;
|
||||
background-color: rgba(255, 255, 255, 0.07); }
|
||||
@media screen and (max-width: 544px) {
|
||||
.Box {
|
||||
margin-top: 0.61805rem;
|
||||
padding: 0.23608rem 0.38198rem; } }
|
||||
.Box p:first-child {
|
||||
margin-top: 0; }
|
||||
|
||||
body {
|
||||
position: relative;
|
||||
padding: 1rem;
|
||||
overflow-y: auto; }
|
||||
@media screen and (max-width: 544px) {
|
||||
body {
|
||||
padding: 0.61805rem; } }
|
||||
body > * {
|
||||
margin-left: auto;
|
||||
margin-right: auto; }
|
||||
|
||||
h1, h2 {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none; }
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 2.02729em;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem; }
|
||||
@media screen and (max-width: 544px) {
|
||||
h1 {
|
||||
font-size: 1.42383em;
|
||||
margin-bottom: 0.61805rem; } }
|
||||
@media screen and (min-width: 545px) and (max-width: 1000px) {
|
||||
h1 {
|
||||
font-size: 1.80203em; } }
|
||||
|
||||
h2 {
|
||||
font-size: 1.26563em;
|
||||
margin-bottom: 0.61805rem; }
|
||||
|
||||
td, th {
|
||||
padding: 0.38198rem;
|
||||
white-space: nowrap; }
|
||||
@media screen and (max-width: 544px) {
|
||||
td, th {
|
||||
padding: 0.23608rem; } }
|
||||
|
||||
tbody th {
|
||||
text-align: right;
|
||||
width: 130px;
|
||||
color: white; }
|
||||
@media screen and (max-width: 544px) {
|
||||
tbody th {
|
||||
width: auto; } }
|
||||
|
||||
tbody td input[type="text"], tbody td input[type="number"] {
|
||||
width: 10em; }
|
||||
@media screen and (max-width: 544px) {
|
||||
tbody td input[type="text"], tbody td input[type="number"] {
|
||||
width: 8em; } }
|
||||
|
||||
#loader {
|
||||
position: absolute;
|
||||
right: 1.618rem;
|
||||
top: 1.618rem;
|
||||
transition: opacity .2s;
|
||||
left: 50%;
|
||||
-webkit-transform: translate(-50%, 0);
|
||||
-moz-transform: translate(-50%, 0);
|
||||
-ms-transform: translate(-50%, 0);
|
||||
-o-transform: translate(-50%, 0);
|
||||
transform: translate(-50%, 0);
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
-webkit-transform: translateZ(0) scale(1, 1);
|
||||
background: #37a349;
|
||||
color: white;
|
||||
text-shadow: 0 0 2px black;
|
||||
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.6);
|
||||
border-radius: 5px;
|
||||
max-width: 80%;
|
||||
transition: opacity .5s;
|
||||
opacity: 0; }
|
||||
.NotifyMsg.error {
|
||||
background: #d03e42; }
|
||||
@media screen and (max-width: 544px) {
|
||||
#loader {
|
||||
top: 1rem;
|
||||
right: 1rem; } }
|
||||
#loader.show {
|
||||
.NotifyMsg {
|
||||
width: calc(100% - 1rem); } }
|
||||
.NotifyMsg.visible {
|
||||
opacity: 1; }
|
||||
|
||||
ul > * {
|
||||
padding-top: .1em;
|
||||
padding-bottom: .1em; }
|
||||
|
||||
#botnav {
|
||||
padding-top: 1.5em;
|
||||
text-align: center; }
|
||||
#botnav a {
|
||||
padding: 0 0.38198rem;
|
||||
text-decoration: underline; }
|
||||
#botnav a, #botnav a:visited, #botnav a:link {
|
||||
color: #2e4d6e; }
|
||||
#botnav a:hover {
|
||||
color: #5abfff; }
|
||||
.NotifyMsg.hidden {
|
||||
display: none; }
|
||||
|
||||
button, input[type=submit], .button {
|
||||
text-align: center;
|
||||
@@ -583,8 +665,8 @@ button, input[type=submit], .button {
|
||||
|
||||
input[type="number"], input[type="password"], input[type="text"], textarea, select {
|
||||
border: 0 none;
|
||||
border-bottom: 2px solid #214e7a;
|
||||
background-color: #303030;
|
||||
border-bottom: 2px solid #2972ba;
|
||||
background-color: #3c3c3c;
|
||||
color: white;
|
||||
padding: 6px;
|
||||
line-height: 1em;
|
||||
@@ -592,13 +674,154 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
|
||||
-moz-outline: 0 none !important;
|
||||
font-weight: normal; }
|
||||
input[type="number"]:focus, input[type="number"]:hover, input[type="password"]:focus, input[type="password"]:hover, input[type="text"]:focus, input[type="text"]:hover, textarea:focus, textarea:hover, select:focus, select:hover {
|
||||
border-bottom-color: #2972ba; }
|
||||
border-bottom-color: #2ea1f9; }
|
||||
|
||||
.Row.checkbox {
|
||||
line-height: 27px; }
|
||||
.Row.checkbox .box {
|
||||
width: 27px;
|
||||
height: 27px;
|
||||
border: 1px solid #808080;
|
||||
border-radius: 3px;
|
||||
background: #3c3c3c;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
color: #2ea1f9; }
|
||||
.Row.checkbox .box::before {
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
content: '×';
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
line-height: 26px;
|
||||
text-align: center;
|
||||
font-size: 27px;
|
||||
vertical-align: middle;
|
||||
display: none; }
|
||||
.Row.checkbox .box.checked::before {
|
||||
display: block; }
|
||||
|
||||
.Row.range .display {
|
||||
margin-left: 1ex; }
|
||||
.Row.range label .display {
|
||||
font-weight: normal; }
|
||||
|
||||
#psk-modal form > *, #wificonfbox form > * {
|
||||
margin-right: 0.38198rem; }
|
||||
#psk-modal form > *:last-child, #wificonfbox form > *:last-child {
|
||||
margin-right: 0; }
|
||||
|
||||
form {
|
||||
border: 0 none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-decoration: none; }
|
||||
|
||||
input[type="number"], input[type="password"], input[type="text"], textarea, select, label.select-wrap {
|
||||
width: 250px; }
|
||||
|
||||
input[type="number"] {
|
||||
width: 125px; }
|
||||
|
||||
form .Row {
|
||||
vertical-align: middle;
|
||||
margin: 12px auto;
|
||||
text-align: left;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center; }
|
||||
form .Row:first-child {
|
||||
margin-top: 0; }
|
||||
form .Row:last-child {
|
||||
margin-bottom: 0; }
|
||||
form .Row .spacer {
|
||||
width: 160px; }
|
||||
@media screen and (max-width: 544px) {
|
||||
form .Row .spacer {
|
||||
display: none; } }
|
||||
form .Row.buttons {
|
||||
margin: 16px auto; }
|
||||
form .Row.buttons input, form .Row.buttons .button {
|
||||
margin-right: 0.61805rem; }
|
||||
form .Row.centered {
|
||||
justify-content: center; }
|
||||
form .Row.message {
|
||||
font-size: 1em;
|
||||
text-shadow: 1px 1px 3px black;
|
||||
text-align: center; }
|
||||
form .Row.message.error {
|
||||
color: crimson; }
|
||||
form .Row.message.ok {
|
||||
color: #0fe851; }
|
||||
form .Row.separator {
|
||||
padding-top: 14px;
|
||||
border-top: 2px solid rgba(255, 255, 255, 0.1); }
|
||||
form .Row textarea {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
min-height: 10rem;
|
||||
flex-grow: 1;
|
||||
resize: vertical; }
|
||||
form .Row label {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
display: inline-block;
|
||||
width: 160px;
|
||||
text-align: right;
|
||||
text-shadow: 1px 1px 3px black;
|
||||
padding: 8px;
|
||||
align-self: flex-start;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal; }
|
||||
form .Row input[type="range"] {
|
||||
width: 200px; }
|
||||
@media screen and (max-width: 544px) {
|
||||
form .Row {
|
||||
flex-direction: column; }
|
||||
form .Row.buttons, form .Row.centered, form .Row.checkbox {
|
||||
flex-direction: row; }
|
||||
form .Row.buttons {
|
||||
justify-content: center; }
|
||||
form .Row.buttons :last-child {
|
||||
margin-right: 0; }
|
||||
form .Row label {
|
||||
padding-left: 0;
|
||||
text-align: left;
|
||||
width: auto; }
|
||||
form .Row .checkbox-wrap {
|
||||
order: 1;
|
||||
text-align: left;
|
||||
padding-bottom: 0;
|
||||
border-radius: .4px;
|
||||
width: auto; }
|
||||
form .Row .checkbox-wrap + label {
|
||||
width: auto; }
|
||||
form .Row input[type="number"], form .Row input[type="password"], form .Row input[type="text"], form .Row textarea, form .Row input[type="range"], form .Row textarea {
|
||||
width: 100%; } }
|
||||
|
||||
form span.required {
|
||||
color: red; }
|
||||
|
||||
.RadioGroup {
|
||||
display: inline-block;
|
||||
line-height: 1.5em;
|
||||
vertical-align: middle; }
|
||||
.RadioGroup label {
|
||||
width: auto;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
font-weight: normal; }
|
||||
.RadioGroup input[type="radio"] {
|
||||
vertical-align: middle;
|
||||
margin: 0 0 0 5px; }
|
||||
|
||||
#ap-list {
|
||||
column-count: 3;
|
||||
column-gap: 0;
|
||||
@@ -629,6 +852,40 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
|
||||
#psk-modal form input[type=password] {
|
||||
min-width: 5rem; }
|
||||
|
||||
.AP .inner, .AP-preview .wrap {
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
background: #afafaf;
|
||||
transition: background-color 0.5s;
|
||||
display: flex; }
|
||||
.AP .inner:active, .AP-preview .wrap:active {
|
||||
left: 0;
|
||||
top: 1px; }
|
||||
.AP .inner:hover, .AP-preview .wrap:hover {
|
||||
background: white; }
|
||||
.AP .inner .rssi, .AP-preview .wrap .rssi {
|
||||
min-width: 2.5rem;
|
||||
flex: 0 0 15%;
|
||||
text-align: right; }
|
||||
.AP .inner .rssi:after, .AP-preview .wrap .rssi:after {
|
||||
padding-left: 0.09018rem;
|
||||
content: '%';
|
||||
font-size: 0.88889em; }
|
||||
.AP .inner .essid, .AP-preview .wrap .essid {
|
||||
flex: 1 1 70%;
|
||||
min-width: 0;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
font-weight: bold; }
|
||||
.AP .inner .auth, .AP-preview .wrap .auth {
|
||||
flex: 0 0 15%; }
|
||||
|
||||
.AP {
|
||||
break-inside: avoid-column;
|
||||
max-width: 500px;
|
||||
@@ -637,50 +894,55 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
|
||||
background: #42a6f9 !important;
|
||||
cursor: default;
|
||||
top: 0 !important; }
|
||||
.AP .inner {
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
background: #afafaf;
|
||||
transition: background-color 0.5s;
|
||||
display: flex; }
|
||||
.AP .inner:active {
|
||||
left: 0;
|
||||
top: 1px; }
|
||||
.AP .inner:hover {
|
||||
background: white; }
|
||||
.AP .inner > * {
|
||||
.AP .inner > * {
|
||||
padding: 0.61805rem;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal; }
|
||||
|
||||
.AP-preview .wrap {
|
||||
flex-direction: row;
|
||||
background: #eee !important;
|
||||
cursor: default;
|
||||
top: 0 !important;
|
||||
overflow: hidden; }
|
||||
.AP-preview .wrap .inner {
|
||||
display: flex;
|
||||
flex-direction: column; }
|
||||
.AP-preview .wrap .inner > * {
|
||||
padding: 0.61805rem;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal; }
|
||||
.AP .inner .rssi {
|
||||
min-width: 2.5rem;
|
||||
flex: 0 0 15%;
|
||||
text-align: right; }
|
||||
.AP .inner .rssi:after {
|
||||
padding-left: 0.09018rem;
|
||||
content: '%';
|
||||
font-size: 0.88889em; }
|
||||
.AP .inner .essid {
|
||||
flex: 1 1 70%;
|
||||
min-width: 0;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
font-weight: bold; }
|
||||
.AP .inner .auth {
|
||||
flex: 0 0 15%; }
|
||||
.AP-preview .wrap .forget {
|
||||
align-self: stretch;
|
||||
line-height: 100%;
|
||||
padding: 0.61805rem;
|
||||
border-left: 1px solid #bbb;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28px; }
|
||||
.AP-preview .wrap .forget, .AP-preview .wrap .forget:hover {
|
||||
color: black;
|
||||
text-decoration: none; }
|
||||
.AP-preview .wrap .forget:hover {
|
||||
background: #dc4a6a;
|
||||
color: white;
|
||||
border-left: 1px solid #666;
|
||||
border-bottom-right-radius: 3px;
|
||||
border-top-right-radius: 3px; }
|
||||
.AP-preview .wrap .forget:active {
|
||||
position: relative;
|
||||
padding-top: calc(0.61805rem + 1px); }
|
||||
.AP-preview .wrap .essid, .AP-preview .wrap .passwd {
|
||||
padding-bottom: 0; }
|
||||
.AP-preview .wrap .passwd {
|
||||
font-family: monospace; }
|
||||
|
||||
.page-term h1 {
|
||||
body.term h1 {
|
||||
font-size: 1.80203em; }
|
||||
@media screen and (max-width: 544px) {
|
||||
.page-term h1 {
|
||||
body.term h1 {
|
||||
font-size: 1.42383em; } }
|
||||
.page-term #screen {
|
||||
body.term #screen {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
@@ -692,18 +954,18 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
|
||||
padding: 6px;
|
||||
display: inline-block;
|
||||
border: 2px solid #3983CD; }
|
||||
.page-term #screen span {
|
||||
body.term #screen span {
|
||||
white-space: pre;
|
||||
cursor: pointer; }
|
||||
.page-term #screen span:hover {
|
||||
body.term #screen span:hover {
|
||||
outline: 1px solid rgba(255, 255, 255, 0.4); }
|
||||
@media screen and (max-width: 544px) {
|
||||
.page-term #screen span:hover {
|
||||
body.term #screen span:hover {
|
||||
outline: 0 none; } }
|
||||
.page-term #buttons {
|
||||
body.term #buttons {
|
||||
margin-top: 10px;
|
||||
white-space: nowrap; }
|
||||
.page-term #buttons button {
|
||||
body.term #buttons button {
|
||||
margin: 0 3px;
|
||||
padding: 10px 0;
|
||||
width: 18%;
|
||||
@@ -711,6 +973,16 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
|
||||
min-width: initial;
|
||||
cursor: pointer;
|
||||
font-weight: bold; }
|
||||
body.term #botnav {
|
||||
padding-top: 1.5em;
|
||||
text-align: center; }
|
||||
body.term #botnav a {
|
||||
padding: 0 0.38198rem;
|
||||
text-decoration: underline; }
|
||||
body.term #botnav a, body.term #botnav a:visited, body.term #botnav a:link {
|
||||
color: #2e4d6e; }
|
||||
body.term #botnav a:hover {
|
||||
color: #5abfff; }
|
||||
|
||||
#termwrap {
|
||||
text-align: center; }
|
||||
@@ -866,3 +1138,5 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
|
||||
@media screen and (max-width: 1000px) {
|
||||
.mq-normal-min {
|
||||
display: none; } }
|
||||
|
||||
/*# sourceMappingURL=app.css.map */
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
require '_env.php';
|
||||
$prod = defined('STDIN');
|
||||
define ('DEBUG', !$prod);
|
||||
$root = DEBUG ? ESP_IP : '';
|
||||
define ('LIVE_ROOT', $root);
|
||||
|
||||
define('CUR_PAGE', $_GET['page'] ?: 'term');
|
||||
define('LOCALE', $_GET['locale'] ?: 'en');
|
||||
|
||||
$_messages = require(__DIR__ . '/messages/' . LOCALE . '.php');
|
||||
$_pages = require('_pages.php');
|
||||
|
||||
define('APP_NAME', 'ESPTerm');
|
||||
define('PAGE_TITLE', $_pages[CUR_PAGE]->label . ' :: ' . APP_NAME);
|
||||
define('BODYCLASS', $_pages[CUR_PAGE]->bodyclass);
|
||||
|
||||
/** URL (dev or production) */
|
||||
function url($name, $root=false) {
|
||||
global $_pages;
|
||||
if ($root) return LIVE_ROOT . $_pages[$name]->path;
|
||||
|
||||
if (DEBUG) return "/index.php?page=$name";
|
||||
else return $_pages[$name]->path;
|
||||
}
|
||||
|
||||
/** URL label for a button */
|
||||
function label($name) {
|
||||
global $_pages;
|
||||
return $_pages[$name]->label;
|
||||
}
|
||||
|
||||
function e($s) {
|
||||
return htmlspecialchars($s, ENT_HTML5|ENT_QUOTES);
|
||||
}
|
||||
|
||||
function tr($key) {
|
||||
global $_messages;
|
||||
return $_messages[$key] ?: ('??'.$key.'??');
|
||||
}
|
||||
|
||||
/** Like eval, but allows <?php and ?> */
|
||||
function include_str($code) {
|
||||
$tmp = tmpfile();
|
||||
$tmpf = stream_get_meta_data($tmp);
|
||||
$tmpf = $tmpf ['uri'];
|
||||
fwrite($tmp, $code);
|
||||
$ret = include($tmpf);
|
||||
fclose($tmp);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
require 'pages/_head.php';
|
||||
$_pf = 'pages/'.CUR_PAGE.'.php';
|
||||
if (file_exists($_pf)) {
|
||||
$f = file_get_contents($_pf);
|
||||
$reps = require('_debug_replacements.php');
|
||||
$str = str_replace(array_keys($reps), array_values($reps), $f);
|
||||
include_str($str);
|
||||
} else {
|
||||
echo "404";
|
||||
}
|
||||
require 'pages/_tail.php';
|
||||
+20
-7
@@ -393,8 +393,9 @@
|
||||
return cb;
|
||||
};
|
||||
// Toggle class
|
||||
cb.toggleClass = function (classes) {
|
||||
classHelper(classes, 'toggle', nodes);
|
||||
cb.toggleClass = function (classes, set) {
|
||||
var method = ((typeof set === 'undefined') ? 'toggle' : (+set ? 'add' : 'remove'));
|
||||
classHelper(classes, method, nodes);
|
||||
return cb;
|
||||
};
|
||||
// Has class
|
||||
@@ -795,6 +796,18 @@ String.prototype.format = function () {
|
||||
return out;
|
||||
};
|
||||
|
||||
function e(str) {
|
||||
return String(str)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
function undef(x) {
|
||||
return typeof x == 'undefined';
|
||||
}
|
||||
/** Module for toggling a modal overlay */
|
||||
(function () {
|
||||
var modal = {};
|
||||
@@ -1088,7 +1101,7 @@ $._loader = function(vis) {
|
||||
console.warn("SOCKET CLOSED, code "+evt.code+". Reconnecting...");
|
||||
setTimeout(function() {
|
||||
init();
|
||||
}, 2000);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onMessage(evt) {
|
||||
@@ -1211,7 +1224,7 @@ $._loader = function(vis) {
|
||||
// clear the AP list
|
||||
var $list = $('#ap-list');
|
||||
// remove old APs
|
||||
$('.AP').remove();
|
||||
$('#ap-list .AP').remove();
|
||||
|
||||
$list.toggle(done);
|
||||
$('#ap-loader').toggle(!done);
|
||||
@@ -1309,9 +1322,9 @@ $._loader = function(vis) {
|
||||
}
|
||||
|
||||
$('#modeswitch').html([
|
||||
'<a class="button" href="/wifi/setmode?mode=3">Client+AP</a> <a class="button" href="/wifi/setmode?mode=2">AP only</a>',
|
||||
'<a class="button" href="/wifi/setmode?mode=3">Client+AP</a>',
|
||||
'<a class="button" href="/wifi/setmode?mode=1">Client only</a> <a class="button" href="/wifi/setmode?mode=2">AP only</a>'
|
||||
'<a class="button" href="/wifi/set?opmode=3">Client+AP</a> <a class="button" href="/wifi/set?opmode=2">AP only</a>',
|
||||
'<a class="button" href="/wifi/set?opmode=3">Client+AP</a>',
|
||||
'<a class="button" href="/wifi/set?opmode=1">Client only</a> <a class="button" href="/wifi/set?opmode=2">AP only</a>'
|
||||
][obj.mode-1]);
|
||||
};
|
||||
|
||||
|
||||
@@ -393,8 +393,9 @@
|
||||
return cb;
|
||||
};
|
||||
// Toggle class
|
||||
cb.toggleClass = function (classes) {
|
||||
classHelper(classes, 'toggle', nodes);
|
||||
cb.toggleClass = function (classes, set) {
|
||||
var method = ((typeof set === 'undefined') ? 'toggle' : (+set ? 'add' : 'remove'));
|
||||
classHelper(classes, method, nodes);
|
||||
return cb;
|
||||
};
|
||||
// Has class
|
||||
|
||||
@@ -93,3 +93,15 @@ String.prototype.format = function () {
|
||||
return out;
|
||||
};
|
||||
|
||||
function e(str) {
|
||||
return String(str)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
function undef(x) {
|
||||
return typeof x == 'undefined';
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
// clear the AP list
|
||||
var $list = $('#ap-list');
|
||||
// remove old APs
|
||||
$('.AP').remove();
|
||||
$('#ap-list .AP').remove();
|
||||
|
||||
$list.toggle(done);
|
||||
$('#ap-loader').toggle(!done);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'appname' => 'ESPTerm',
|
||||
|
||||
'menu.cfg_wifi' => 'WiFi Settings',
|
||||
'menu.cfg_network' => 'Network Configuration',
|
||||
'menu.cfg_term' => 'Terminal Settings',
|
||||
'menu.about' => 'About ESPTerm',
|
||||
'menu.help' => 'Help',
|
||||
'menu.term' => 'Back to Terminal',
|
||||
|
||||
'box.ap' => 'Built-in Access Point',
|
||||
'box.sta' => 'Client Mode',
|
||||
|
||||
'wifi.enable' => 'Enabled:',
|
||||
'wifi.tpw' => 'Transmit Power:',
|
||||
'wifi.ap_channel' => 'Channel:',
|
||||
'wifi.ap_ssid' => 'AP SSID:',
|
||||
'wifi.ap_password' => 'Password:',
|
||||
'wifi.ap_hidden' => 'Hide SSID:',
|
||||
'wifi.sta_info' => 'Selected Network:',
|
||||
|
||||
'wifi.sta_ssid' => 'Network SSID:',
|
||||
'wifi.sta_password' => 'Password:',
|
||||
'wifi.not_conn' => 'Not connected.',
|
||||
'wifi.forget' => '',
|
||||
|
||||
'wifi.submit' => 'Apply!',
|
||||
|
||||
'enabled' => 'Enabled',
|
||||
'disabled' => 'Disabled',
|
||||
'yes' => 'Yes',
|
||||
'no' => 'No',
|
||||
];
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
<nav id="menu">
|
||||
<div id="brand" onclick="$('#menu').toggleClass('expanded')"><?= tr('appname') ?></div>
|
||||
<?php
|
||||
// generate the menu
|
||||
foreach($_pages as $k => $page) {
|
||||
if ($page->bodyclass !== 'cfg') continue;
|
||||
$sel = (CUR_PAGE == $k) ? ' class="selected"' : '';
|
||||
$text = $page->label;
|
||||
$url = e(url($k));
|
||||
echo "<a href=\"$url\"$sel>$text</a>";
|
||||
}
|
||||
?><a href="<?= e(url('term')) ?>"><?= tr('menu.term') ?></a>
|
||||
|
||||
</nav>
|
||||
@@ -0,0 +1,26 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title><?= PAGE_TITLE ?></title>
|
||||
<link href="/css/app.css" rel="stylesheet">
|
||||
<script src="/js/app.js"></script>
|
||||
<script>var _root = <?= json_encode(LIVE_ROOT) ?>;</script>
|
||||
</head>
|
||||
<body class="<?= BODYCLASS ?>">
|
||||
<div id="outer">
|
||||
<?php
|
||||
$cfg = false;
|
||||
if ($_pages[CUR_PAGE]->bodyclass == 'cfg') {
|
||||
$cfg = true;
|
||||
require __DIR__ . '/_cfg_menu.php';
|
||||
}
|
||||
?>
|
||||
|
||||
<div id="content">
|
||||
<img src="/img/loader.gif" alt="Loading…" id="loader">
|
||||
<?php if ($cfg): ?>
|
||||
<h1><?= tr('menu.' . CUR_PAGE) ?></h1>
|
||||
<?php endif; ?>
|
||||
@@ -0,0 +1,5 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,123 @@
|
||||
<form class="Box str mobcol" action="<?= e(url('wifi_set')) ?>" method="POST">
|
||||
<h2><?= tr('box.ap') ?></h2>
|
||||
|
||||
<div class="Row checkbox">
|
||||
<label><?= tr('wifi.enable') ?></label><!--
|
||||
--><span class="box"></span>
|
||||
<input type="hidden" name="ap_enable" value="%ap_enable%">
|
||||
</div>
|
||||
|
||||
<div class="Row">
|
||||
<label for="ap_ssid"><?= tr('wifi.ap_ssid') ?></label>
|
||||
<input type="text" name="ap_ssid" id="ap_ssid" value="%ap_ssid%" required>
|
||||
</div>
|
||||
|
||||
<div class="Row">
|
||||
<label for="ap_password"><?= tr('wifi.ap_password') ?></label>
|
||||
<input type="text" name="ap_password" id="ap_password" value="%ap_password%">
|
||||
</div>
|
||||
|
||||
<div class="Row">
|
||||
<label for="ap_channel"><?= tr('wifi.ap_channel') ?></label>
|
||||
<input type="number" name="ap_channel" id="ap_channel" min=1 max=14 value="%ap_channel%" required>
|
||||
</div>
|
||||
|
||||
<div class="Row range">
|
||||
<label for="tpw">
|
||||
<?= tr('wifi.tpw') ?>
|
||||
<span class="display x-disp1 mq-phone"></span>
|
||||
</label>
|
||||
<input type="range" name="tpw" id="tpw" step=1 min=0 max=82 value="%tpw%">
|
||||
<span class="display x-disp2 mq-tablet-min"></span>
|
||||
</div>
|
||||
|
||||
<div class="Row checkbox">
|
||||
<label><?= tr('wifi.ap_hidden') ?></label><!--
|
||||
--><span class="box"></span>
|
||||
<input type="hidden" name="ap_hidden" value="%ap_hidden%">
|
||||
</div>
|
||||
|
||||
<div class="Row buttons">
|
||||
<input type="submit" value="<?= tr('wifi.submit') ?>">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form class="Box str mobcol" action="<?= e(url('wifi_set')) ?>" method="POST">
|
||||
<h2><?= tr('box.sta') ?></h2>
|
||||
|
||||
<div class="Row checkbox">
|
||||
<label><?= tr('wifi.enable') ?></label><!--
|
||||
--><span class="box"></span>
|
||||
<input type="hidden" name="sta_enable" value="%sta_enable%">
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="sta_ssid" id="sta_ssid" value="%sta_ssid%">
|
||||
<input type="hidden" name="sta_password" id="sta_password" value="%sta_password%">
|
||||
|
||||
<div class="Row sta-info">
|
||||
<label><?= tr('wifi.sta_info') ?></label>
|
||||
<div class="AP-preview" id="sta-nw">
|
||||
<div class="wrap">
|
||||
<div class="inner">
|
||||
<div class="essid"></div>
|
||||
<div class="passwd"></div>
|
||||
<div class="ip"></div>
|
||||
</div>
|
||||
<a class="forget" id="forget-sta">×</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="Row buttons">
|
||||
<input type="submit" value="<?= tr('wifi.submit') ?>">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
$('.Row.checkbox').forEach(function(x) {
|
||||
var inp = x.querySelector('input');
|
||||
var box = x.querySelector('.box');
|
||||
|
||||
$(box).toggleClass('checked', inp.value);
|
||||
|
||||
$(x).on('click', function() {
|
||||
inp.value = 1 - inp.value;
|
||||
$(box).toggleClass('checked', inp.value)
|
||||
});
|
||||
});
|
||||
|
||||
$('.Box.mobcol').forEach(function(x) {
|
||||
var h = x.querySelector('h2');
|
||||
$(h).on('click', function() {
|
||||
$(x).toggleClass('expanded');
|
||||
});
|
||||
});
|
||||
|
||||
function rangePt(inp) {
|
||||
return Math.round(((inp.value / inp.max)*100)) + '%';
|
||||
}
|
||||
|
||||
$('.Row.range').forEach(function(x) {
|
||||
var inp = x.querySelector('input');
|
||||
var disp1 = x.querySelector('.x-disp1');
|
||||
var disp2 = x.querySelector('.x-disp2');
|
||||
var t = rangePt(inp);
|
||||
$(disp1).html(t);
|
||||
$(disp2).html(t);
|
||||
$(inp).on('input', function() {
|
||||
t = rangePt(inp);
|
||||
$(disp1).html(t);
|
||||
$(disp2).html(t);
|
||||
});
|
||||
});
|
||||
|
||||
function wifiShowSelected(name, password, ip) {
|
||||
$('#sta-nw .essid').html(e(name));
|
||||
var nopw = undef(password) || password.length == 0;
|
||||
$('#sta-nw .passwd').html(e(password)).toggleClass('hidden', nopw);
|
||||
$('#sta-nw .ip').html(ip.length>0 ? ip : '<?=tr('wifi.not_conn')?>');
|
||||
}
|
||||
|
||||
wifiShowSelected('%sta_ssid%', '%sta_password%', '%sta_active_ip%');
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,37 @@
|
||||
<script>
|
||||
// Workaround for badly loaded page
|
||||
setTimeout(function() {
|
||||
if (typeof termInit == 'undefined' || typeof $ == 'undefined') {
|
||||
location.reload(true);
|
||||
}
|
||||
}, 2000);
|
||||
</script>
|
||||
|
||||
<h1 onclick="location.href='<?= e(url('cfg_wifi_simple')) ?>'">%term_title%</h1>
|
||||
|
||||
<div id="termwrap">
|
||||
<div id="screen"></div>
|
||||
|
||||
<div id="buttons">
|
||||
<button data-n="1" class="btn-blue">%b1%</button><!--
|
||||
--><button data-n="2" class="btn-blue">%b2%</button><!--
|
||||
--><button data-n="3" class="btn-blue">%b3%</button><!--
|
||||
--><button data-n="4" class="btn-blue">%b4%</button><!--
|
||||
--><button data-n="5" class="btn-blue">%b5%</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav id="botnav">
|
||||
<a href="<?= url('cfg_wifi_simple') ?>"><?= tr('menu.cfg_wifi') ?></a><!--
|
||||
--><a href="<?= url('help') ?>">Help</a><!--
|
||||
--><a href="<?= url('about') ?>">About</a>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
try {
|
||||
termInit(%screenData%);
|
||||
} catch(e) {
|
||||
console.error("Fail, reloading...");
|
||||
location.reload(true);
|
||||
}
|
||||
</script>
|
||||
@@ -1,178 +0,0 @@
|
||||
html {
|
||||
font-family: Arial, sans-serif;
|
||||
color: #D0D0D0;
|
||||
background: #131315;
|
||||
}
|
||||
|
||||
html, body {
|
||||
@include naked();
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
a, a:visited, a:link {
|
||||
cursor: pointer;
|
||||
color: #5abfff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #5abfff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.Box {
|
||||
display: block;
|
||||
max-width: 900px;
|
||||
|
||||
margin-top: dist(0);
|
||||
padding: dist(-1) dist(0);
|
||||
|
||||
@include media($phone) {
|
||||
margin-top: dist(-1);
|
||||
padding: dist(-3) dist(-2);
|
||||
}
|
||||
//
|
||||
//h1 + & {
|
||||
// margin-top: 0;
|
||||
//}
|
||||
//
|
||||
//h2 {
|
||||
// margin-top: 0;
|
||||
//}
|
||||
|
||||
p:first-child {
|
||||
margin-top:0;
|
||||
}
|
||||
|
||||
border-radius: 3px;
|
||||
background-color: rgba(white, .07);
|
||||
|
||||
//&.wide {
|
||||
// width: initial;
|
||||
// max-width: initial;
|
||||
//}
|
||||
//
|
||||
//&.medium {
|
||||
// max-width: 1200px;
|
||||
//}
|
||||
//
|
||||
//.Valfield {
|
||||
// display: inline-block;
|
||||
// min-width: 10em;
|
||||
//}
|
||||
}
|
||||
|
||||
body {
|
||||
position: relative;
|
||||
|
||||
padding: dist(0);
|
||||
@include media($phone) {
|
||||
padding: dist(-1);
|
||||
}
|
||||
|
||||
overflow-y: auto;
|
||||
|
||||
& > * {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
h1,h2 {
|
||||
@include noselect();
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: fsize(6);
|
||||
margin-top: 0;
|
||||
margin-bottom: dist(0);
|
||||
|
||||
@include media($phone) {
|
||||
font-size: fsize(3);
|
||||
margin-bottom: dist(-1);
|
||||
}
|
||||
|
||||
@include media($tablet) {
|
||||
font-size: fsize(5);
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: fsize(2);
|
||||
margin-bottom: dist(-1);
|
||||
//&:first-child{margin-top:0}
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding: dist(-2);
|
||||
white-space: nowrap;
|
||||
|
||||
@include media($phone) {
|
||||
padding: dist(-3);
|
||||
}
|
||||
}
|
||||
|
||||
tbody th {
|
||||
text-align: right;
|
||||
width: $form-label-w;
|
||||
color: $c-form-label-fg;
|
||||
|
||||
@include media($phone) {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
tbody td {
|
||||
input[type="text"], input[type="number"] {
|
||||
width: 10em;
|
||||
|
||||
@include media($phone) {
|
||||
width: 8em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loader wheel in top right corner
|
||||
#loader {
|
||||
position: absolute;
|
||||
right: dist(1);
|
||||
top: dist(1);
|
||||
|
||||
transition: opacity .2s;
|
||||
opacity: 0;
|
||||
|
||||
@include media($phone) {
|
||||
top: dist(0);
|
||||
right: dist(0);
|
||||
}
|
||||
|
||||
&.show {
|
||||
opacity:1;
|
||||
}
|
||||
}
|
||||
|
||||
ul > * {
|
||||
padding-top: .1em;
|
||||
padding-bottom: .1em;
|
||||
}
|
||||
|
||||
#botnav {
|
||||
padding-top: 1.5em;
|
||||
text-align: center;
|
||||
|
||||
a {
|
||||
padding: 0 dist(-2);
|
||||
text-decoration: underline;
|
||||
|
||||
&, &:visited, &:link {
|
||||
color: #2e4d6e;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #5abfff;
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-14
@@ -6,15 +6,15 @@
|
||||
|
||||
@import "utils";
|
||||
|
||||
$form-label-w: 130px;
|
||||
$form-label-w: 160px;
|
||||
$form-label-gap: 8px;
|
||||
$form-field-w: 250px;
|
||||
|
||||
$c-form-label-fg: white;
|
||||
$c-form-field-bg: #303030;
|
||||
$c-form-field-bg: #3c3c3c;
|
||||
$c-form-field-fg: white;
|
||||
$c-form-highlight: #214e7a;
|
||||
$c-form-highlight-a: #2972ba;
|
||||
$c-form-highlight: #2972ba;
|
||||
$c-form-highlight-a: #2ea1f9;
|
||||
|
||||
@function dist($x) {
|
||||
@return modular-scale($x, 1rem, $golden);
|
||||
@@ -24,16 +24,7 @@ $c-form-highlight-a: #2972ba;
|
||||
@return modular-scale($x, 1em, $major-second);
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
[onclick] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@import "modal";
|
||||
@import "layout";
|
||||
@import "layout/index";
|
||||
@import "form/index";
|
||||
|
||||
// import all our pages
|
||||
|
||||
@@ -16,6 +16,47 @@
|
||||
}
|
||||
}
|
||||
|
||||
.Row.checkbox {
|
||||
$h: 27px;
|
||||
line-height: $h;
|
||||
|
||||
.box {
|
||||
width: $h;
|
||||
height: $h;
|
||||
border: 1px solid #808080;
|
||||
border-radius: 3px;
|
||||
background: $c-form-field-bg;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
color: $c-form-highlight-a;
|
||||
|
||||
&::before {
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
content: '×';
|
||||
left: 0; top: 0; right: 0; bottom: 0;
|
||||
line-height: $h - 1px;
|
||||
text-align: center;
|
||||
font-size: $h;
|
||||
vertical-align: middle;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.checked::before {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.Row.range {
|
||||
.display {
|
||||
margin-left: 1ex;
|
||||
}
|
||||
|
||||
label .display { font-weight: normal; }
|
||||
}
|
||||
|
||||
//#{$all-text-inputs} {
|
||||
// @include can-select();
|
||||
//}
|
||||
|
||||
@@ -5,13 +5,18 @@ form { @include naked(); }
|
||||
width: $form-field-w;
|
||||
}
|
||||
|
||||
input[type="number"] {
|
||||
width: $form-field-w/2;
|
||||
}
|
||||
|
||||
form .Row {
|
||||
vertical-align: middle;
|
||||
margin: 14px auto;
|
||||
margin: 12px auto;
|
||||
text-align: left;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
@@ -30,6 +35,7 @@ form .Row {
|
||||
}
|
||||
|
||||
&.buttons {
|
||||
margin: 16px auto;
|
||||
input, .button {
|
||||
margin-right: dist(-1);
|
||||
}
|
||||
@@ -80,34 +86,39 @@ form .Row {
|
||||
align-self: flex-start;
|
||||
|
||||
@include noselect;
|
||||
@include nowrap;
|
||||
}
|
||||
|
||||
.checkbox-wrap {
|
||||
display: inline-block;
|
||||
width: $form-label-w;
|
||||
padding: $form-label-gap;
|
||||
text-align: right;
|
||||
align-self: flex-start;
|
||||
//.checkbox-wrap {
|
||||
// display: inline-block;
|
||||
// width: $form-label-w;
|
||||
// padding: $form-label-gap;
|
||||
// text-align: right;
|
||||
// align-self: flex-start;
|
||||
//
|
||||
// input[type=checkbox] {
|
||||
// margin: auto;
|
||||
// width: auto;
|
||||
// height: auto;
|
||||
// }
|
||||
//
|
||||
// & + label {
|
||||
// width: $form-field-w;
|
||||
// padding-left: 0;
|
||||
// text-align: left;
|
||||
// cursor: pointer;
|
||||
// }
|
||||
//}
|
||||
|
||||
input[type=checkbox] {
|
||||
margin: auto;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
& + label {
|
||||
width: $form-field-w;
|
||||
padding-left: 0;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
input[type="range"] {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
// special phone style
|
||||
@include media($phone) {
|
||||
flex-direction: column;
|
||||
|
||||
&.buttons, &.centered {
|
||||
&.buttons, &.centered, &.checkbox {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
@@ -139,7 +150,7 @@ form .Row {
|
||||
}
|
||||
}
|
||||
|
||||
#{$all-text-inputs}, textarea {
|
||||
#{$all-text-inputs}, input[type="range"], textarea {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
}
|
||||
}
|
||||
|
||||
//@import 'form_layout';
|
||||
@import 'form_layout';
|
||||
//@import 'select';
|
||||
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
html {
|
||||
font-family: Arial, sans-serif;
|
||||
color: #D0D0D0;
|
||||
background: #131315;
|
||||
}
|
||||
|
||||
html, body {
|
||||
@include naked();
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
a, a:visited, a:link {
|
||||
cursor: pointer;
|
||||
color: #5abfff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #5abfff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
[onclick] {
|
||||
cursor: pointer;
|
||||
}
|
||||
Executable
+91
@@ -0,0 +1,91 @@
|
||||
.Box {
|
||||
display: block;
|
||||
max-width: 900px;
|
||||
|
||||
margin-top: dist(0);
|
||||
padding: dist(-1) dist(0);
|
||||
|
||||
@include media($phone) {
|
||||
margin-top: dist(-1);
|
||||
}
|
||||
|
||||
h1 + & {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
border-radius: 3px;
|
||||
background-color: rgba(white, .07);
|
||||
|
||||
&.wide {
|
||||
width: initial;
|
||||
max-width: initial;
|
||||
}
|
||||
|
||||
&.medium {
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
//.Valfield {
|
||||
// display: inline-block;
|
||||
// min-width: 10em;
|
||||
//}
|
||||
|
||||
&.str {
|
||||
position: relative;
|
||||
|
||||
.Row.buttons {
|
||||
position: absolute;
|
||||
right: dist(0);
|
||||
top: 2.7em;
|
||||
margin: 12px auto;
|
||||
}
|
||||
|
||||
@include media($tablet-min) {
|
||||
.Row.buttons {
|
||||
//position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
//margin: 12px auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media($phone) {
|
||||
.Box.mobcol {
|
||||
h2 {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
content: '▸';
|
||||
|
||||
top:50%;
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
transform: translate(0,-50%) rotate(90deg);
|
||||
}
|
||||
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
&.expanded h2::after {
|
||||
transform: translate(-25%,-50%) rotate(-90deg);
|
||||
margin-bottom: dist(0);
|
||||
}
|
||||
|
||||
.Row {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.expanded .Row {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#content {
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
|
||||
padding: dist(0);
|
||||
@include media($phone) {
|
||||
padding: dist(-1);
|
||||
}
|
||||
|
||||
overflow-y: auto;
|
||||
|
||||
& > * {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: fsize(7);
|
||||
margin-top: 0;
|
||||
margin-bottom: dist(0);
|
||||
}
|
||||
|
||||
@include media($phone) {
|
||||
h1 {
|
||||
font-size: fsize(5);
|
||||
margin-bottom: dist(-1);
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: fsize(3);
|
||||
margin-bottom: dist(-1);
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding: dist(-2);
|
||||
}
|
||||
|
||||
tbody th {
|
||||
text-align: right;
|
||||
width: $form-label-w;
|
||||
color: $c-form-label-fg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
|
||||
ul > * {
|
||||
padding-top: .1em;
|
||||
padding-bottom: .1em;
|
||||
}
|
||||
|
||||
h1,h2 {
|
||||
@include noselect();
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: fsize(6);
|
||||
margin-top: 0;
|
||||
margin-bottom: dist(0);
|
||||
|
||||
@include media($phone) {
|
||||
font-size: fsize(3);
|
||||
margin-bottom: dist(-1);
|
||||
}
|
||||
|
||||
@include media($tablet) {
|
||||
font-size: fsize(5);
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: fsize(2);
|
||||
margin-bottom: dist(-1);
|
||||
//&:first-child{margin-top:0}
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding: dist(-2);
|
||||
white-space: nowrap;
|
||||
|
||||
@include media($phone) {
|
||||
padding: dist(-3);
|
||||
}
|
||||
}
|
||||
|
||||
tbody th {
|
||||
text-align: right;
|
||||
width: $form-label-w;
|
||||
color: $c-form-label-fg;
|
||||
|
||||
@include media($phone) {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
tbody td {
|
||||
input[type="text"], input[type="number"] {
|
||||
width: 10em;
|
||||
|
||||
@include media($phone) {
|
||||
width: 8em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
position: relative;
|
||||
|
||||
padding: dist(0);
|
||||
@include media($phone) {
|
||||
padding: dist(-1);
|
||||
}
|
||||
|
||||
overflow-y: auto;
|
||||
|
||||
& > * {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
@import "base";
|
||||
|
||||
@import "outer-wrap";
|
||||
@import "menu";
|
||||
@import "content";
|
||||
@import "loader";
|
||||
|
||||
@import "box";
|
||||
@import "modal";
|
||||
@@ -0,0 +1,18 @@
|
||||
// Loader wheel in top right corner
|
||||
#loader {
|
||||
position: absolute;
|
||||
right: dist(1);
|
||||
top: dist(1);
|
||||
|
||||
transition: opacity .2s;
|
||||
opacity: 0;
|
||||
|
||||
@include media($phone) {
|
||||
top: dist(0);
|
||||
right: dist(0);
|
||||
}
|
||||
|
||||
&.show {
|
||||
opacity:1;
|
||||
}
|
||||
}
|
||||
Executable
+98
@@ -0,0 +1,98 @@
|
||||
#menu {
|
||||
$menu-bg: #3983CD;
|
||||
$menu-hl: #5badff; //#1bd886;
|
||||
$menu-fg: white;
|
||||
|
||||
flex: 0 0 15rem;
|
||||
background: $menu-bg;
|
||||
|
||||
& > * {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
padding: dist(-1) dist(0);
|
||||
|
||||
@include nowrap;
|
||||
@include noselect;
|
||||
}
|
||||
|
||||
#brand {
|
||||
color: $menu-fg;
|
||||
background: darken($menu-bg, 10%);
|
||||
font-size: 120%;
|
||||
text-align: center;
|
||||
position:relative;
|
||||
transition: none;
|
||||
font-weight: bold;
|
||||
|
||||
margin-bottom: dist(0);
|
||||
|
||||
@include media($phone) {
|
||||
background: $menu-bg;
|
||||
cursor: pointer;
|
||||
margin-bottom: dist(-2);
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
color: rgba(black, .4);
|
||||
right: dist(0);
|
||||
content: '▸';
|
||||
|
||||
top:50%;
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
transform: translate(0,-50%) rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
&.expanded #brand {
|
||||
background: darken($menu-bg, 10%);
|
||||
|
||||
@include media($phone) {
|
||||
&:after { transform: translate(-25%,-50%) rotate(-90deg) }
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
font-size: 130%;
|
||||
color: $menu-fg;
|
||||
|
||||
transition: background-color 0.2s;
|
||||
text-shadow: 0 0 5px rgba(black, .4);
|
||||
|
||||
&:hover, &.selected {
|
||||
background: $menu-hl;
|
||||
text-shadow: 0 0 5px rgba(black, .6);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
position: relative;
|
||||
box-shadow: 0 0 5px rgba(black, .5);
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "▸";
|
||||
padding-right: .5rem;
|
||||
position: relative;
|
||||
top: -0.1rem;
|
||||
}
|
||||
|
||||
@include media($phone) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.expanded a { display:block }
|
||||
|
||||
@include media($tablet) {
|
||||
#brand {
|
||||
font-size: 95%;
|
||||
margin-bottom: dist(-1);
|
||||
}
|
||||
|
||||
a { font-size: 105%; }
|
||||
|
||||
flex-basis: 10rem;
|
||||
|
||||
& > * { padding: dist(-2) dist(-1); }
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,8 @@
|
||||
//min-height: 15rem;
|
||||
|
||||
background: #1c1c1e;
|
||||
border-left: 6px solid $c-form-highlight-a;
|
||||
border-right: 6px solid $c-form-highlight-a;
|
||||
border-left: 6px solid $c-form-highlight;
|
||||
border-right: 6px solid $c-form-highlight;
|
||||
box-shadow: 0 0 2px 0 #434349, 0 0 6px 0 black;
|
||||
|
||||
border-radius: 6px;
|
||||
@@ -40,7 +40,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// "toast"
|
||||
.NotifyMsg {
|
||||
position: fixed;
|
||||
@@ -75,4 +74,3 @@
|
||||
&.visible { opacity: 1 }
|
||||
&.hidden { display: none }
|
||||
}
|
||||
*/
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
/* Main outer container */
|
||||
#outer {
|
||||
display: flex;
|
||||
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
@include media($phone) {
|
||||
#outer {
|
||||
display: block;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
.page-term {
|
||||
body.term {
|
||||
h1 {
|
||||
font-size: fsize(5);
|
||||
@include media($phone) {
|
||||
@@ -42,6 +42,24 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
#botnav {
|
||||
padding-top: 1.5em;
|
||||
text-align: center;
|
||||
|
||||
a {
|
||||
padding: 0 dist(-2);
|
||||
text-decoration: underline;
|
||||
|
||||
&, &:visited, &:link {
|
||||
color: #2e4d6e;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #5abfff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#termwrap {
|
||||
|
||||
@@ -43,6 +43,50 @@
|
||||
@extend %form-row-spacing;
|
||||
}
|
||||
|
||||
%ap-inner {
|
||||
cursor: pointer;
|
||||
@include noselect;
|
||||
|
||||
position: relative;
|
||||
&:active {
|
||||
left: 0;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
|
||||
background: #afafaf;
|
||||
transition: background-color 0.5s;
|
||||
&:hover { background: white }
|
||||
|
||||
display: flex;
|
||||
|
||||
.rssi {
|
||||
min-width: 2.5rem;
|
||||
flex: 0 0 15%;
|
||||
text-align: right;
|
||||
|
||||
&:after {
|
||||
padding-left: dist(-5);
|
||||
content: '%';
|
||||
font-size: fsize(-1);
|
||||
}
|
||||
}
|
||||
|
||||
.essid {
|
||||
flex: 1 1 70%;
|
||||
min-width: 0;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.auth {
|
||||
flex: 0 0 15%;
|
||||
}
|
||||
}
|
||||
|
||||
.AP {
|
||||
// can't use margins inside a column
|
||||
|
||||
@@ -56,53 +100,70 @@
|
||||
top: 0 !important; // no click effect
|
||||
}
|
||||
|
||||
// the actual silver box
|
||||
.inner {
|
||||
cursor: pointer;
|
||||
@include noselect;
|
||||
|
||||
position: relative;
|
||||
&:active {
|
||||
left: 0;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
|
||||
background: #afafaf;
|
||||
transition: background-color 0.5s;
|
||||
&:hover { background: white }
|
||||
|
||||
display: flex;
|
||||
@extend %ap-inner;
|
||||
|
||||
& > * {
|
||||
padding: dist(-1);
|
||||
@include nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rssi {
|
||||
min-width: 2.5rem;
|
||||
flex: 0 0 15%;
|
||||
text-align: right;
|
||||
.AP-preview {
|
||||
.wrap {
|
||||
@extend %ap-inner;
|
||||
|
||||
&:after {
|
||||
padding-left: dist(-5);
|
||||
content: '%';
|
||||
font-size: fsize(-1);
|
||||
flex-direction: row;
|
||||
background: #eee !important; // override the hover effect #43de81
|
||||
cursor: default;
|
||||
top: 0 !important; // no click effect
|
||||
overflow: hidden;
|
||||
|
||||
.inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
& > * {
|
||||
padding: dist(-1);
|
||||
@include nowrap;
|
||||
}
|
||||
}
|
||||
.forget {
|
||||
align-self: stretch;
|
||||
line-height: 100%;
|
||||
padding: dist(-1);
|
||||
border-left: 1px solid #bbb;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&, &:hover {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
font-size: 28px;
|
||||
|
||||
&:hover {
|
||||
background: #dc4a6a;
|
||||
color: white;
|
||||
border-left: 1px solid #666;
|
||||
border-bottom-right-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
|
||||
&:active {
|
||||
position: relative;
|
||||
padding-top: calc(#{dist(-1)} + 1px);
|
||||
}
|
||||
}
|
||||
|
||||
.essid {
|
||||
flex: 1 1 70%;
|
||||
min-width: 0;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
font-weight: bold;
|
||||
.essid, .passwd {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.auth {
|
||||
flex: 0 0 15%;
|
||||
.passwd {
|
||||
font-family: monospace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+68
@@ -0,0 +1,68 @@
|
||||
|
||||
// Utilities for background tiling
|
||||
|
||||
// Use a tile as background (w, h - size of time)
|
||||
@mixin tile_xy($w, $h, $x, $y) {
|
||||
background-position: (-$x*$w) (-$y*$h);
|
||||
}
|
||||
|
||||
|
||||
// Use a square tile as background (size - w & h of time)
|
||||
@mixin tile($size, $x, $y) {
|
||||
@include tile_xy($size, $size, $x, $y);
|
||||
}
|
||||
|
||||
|
||||
// Button with sprite-sheet
|
||||
// A B
|
||||
// B:hover B:hover
|
||||
@mixin tile_btn_h($w, $h, $x) {
|
||||
@include tile_xy($w, $h, $x, 0);
|
||||
&:hover {
|
||||
@include tile_xy($w, $h, $x, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// active the same as hover
|
||||
@mixin tile_btn_h_act($w, $h, $x) {
|
||||
@include tile_xy($w, $h, $x, 0);
|
||||
&:hover, &.active {
|
||||
@include tile_xy($w, $h, $x, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Button with sprite-sheet
|
||||
// A A:hover
|
||||
// B B:hover
|
||||
@mixin tile_btn_v($w, $h, $y) {
|
||||
@include tile_xy($w, $h, 0, $y);
|
||||
&:hover {
|
||||
@include tile_xy($w, $h, 1, $y);
|
||||
}
|
||||
}
|
||||
|
||||
// active the same as hover
|
||||
@mixin tile_btn_v_act($w, $h, $y) {
|
||||
@include tile_xy($w, $h, 0, $y);
|
||||
&:hover, &.active {
|
||||
@include tile_xy($w, $h, 1, $y);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin inset-shadow-top($w, $c) {
|
||||
box-shadow: inset 0 $w ($w*2) (-$w) $c;
|
||||
}
|
||||
|
||||
@mixin inset-shadow-bottom($w, $c) {
|
||||
box-shadow: inset 0 (-$w) ($w*2) (-$w) $c;
|
||||
}
|
||||
|
||||
@mixin inset-shadow-left($w, $c) {
|
||||
box-shadow: inset $w 0 ($w*2) (-$w) $c;
|
||||
}
|
||||
|
||||
@mixin inset-shadow-right($w, $c) {
|
||||
box-shadow: inset (-$w) 0 ($w*2) (-$w) $c;
|
||||
}
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
@import "background-tiling";
|
||||
@import "pointer";
|
||||
@import "misc";
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
// Add a highlight for debugging
|
||||
@mixin highlight($color) {
|
||||
outline: 1px solid $color;
|
||||
background: rgba($color, .05);
|
||||
box-shadow: 0 0 2px 2px rgba($color, .2), inset 0 0 2px 2px rgba($color, .2);
|
||||
}
|
||||
|
||||
// Ellipsis, but for block elements
|
||||
@mixin block-ellipsis($width: 100%) {
|
||||
display: block;
|
||||
max-width: $width;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
// No margins, padding, borders
|
||||
@mixin naked() {
|
||||
border: 0 none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@mixin translate($x, $y) {
|
||||
@include transform(translate($x, $y));
|
||||
}
|
||||
|
||||
// Disallow wrapping
|
||||
@mixin nowrap() {
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
}
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
|
||||
@mixin click-through() {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
// Disallow text selection
|
||||
@mixin noselect() {
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
// Allow text selection
|
||||
@mixin can-select() {
|
||||
-webkit-user-select: text;
|
||||
-khtml-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
|
||||
cursor: text;
|
||||
}
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
xterm -e "php -S localhost:2000"
|
||||
xterm -e "php -S 0.0.0.0:2000"
|
||||
|
||||
+107
-47
@@ -444,14 +444,38 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
}
|
||||
}
|
||||
|
||||
if (GET_ARG("ap_enable")) {
|
||||
dbg("Enable AP: %s", buff);
|
||||
int enable = atoi(buff);
|
||||
|
||||
if (enable) {
|
||||
wificonf->opmode |= SOFTAP_MODE;
|
||||
} else {
|
||||
wificonf->opmode &= ~SOFTAP_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
if (GET_ARG("sta_enable")) {
|
||||
dbg("Enable STA: %s", buff);
|
||||
int enable = atoi(buff);
|
||||
|
||||
if (enable) {
|
||||
wificonf->opmode |= STATION_MODE;
|
||||
} else {
|
||||
wificonf->opmode &= ~STATION_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- AP transmit power ----
|
||||
|
||||
if (GET_ARG("tpw")) {
|
||||
dbg("Setting AP power to: %s", buff);
|
||||
int tpw = atoi(buff);
|
||||
if (tpw >= 0 && tpw <= 82) { // 0 actually isn't 0 but quite low. 82 is very strong
|
||||
wificonf->tpw = (u8) tpw;
|
||||
wifi_change_flags.ap = true;
|
||||
if (wificonf->tpw != tpw) {
|
||||
wificonf->tpw = (u8) tpw;
|
||||
wifi_change_flags.ap = true;
|
||||
}
|
||||
} else {
|
||||
warn("tpw %s out of allowed range 0-82.", buff);
|
||||
redir_url += sprintf(redir_url, "tpw,");
|
||||
@@ -464,8 +488,10 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
info("ap_channel = %s", buff);
|
||||
int channel = atoi(buff);
|
||||
if (channel > 0 && channel < 15) {
|
||||
wificonf->ap_channel = (u8) channel;
|
||||
wifi_change_flags.ap = true;
|
||||
if (wificonf->ap_channel != channel) {
|
||||
wificonf->ap_channel = (u8) channel;
|
||||
wifi_change_flags.ap = true;
|
||||
}
|
||||
} else {
|
||||
warn("Bad channel value \"%s\", allowed 1-14", buff);
|
||||
redir_url += sprintf(redir_url, "ap_channel,");
|
||||
@@ -485,9 +511,11 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
buff[i] = 0;
|
||||
|
||||
if (strlen(buff) > 0) {
|
||||
info("Setting SSID to \"%s\"", buff);
|
||||
strncpy_safe(wificonf->ap_ssid, buff, SSID_LEN);
|
||||
wifi_change_flags.ap = true;
|
||||
if (!streq(wificonf->ap_ssid, buff)) {
|
||||
info("Setting SSID to \"%s\"", buff);
|
||||
strncpy_safe(wificonf->ap_ssid, buff, SSID_LEN);
|
||||
wifi_change_flags.ap = true;
|
||||
}
|
||||
} else {
|
||||
warn("Bad SSID len.");
|
||||
redir_url += sprintf(redir_url, "ap_ssid,");
|
||||
@@ -500,9 +528,11 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
// Users are free to use any stupid shit in ther password,
|
||||
// but it may lock them out.
|
||||
if (strlen(buff) == 0 || (strlen(buff) >= 8 && strlen(buff) < PASSWORD_LEN-1)) {
|
||||
info("Setting AP password to \"%s\"", buff);
|
||||
strncpy_safe(wificonf->ap_password, buff, PASSWORD_LEN);
|
||||
wifi_change_flags.ap = true;
|
||||
if (!streq(wificonf->ap_password, buff)) {
|
||||
info("Setting AP password to \"%s\"", buff);
|
||||
strncpy_safe(wificonf->ap_password, buff, PASSWORD_LEN);
|
||||
wifi_change_flags.ap = true;
|
||||
}
|
||||
} else {
|
||||
warn("Bad password len.");
|
||||
redir_url += sprintf(redir_url, "ap_password,");
|
||||
@@ -514,8 +544,10 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
if (GET_ARG("ap_hidden")) {
|
||||
dbg("AP hidden = %s", buff);
|
||||
int hidden = atoi(buff);
|
||||
wificonf->ap_hidden = (hidden != 0);
|
||||
wifi_change_flags.ap = true;
|
||||
if (hidden != wificonf->ap_hidden) {
|
||||
wificonf->ap_hidden = (hidden != 0);
|
||||
wifi_change_flags.ap = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- AP DHCP server lease time ----
|
||||
@@ -524,8 +556,10 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
dbg("Setting DHCP lease time to: %s min.", buff);
|
||||
int min = atoi(buff);
|
||||
if (min >= 1 && min <= 2880) {
|
||||
wificonf->ap_dhcp_time = (u16) min;
|
||||
wifi_change_flags.ap = true;
|
||||
if (wificonf->ap_dhcp_time != min) {
|
||||
wificonf->ap_dhcp_time = (u16) min;
|
||||
wifi_change_flags.ap = true;
|
||||
}
|
||||
} else {
|
||||
warn("Lease time %s out of allowed range 1-2880.", buff);
|
||||
redir_url += sprintf(redir_url, "ap_dhcp_time,");
|
||||
@@ -534,27 +568,31 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
|
||||
// ---- AP DHCP start and end IP ----
|
||||
|
||||
if (GET_ARG("ap_dhcp_range_start")) {
|
||||
if (GET_ARG("ap_dhcp_start")) {
|
||||
dbg("Setting DHCP range start IP to: \"%s\"", buff);
|
||||
u32 ip = ipaddr_addr(buff);
|
||||
if (ip != 0) {
|
||||
wificonf->ap_dhcp_range.start_ip.addr = ip;
|
||||
wifi_change_flags.ap = true;
|
||||
if (wificonf->ap_dhcp_range.start_ip.addr != ip) {
|
||||
wificonf->ap_dhcp_range.start_ip.addr = ip;
|
||||
wifi_change_flags.ap = true;
|
||||
}
|
||||
} else {
|
||||
warn("Bad IP: %s", buff);
|
||||
redir_url += sprintf(redir_url, "ap_dhcp_range_start,");
|
||||
redir_url += sprintf(redir_url, "ap_dhcp_start,");
|
||||
}
|
||||
}
|
||||
|
||||
if (GET_ARG("ap_dhcp_range_end")) {
|
||||
if (GET_ARG("ap_dhcp_end")) {
|
||||
dbg("Setting DHCP range end IP to: \"%s\"", buff);
|
||||
u32 ip = ipaddr_addr(buff);
|
||||
if (ip != 0) {
|
||||
wificonf->ap_dhcp_range.end_ip.addr = ip;
|
||||
wifi_change_flags.ap = true;
|
||||
if (wificonf->ap_dhcp_range.end_ip.addr != ip) {
|
||||
wificonf->ap_dhcp_range.end_ip.addr = ip;
|
||||
wifi_change_flags.ap = true;
|
||||
}
|
||||
} else {
|
||||
warn("Bad IP: %s", buff);
|
||||
redir_url += sprintf(redir_url, "ap_dhcp_range_end,");
|
||||
redir_url += sprintf(redir_url, "ap_dhcp_end,");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,9 +602,11 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
dbg("Setting AP local IP to: \"%s\"", buff);
|
||||
u32 ip = ipaddr_addr(buff);
|
||||
if (ip != 0) {
|
||||
wificonf->ap_addr.ip.addr = ip;
|
||||
wificonf->ap_addr.gw.addr = ip; // always the same, we're the router here
|
||||
wifi_change_flags.ap = true;
|
||||
if (wificonf->ap_addr.ip.addr != ip) {
|
||||
wificonf->ap_addr.ip.addr = ip;
|
||||
wificonf->ap_addr.gw.addr = ip; // always the same, we're the router here
|
||||
wifi_change_flags.ap = true;
|
||||
}
|
||||
} else {
|
||||
warn("Bad IP: %s", buff);
|
||||
redir_url += sprintf(redir_url, "ap_addr_ip,");
|
||||
@@ -577,10 +617,12 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
dbg("Setting AP local IP netmask to: \"%s\"", buff);
|
||||
u32 ip = ipaddr_addr(buff);
|
||||
if (ip != 0) {
|
||||
// ideally this should be checked to match the IP.
|
||||
// Let's hope users know what they're doing
|
||||
wificonf->ap_addr.netmask.addr = ip;
|
||||
wifi_change_flags.ap = true;
|
||||
if (wificonf->ap_addr.netmask.addr != ip) {
|
||||
// ideally this should be checked to match the IP.
|
||||
// Let's hope users know what they're doing
|
||||
wificonf->ap_addr.netmask.addr = ip;
|
||||
wifi_change_flags.ap = true;
|
||||
}
|
||||
} else {
|
||||
warn("Bad IP mask: %s", buff);
|
||||
redir_url += sprintf(redir_url, "ap_addr_mask,");
|
||||
@@ -590,19 +632,23 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
// ---- Station SSID (to connect to) ----
|
||||
|
||||
if (GET_ARG("sta_ssid")) {
|
||||
// No verification needed, at worst it fails to connect
|
||||
info("Setting station SSID to: \"%s\"", buff);
|
||||
strncpy_safe(wificonf->sta_ssid, buff, SSID_LEN);
|
||||
wifi_change_flags.sta = true;
|
||||
if (!streq(wificonf->sta_ssid, buff)) {
|
||||
// No verification needed, at worst it fails to connect
|
||||
info("Setting station SSID to: \"%s\"", buff);
|
||||
strncpy_safe(wificonf->sta_ssid, buff, SSID_LEN);
|
||||
wifi_change_flags.sta = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Station password (empty for none is allowed) ----
|
||||
|
||||
if (GET_ARG("sta_password")) {
|
||||
// No verification needed, at worst it fails to connect
|
||||
info("Setting station password to: \"%s\"", buff);
|
||||
strncpy_safe(wificonf->sta_password, buff, PASSWORD_LEN);
|
||||
wifi_change_flags.sta = true;
|
||||
if (!streq(wificonf->sta_password, buff)) {
|
||||
// No verification needed, at worst it fails to connect
|
||||
info("Setting station password to: \"%s\"", buff);
|
||||
strncpy_safe(wificonf->sta_password, buff, PASSWORD_LEN);
|
||||
wifi_change_flags.sta = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Station enable/disable DHCP ----
|
||||
@@ -611,8 +657,10 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
if (GET_ARG("sta_dhcp_enable")) {
|
||||
dbg("DHCP enable = %s", buff);
|
||||
int enable = atoi(buff);
|
||||
wificonf->sta_dhcp_enable = (enable != 0);
|
||||
wifi_change_flags.sta = true;
|
||||
if (wificonf->sta_dhcp_enable != enable) {
|
||||
wificonf->sta_dhcp_enable = (bool)enable;
|
||||
wifi_change_flags.sta = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Station IP config (Static IP) ----
|
||||
@@ -621,8 +669,10 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
dbg("Setting Station mode static IP to: \"%s\"", buff);
|
||||
u32 ip = ipaddr_addr(buff);
|
||||
if (ip != 0) {
|
||||
wificonf->sta_addr.ip.addr = ip;
|
||||
wifi_change_flags.sta = true;
|
||||
if (wificonf->sta_addr.ip.addr != ip) {
|
||||
wificonf->sta_addr.ip.addr = ip;
|
||||
wifi_change_flags.sta = true;
|
||||
}
|
||||
} else {
|
||||
warn("Bad IP: %s", buff);
|
||||
redir_url += sprintf(redir_url, "sta_addr_ip,");
|
||||
@@ -633,8 +683,10 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
dbg("Setting Station mode static IP netmask to: \"%s\"", buff);
|
||||
u32 ip = ipaddr_addr(buff);
|
||||
if (ip != 0 && ip != 0xFFFFFFFFUL) {
|
||||
wificonf->sta_addr.netmask.addr = ip;
|
||||
wifi_change_flags.sta = true;
|
||||
if (wificonf->sta_addr.netmask.addr != ip) {
|
||||
wificonf->sta_addr.netmask.addr = ip;
|
||||
wifi_change_flags.sta = true;
|
||||
}
|
||||
} else {
|
||||
warn("Bad IP mask: %s", buff);
|
||||
redir_url += sprintf(redir_url, "sta_addr_mask,");
|
||||
@@ -645,8 +697,10 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
|
||||
dbg("Setting Station mode static IP default gateway to: \"%s\"", buff);
|
||||
u32 ip = ipaddr_addr(buff);
|
||||
if (ip != 0) {
|
||||
wificonf->sta_addr.gw.addr = ip;
|
||||
wifi_change_flags.sta = true;
|
||||
if (wificonf->sta_addr.gw.addr != ip) {
|
||||
wificonf->sta_addr.gw.addr = ip;
|
||||
wifi_change_flags.sta = true;
|
||||
}
|
||||
} else {
|
||||
warn("Bad gw IP: %s", buff);
|
||||
redir_url += sprintf(redir_url, "sta_addr_gw,");
|
||||
@@ -700,6 +754,12 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token,
|
||||
else if (streq(token, "opmode")) {
|
||||
sprintf(buff, "%d", wificonf->opmode);
|
||||
}
|
||||
else if (streq(token, "sta_enable")) {
|
||||
sprintf(buff, "%d", (wificonf->opmode & STATION_MODE) != 0);
|
||||
}
|
||||
else if (streq(token, "ap_enable")) {
|
||||
sprintf(buff, "%d", (wificonf->opmode & SOFTAP_MODE) != 0);
|
||||
}
|
||||
else if (streq(token, "tpw")) {
|
||||
sprintf(buff, "%d", wificonf->tpw);
|
||||
}
|
||||
@@ -718,10 +778,10 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token,
|
||||
else if (streq(token, "ap_dhcp_time")) {
|
||||
sprintf(buff, "%d", wificonf->ap_dhcp_time);
|
||||
}
|
||||
else if (streq(token, "ap_dhcp_range_start")) {
|
||||
else if (streq(token, "ap_dhcp_start")) {
|
||||
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.start_ip.addr));
|
||||
}
|
||||
else if (streq(token, "ap_dhcp_range_end")) {
|
||||
else if (streq(token, "ap_dhcp_end")) {
|
||||
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.end_ip.addr));
|
||||
}
|
||||
else if (streq(token, "ap_addr_ip")) {
|
||||
|
||||
Reference in New Issue
Block a user