add js error handler with notify balloon, fix file upload

cpsdqs/unified-input
Ondřej Hruška 7 years ago
parent 3e4394f0cb
commit 2f0d0187a1
  1. 52
      js/notif.js
  2. 7
      js/soft_keyboard.js
  3. 21
      js/term.js
  4. 50
      js/term_upload.js
  5. 10
      pages/term.php
  6. 2
      sass/layout/_modal.scss

@ -1,34 +1,64 @@
window.Notify = (function () {
let nt = {}
const sel = '#notif'
let $balloon
let hideTmeo1 // timeout to start hiding (transition)
let hideTmeo2 // timeout to add the hidden class
let timerHideBegin // timeout to start hiding (transition)
let timerHideEnd // timeout to add the hidden class
let timerCanCancel
let canCancel = false
nt.show = function (message, timeout) {
$(sel).html(message)
Modal.show(sel)
let stopTimeouts = function () {
clearTimeout(timerHideBegin)
clearTimeout(timerHideEnd)
}
nt.show = function (message, timeout, isError) {
$balloon.toggleClass('error', isError === true)
$balloon.html(message)
Modal.show($balloon)
stopTimeouts()
clearTimeout(hideTmeo1)
clearTimeout(hideTmeo2)
if (undef(timeout) || timeout === null || timeout <= 0) {
timeout = 2500
}
if (undef(timeout)) timeout = 2500
timerHideBegin = setTimeout(nt.hide, timeout)
hideTmeo1 = setTimeout(nt.hide, timeout)
canCancel = false
timerCanCancel = setTimeout(function () {
canCancel = true
}, 500)
}
nt.hide = function () {
let $m = $(sel)
$m.removeClass('visible')
hideTmeo2 = setTimeout(function () {
timerHideEnd = setTimeout(function () {
$m.addClass('hidden')
}, 250) // transition time
}
nt.init = function () {
$(sel).on('click', function () {
$balloon = $(sel)
// close by click outside
$(document).on('click', function () {
if (!canCancel) return
nt.hide(this)
})
// click caused by selecting, prevent it from bubbling
$balloon.on('click', function (e) {
e.stopImmediatePropagation()
return false
})
// stop fading if moused
$balloon.on('mouseenter', function () {
stopTimeouts()
$balloon.removeClass('hidden').addClass('visible')
})
}
return nt

@ -20,13 +20,18 @@ window.initSoftKeyboard = function (screen, input) {
screen.on('cursor-moved', updateInputPosition)
window.kbOpen = function openSoftKeyboard (open) {
let kbOpen = function (open) {
keyboardOpen = open
updateInputPosition()
if (open) keyInput.focus()
else keyInput.blur()
}
qs('#term-kb-open').addEventListener('click', function () {
kbOpen(true)
return false
})
// Chrome for Android doesn't send proper keydown/keypress events with
// real key values instead of 229 “Unidentified,” so here's a workaround
// that deals with the input composition events.

@ -1,15 +1,21 @@
/** Init the terminal sub-module - called from HTML */
window.termInit = function (labels, theme) {
const screen = new window.TermScreen()
const conn = window.Conn(screen)
const input = window.Input(conn)
const termUpload = window.TermUpl(conn, input)
const screen = new TermScreen()
const conn = Conn(screen)
const input = Input(conn)
const termUpload = TermUpl(conn, input)
screen.input = input
conn.init()
input.init()
termUpload.init()
Notify.init()
window.onerror = function (errorMsg, file, line, col) {
Notify.show(`<b>JS ERROR!</b><br>${errorMsg}<br>at ${file}:${line}:${col}`, 10000, true)
return false
}
qs('#screen').appendChild(screen.canvas)
screen.load(labels, theme) // load labels and theme
@ -23,7 +29,7 @@ window.termInit = function (labels, theme) {
fitScreenIfNeeded()
window.addEventListener('resize', fitScreenIfNeeded)
window.toggleFitScreen = function () {
let toggleFitScreen = function () {
fitScreen = !fitScreen
const resizeButtonIcon = qs('#resize-button-icon')
if (fitScreen) {
@ -35,6 +41,11 @@ window.termInit = function (labels, theme) {
}
fitScreenIfNeeded()
}
qs('#term-fit-screen').addEventListener('click', function () {
toggleFitScreen()
return false
})
}
window.initSoftKeyboard(screen, input)

@ -12,25 +12,25 @@ window.TermUpl = function (conn, input) {
// sending a super-ling string through the socket is not a good idea
const MAX_LINE_LEN = 128
function fuOpen () {
fuStatus('Ready...')
Modal.show('#fu_modal', onClose)
function openUploadDialog () {
updateStatus('Ready...')
Modal.show('#fu_modal', onDialogClose)
$('#fu_form').toggleClass('busy', false)
input.blockKeys(true)
}
function onClose () {
function onDialogClose () {
console.log('Upload modal closed.')
clearTimeout(fuTout)
line_i = 0
input.blockKeys(false)
}
function fuStatus (msg) {
function updateStatus (msg) {
qs('#fu_prog').textContent = msg
}
function fuSend () {
function startUpload () {
let v = qs('#fu_text').value
if (!v.length) {
fuClose()
@ -55,11 +55,11 @@ window.TermUpl = function (conn, input) {
}[qs('#fu_crlf').value]
$('#fu_form').toggleClass('busy', true)
fuStatus('Starting...')
fuSendLine()
updateStatus('Starting...')
uploadLine()
}
function fuSendLine () {
function uploadLine () {
if (!$('#fu_modal').hasClass('visible')) {
// Modal is closed, cancel
return
@ -67,7 +67,7 @@ window.TermUpl = function (conn, input) {
if (!conn.canSend()) {
// postpone
fuTout = setTimeout(fuSendLine, 1)
fuTout = setTimeout(uploadLine, 1)
return
}
@ -85,16 +85,16 @@ window.TermUpl = function (conn, input) {
}
if (!input.sendString(chunk)) {
fuStatus('FAILED!')
updateStatus('FAILED!')
return
}
let all = lines.length
fuStatus(line_i + ' / ' + all + ' (' + (Math.round((line_i / all) * 1000) / 10) + '%)')
updateStatus(line_i + ' / ' + all + ' (' + (Math.round((line_i / all) * 1000) / 10) + '%)')
if (lines.length > line_i || inline_pos > 0) {
fuTout = setTimeout(fuSendLine, send_delay_ms)
fuTout = setTimeout(uploadLine, send_delay_ms)
} else {
closeWhenReady()
}
@ -103,10 +103,10 @@ window.TermUpl = function (conn, input) {
function closeWhenReady () {
if (!conn.canSend()) {
// stuck in XOFF still, wait to process...
fuStatus('Waiting for Tx buffer...')
updateStatus('Waiting for Tx buffer...')
setTimeout(closeWhenReady, 100)
} else {
fuStatus('Done.')
updateStatus('Done.')
// delay to show it
setTimeout(function () {
fuClose()
@ -138,9 +138,21 @@ window.TermUpl = function (conn, input) {
console.log('Loading file...')
reader.readAsText(file)
}, false)
},
close: fuClose,
start: fuSend,
open: fuOpen
qs('#term-fu-open').addEventListener('click', function () {
openUploadDialog()
return false
})
qs('#term-fu-start').addEventListener('click', function () {
startUpload()
return false
})
qs('#term-fu-close').addEventListener('click', function () {
fuClose()
return false
})
}
}
}

@ -33,8 +33,8 @@
</p>
</div>
<div class="fu-buttons">
<button onclick="TermUpl.start()" class="icn-ok x-fu-go">Start</button>&nbsp;
<button onclick="TermUpl.close()" class="icn-cancel x-fu-cancel">Cancel</button>&nbsp;
<button id="term-fu-start" class="icn-ok x-fu-go">Start</button>&nbsp;
<button id="term-fu-close" class="icn-cancel x-fu-cancel">Cancel</button>&nbsp;
<i class="fu-prog-box">Upload: <span id="fu_prog"></span></i>
</div>
</div>
@ -60,9 +60,9 @@
</div>
<nav id="term-nav">
<a href="#" onclick="toggleFitScreen();return false" class="mq-tablet-max"><i id="resize-button-icon" class="icn-resize-small"></i></a><!--
--><a href="#" onclick="kbOpen(true);return false" class="mq-tablet-max"><i class="icn-keyboard"></i><span><?= tr('term_nav.keybd') ?></span></a><!--
--><a href="#" onclick="TermUpl.open();return false"><i class="icn-download"></i><span><?= tr('term_nav.upload') ?></span></a><!--
<a href="#" id="term-fit-screen" class="mq-tablet-max"><i id="resize-button-icon" class="icn-resize-small"></i></a><!--
--><a href="#" id="term-kb-open" class="mq-tablet-max"><i class="icn-keyboard"></i><span><?= tr('term_nav.keybd') ?></span></a><!--
--><a href="#" id="term-fu-open"><i class="icn-download"></i><span><?= tr('term_nav.upload') ?></span></a><!--
--><a href="<?= url('cfg_term') ?>" class="x-term-conf-btn"><i class="icn-configure"></i><span><?= tr('term_nav.config') ?></span></a><!--
--><a href="<?= url('cfg_wifi') ?>" class="x-term-conf-btn"><i class="icn-wifi"></i><span><?= tr('term_nav.wifi') ?></span></a><!--
--><a href="<?= url('help') ?>" class="x-term-conf-btn"><i class="icn-help"></i><span><?= tr('term_nav.help') ?></span></a><!--

@ -82,7 +82,7 @@
box-shadow: 0 0 6px 0 rgba(black, .6);
border-radius: 5px;
max-width: 80%;
max-width: 600px;
@include media($phone) {
width: calc(100% - #{dist(0)});

Loading…
Cancel
Save