frontend improvements
This commit is contained in:
+51
-207
@@ -705,20 +705,16 @@
|
||||
function mk(e) {return document.createElement(e)}
|
||||
|
||||
/** Find one by query */
|
||||
function qq(s) {return document.querySelector(s)}
|
||||
function qs(s) {return document.querySelector(s)}
|
||||
|
||||
/** Find all by query */
|
||||
function qa(s) {return document.querySelectorAll(s)}
|
||||
function qsa(s) {return document.querySelectorAll(s)}
|
||||
|
||||
/** Convert any to bool safely */
|
||||
function bool(x) {
|
||||
return (x === 1 || x === '1' || x === true || x === 'true');
|
||||
}
|
||||
|
||||
function intval(x) {
|
||||
return parseInt(x);
|
||||
}
|
||||
|
||||
/** Extend an objects with options */
|
||||
function extend(defaults, options) {
|
||||
var target = {};
|
||||
@@ -739,23 +735,23 @@ function rgxe(str) {
|
||||
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||
}
|
||||
|
||||
/** Format number to N decimal places, output as string */
|
||||
function numfmt(x, places) {
|
||||
var pow = Math.pow(10, places);
|
||||
return Math.round(x*pow) / pow;
|
||||
}
|
||||
|
||||
function estimateLoadTime(fs, n) {
|
||||
return (1000/fs)*n+1500;
|
||||
}
|
||||
|
||||
/** Get millisecond timestamp */
|
||||
function msNow() {
|
||||
return +(new Date);
|
||||
}
|
||||
|
||||
/** Get ms elapsed since msNow() */
|
||||
function msElapsed(start) {
|
||||
return msNow() - start;
|
||||
}
|
||||
|
||||
/** Shim for log base 10 */
|
||||
Math.log10 = Math.log10 || function(x) {
|
||||
return Math.log(x) / Math.LN10;
|
||||
};
|
||||
@@ -796,18 +792,25 @@ String.prototype.format = function () {
|
||||
return out;
|
||||
};
|
||||
|
||||
/** HTML escape */
|
||||
function e(str) {
|
||||
return String(str)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
return $.htmlEscape(str);
|
||||
}
|
||||
|
||||
/** Check for undefined */
|
||||
function undef(x) {
|
||||
return typeof x == 'undefined';
|
||||
}
|
||||
|
||||
/** Safe json parse */
|
||||
function jsp() {
|
||||
try {
|
||||
return JSON.parse(e);
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/** Module for toggling a modal overlay */
|
||||
(function () {
|
||||
var modal = {};
|
||||
@@ -851,6 +854,27 @@ function undef(x) {
|
||||
})();
|
||||
/** Global generic init */
|
||||
$.ready(function () {
|
||||
// Checkbox UI (checkbox CSS and hidden input with int value)
|
||||
$('.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)
|
||||
});
|
||||
});
|
||||
|
||||
// Expanding boxes on mobile
|
||||
$('.Box.mobcol').forEach(function(x) {
|
||||
var h = x.querySelector('h2');
|
||||
$(h).on('click', function() {
|
||||
$(x).toggleClass('expanded');
|
||||
});
|
||||
});
|
||||
|
||||
// loader dots...
|
||||
setInterval(function () {
|
||||
$('.anim-dots').each(function (x) {
|
||||
@@ -863,12 +887,13 @@ $.ready(function () {
|
||||
|
||||
// flipping number boxes with the mouse wheel
|
||||
$('input[type=number]').on('mousewheel', function(e) {
|
||||
var val = +$(this).val();
|
||||
var $this = $(this);
|
||||
var val = +$this.val();
|
||||
if (isNaN(val)) val = 1;
|
||||
|
||||
var step = +($(this).attr('step') || 1);
|
||||
var min = +$(this).attr('min');
|
||||
var max = +$(this).attr('max');
|
||||
var step = +($this.attr('step') || 1);
|
||||
var min = +$this.attr('min');
|
||||
var max = +$this.attr('max');
|
||||
if(e.wheelDelta > 0) {
|
||||
val += step;
|
||||
} else {
|
||||
@@ -877,14 +902,14 @@ $.ready(function () {
|
||||
|
||||
if (typeof min != 'undefined') val = Math.max(val, +min);
|
||||
if (typeof max != 'undefined') val = Math.min(val, +max);
|
||||
$(this).val(val);
|
||||
$this.val(val);
|
||||
|
||||
if ("createEvent" in document) {
|
||||
var evt = document.createEvent("HTMLEvents");
|
||||
evt.initEvent("change", false, true);
|
||||
$(this)[0].dispatchEvent(evt);
|
||||
$this[0].dispatchEvent(evt);
|
||||
} else {
|
||||
$(this)[0].fireEvent("onchange");
|
||||
$this[0].fireEvent("onchange");
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
@@ -894,10 +919,7 @@ $.ready(function () {
|
||||
});
|
||||
|
||||
$._loader = function(vis) {
|
||||
if(vis)
|
||||
$('#loader').addClass('show');
|
||||
else
|
||||
$('#loader').removeClass('show');
|
||||
$('#loader').toggleClass('show', vis);
|
||||
};
|
||||
(function() {
|
||||
/**
|
||||
@@ -1036,7 +1058,7 @@ $._loader = function(vis) {
|
||||
H = obj.h;
|
||||
|
||||
/* Build screen & show */
|
||||
var e, cell, scr = qq('#screen');
|
||||
var e, cell, scr = qs('#screen');
|
||||
|
||||
// Empty the screen node
|
||||
while (scr.firstChild) scr.removeChild(scr.firstChild);
|
||||
@@ -1182,7 +1204,7 @@ $._loader = function(vis) {
|
||||
}
|
||||
});
|
||||
|
||||
qa('#buttons button').forEach(function(s) {
|
||||
qsa('#buttons button').forEach(function(s) {
|
||||
s.addEventListener('click', function() {
|
||||
sendBtnMsg(+this.dataset['n']);
|
||||
});
|
||||
@@ -1202,181 +1224,3 @@ $._loader = function(vis) {
|
||||
Input.init();
|
||||
}
|
||||
})();
|
||||
/** Wifi page */
|
||||
(function () {
|
||||
var authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2'];
|
||||
var curSSID;
|
||||
|
||||
/** Update display for received response */
|
||||
function onScan(resp, status) {
|
||||
if (status != 200) {
|
||||
// bad response
|
||||
rescan(5000); // wait 5sm then retry
|
||||
return;
|
||||
}
|
||||
|
||||
resp = JSON.parse(resp);
|
||||
|
||||
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
|
||||
rescan(done ? 15000 : 1000);
|
||||
if (!done) return; // no redraw yet
|
||||
|
||||
// clear the AP list
|
||||
var $list = $('#ap-list');
|
||||
// remove old APs
|
||||
$('#ap-list .AP').remove();
|
||||
|
||||
$list.toggle(done);
|
||||
$('#ap-loader').toggle(!done);
|
||||
|
||||
// scan done
|
||||
resp.result.APs.sort(function (a, b) {
|
||||
return b.rssi - a.rssi;
|
||||
}).forEach(function (ap) {
|
||||
ap.enc = intval(ap.enc);
|
||||
|
||||
if (ap.enc > 4) return; // hide unsupported auths
|
||||
|
||||
var item = document.createElement('div');
|
||||
|
||||
var $item = $(item)
|
||||
.data('ssid', ap.essid)
|
||||
.data('pwd', ap.enc != 0)
|
||||
.addClass('AP');
|
||||
|
||||
// mark current SSID
|
||||
if (ap.essid == curSSID) {
|
||||
$item.addClass('selected');
|
||||
}
|
||||
|
||||
var inner = document.createElement('div');
|
||||
$(inner).addClass('inner')
|
||||
.htmlAppend('<div class="rssi">{0}</div>'.format(ap.rssi_perc))
|
||||
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format($.htmlEscape(ap.essid)))
|
||||
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
|
||||
|
||||
$item.on('click', function () {
|
||||
var $th = $(this);
|
||||
|
||||
// populate the form
|
||||
$('#conn-essid').val($th.data('ssid'));
|
||||
$('#conn-passwd').val(''); // clear
|
||||
|
||||
if ($th.data('pwd')) {
|
||||
// this AP needs a password
|
||||
Modal.show('#psk-modal');
|
||||
} else {
|
||||
Modal.show('#reset-modal');
|
||||
$('#conn-form').submit();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
item.appendChild(inner);
|
||||
$list[0].appendChild(item);
|
||||
});
|
||||
}
|
||||
|
||||
/** Ask the CGI what APs are visible (async) */
|
||||
function scanAPs() {
|
||||
$.get('http://'+_root+'/wifi/scan', onScan);
|
||||
}
|
||||
|
||||
function rescan(time) {
|
||||
setTimeout(scanAPs, time);
|
||||
}
|
||||
|
||||
/** Set up the WiFi page */
|
||||
window.wifiInit = function (obj) {
|
||||
//var ap_json = {
|
||||
// "result": {
|
||||
// "inProgress": "0",
|
||||
// "APs": [
|
||||
// {"essid": "Chlivek", "bssid": "88:f7:c7:52:b3:99", "rssi": "204", "enc": "4", "channel": "1"},
|
||||
// {"essid": "TyNikdy", "bssid": "5c:f4:ab:0d:f1:1b", "rssi": "164", "enc": "3", "channel": "1"},
|
||||
// ]
|
||||
// }
|
||||
//};
|
||||
|
||||
// Hide what should be hidden in this mode
|
||||
$('.x-hide-'+obj.mode).addClass('hidden');
|
||||
obj.mode = +obj.mode;
|
||||
|
||||
// Channel writable only in AP mode
|
||||
if (obj.mode != 2) $('#channel').attr('readonly', 1);
|
||||
|
||||
curSSID = obj.staSSID;
|
||||
|
||||
// add SSID to the opmode field
|
||||
if (curSSID) {
|
||||
var box = $('#opmodebox');
|
||||
box.html(box.html() + ' (' + curSSID + ')');
|
||||
}
|
||||
|
||||
// hide IP if IP not received
|
||||
if (!obj.staIP) $('.x-hide-noip').addClass('hidden');
|
||||
|
||||
// scan if not AP
|
||||
if (obj.mode != 2) {
|
||||
scanAPs();
|
||||
}
|
||||
|
||||
$('#modeswitch').html([
|
||||
'<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]);
|
||||
};
|
||||
|
||||
window.wifiConn = function () {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var abortTmeo;
|
||||
|
||||
function getStatus() {
|
||||
xhr.open("GET", 'http://'+_root+"/wifi/connstatus");
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4 && xhr.status >= 200 && xhr.status < 300) {
|
||||
clearTimeout(abortTmeo);
|
||||
var data = JSON.parse(xhr.responseText);
|
||||
var done = false;
|
||||
var msg = '...';
|
||||
|
||||
if (data.status == "idle") {
|
||||
msg = "Preparing to connect";
|
||||
}
|
||||
else if (data.status == "success") {
|
||||
msg = "Connected! Received IP " + data.ip + ".";
|
||||
done = true;
|
||||
}
|
||||
else if (data.status == "working") {
|
||||
msg = "Connecting to selected AP";
|
||||
}
|
||||
else if (data.status == "fail") {
|
||||
msg = "Connection failed, check your password and try again.";
|
||||
done = true;
|
||||
}
|
||||
|
||||
$("#status").html(msg);
|
||||
|
||||
if (done) {
|
||||
$('#backbtn').removeClass('hidden');
|
||||
$('.anim-dots').addClass('hidden');
|
||||
} else {
|
||||
window.setTimeout(getStatus, 1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
abortTmeo = setTimeout(function () {
|
||||
xhr.abort();
|
||||
$("#status").html("Telemetry lost, try reconnecting to the AP.");
|
||||
$('#backbtn').removeClass('hidden');
|
||||
$('.anim-dots').addClass('hidden');
|
||||
}, 4000);
|
||||
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
getStatus();
|
||||
};
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user