Merge branch 'master' into work

box-drawing
Ondřej Hruška 7 years ago
commit ced948b6eb
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 6
      base.php
  2. 19
      compile_html.php
  3. 37
      js/appcommon.js
  4. 15
      js/term/connection.js
  5. 36
      js/term/index.js
  6. 9
      js/term/screen.js
  7. 2
      js/term/screen_parser.js
  8. 8
      js/wifi.js
  9. 192
      lang/en.php
  10. 2
      pages/_head.php
  11. 3
      pages/cfg_network.php
  12. 90
      pages/cfg_system.php
  13. 40
      pages/cfg_term.php
  14. 2
      pages/cfg_wifi.php
  15. 20
      pages/cfg_wifi_conn.php
  16. 2
      pages/help/charsets.php
  17. 4
      pages/help/cmd_system.php
  18. 2
      pages/help/sgr_colors.php
  19. 2
      pages/help/sgr_styles.php
  20. 2
      sass/app.scss
  21. 16
      sass/form/_form_layout.scss
  22. 15
      sass/layout/_box.scss
  23. 3
      sass/pages/_about.scss

@ -97,7 +97,11 @@ function je($s)
function tr($key)
{
global $_messages;
return isset($_messages[$key]) ? $_messages[$key] : ('??' . $key . '??');
if (isset($_messages[$key])) return $_messages[$key];
else {
ob_end_clean();
die('??' . $key . '??');
}
}
/** Like eval, but allows <?php and ?> */

