<!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>