mirror of
https://github.com/nodemcu/nodemcu-firmware.git
synced 2025-01-30 21:12:55 +08:00
a48e88d4a3
- Bug fixes and improvements - FIX: Ensure that station is enabled before doing network scan (this seems to be the cause of #1578) - FIX: Check if state == NULL on enduser_setup.stop() - IMPROVEMENT: Look for both enduser_setup.html.gz and enduser_setup.html as valid filenames, for semantic reasons - IMPROVEMENT: Show a generic status message on HTML page if failure occurred before user even submitted data (i.e., would have come from previously stored config when the STA was started by EUS)
322 lines
6.5 KiB
HTML
322 lines
6.5 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
|
<title>WiFi Login</title>
|
|
<style type=text/css>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
height: 100%;
|
|
font-family: sans-serif;
|
|
text-align: center;
|
|
background: #444d44;
|
|
}
|
|
|
|
#content {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
width: 320px;
|
|
height: 480px;
|
|
margin: auto;
|
|
}
|
|
|
|
input,
|
|
button,
|
|
select {
|
|
-webkit-appearance: none;
|
|
border-radius: 0;
|
|
}
|
|
|
|
fieldset {
|
|
border: 0;
|
|
box-shadow: 0 0 15px 1px rgba(0, 0, 0, .4);
|
|
box-sizing: border-box;
|
|
padding: 20px 30px;
|
|
background: #fff;
|
|
min-height: 320px;
|
|
margin: -1px;
|
|
}
|
|
|
|
input {
|
|
border: 1px solid #ccc;
|
|
margin-bottom: 10px;
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
color: #222;
|
|
font: 16px monospace;
|
|
padding: 15px;
|
|
}
|
|
|
|
select {
|
|
font: 16px monospace;
|
|
background-color: transparent;
|
|
padding: 15px;
|
|
}
|
|
|
|
button {
|
|
color: #fff;
|
|
border: 0;
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
display: block;
|
|
font: 16px sans-serif;
|
|
text-decoration: none;
|
|
padding: 10px 5px;
|
|
background: #31b457;
|
|
width: 100%;
|
|
}
|
|
|
|
button:focus,
|
|
button:hover {
|
|
box-shadow: 0 0 0 2px #fff, 0 0 0 3px #31b457;
|
|
}
|
|
|
|
h3 {
|
|
font-size: 16px;
|
|
color: #666;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
h4 {
|
|
color: #ccc;
|
|
padding: 10px;
|
|
}
|
|
|
|
.utility {
|
|
float: right;
|
|
clear: both;
|
|
max-width: 75%;
|
|
font-size: 13px;
|
|
color: #222;
|
|
margin: 10px 0;
|
|
padding: 5px 10px;
|
|
background: #ccc;
|
|
}
|
|
|
|
.utility:focus,
|
|
.utility:hover {
|
|
box-shadow: 0 0 0 2px #fff, 0 0 0 3px #ccc;
|
|
}
|
|
|
|
#dropdown,
|
|
#f2,
|
|
#f3,
|
|
#bk2 {
|
|
display: none;
|
|
}
|
|
|
|
#dropdown {
|
|
position: relative;
|
|
width: 100%;
|
|
overflow: auto;
|
|
height: 51px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
#aplist {
|
|
position: absolute;
|
|
width: 100%;
|
|
height: 100%;
|
|
top: 0;
|
|
left: 0;
|
|
bottom: 0;
|
|
border: 1px solid #ccc;
|
|
font-family: monospace;
|
|
padding: 10px 5px;
|
|
}
|
|
|
|
#arrow {
|
|
color: #888;
|
|
position: absolute;
|
|
right: 8px;
|
|
top: 15px;
|
|
}
|
|
|
|
#i {
|
|
text-align: center;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div id=content>
|
|
<fieldset>
|
|
<div id=deviceId></div>
|
|
<div id=f1>
|
|
<h3>Connect device to your Wi-Fi</h3>
|
|
<button id=networks type=button class=utility></button>
|
|
<div id=dropdown>
|
|
<span id=arrow>▼</span>
|
|
<select id=aplist name=aplist></select>
|
|
</div>
|
|
<input id=ssid type=text autocorrect=off autocapitalize=none placeholder='Wi-Fi Name' />
|
|
<input id=wifi_password type=text autocorrect=off autocapitalize=none autocomplete=off placeholder=Password />
|
|
<button id=submit type=button>Save</button>
|
|
</div>
|
|
<div id=f2>
|
|
<h1>Success!</h1>
|
|
<div id=i>
|
|
<h3>Your device has successfully connected to the Wi-Fi network.<br /><br/>You may now close this web page.</h3>
|
|
</div>
|
|
</div>
|
|
<div id=f3>
|
|
<h2>Trying...</h2>
|
|
<button id=bk2 type=button class='utility'>Go Back to Wi-Fi Setup</button>
|
|
</div>
|
|
</fieldset>
|
|
<h4 id='st'>Updating Status...</h4>
|
|
</div>
|
|
<script>
|
|
var $ = function (selector) { return document.querySelector(selector); };
|
|
var ab = $('#networks'), ap = $('#aplist');
|
|
var stopAll = false, ra, rs, submitted = false;
|
|
|
|
function show(f, y) {
|
|
if (y == null) y = f;
|
|
$(f).style.display = y == f ? 'block' : 'none';
|
|
}
|
|
function hide(f) {
|
|
$(f).style.display = 'none';
|
|
}
|
|
function to(cb, x) {
|
|
return setTimeout(cb, 1000 * x);
|
|
}
|
|
function refr() {
|
|
if (!stopAll)
|
|
fetch('/status.json?n=' + Math.random(), 'GET', newSt, 2);
|
|
}
|
|
function cur(f) {
|
|
show('#f1', f);
|
|
show('#f2', f);
|
|
show('#f3', f);
|
|
}
|
|
function newSt(s, d) {
|
|
clearTimeout(rs);
|
|
rs = to(refr, 3);
|
|
|
|
if (s != 200) {
|
|
$('#st').innerText = 'Awaiting Status (' + s + ')';
|
|
} else {
|
|
if (typeof d === 'string') {
|
|
d = JSON.parse(d);
|
|
}
|
|
|
|
$('#deviceId').innerText = "Device: " + d.deviceid;
|
|
|
|
var c = d.pairing;
|
|
|
|
var st = [
|
|
'Idle',
|
|
'Connecting...',
|
|
'Failed - wrong password',
|
|
'Failed - network not found',
|
|
'Failed',
|
|
'Wi-Fi successfully connected!'
|
|
][d.status];
|
|
|
|
if (st == null)
|
|
st = "";
|
|
|
|
if (!submitted && d.status > 1 && d.status < 5)
|
|
st = "Need a valid Network and Password";
|
|
|
|
$('#st').innerText = st;
|
|
|
|
if (d.status === 5) {
|
|
cur('#f2');
|
|
stopAll = true;
|
|
clearTimeout(ra);
|
|
} else if (d.status > 1) {
|
|
cur('#f1');
|
|
}
|
|
}
|
|
}
|
|
function submit() {
|
|
submitted = true;
|
|
var url = '/setwifi?wifi_ssid=' + encodeURIComponent($('#ssid').value) + '&wifi_password=' + encodeURIComponent($('#wifi_password').value);
|
|
clearTimeout(rs);
|
|
fetch(url, 'GET', newSt, 2);
|
|
cur('#f3');
|
|
}
|
|
function fetch(url, method, callback, time_out) {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.onloadend = function () {
|
|
callback(xhr.status, xhr.responseText);
|
|
}
|
|
xhr.ontimeout = function () {
|
|
callback(-1, null);
|
|
}
|
|
xhr.open(method, url, true);
|
|
xhr.setRequestHeader('Accept', 'application/json');
|
|
xhr.timeout = (time_out || 10) * 1000;
|
|
xhr.send();
|
|
}
|
|
function gotAp(s, json) {
|
|
var list;
|
|
if (s === 200 && json != null) {
|
|
if (typeof json === 'string' && json.length > 0) {
|
|
list = JSON.parse(json);
|
|
} else if (typeof json === 'object') {
|
|
list = json;
|
|
}
|
|
|
|
list.sort(function (a, b) {
|
|
return b.rssi - a.rssi;
|
|
});
|
|
var ops = '<option>Select a Network...</option>';
|
|
for (var i = 0; i < list.length; ++i) {
|
|
ops += '<option>' + list[i].ssid + '</option>';
|
|
}
|
|
ap.innerHTML = ops;
|
|
ab.disabled = false;
|
|
togAp(null, true);
|
|
ab.onclick = togAp;
|
|
} else {
|
|
ab.innerText = 'No networks found (' + s + ')';
|
|
ra = to(refrAp, 5);
|
|
}
|
|
}
|
|
function togAp(ev, force) {
|
|
if (!force || ap.style.display == 'block') {
|
|
hide('#dropdown');
|
|
show('#ssid');
|
|
ab.innerText = 'Scan for Networks';
|
|
ab.onclick = refrAp;
|
|
} else {
|
|
show('#dropdown');
|
|
hide('#ssid');
|
|
ab.innerText = 'Manual Entry';
|
|
}
|
|
}
|
|
function refrAp() {
|
|
ab.innerText = 'Searching for networks...';
|
|
ab.disabled = true;
|
|
ap.innerHTML = '<option disabled>Scanning...</option>';
|
|
if (!stopAll)
|
|
fetch('/aplist?n=' + Math.random(), 'GET', gotAp, 10);
|
|
}
|
|
window.onload = function() {
|
|
ab.innerText = 'Scan for Networks';
|
|
ab.onclick = refrAp;
|
|
$('#aplist').onchange = function () {
|
|
$('#ssid').value = $('#aplist').value;
|
|
};
|
|
$('#submit').onclick = submit;
|
|
$('#bk2').onclick = function () {
|
|
cur('#f1')
|
|
}
|
|
rs = to(refr, 0.5);
|
|
}
|
|
</script>
|
|
</body>
|
|
|
|
</html> |