frontend improvements
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Those replacements are done by the development server to test it locally
|
||||||
|
* without esphttpd. This is needed mainly for places where the replacements
|
||||||
|
* are given to JavaScript, to avoid syntax errors with %%
|
||||||
|
*/
|
||||||
return [
|
return [
|
||||||
'%term_title%' => 'ESP8266 Wireless Terminal',
|
'%term_title%' => 'ESP8266 Wireless Terminal',
|
||||||
|
|
||||||
@@ -28,4 +33,10 @@ return [
|
|||||||
|
|
||||||
'%sta_enable%' => '1',
|
'%sta_enable%' => '1',
|
||||||
'%opmode%' => '3',
|
'%opmode%' => '3',
|
||||||
|
'%vers_fw%' => '1.2.3',
|
||||||
|
'%date%' => date('Y-m-d'),
|
||||||
|
'%time%' => date('G:i'),
|
||||||
|
'%vers_httpd%' => '4.5.6',
|
||||||
|
'%vers_sdk%' => '1.52',
|
||||||
|
'%githubrepo%' => 'https://github.com/MightyPork/esp-vt100-firmware',
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -13,14 +13,16 @@ function pg($key, $bc, $path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pg('cfg_wifi', 'cfg', '/cfg/wifi');
|
pg('cfg_wifi', 'cfg', '/cfg/wifi');
|
||||||
|
pg('cfg_wifi_conn', '', '/wifi/connecting'); // page without menu that tries to show the connection progress
|
||||||
pg('cfg_network', 'cfg', '/cfg/network');
|
pg('cfg_network', 'cfg', '/cfg/network');
|
||||||
pg('cfg_term', 'cfg', '/cfg/term');
|
pg('cfg_term', 'cfg', '/cfg/term');
|
||||||
pg('about', 'cfg', '/about');
|
pg('about', 'cfg page-about', '/about');
|
||||||
pg('help', 'cfg', '/help');
|
pg('help', 'cfg page-help', '/help');
|
||||||
pg('term', 'term', '/');
|
pg('term', 'term', '/');
|
||||||
|
|
||||||
// technical
|
// ajax API
|
||||||
pg('wifi_set', '', '/wifi/set');//'/cfg/wifi/set');
|
pg('wifi_set', '', '/wifi/set');//'/cfg/wifi/set');
|
||||||
pg('wifi_scan', '', '/wifi/scan');//'/cfg/wifi/scan');
|
pg('wifi_scan', '', '/wifi/scan');//'/cfg/wifi/scan');
|
||||||
|
pg('wifi_connstatus', '', '/wifi/connstatus');
|
||||||
|
|
||||||
return $pages;
|
return $pages;
|
||||||
|
|||||||
@@ -343,6 +343,10 @@ a:hover {
|
|||||||
[onclick] {
|
[onclick] {
|
||||||
cursor: pointer; }
|
cursor: pointer; }
|
||||||
|
|
||||||
|
ul > * {
|
||||||
|
padding-top: .2em;
|
||||||
|
padding-bottom: .2em; }
|
||||||
|
|
||||||
/* Main outer container */
|
/* Main outer container */
|
||||||
#outer {
|
#outer {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
+9
-5
@@ -1,15 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
if (! file_exists('_env.php')) {
|
||||||
|
die("Copy <b>_env.php.example</b> to <b>_env.php</b> and check the settings inside!");
|
||||||
|
}
|
||||||
require '_env.php';
|
require '_env.php';
|
||||||
|
|
||||||
$prod = defined('STDIN');
|
$prod = defined('STDIN');
|
||||||
define ('DEBUG', !$prod);
|
define ('DEBUG', !$prod);
|
||||||
$root = DEBUG ? ESP_IP : '';
|
$root = DEBUG ? json_encode(ESP_IP) : 'window.location.href';
|
||||||
define ('LIVE_ROOT', $root);
|
define ('JS_WEB_ROOT', $root);
|
||||||
|
|
||||||
define('CUR_PAGE', $_GET['page'] ?: 'term');
|
define('CUR_PAGE', $_GET['page'] ?: 'term');
|
||||||
define('LOCALE', $_GET['locale'] ?: 'en');
|
define('LOCALE', $_GET['locale'] ?: 'en');
|
||||||
|
|
||||||
$_messages = require(__DIR__ . '/messages/' . LOCALE . '.php');
|
$_messages = require(__DIR__ . '/lang/' . LOCALE . '.php');
|
||||||
$_pages = require('_pages.php');
|
$_pages = require('_pages.php');
|
||||||
|
|
||||||
define('APP_NAME', 'ESPTerm');
|
define('APP_NAME', 'ESPTerm');
|
||||||
@@ -17,9 +21,9 @@ define('PAGE_TITLE', $_pages[CUR_PAGE]->label . ' :: ' . APP_NAME);
|
|||||||
define('BODYCLASS', $_pages[CUR_PAGE]->bodyclass);
|
define('BODYCLASS', $_pages[CUR_PAGE]->bodyclass);
|
||||||
|
|
||||||
/** URL (dev or production) */
|
/** URL (dev or production) */
|
||||||
function url($name, $root=false) {
|
function url($name, $relative=false) {
|
||||||
global $_pages;
|
global $_pages;
|
||||||
if ($root) return $_pages[$name]->path;
|
if ($relative) return $_pages[$name]->path;
|
||||||
|
|
||||||
if (DEBUG) return "/index.php?page=$name";
|
if (DEBUG) return "/index.php?page=$name";
|
||||||
else return $_pages[$name]->path;
|
else return $_pages[$name]->path;
|
||||||
|
|||||||
+51
-207
@@ -705,20 +705,16 @@
|
|||||||
function mk(e) {return document.createElement(e)}
|
function mk(e) {return document.createElement(e)}
|
||||||
|
|
||||||
/** Find one by query */
|
/** Find one by query */
|
||||||
function qq(s) {return document.querySelector(s)}
|
function qs(s) {return document.querySelector(s)}
|
||||||
|
|
||||||
/** Find all by query */
|
/** Find all by query */
|
||||||
function qa(s) {return document.querySelectorAll(s)}
|
function qsa(s) {return document.querySelectorAll(s)}
|
||||||
|
|
||||||
/** Convert any to bool safely */
|
/** Convert any to bool safely */
|
||||||
function bool(x) {
|
function bool(x) {
|
||||||
return (x === 1 || x === '1' || x === true || x === 'true');
|
return (x === 1 || x === '1' || x === true || x === 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
function intval(x) {
|
|
||||||
return parseInt(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Extend an objects with options */
|
/** Extend an objects with options */
|
||||||
function extend(defaults, options) {
|
function extend(defaults, options) {
|
||||||
var target = {};
|
var target = {};
|
||||||
@@ -739,23 +735,23 @@ function rgxe(str) {
|
|||||||
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Format number to N decimal places, output as string */
|
||||||
function numfmt(x, places) {
|
function numfmt(x, places) {
|
||||||
var pow = Math.pow(10, places);
|
var pow = Math.pow(10, places);
|
||||||
return Math.round(x*pow) / pow;
|
return Math.round(x*pow) / pow;
|
||||||
}
|
}
|
||||||
|
|
||||||
function estimateLoadTime(fs, n) {
|
/** Get millisecond timestamp */
|
||||||
return (1000/fs)*n+1500;
|
|
||||||
}
|
|
||||||
|
|
||||||
function msNow() {
|
function msNow() {
|
||||||
return +(new Date);
|
return +(new Date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get ms elapsed since msNow() */
|
||||||
function msElapsed(start) {
|
function msElapsed(start) {
|
||||||
return msNow() - start;
|
return msNow() - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Shim for log base 10 */
|
||||||
Math.log10 = Math.log10 || function(x) {
|
Math.log10 = Math.log10 || function(x) {
|
||||||
return Math.log(x) / Math.LN10;
|
return Math.log(x) / Math.LN10;
|
||||||
};
|
};
|
||||||
@@ -796,18 +792,25 @@ String.prototype.format = function () {
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** HTML escape */
|
||||||
function e(str) {
|
function e(str) {
|
||||||
return String(str)
|
return $.htmlEscape(str);
|
||||||
.replace(/&/g, '&')
|
|
||||||
.replace(/"/g, '"')
|
|
||||||
.replace(/'/g, ''')
|
|
||||||
.replace(/</g, '<')
|
|
||||||
.replace(/>/g, '>');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check for undefined */
|
||||||
function undef(x) {
|
function undef(x) {
|
||||||
return typeof x == 'undefined';
|
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 */
|
/** Module for toggling a modal overlay */
|
||||||
(function () {
|
(function () {
|
||||||
var modal = {};
|
var modal = {};
|
||||||
@@ -851,6 +854,27 @@ function undef(x) {
|
|||||||
})();
|
})();
|
||||||
/** Global generic init */
|
/** Global generic init */
|
||||||
$.ready(function () {
|
$.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...
|
// loader dots...
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
$('.anim-dots').each(function (x) {
|
$('.anim-dots').each(function (x) {
|
||||||
@@ -863,12 +887,13 @@ $.ready(function () {
|
|||||||
|
|
||||||
// flipping number boxes with the mouse wheel
|
// flipping number boxes with the mouse wheel
|
||||||
$('input[type=number]').on('mousewheel', function(e) {
|
$('input[type=number]').on('mousewheel', function(e) {
|
||||||
var val = +$(this).val();
|
var $this = $(this);
|
||||||
|
var val = +$this.val();
|
||||||
if (isNaN(val)) val = 1;
|
if (isNaN(val)) val = 1;
|
||||||
|
|
||||||
var step = +($(this).attr('step') || 1);
|
var step = +($this.attr('step') || 1);
|
||||||
var min = +$(this).attr('min');
|
var min = +$this.attr('min');
|
||||||
var max = +$(this).attr('max');
|
var max = +$this.attr('max');
|
||||||
if(e.wheelDelta > 0) {
|
if(e.wheelDelta > 0) {
|
||||||
val += step;
|
val += step;
|
||||||
} else {
|
} else {
|
||||||
@@ -877,14 +902,14 @@ $.ready(function () {
|
|||||||
|
|
||||||
if (typeof min != 'undefined') val = Math.max(val, +min);
|
if (typeof min != 'undefined') val = Math.max(val, +min);
|
||||||
if (typeof max != 'undefined') val = Math.min(val, +max);
|
if (typeof max != 'undefined') val = Math.min(val, +max);
|
||||||
$(this).val(val);
|
$this.val(val);
|
||||||
|
|
||||||
if ("createEvent" in document) {
|
if ("createEvent" in document) {
|
||||||
var evt = document.createEvent("HTMLEvents");
|
var evt = document.createEvent("HTMLEvents");
|
||||||
evt.initEvent("change", false, true);
|
evt.initEvent("change", false, true);
|
||||||
$(this)[0].dispatchEvent(evt);
|
$this[0].dispatchEvent(evt);
|
||||||
} else {
|
} else {
|
||||||
$(this)[0].fireEvent("onchange");
|
$this[0].fireEvent("onchange");
|
||||||
}
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -894,10 +919,7 @@ $.ready(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$._loader = function(vis) {
|
$._loader = function(vis) {
|
||||||
if(vis)
|
$('#loader').toggleClass('show', vis);
|
||||||
$('#loader').addClass('show');
|
|
||||||
else
|
|
||||||
$('#loader').removeClass('show');
|
|
||||||
};
|
};
|
||||||
(function() {
|
(function() {
|
||||||
/**
|
/**
|
||||||
@@ -1036,7 +1058,7 @@ $._loader = function(vis) {
|
|||||||
H = obj.h;
|
H = obj.h;
|
||||||
|
|
||||||
/* Build screen & show */
|
/* Build screen & show */
|
||||||
var e, cell, scr = qq('#screen');
|
var e, cell, scr = qs('#screen');
|
||||||
|
|
||||||
// Empty the screen node
|
// Empty the screen node
|
||||||
while (scr.firstChild) scr.removeChild(scr.firstChild);
|
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() {
|
s.addEventListener('click', function() {
|
||||||
sendBtnMsg(+this.dataset['n']);
|
sendBtnMsg(+this.dataset['n']);
|
||||||
});
|
});
|
||||||
@@ -1202,181 +1224,3 @@ $._loader = function(vis) {
|
|||||||
Input.init();
|
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();
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|||||||
@@ -1,5 +1,26 @@
|
|||||||
/** Global generic init */
|
/** Global generic init */
|
||||||
$.ready(function () {
|
$.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...
|
// loader dots...
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
$('.anim-dots').each(function (x) {
|
$('.anim-dots').each(function (x) {
|
||||||
@@ -12,12 +33,13 @@ $.ready(function () {
|
|||||||
|
|
||||||
// flipping number boxes with the mouse wheel
|
// flipping number boxes with the mouse wheel
|
||||||
$('input[type=number]').on('mousewheel', function(e) {
|
$('input[type=number]').on('mousewheel', function(e) {
|
||||||
var val = +$(this).val();
|
var $this = $(this);
|
||||||
|
var val = +$this.val();
|
||||||
if (isNaN(val)) val = 1;
|
if (isNaN(val)) val = 1;
|
||||||
|
|
||||||
var step = +($(this).attr('step') || 1);
|
var step = +($this.attr('step') || 1);
|
||||||
var min = +$(this).attr('min');
|
var min = +$this.attr('min');
|
||||||
var max = +$(this).attr('max');
|
var max = +$this.attr('max');
|
||||||
if(e.wheelDelta > 0) {
|
if(e.wheelDelta > 0) {
|
||||||
val += step;
|
val += step;
|
||||||
} else {
|
} else {
|
||||||
@@ -26,14 +48,14 @@ $.ready(function () {
|
|||||||
|
|
||||||
if (typeof min != 'undefined') val = Math.max(val, +min);
|
if (typeof min != 'undefined') val = Math.max(val, +min);
|
||||||
if (typeof max != 'undefined') val = Math.min(val, +max);
|
if (typeof max != 'undefined') val = Math.min(val, +max);
|
||||||
$(this).val(val);
|
$this.val(val);
|
||||||
|
|
||||||
if ("createEvent" in document) {
|
if ("createEvent" in document) {
|
||||||
var evt = document.createEvent("HTMLEvents");
|
var evt = document.createEvent("HTMLEvents");
|
||||||
evt.initEvent("change", false, true);
|
evt.initEvent("change", false, true);
|
||||||
$(this)[0].dispatchEvent(evt);
|
$this[0].dispatchEvent(evt);
|
||||||
} else {
|
} else {
|
||||||
$(this)[0].fireEvent("onchange");
|
$this[0].fireEvent("onchange");
|
||||||
}
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -43,8 +65,5 @@ $.ready(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$._loader = function(vis) {
|
$._loader = function(vis) {
|
||||||
if(vis)
|
$('#loader').toggleClass('show', vis);
|
||||||
$('#loader').addClass('show');
|
|
||||||
else
|
|
||||||
$('#loader').removeClass('show');
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
(function (nt) {
|
||||||
|
var sel = '#notif';
|
||||||
|
|
||||||
|
var hideTmeo1; // timeout to start hiding (transition)
|
||||||
|
var hideTmeo2; // timeout to add the hidden class
|
||||||
|
|
||||||
|
nt.show = function (message, timeout) {
|
||||||
|
$(sel).html(message);
|
||||||
|
Modal.show(sel);
|
||||||
|
|
||||||
|
clearTimeout(hideTmeo1);
|
||||||
|
clearTimeout(hideTmeo2);
|
||||||
|
|
||||||
|
if (undef(timeout)) timeout = 2500;
|
||||||
|
|
||||||
|
hideTmeo1 = setTimeout(nt.hide, timeout);
|
||||||
|
};
|
||||||
|
|
||||||
|
nt.hide = function () {
|
||||||
|
var $m = $(sel);
|
||||||
|
$m.removeClass('visible');
|
||||||
|
hideTmeo2 = setTimeout(function () {
|
||||||
|
$m.addClass('hidden');
|
||||||
|
}, 250); // transition time
|
||||||
|
};
|
||||||
|
|
||||||
|
nt.init = function() {
|
||||||
|
$(sel).on('click', function() {
|
||||||
|
nt.hide(this);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
})(window.Notify = {});
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
H = obj.h;
|
H = obj.h;
|
||||||
|
|
||||||
/* Build screen & show */
|
/* Build screen & show */
|
||||||
var e, cell, scr = qq('#screen');
|
var e, cell, scr = qs('#screen');
|
||||||
|
|
||||||
// Empty the screen node
|
// Empty the screen node
|
||||||
while (scr.firstChild) scr.removeChild(scr.firstChild);
|
while (scr.firstChild) scr.removeChild(scr.firstChild);
|
||||||
@@ -281,7 +281,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
qa('#buttons button').forEach(function(s) {
|
qsa('#buttons button').forEach(function(s) {
|
||||||
s.addEventListener('click', function() {
|
s.addEventListener('click', function() {
|
||||||
sendBtnMsg(+this.dataset['n']);
|
sendBtnMsg(+this.dataset['n']);
|
||||||
});
|
});
|
||||||
|
|||||||
+19
-16
@@ -2,20 +2,16 @@
|
|||||||
function mk(e) {return document.createElement(e)}
|
function mk(e) {return document.createElement(e)}
|
||||||
|
|
||||||
/** Find one by query */
|
/** Find one by query */
|
||||||
function qq(s) {return document.querySelector(s)}
|
function qs(s) {return document.querySelector(s)}
|
||||||
|
|
||||||
/** Find all by query */
|
/** Find all by query */
|
||||||
function qa(s) {return document.querySelectorAll(s)}
|
function qsa(s) {return document.querySelectorAll(s)}
|
||||||
|
|
||||||
/** Convert any to bool safely */
|
/** Convert any to bool safely */
|
||||||
function bool(x) {
|
function bool(x) {
|
||||||
return (x === 1 || x === '1' || x === true || x === 'true');
|
return (x === 1 || x === '1' || x === true || x === 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
function intval(x) {
|
|
||||||
return parseInt(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Extend an objects with options */
|
/** Extend an objects with options */
|
||||||
function extend(defaults, options) {
|
function extend(defaults, options) {
|
||||||
var target = {};
|
var target = {};
|
||||||
@@ -36,23 +32,23 @@ function rgxe(str) {
|
|||||||
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Format number to N decimal places, output as string */
|
||||||
function numfmt(x, places) {
|
function numfmt(x, places) {
|
||||||
var pow = Math.pow(10, places);
|
var pow = Math.pow(10, places);
|
||||||
return Math.round(x*pow) / pow;
|
return Math.round(x*pow) / pow;
|
||||||
}
|
}
|
||||||
|
|
||||||
function estimateLoadTime(fs, n) {
|
/** Get millisecond timestamp */
|
||||||
return (1000/fs)*n+1500;
|
|
||||||
}
|
|
||||||
|
|
||||||
function msNow() {
|
function msNow() {
|
||||||
return +(new Date);
|
return +(new Date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get ms elapsed since msNow() */
|
||||||
function msElapsed(start) {
|
function msElapsed(start) {
|
||||||
return msNow() - start;
|
return msNow() - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Shim for log base 10 */
|
||||||
Math.log10 = Math.log10 || function(x) {
|
Math.log10 = Math.log10 || function(x) {
|
||||||
return Math.log(x) / Math.LN10;
|
return Math.log(x) / Math.LN10;
|
||||||
};
|
};
|
||||||
@@ -93,15 +89,22 @@ String.prototype.format = function () {
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** HTML escape */
|
||||||
function e(str) {
|
function e(str) {
|
||||||
return String(str)
|
return $.htmlEscape(str);
|
||||||
.replace(/&/g, '&')
|
|
||||||
.replace(/"/g, '"')
|
|
||||||
.replace(/'/g, ''')
|
|
||||||
.replace(/</g, '<')
|
|
||||||
.replace(/>/g, '>');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check for undefined */
|
||||||
function undef(x) {
|
function undef(x) {
|
||||||
return typeof x == 'undefined';
|
return typeof x == 'undefined';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Safe json parse */
|
||||||
|
function jsp() {
|
||||||
|
try {
|
||||||
|
return JSON.parse(e);
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+3
-53
@@ -11,9 +11,9 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = JSON.parse(resp);
|
resp = jsp(resp);
|
||||||
|
|
||||||
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
|
var done = resp && !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
|
||||||
rescan(done ? 15000 : 1000);
|
rescan(done ? 15000 : 1000);
|
||||||
if (!done) return; // no redraw yet
|
if (!done) return; // no redraw yet
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
resp.result.APs.sort(function (a, b) {
|
resp.result.APs.sort(function (a, b) {
|
||||||
return b.rssi - a.rssi;
|
return b.rssi - a.rssi;
|
||||||
}).forEach(function (ap) {
|
}).forEach(function (ap) {
|
||||||
ap.enc = intval(ap.enc);
|
ap.enc = parseInt(ap.enc);
|
||||||
|
|
||||||
if (ap.enc > 4) return; // hide unsupported auths
|
if (ap.enc > 4) return; // hide unsupported auths
|
||||||
|
|
||||||
@@ -124,55 +124,5 @@
|
|||||||
][obj.mode-1]);
|
][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();
|
|
||||||
};
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ return [
|
|||||||
'menu.cfg_network' => 'Network Configuration',
|
'menu.cfg_network' => 'Network Configuration',
|
||||||
'menu.cfg_term' => 'Terminal Settings',
|
'menu.cfg_term' => 'Terminal Settings',
|
||||||
'menu.about' => 'About ESPTerm',
|
'menu.about' => 'About ESPTerm',
|
||||||
'menu.help' => 'Help',
|
'menu.help' => 'Terminal Help',
|
||||||
'menu.term' => 'Back to Terminal',
|
'menu.term' => 'Back to Terminal',
|
||||||
|
'menu.cfg_wifi_conn' => 'Connecting to External Network',
|
||||||
|
|
||||||
'box.ap' => 'Built-in Access Point',
|
'box.ap' => 'Built-in Access Point',
|
||||||
'box.sta' => 'Connect to External Network',
|
'box.sta' => 'Connect to External Network',
|
||||||
@@ -32,6 +33,15 @@ return [
|
|||||||
'wifi.cant_scan_no_sta' => 'Can\'t scan with Client mode disabled.',
|
'wifi.cant_scan_no_sta' => 'Can\'t scan with Client mode disabled.',
|
||||||
'wifi.select_ssid' => 'Available networks:',
|
'wifi.select_ssid' => 'Available networks:',
|
||||||
|
|
||||||
|
'wifi.conn.status' => 'Status:',
|
||||||
|
'wifi.conn.back_to_config' => 'Back to WiFi config',
|
||||||
|
'wifi.conn.telemetry_lost' => 'Telemetry lost, something went wrong. Try again...',
|
||||||
|
|
||||||
|
'wifi.conn.idle' =>"Preparing to connect",
|
||||||
|
'wifi.conn.success' => "Connected! Received IP ",
|
||||||
|
'wifi.conn.working' => "Connecting to selected AP",
|
||||||
|
'wifi.conn.fail' => "Connection failed, check your password and try again.",
|
||||||
|
|
||||||
'enabled' => 'Enabled',
|
'enabled' => 'Enabled',
|
||||||
'disabled' => 'Disabled',
|
'disabled' => 'Disabled',
|
||||||
'yes' => 'Yes',
|
'yes' => 'Yes',
|
||||||
+1
-2
@@ -6,5 +6,4 @@ cat jssrc/chibi.js \
|
|||||||
jssrc/utils.js \
|
jssrc/utils.js \
|
||||||
jssrc/modal.js \
|
jssrc/modal.js \
|
||||||
jssrc/appcommon.js \
|
jssrc/appcommon.js \
|
||||||
jssrc/term.js \
|
jssrc/term.js > js/app.js
|
||||||
jssrc/wifi.js > js/app.js
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
<?php
|
<?php
|
||||||
// generate the menu
|
// generate the menu
|
||||||
foreach($_pages as $k => $page) {
|
foreach($_pages as $k => $page) {
|
||||||
if ($page->bodyclass !== 'cfg') continue;
|
if (strpos($page->bodyclass, 'cfg') === false) continue;
|
||||||
|
|
||||||
$sel = (CUR_PAGE == $k) ? ' class="selected"' : '';
|
$sel = (CUR_PAGE == $k) ? ' class="selected"' : '';
|
||||||
$text = $page->label;
|
$text = $page->label;
|
||||||
$url = e(url($k));
|
$url = e(url($k));
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
<title><?= PAGE_TITLE ?></title>
|
<title><?= PAGE_TITLE ?></title>
|
||||||
<link href="/css/app.css" rel="stylesheet">
|
<link href="/css/app.css" rel="stylesheet">
|
||||||
<script src="/js/app.js"></script>
|
<script src="/js/app.js"></script>
|
||||||
<script>var _root = <?= json_encode(LIVE_ROOT) ?>;</script>
|
<script>var _root = <?= JS_WEB_ROOT ?>;</script>
|
||||||
</head>
|
</head>
|
||||||
<body class="<?= BODYCLASS ?>">
|
<body class="<?= BODYCLASS ?>">
|
||||||
<div id="outer">
|
<div id="outer">
|
||||||
<?php
|
<?php
|
||||||
$cfg = false;
|
$cfg = false;
|
||||||
if ($_pages[CUR_PAGE]->bodyclass == 'cfg') {
|
if (strpos($_pages[CUR_PAGE]->bodyclass, 'cfg') !== false) {
|
||||||
$cfg = true;
|
$cfg = true;
|
||||||
require __DIR__ . '/_cfg_menu.php';
|
require __DIR__ . '/_cfg_menu.php';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,26 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>About - ESP8266 Remote Terminal</title>
|
|
||||||
<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">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="/css/app.css">
|
|
||||||
<script src="/js/app.js"></script>
|
|
||||||
</head>
|
|
||||||
<body class="page-about">
|
|
||||||
|
|
||||||
<h1 onclick="location.href='/'">About</h1>
|
|
||||||
|
|
||||||
<div class="Box">
|
<div class="Box">
|
||||||
<img src="/img/cvut.svg" id="logo" class="mq-tablet-min">
|
<img src="/img/cvut.svg" id="logo" class="mq-tablet-min">
|
||||||
<h2>ESP8266 Remote Terminal</h2>
|
<h2>ESP8266 Remote Terminal</h2>
|
||||||
|
|
||||||
<img src="/img/cvut.svg" id="logo2" class="mq-phone">
|
<img src="/img/cvut.svg" id="logo2" class="mq-phone">
|
||||||
|
|
||||||
<p>© Ondřej Hruška, 2017 <<a href="mailto:ondra@ondrovo.com">ondra@ondrovo.com</a>></p>
|
<p>
|
||||||
|
© Ondřej Hruška, 2016-2017
|
||||||
|
<<a href="mailto:ondra@ondrovo.com">ondra@ondrovo.com</a>>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p><a href="http://measure.feld.cvut.cz/" target="blank">Katedra měření, FEL ČVUT</a><br>Department of Measurement, FEE CTU</p>
|
<p>
|
||||||
|
<a href="http://measure.feld.cvut.cz/" target="blank">Katedra měření, FEL ČVUT</a><br>
|
||||||
|
Department of Measurement, FEE CTU
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="Box">
|
<div class="Box">
|
||||||
<h2>Firmware</h2>
|
<h2>Version</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Firmware</th>
|
<th>ESPTerm</th>
|
||||||
<td>v%vers_fw%, build <i>%date%</i> at <i>%time%</i></td>
|
<td>v%vers_fw%, build %date% at %time%</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>libesphttpd</th>
|
<th>libesphttpd</th>
|
||||||
@@ -55,7 +47,14 @@
|
|||||||
<div class="Box">
|
<div class="Box">
|
||||||
<h2>Contributing</h2>
|
<h2>Contributing</h2>
|
||||||
<p>
|
<p>
|
||||||
Submit your improvements and ideas to the project on <a href="%githubrepo%">GitHub</a>.<br>
|
Submit your improvements and ideas to the project on
|
||||||
|
<a href="%githubrepo%">GitHub</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You can donate on <a href="https://paypal.me/mightypork">PayPal</a> or
|
||||||
|
<a href="https://liberapay.com/MightyPork/">LiberaPay</a> to help keep
|
||||||
|
the project going.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -66,15 +65,7 @@
|
|||||||
<a href="https://github.com/Spritetm/esphttpd">esphttpd</a> library by Jeroen Domburg (Sprite_tm).
|
<a href="https://github.com/Spritetm/esphttpd">esphttpd</a> library by Jeroen Domburg (Sprite_tm).
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Using (modified) JS library <a href="https://github.com/kylebarrow/chibi">chibi.js</a> by Kyle Barrow as a lightweight jQuery alternative.
|
Using (modified) JS library <a href="https://github.com/kylebarrow/chibi">chibi.js</a> by
|
||||||
|
Kyle Barrow as a lightweight jQuery alternative.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav id="botnav">
|
|
||||||
<a href="/">Terminal</a><!--
|
|
||||||
--><a href="/help">Help</a><!--
|
|
||||||
--><a href="/wifi">WiFi config</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="Box str mobcol" action="<?= e(url('wifi_set')) ?>" method="POST">
|
<form class="Box str mobcol" action="<?= e(url('wifi_set')) ?>" method="GET">
|
||||||
<h2><?= tr('box.ap') ?></h2>
|
<h2><?= tr('box.ap') ?></h2>
|
||||||
|
|
||||||
<div class="Row buttons mq-phone">
|
<div class="Row buttons mq-phone">
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form class="Box str mobcol" action="<?= e(url('wifi_set')) ?>" method="POST">
|
<form class="Box str mobcol" action="<?= e(url('wifi_set')) ?>" method="GET">
|
||||||
<h2><?= tr('box.sta') ?></h2>
|
<h2><?= tr('box.sta') ?></h2>
|
||||||
|
|
||||||
<div class="Row buttons mq-phone">
|
<div class="Row buttons mq-phone">
|
||||||
@@ -103,27 +103,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Magic checkbox
|
|
||||||
$('.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');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get XX % for a slider input
|
// Get XX % for a slider input
|
||||||
function rangePt(inp) {
|
function rangePt(inp) {
|
||||||
return Math.round(((inp.value / inp.max)*100)) + '%';
|
return Math.round(((inp.value / inp.max)*100)) + '%';
|
||||||
@@ -213,7 +192,7 @@
|
|||||||
resp.result.APs.sort(function (a, b) {
|
resp.result.APs.sort(function (a, b) {
|
||||||
return b.rssi - a.rssi;
|
return b.rssi - a.rssi;
|
||||||
}).forEach(function (ap) {
|
}).forEach(function (ap) {
|
||||||
ap.enc = intval(ap.enc);
|
ap.enc = parseInt(ap.enc);
|
||||||
|
|
||||||
if (ap.enc > 4) return; // hide unsupported auths
|
if (ap.enc > 4) return; // hide unsupported auths
|
||||||
|
|
||||||
|
|||||||
Executable
+53
@@ -0,0 +1,53 @@
|
|||||||
|
<h1><?= tr('menu.cfg_wifi_conn') ?></h1>
|
||||||
|
|
||||||
|
<div class="Box">
|
||||||
|
<p><b><?= tr('wifi.conn.status') ?></b> <span id="status"></span><span class="anim-dots">.</span></p>
|
||||||
|
<a href="<?= e(url('cfg_wifi')) ?>" id="backbtn" class="button"><?= tr('wifi.conn.back_to_config') ?></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
var abortTmeo;
|
||||||
|
|
||||||
|
var messages = <?= json_encode([
|
||||||
|
'idle' => tr('wifi.conn.idle'),
|
||||||
|
'success' => tr('wifi.conn.success'),
|
||||||
|
'working' => tr('wifi.conn.working'),
|
||||||
|
'fail' => tr('wifi.conn.fail'),
|
||||||
|
]) ?>;
|
||||||
|
|
||||||
|
function getStatus() {
|
||||||
|
xhr.open("GET", 'http://'+_root+'<?= url('wifi_connstatus', true) ?>');
|
||||||
|
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 = messages[data.status] || '...';
|
||||||
|
if (data.status == 'success') msg += data.ip;
|
||||||
|
|
||||||
|
$("#status").html(msg);
|
||||||
|
|
||||||
|
if (done) {
|
||||||
|
// $('#backbtn').removeClass('hidden');
|
||||||
|
$('.anim-dots').addClass('hidden');
|
||||||
|
} else {
|
||||||
|
window.setTimeout(getStatus, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
abortTmeo = setTimeout(function () {
|
||||||
|
xhr.abort();
|
||||||
|
$("#status").html(<?= json_encode(tr('wifi.conn.telemetry_lost')) ?>);
|
||||||
|
// $('#backbtn').removeClass('hidden');
|
||||||
|
$('.anim-dots').addClass('hidden');
|
||||||
|
}, 4000);
|
||||||
|
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
getStatus();
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
@@ -1,29 +1,15 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Help - ESP8266 Remote Terminal</title>
|
|
||||||
<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">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="/css/app.css">
|
|
||||||
<script src="/js/app.js"></script>
|
|
||||||
</head>
|
|
||||||
<body class="page-help">
|
|
||||||
|
|
||||||
<h1 onclick="location.href='/'">Quick Reference</h1>
|
|
||||||
|
|
||||||
<div class="Box">
|
<div class="Box">
|
||||||
<h2>Wiring</h2>
|
<h2>Wiring</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Communication UART on pins <b>Rx, Tx</b> at 115200-8-1-N</li>
|
<li>Communication UART is on pins <b>Rx, Tx</b> at 115200-8-1-N. The baud rate can be changed in Terminal Settings.
|
||||||
<li>Debug log on pin <b>GPIO2</b> at 115200-8-1-N</li>
|
<li>Debug log is on pin <b>GPIO2</b> (P2) at 115200-8-1-N. This baud rate is fixed.
|
||||||
<li>Use 3.3V logic, or 5V with protection resistors (470R or more)</li>
|
<li>Compatible with 3.3 V and 5 V logic. For 5 V, 470 R protection resistors are recommended.
|
||||||
<li>If the "LVD" LED on the ESP Term board lights up, the module doesn't get enough power. Check your connections.</li>
|
<li>If the "LVD" LED on the ESPTerm module lights up, it doesn't get enough power to run correctly. Check your connections.
|
||||||
<li>Connect Rx and Tx with a piece of wire to test the terminal alone, you should see what you type in the browser.
|
<li>Connect Rx and Tx with a piece of wire to test the terminal alone, you should see what you type in the browser.
|
||||||
NOTE: This won't work if your ESP8266 board has a built-in USB-serial (like NodeMCU).</li>
|
<i>NOTE: This won't work if your ESP8266 board has a built-in USB-serial converter (like NodeMCU).</i>
|
||||||
<li>For best performance, use the module in the Client mode. In AP mode, check that the channel used is clear;
|
<li>For best performance, use the module in Client mode (connected to external network).
|
||||||
interference may cause lag in the terminal.</li>
|
<li>In AP mode, check that the channel used is clear; interference may cause a flaky connection.
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -328,12 +314,3 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav id="botnav">
|
|
||||||
<a href="/">Terminal</a><!--
|
|
||||||
--><a href="/wifi">WiFi config</a><!--
|
|
||||||
--><a href="/about">About</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -29,3 +29,8 @@ a:hover {
|
|||||||
[onclick] {
|
[onclick] {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul > * {
|
||||||
|
padding-top: .2em;
|
||||||
|
padding-bottom: .2em;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>ESP8266 Remote Terminal</title>
|
|
||||||
<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">
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Workaround for badly loaded page
|
|
||||||
setTimeout(function() {
|
|
||||||
if (typeof termInit == 'undefined' || typeof $ == 'undefined') {
|
|
||||||
location.reload(true);
|
|
||||||
}
|
|
||||||
}, 2000);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="/css/app.css">
|
|
||||||
<script src="/js/app.js"></script>
|
|
||||||
</head>
|
|
||||||
<body class="page-term">
|
|
||||||
|
|
||||||
<h1 onclick="location.href='/wifi'">ESP8266 Remote Terminal</h1>
|
|
||||||
|
|
||||||
<div id="termwrap">
|
|
||||||
<div id="screen"></div>
|
|
||||||
|
|
||||||
<div id="buttons">
|
|
||||||
<button data-n="1" class="btn-blue">1</button><!--
|
|
||||||
--><button data-n="2" class="btn-blue">2</button><!--
|
|
||||||
--><button data-n="3" class="btn-blue">3</button><!--
|
|
||||||
--><button data-n="4" class="btn-blue">4</button><!--
|
|
||||||
--><button data-n="5" class="btn-blue">5</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<nav id="botnav">
|
|
||||||
<a href="/wifi">WiFi config</a><!--
|
|
||||||
--><a href="/help">Help</a><!--
|
|
||||||
--><a href="/about">About</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
try {
|
|
||||||
_root = window.location.host;
|
|
||||||
termInit(%screenData%);
|
|
||||||
} catch(e) {
|
|
||||||
console.error("Fail, reloading...");
|
|
||||||
location.reload(true);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require '_test_env.php';
|
|
||||||
|
|
||||||
$f = file_get_contents('term.html');
|
|
||||||
|
|
||||||
$f = str_replace('%screenData%',
|
|
||||||
'{
|
|
||||||
"w": 26, "h": 10,
|
|
||||||
"x": 0, "y": 0,
|
|
||||||
"cv": 1,
|
|
||||||
"screen": "70 t259"
|
|
||||||
}', $f);
|
|
||||||
|
|
||||||
$f = str_replace('window.location.host', json_encode(ESP_IP), $f);
|
|
||||||
|
|
||||||
echo $f;
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
<!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/set" method="GET">
|
|
||||||
<input name="ap_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/set" method="GET">
|
|
||||||
<input name="ap_ssid" 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>
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<!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>Connecting…</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="css/app.css">
|
|
||||||
<script src="js/app.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<h1>Connecting to network</h1>
|
|
||||||
|
|
||||||
<div class="Box">
|
|
||||||
<p><b>Status:</b><br><span id="status"></span><span class="anim-dots">.</span></p>
|
|
||||||
<a href="/wifi" id="backbtn" class="hidden button">Back to WiFi config</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
_root = window.location.host;
|
|
||||||
wifiConn();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require '_test_env.php';
|
|
||||||
|
|
||||||
$f = file_get_contents('wifi.html');
|
|
||||||
|
|
||||||
$f = str_replace('%StaSSID%', 'Chlivek', $f);
|
|
||||||
$f = str_replace('%StaIP%', json_encode(ESP_IP), $f);
|
|
||||||
$f = str_replace('%WiFiModeNum%', '1', $f);
|
|
||||||
$f = str_replace('%WiFiMode%', 'Client', $f);
|
|
||||||
$f = str_replace('%WiFiChannel%', '1', $f);
|
|
||||||
|
|
||||||
$f = str_replace('window.location.host', json_encode(ESP_IP), $f);
|
|
||||||
|
|
||||||
echo $f;
|
|
||||||
Reference in New Issue
Block a user