@ -22,9 +22,22 @@ ob_start();
foreach($_pages as $_k => $p) {
if ($p->bodyclass == 'api') {
if (ESP_DEMO) {
$target = 'term.html';
echo "Generating: ~$_k.html -> $target\n";
$s = "<!DOCTYPE HTML><meta http-equiv=\"refresh\" content=\"0;url=$target\">";
echo "Generating: ~$_k.html (bounce)\n";
if ($_k=='index') {
$s = "<!DOCTYPE HTML><meta http-equiv=\"refresh\" content=\"0;url=term.html\">";
}
else {
$s = "<!DOCTYPE HTML>
<script>
var ref = document.referrer;
var qat = document.referrer.indexOf('?');
if (qat !== -1) ref = ref.substring(0, qat)
location.href=ref+'?msg=Request ignored, this is a demo.';
</script>";
}
} else {
continue;
}

@ -33,7 +33,11 @@ $.ready(function () {
let h = x.querySelector('h2')
let hdl = function () {
$(x).toggleClass('expanded')
if ($(x).hasClass('d-expanded')) {
$(x).removeClass('d-expanded')
} else {
$(x).toggleClass('expanded')
}
}
$(h).on('click', hdl).on('keypress', cr(hdl))
})
@ -90,24 +94,39 @@ $.ready(function () {
// (a way to pass errors back from server via redirect)
let errAt = window.location.search.indexOf('err=')
if (errAt !== -1 && qs('.Box.errors')) {
let errs = window.location.search.substr(errAt + 4).split(',')
let errs = decodeURIComponent(window.location.search.substr(errAt + 4)).split(',')
let humanReadableErrors = []
errs.forEach(function (er) {
let lbls = qsa('label[for="' + er + '"]')
for (let i = 0; i < lbls.length; i++) {
let lbl = lbls[i]
lbl.classList.add('error')
if (i === 0) humanReadableErrors.push(lbl.childNodes[0].textContent.trim().replace(/: ?$/, ''))
if (lbls) {
for (let i = 0; i < lbls.length; i++) {
let lbl = lbls[i]
lbl.classList.add('error')
if (i === 0) humanReadableErrors.push(lbl.childNodes[0].textContent.trim().replace(/: ?$/, ''))
}
} else {
humanReadableErrors.push(er)
}
// else {
// hres.push(er)
// }
})
qs('.Box.errors .list').innerHTML = humanReadableErrors.join(', ')
qs('.Box.errors').classList.remove('hidden')
}
let msgAt = window.location.search.indexOf('msg=')
if (msgAt !== -1 && qs('.Box.message')) {
let msg = decodeURIComponent(window.location.search.substr(msgAt + 4))
let box = qs('.Box.message')
box.innerHTML = msg
box.classList.remove('hidden')
setTimeout(() => {
box.classList.add('hiding')
setTimeout(() => {
box.classList.add('hidden')
}, 1000)
}, 2000)
}
modal.init()
notify.init()

@ -19,12 +19,18 @@ module.exports = class TermConnection extends EventEmitter {
this.pageShown = false
this.disconnectTimeout = null
document.addEventListener('visibilitychange', () => {
if (document.hidden === true) {
console.info('Window lost focus, freeing socket')
this.closeSocket()
clearTimeout(this.heartbeatTimeout)
// Delayed, avoid disconnecting if the background time is short
this.disconnectTimeout = setTimeout(() => {
this.closeSocket()
clearTimeout(this.heartbeatTimeout)
}, 1000)
} else {
clearTimeout(this.disconnectTimeout)
console.info('Window got focus, re-connecting')
this.init()
}
@ -80,7 +86,6 @@ module.exports = class TermConnection extends EventEmitter {
break
default:
this.emit('load')
this.screen.load(evt.data)
if (!this.pageShown) {
window.showPage()
@ -118,7 +123,7 @@ module.exports = class TermConnection extends EventEmitter {
console.error('Socket not ready')
return false
}
if (typeof message != 'string') {
if (typeof message !== 'string') {
message = JSON.stringify(message)
}
this.ws.send(message)
@ -161,7 +166,7 @@ module.exports = class TermConnection extends EventEmitter {
heartbeat () {
clearTimeout(this.heartbeatTimeout)
this.heartbeatTimeout = setTimeout(() => this.onHeartbeatFail(), 2000)
this.heartbeatTimeout = setTimeout(() => this.onHeartbeatFail(), 2500)
}
onHeartbeatFail () {

@ -14,33 +14,47 @@ module.exports = function (opts) {
const input = TermInput(conn, screen)
const termUpload = TermUpload(conn, input, screen)
screen.input = input
screen.conn = conn
input.termUpload = termUpload
// we delay the display of "connecting" to avoid flash when changing tabs with the terminal open
let showConnectingTimeout = -1
let showSplashTimeout = null
let showSplash = (obj, delay = 250) => {
clearTimeout(showSplashTimeout)
showSplashTimeout = setTimeout(() => {
screen.window.statusScreen = obj
}, delay)
}
conn.on('open', () => {
showConnectingTimeout = setTimeout(() => {
screen.window.statusScreen = { title: 'Connecting', loading: true }
}, 250)
// console.log('*open')
showSplash({ title: 'Connecting', loading: true })
})
conn.on('connect', () => {
clearTimeout(showConnectingTimeout)
screen.window.statusScreen = { title: 'Waiting for content', loading: true }
// console.log('*connect')
showSplash({ title: 'Waiting for content', loading: true })
})
conn.on('load', () => {
// console.log('*load')
clearTimeout(showSplashTimeout)
if (screen.window.statusScreen) screen.window.statusScreen = null
})
conn.on('disconnect', () => {
clearTimeout(showConnectingTimeout)
screen.window.statusScreen = { title: 'Disconnected' }
// console.log('*disconnect')
showSplash({ title: 'Disconnected' })
screen.screen = []
screen.screenFG = []
screen.screenBG = []
screen.screenAttrs = []
})
conn.on('silence', () => { screen.window.statusScreen = { title: 'Waiting for server', loading: true } })
conn.on('silence', () => {
// console.log('*silence')
showSplash({ title: 'Waiting for server', loading: true }, 0)
})
// conn.on('ping-fail', () => { screen.window.statusScreen = { title: 'Disconnected' } })
conn.on('ping-success', () => { screen.window.statusScreen = { title: 'Re-connecting', loading: true } })
conn.on('ping-success', () => {
// console.log('*ping-success')
showSplash({ title: 'Re-connecting', loading: true }, 0)
})
conn.init()
input.init(opts)

@ -30,6 +30,15 @@ module.exports = class TermScreen extends EventEmitter {
return () => console.warn('TermScreen#input not set!')
}
})
// dummy. Handle for Conn
this.conn = new Proxy({}, {
get () {
return () => console.warn('TermScreen#conn not set!')
},
set (a, b) {
return () => console.warn('TermScreen#conn not set!')
}
})
this.cursor = {
x: 0,

@ -199,7 +199,7 @@ module.exports = class ScreenParser {
if (this.screen.window.debug) console.log(`Blinky cells: ${this.screen.blinkingCellCount}`)
this.screen.renderer.scheduleDraw('load', 16)
this.screen.emit('load')
this.screen.conn.emit('load')
}
/**

@ -7,8 +7,8 @@ const tr = require('./lang')
let curSSID
// Get XX % for a slider input
function rangePt (inp) {
return Math.round(((inp.value / inp.max) * 100)) + '%'
function calc_dBm (inp) {
return `+${(inp.value * 0.25).toFixed(2)} dBm`
}
// Display selected STA SSID etc
@ -142,11 +142,11 @@ const tr = require('./lang')
let inp = x.querySelector('input')
let disp1 = x.querySelector('.x-disp1')
let disp2 = x.querySelector('.x-disp2')
let t = rangePt(inp)
let t = calc_dBm(inp)
$(disp1).html(t)
$(disp2).html(t)
$(inp).on('input', function () {
t = rangePt(inp)
t = calc_dBm(inp)
$(disp1).html(t)
$(disp2).html(t)
})

@ -12,10 +12,24 @@ return [
'menu.term' => 'Back to Terminal',
'menu.cfg_system' => 'System Settings',
'menu.cfg_wifi_conn' => 'Connecting to Network',
'menu.settings' => 'Settings',
'title.term' => 'Terminal',
// not used - api etc. Added to suppress warnings
'menu.term_set' => '',
'menu.wifi_connstatus' => '',
'menu.wifi_set' => '',
'menu.wifi_scan' => '',
'menu.network_set' => '',
'menu.system_set' => '',
'menu.write_defaults' => '',
'menu.restore_defaults' => '',
'menu.restore_hard' => '',
'menu.reset_screen' => '',
'menu.index' => '',
// Terminal page
'title.term' => 'Terminal', // page title of the terminal page
'term_nav.config' => 'Config',
'term_nav.wifi' => 'WiFi',
@ -26,18 +40,14 @@ return [
'term_nav.keybd' => 'Keyboard',
'term_nav.paste_prompt' => 'Paste text to send:',
'net.ap' => 'DHCP Server (AP)',
'net.sta' => 'DHCP Client (Station)',
'net.sta_mac' => 'Station MAC',
'net.ap_mac' => 'AP MAC',
'net.details' => 'MAC addresses',
// Terminal settings page
'term.defaults' => 'Initial Settings',
'term.expert' => 'Expert Options',
'term.explain_initials' => '
Those are the initial settings used after ESPTerm powers on or when the screen
reset command is received. Some options can be changed by the application via escape sequences,
those changes won\'t be saved in Flash.
Those are the initial settings used after ESPTerm powers on, or when the screen
reset command is received (<code>\ec</code>). They can be changed by the
terminal application using escape sequences.
',
'term.explain_expert' => '
Those are advanced config options that usually don\'t need to be changed.
@ -58,7 +68,7 @@ return [
'term.term_width' => 'Width',
'term.term_height' => 'Height',
'term.buttons' => 'Button labels',
'term.theme' => 'Color scheme',
'term.theme' => 'Color palette',
'term.cursor_shape' => 'Cursor style',
'term.parser_tout_ms' => 'Parser timeout',
'term.display_tout_ms' => 'Redraw delay',
@ -66,14 +76,14 @@ return [
'term.fn_alt_mode' => 'SS3 Fn keys',
'term.show_config_links' => 'Show nav links',
'term.show_buttons' => 'Show buttons',
'term.loopback' => 'Local Echo',
'term.crlf_mode' => 'Enter sends CR+LF',
'term.loopback' => 'Local Echo (<span style="text-decoration:overline">SRM</span>)',
'term.crlf_mode' => 'Enter = CR+LF (LNM)',
'term.want_all_fn' => 'Capture all keys<br>(F5, F11, F12…)',
'term.button_msgs' => 'Button codes<br>(ASCII, dec, CSV)',
'term.color_fg' => 'Default fg.',
'term.color_bg' => 'Default bg.',
'term.color_fg_prev' => 'Fg. colors',
'term.color_bg_prev' => 'Bg. colors',
'term.color_fg_prev' => 'Foreground',
'term.color_bg_prev' => 'Background',
'term.colors_preview' => 'Defaults',
'cursor.block_blink' => 'Block, blinking',
@ -83,23 +93,7 @@ return [
'cursor.bar_blink' => 'I-bar, blinking',
'cursor.bar_steady' => 'I-bar, steady',
// // terminal color labels
// 'color.0' => 'Black',
// 'color.1' => 'Red',
// 'color.2' => 'Green',
// 'color.3' => 'Yellow',
// 'color.4' => 'Blue',
// 'color.5' => 'Purple',
// 'color.6' => 'Cyan',
// 'color.7' => 'Silver',
// 'color.8' => 'Gray',
// 'color.9' => 'Light Red',
// 'color.10' => 'Light Green',
// 'color.11' => 'Light Yellow',
// 'color.12' => 'Light Blue',
// 'color.13' => 'Light Purple',
// 'color.14' => 'Light Cyan',
// 'color.15' => 'White',
// Network config page
'net.explain_sta' => '
Switch off Dynamic IP to configure the static IP address.',
@ -118,6 +112,14 @@ return [
'net.sta_addr_mask' => 'Subnet mask',
'net.sta_addr_gw' => 'Gateway IP',
'net.ap' => 'DHCP Server (AP)',
'net.sta' => 'DHCP Client (Station)',
'net.sta_mac' => 'Station MAC',
'net.ap_mac' => 'AP MAC',
'net.details' => 'MAC addresses',
// Wifi config page
'wifi.ap' => 'Built-in Access Point',
'wifi.sta' => 'Join Existing Network',
@ -143,76 +145,89 @@ return [
'wifi.enter_passwd' => 'Enter password for ":ssid:"',
'wifi.sta_explain' => 'After selecting a network, press Apply to connect.',
'wifi.conn.status' => 'Status:',
'wifi.conn.back_to_config' => 'Back to WiFi config',
'wifi.conn.telemetry_lost' => 'Telemetry lost; something went wrong, or your device disconnected.',
'wifi.conn.explain_android_sucks' => '
// Wifi connecting status page
'wificonn.status' => 'Status:',
'wificonn.back_to_config' => 'Back to WiFi config',
'wificonn.telemetry_lost' => 'Telemetry lost; something went wrong, or your device disconnected.',
'wificonn.explain_android_sucks' => '
If you\'re configuring ESPTerm via a smartphone, or were connected
from another external network, your device may lose connection and this
progress indicator won\'t work. Please wait a while (~ 15 seconds),
then check if the connection succeeded.',
'wifi.conn.explain_reset' => '
'wificonn.explain_reset' => '
To force enable the built-in AP, hold the BOOT
button until the blue LED starts flashing. Hold the button longer (until the LED
flashes rapidly) for a "factory reset".',
'wifi.conn.disabled' =>"Station mode is disabled.",
'wifi.conn.idle' =>"Idle, not connected and has no IP.",
'wifi.conn.success' => "Connected! Received IP ",
'wifi.conn.working' => "Connecting to selected AP",
'wifi.conn.fail' => "Connection failed, check settings & try again. Cause: ",
'wificonn.disabled' =>"Station mode is disabled.",
'wificonn.idle' =>"Idle, not connected and has no IP.",
'wificonn.success' => "Connected! Received IP ",
'wificonn.working' => "Connecting to selected AP",
'wificonn.fail' => "Connection failed, check settings & try again. Cause: ",
'system.save_restore' => 'Save & Restore',
'system.confirm_restore' => 'Restore all settings to their default values?',
'system.confirm_restore_hard' =>
'Restore to firmware default settings? This will reset ' .
'all active settings and switch to AP mode with the default SSID.',
'system.confirm_store_defaults' =>
'Enter admin password to confirm you want to overwrite the default settings.',
'system.password' => 'Admin password:',
'system.restore_defaults' => 'Reset to saved defaults',
'system.write_defaults' => 'Save active settings as defaults',
'system.restore_hard' => 'Reset active settings to firmware defaults',
'system.explain_persist' => '
ESPTerm saves all settings in Flash. The active settings can be copied to
the "defaults area" and restored later using the blue button below.
',
'system.uart' => 'Serial Port',
'system.explain_uart' => '
This form controls the primary, communication UART. The debug UART is fixed
at 115.200 baud, one stop-bit and no parity.
',
// Access restrictions form
'system.security' => 'Access Restrictions',
'system.explain_security' => '
'pwlock.title' => 'Access Restrictions',
'pwlock.explain' => '
Some parts, or all of the web interface can be protected by a password prompt.
Leave the new password fields empty if you do not wish to change it.
Leave the new password fields empty if you do not wish to change it.<br>
The default password is "%def_access_pw%".
',
'system.pwlock' => 'Protected pages',
'system.pwlock.none' => 'None, all open',
'system.pwlock.settings_noterm' => 'WiFi, Net & System settings',
'system.pwlock.settings' => 'All settings pages',
'system.pwlock.menus' => 'This entire menu section',
'system.pwlock.all' => 'Everything, even terminal',
'system.new_access_pw' => 'New password',
'system.new_access_pw2' => 'New pass., repeat',
'system.admin_pw' => 'Admin password',
'system.access_name' => 'Username',
'system.change_adminpw' => 'Change Admin Password',
'system.explain_adminpw' =>
'pwlock.region' => 'Protected pages',
'pwlock.region.none' => 'None, all open',
'pwlock.region.settings_noterm' => 'WiFi, Net & System settings',
'pwlock.region.settings' => 'All settings pages',
'pwlock.region.menus' => 'This entire menu section',
'pwlock.region.all' => 'Everything, even terminal',
'pwlock.new_access_pw' => 'New password',
'pwlock.new_access_pw2' => 'Repeat',
'pwlock.admin_pw' => 'Admin password',
'pwlock.access_name' => 'Username',
// Setting admin password
'adminpw.title' => 'Change Admin Password',
'adminpw.explain' =>
'
The "admin password" is used to manipulate the stored default settings
and to change access restrictions. This password is not saved as part
of the main config, i.e. using save / restore does not affect this
password. When the admin password is forgotten, the easiest way to
re-gain access is to wipe and re-flash the chip.
re-gain access is to wipe and re-flash the chip.<br>
The default admin password is "%def_admin_pw%".
',
'adminpw.new_admin_pw' => 'New admin password',
'adminpw.new_admin_pw2' => 'Repeat',
'adminpw.old_admin_pw' => 'Old admin password',
// Persist form
'persist.title' => 'Save & Restore',
'persist.explain' => '
ESPTerm saves all settings in Flash. The active settings can be copied to
the "defaults area" and restored later using the blue button below.
',
'system.new_admin_pw' => 'New admin pass.',
'system.new_admin_pw2' => 'New pass., repeat',
'system.old_admin_pw' => 'Old admin pass.',
'persist.confirm_restore' => 'Restore all settings to their default values?',
'persist.confirm_restore_hard' =>
'Restore to firmware default settings? This will reset ' .
'all active settings and switch to AP mode with the default SSID.',
'persist.confirm_store_defaults' =>
'Enter admin password to confirm you want to overwrite the default settings.',
'persist.password' => 'Admin password:',
'persist.restore_defaults' => 'Reset to saved defaults',
'persist.write_defaults' => 'Save active settings as defaults',
'persist.restore_hard' => 'Reset active settings to factory defaults',
'persist.restore_hard_explain' => '(This clears the WiFi config! Does not affect saved defaults or admin password.)',
// UART settings form
'uart.title' => 'Serial Port Parameters',
'uart.explain' => '
This form controls the communication UART. The debug UART is fixed
at 115.200 baud, one stop-bit and no parity.
',
'uart.baud' => 'Baud rate',
'uart.parity' => 'Parity',
'uart.parity.none' => 'None',
@ -223,6 +238,19 @@ return [
'uart.stop_bits.one_and_half' => 'One and half',
'uart.stop_bits.two' => 'Two',
// HW tuning form
'hwtuning.title' => 'Hardware Tuning',
'hwtuning.explain' => '
ESP8266 can be overclocked from 80&nbsp;MHz to 160&nbsp;MHz.
This will make it more responsive and allow faster screen updates
at the expense of slightly higher power consumption. This can also make
it more susceptible to interference. Use with care.
',
'hwtuning.overclock' => 'Overclock to 160MHz',
// Generic button / dialog labels
'apply' => 'Apply!',
'enabled' => 'Enabled',
'disabled' => 'Disabled',

@ -32,4 +32,6 @@ if (strpos($_GET['BODYCLASS'], 'cfg') !== false) {
<span class="lead"><?= tr('form_errors') ?></span>&nbsp;<span class="list"></span>
</div>
<div class="Box message hidden"></div>
<?php endif; ?>

@ -2,6 +2,7 @@
$ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
?>
<!-- STA -->
<form class="Box str mobcol" action="<?= e(url('network_set')) ?>" method="GET" id="form-netsta">
<h2 tabindex=0><?= tr('net.sta') ?></h2>
@ -35,6 +36,7 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
</div>
</form>
<!-- AP -->
<form class="Box str mobcol" action="<?= e(url('network_set')) ?>" method="GET" id="form-netap">
<h2 tabindex=0><?= tr('net.ap') ?></h2>
@ -73,6 +75,7 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
</div>
</form>
<!-- MACs -->
<div class="Box mobcol">
<h2><?= tr('net.details') ?></h2>

@ -1,107 +1,131 @@
<!-- Persist -->
<div class="Box str mobcol">
<h2 tabindex=0><?= tr('system.save_restore') ?></h2>
<h2 tabindex=0><?= tr('persist.title') ?></h2>
<div class="Row explain nomargintop">
<?= tr('system.explain_persist') ?>
<?= tr('persist.explain') ?>
</div>
<div class="Row buttons">
<div class="Row buttons2">
<a class="button icn-restore"
onclick="return confirm('<?= tr('system.confirm_restore') ?>');"
onclick="return confirm('<?= tr('persist.confirm_restore') ?>');"
href="<?= e(url('restore_defaults')) ?>">
<?= tr('system.restore_defaults') ?>
<?= tr('persist.restore_defaults') ?>
</a>
</div>
<div class="Row buttons">
<a onclick="writeDefaults(); return false;" href="#"><?= tr('system.write_defaults') ?></a>
<div class="Row buttons2">
<a onclick="writeDefaults(); return false;" href="#"><?= tr('persist.write_defaults') ?></a>
</div>
<div class="Row buttons">
<a onclick="return confirm('<?= tr('system.confirm_restore_hard') ?>');"
<div class="Row buttons2">
<a onclick="return confirm('<?= tr('persist.confirm_restore_hard') ?>');"
href="<?= e(url('restore_hard')) ?>">
<?= tr('system.restore_hard') ?>
</a>
<?= tr('persist.restore_hard') ?>
</a><br>
<?= tr('persist.restore_hard_explain') ?>
</div>
</div>
<!-- Overclock -->
<form class="Box str mobcol" action="<?= e(url('system_set')) ?>" method="GET" id="form-hw">
<h2 tabindex=0><?= tr('hwtuning.title') ?></h2>
<div class="Row explain">
<?= tr('hwtuning.explain') ?>
</div>
<div class="Row checkbox" >
<label><?= tr('hwtuning.overclock') ?></label><!--
--><span class="box" tabindex=0 role=checkbox></span>
<input type="hidden" id="overclock" name="overclock" value="%overclock%">
</div>
<div class="Row buttons">
<a class="button icn-ok" href="#" onclick="qs('#form-hw').submit()"><?= tr('apply') ?></a>
</div>
</form>
<?php
$NOFILL = 'readonly onfocus="this.removeAttribute(\'readonly\')" style="cursor:text" autocomplete="off"';
?>
<form class="Box str mobcol" action="<?= e(url('system_set')) ?>" method="GET" id="form-2">
<h2 tabindex=0><?= tr('system.security') ?></h2>
<!-- Access perms -->
<form class="Box str mobcol" action="<?= e(url('system_set')) ?>" method="GET" id="form-access">
<h2 tabindex=0><?= tr('pwlock.title') ?></h2>
<div class="Row explain">
<?= tr('system.explain_security') ?>
<?= tr('pwlock.explain') ?>
</div>
<div class="Row">
<label for="pwlock"><?= tr("system.pwlock") ?></label>
<label for="pwlock"><?= tr("pwlock.region") ?></label>
<select name="pwlock" id="pwlock">
<option value="0"><?= tr("system.pwlock.none") ?></option>
<option value="1"><?= tr("system.pwlock.settings_noterm") ?></option>
<option value="2"><?= tr("system.pwlock.settings") ?></option>
<option value="3"><?= tr("system.pwlock.menus") ?></option>
<option value="4"><?= tr("system.pwlock.all") ?></option>
<option value="0"><?= tr("pwlock.region.none") ?></option>
<option value="1"><?= tr("pwlock.region.settings_noterm") ?></option>
<option value="2"><?= tr("pwlock.region.settings") ?></option>
<option value="3"><?= tr("pwlock.region.menus") ?></option>
<option value="4"><?= tr("pwlock.region.all") ?></option>
</select>
</div>
<div class="Row">
<label for="access_name"><?= tr('system.access_name') ?></label>
<label for="access_name"><?= tr('pwlock.access_name') ?></label>
<input type="text" name="access_name" id="access_name" value="%h:access_name%">
</div>
<div class="Row">
<label for="access_pw"><?= tr('system.new_access_pw') ?></label>
<label for="access_pw"><?= tr('pwlock.new_access_pw') ?></label>
<input type="password" name="access_pw" id="access_pw" <?=$NOFILL?>>
</div>
<div class="Row">
<label for="access_pw2"><?= tr('system.new_access_pw2') ?></label>
<label for="access_pw2"><?= tr('pwlock.new_access_pw2') ?></label>
<input type="password" name="access_pw2" id="access_pw2" <?=$NOFILL?>>
</div>
<div class="Row">
<label for="pw"><?= tr('system.admin_pw') ?></label>
<label for="pw"><?= tr('pwlock.admin_pw') ?></label>
<input type="password" name="pw" id="pw" required>
</div>
<div class="Row buttons">
<a class="button icn-ok" href="#" onclick="qs('#form-2').submit()"><?= tr('apply') ?></a>
<a class="button icn-ok" href="#" onclick="qs('#form-access').submit()"><?= tr('apply') ?></a>
</div>
</form>
<form class="Box str mobcol" action="<?= e(url('system_set')) ?>" method="GET" id="form-3">
<h2 tabindex=0><?= tr('system.change_adminpw') ?></h2>
<!-- Admin pw -->
<form class="Box str mobcol" action="<?= e(url('system_set')) ?>" method="GET" id="form-admin">
<h2 tabindex=0><?= tr('adminpw.title') ?></h2>
<div class="Row explain">
<?= tr('system.explain_adminpw') ?>
<?= tr('adminpw.explain') ?>
</div>
<div class="Row">
<label for="admin_pw"><?= tr('system.new_admin_pw') ?></label>
<label for="admin_pw"><?= tr('adminpw.new_admin_pw') ?></label>
<input type="password" name="admin_pw" id="admin_pw">
</div>
<div class="Row">
<label for="admin_pw2"><?= tr('system.new_admin_pw2') ?></label>
<label for="admin_pw2"><?= tr('adminpw.new_admin_pw2') ?></label>
<input type="password" name="admin_pw2" id="admin_pw2">
</div>
<div class="Row">
<label for="pw"><?= tr('system.old_admin_pw') ?></label>
<label for="pw"><?= tr('adminpw.old_admin_pw') ?></label>
<input type="password" name="pw" id="pw" required>
</div>
<div class="Row buttons">
<a class="button icn-ok" href="#" onclick="qs('#form-3').submit()"><?= tr('apply') ?></a>
<a class="button icn-ok" href="#" onclick="qs('#form-admin').submit()"><?= tr('apply') ?></a>
</div>
</form>
<script>
function writeDefaults() {
var pw = prompt('<?= tr('system.confirm_store_defaults') ?>');
var pw = prompt('<?= tr('persist.confirm_store_defaults') ?>');
if (!pw) return;
location.href = <?=json_encode(url('write_defaults')) ?> + '?pw=' + pw;
}

@ -2,7 +2,8 @@
<a href="<?= e(url('reset_screen')) ?>"><?= tr('term.reset_screen') ?></a>
</div>
<form class="Box mobopen str" action="<?= e(url('term_set')) ?>" method="GET" id='form-scheme'>
<!-- Theme -->
<form class="Box mobcol str" action="<?= e(url('term_set')) ?>" method="GET" id='form-scheme'>
<h2><?= tr('term.color_scheme') ?></h2>
<div class="Row explain">
@ -119,7 +120,8 @@
</div>
</form>
<form class="Box fold str" action="<?= e(url('term_set')) ?>" method="GET" id='form-initial'>
<!-- Initials -->
<form class="Box mobcol str" action="<?= e(url('term_set')) ?>" method="GET" id='form-initial'>
<h2><?= tr('term.defaults') ?></h2>
<div class="Row explain">
@ -166,16 +168,29 @@
<input class="tiny" type="text" name="bm5" id="bm5" value="%h:bm5%">
</div>
<div class="Row checkbox" >
<label><?= tr('term.crlf_mode') ?></label><!--
--><span class="box" tabindex=0 role=checkbox></span>
<input type="hidden" id="crlf_mode" name="crlf_mode" value="%crlf_mode%">
</div>
<div class="Row checkbox" >
<label><?= tr('term.loopback') ?></label><!--
--><span class="box" tabindex=0 role=checkbox></span>
<input type="hidden" id="loopback" name="loopback" value="%loopback%">
</div>
<div class="Row buttons">
<a class="button icn-ok" href="#" onclick="qs('#form-initial').submit()"><?= tr('apply') ?></a>
</div>
</form>
<form class="Box fold str" action="<?= e(url('term_set')) ?>" method="GET" id="form-uart">
<h2 tabindex=0><?= tr('system.uart') ?></h2>
<!-- UART -->
<form class="Box mobcol str" action="<?= e(url('term_set')) ?>" method="GET" id="form-uart">
<h2 tabindex=0><?= tr('uart.title') ?></h2>
<div class="Row explain">
<?= tr('system.explain_uart') ?>
<?= tr('uart.explain') ?>
</div>
<div class="Row">
@ -225,7 +240,8 @@
</div>
</form>
<form class="Box fold str" action="<?= e(url('term_set')) ?>" method="GET" id='form-expert'>
<!-- Expert terminal opts -->
<form class="Box mobcol str" action="<?= e(url('term_set')) ?>" method="GET" id='form-expert'>
<h2><?= tr('term.expert') ?></h2>
<div class="Row explain">
@ -262,24 +278,12 @@
<input type="hidden" id="want_all_fn" name="want_all_fn" value="%want_all_fn%">
</div>
<div class="Row checkbox" >
<label><?= tr('term.crlf_mode') ?></label><!--
--><span class="box" tabindex=0 role=checkbox></span>
<input type="hidden" id="crlf_mode" name="crlf_mode" value="%crlf_mode%">
</div>
<div class="Row checkbox" >
<label><?= tr('term.show_config_links') ?></label><!--
--><span class="box" tabindex=0 role=checkbox></span>
<input type="hidden" id="show_config_links" name="show_config_links" value="%show_config_links%">
</div>
<div class="Row checkbox" >
<label><?= tr('term.loopback') ?></label><!--
--><span class="box" tabindex=0 role=checkbox></span>
<input type="hidden" id="loopback" name="loopback" value="%loopback%">
</div>
<div class="Row buttons">
<a class="button icn-ok" href="#" onclick="qs('#form-expert').submit()"><?= tr('apply') ?></a>
</div>

@ -1,3 +1,4 @@
<!-- AP -->
<form class="Box str mobcol" action="<?= e(url('wifi_set')) ?>" method="GET" id="form-ap">
<h2 tabindex=0><?= tr('wifi.ap') ?></h2>
@ -42,6 +43,7 @@
</div>
</form>
<!-- STA -->
<form class="Box str mobcol expanded" action="<?= e(url('wifi_set')) ?>" method="GET" id="form-sta">
<h2 tabindex=0><?= tr('wifi.sta') ?></h2>

@ -1,13 +1,13 @@
<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>
<p><b><?= tr('wificonn.status') ?></b> <span id="status"></span><span class="anim-dots">.</span></p>
<a href="<?= e(url('cfg_wifi')) ?>" id="backbtn" class="button"><?= tr('wificonn.back_to_config') ?></a>
</div>
<div class="Box">
<p><?= tr('wifi.conn.explain_android_sucks') ?></p>
<p><?= tr('wifi.conn.explain_reset') ?></p>
<p><?= tr('wificonn.explain_android_sucks') ?></p>
<p><?= tr('wificonn.explain_reset') ?></p>
</div>
<script>
@ -16,15 +16,15 @@
var failCounter = 0;
var messages = <?= json_encode([
'disabled' => tr('wifi.conn.disabled'),
'idle' => tr('wifi.conn.idle'),
'success' => tr('wifi.conn.success'),
'working' => tr('wifi.conn.working'),
'fail' => tr('wifi.conn.fail'),
'disabled' => tr('wificonn.disabled'),
'idle' => tr('wificonn.idle'),
'success' => tr('wificonn.success'),
'working' => tr('wificonn.working'),
'fail' => tr('wificonn.fail'),
]) ?>;
function onFail() {
$("#status").html(<?= json_encode(tr('wifi.conn.telemetry_lost')) ?>);
$("#status").html(<?= json_encode(tr('wificonn.telemetry_lost')) ?>);
$('.anim-dots').addClass('hidden');
}

@ -41,7 +41,7 @@
}
?>
<h3>Switching commands</h3>
<h3>Codepage switching commands</h3>
<p>
There are two character set slots, G0 and G1.

@ -14,8 +14,8 @@
<tr>
<td>`\ec`</td>
<td>
Clear screen, reset attributes and cursor.
The screen size, title and button labels remain unchanged.
Clear screen, reset attributes and cursor. This command also restores the default
screen size, title, button labels and messages.
</td>
</tr>
<tr>

@ -1,6 +1,6 @@
<div class="Box fold">
<h2>Commands: Color SGR</h2>
<h2>Commands: Color attributes</h2>
<div class="Row v">
<p>

@ -1,5 +1,5 @@
<div class="Box fold">
<h2>Commands: Style SGR</h2>
<h2>Commands: Style attributes</h2>
<div class="Row v">
<p>

@ -7,7 +7,7 @@
@import "utils";
$form-label-w: 160px;
$form-label-w: 180px;
$form-label-gap: 8px;
$form-field-w: 250px;

@ -12,6 +12,16 @@ form { @include naked(); }
}
}
.Box.message {
font-weight: bold;
color: #0fca50;
transition: opacity linear 1s;
opacity: 1;
&.hiding {
opacity: 0;
}
}
.Row {
vertical-align: middle;
margin: 12px auto;
@ -65,13 +75,17 @@ form { @include naked(); }
}
// buttons2 is the same style, but different selector for use in the admin page
&.buttons {
&.buttons, &.buttons2 {
margin: 16px auto;
input, .button {
margin-right: dist(-1);
}
}
&.buttons2 {
display:block;
}
&.centered {
justify-content: center;
}

@ -139,12 +139,27 @@
&.expanded {
.Row {
display: flex;
&.explain { display: block; }
&.v {
display: block;
}
}
}
// desktop-expanded
@include media($tablet-min) {
&.d-expanded {
.Row {
display: flex;
&.explain { display: block; }
&.v {
display: block;
}
}
}
}
}
.Box.fold {

@ -24,7 +24,8 @@
.page-help {
code {
background: rgba(33, 97, 109, 0.31);
background: #2da2b9;
color: black;
border-radius: 1px;
padding: 0 2px;
}

Loading…
Cancel
Save