diff options
Diffstat (limited to 'include/pio/static/app.js')
-rw-r--r-- | include/pio/static/app.js | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/include/pio/static/app.js b/include/pio/static/app.js new file mode 100644 index 0000000..299230c --- /dev/null +++ b/include/pio/static/app.js @@ -0,0 +1,246 @@ +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; +} + +function ge(id) { + return document.getElementById(id) +} + +function hide(el) { + el.style.display = 'none' +} + +function cancelEvent(evt) { + if (evt.preventDefault) evt.preventDefault(); + if (evt.stopPropagation) evt.stopPropagation(); + + evt.cancelBubble = true; + evt.returnValue = false; + + return false; +} + +function errorText(e) { + return e instanceof Error ? e.message : e+'' +} + +(function() { + function request(method, url, data, callback) { + data = data || null; + + if (typeof callback != 'function') { + throw new Error('callback must be a function'); + } + + if (!url) + throw new Error('no url specified'); + + switch (method) { + case 'GET': + if (isObject(data)) { + for (var k in data) { + if (data.hasOwnProperty(k)) + url += (url.indexOf('?') === -1 ? '?' : '&')+encodeURIComponent(k)+'='+encodeURIComponent(data[k]) + } + } + break; + + case 'POST': + if (isObject(data)) { + var sdata = []; + for (var k in data) { + if (data.hasOwnProperty(k)) + sdata.push(encodeURIComponent(k)+'='+encodeURIComponent(data[k])); + } + data = sdata.join('&'); + } + break; + } + + var xhr = new XMLHttpRequest(); + xhr.open(method, url); + + if (method === 'POST') + xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + + xhr.onreadystatechange = function() { + if (xhr.readyState === 4) { + if ('status' in xhr && !/^2|1223/.test(xhr.status)) + throw new Error('http code '+xhr.status) + callback(null, JSON.parse(xhr.responseText)); + } + }; + xhr.onerror = function(e) { + callback(e, null); + }; + + xhr.send(method === 'GET' ? null : data); + return xhr; + } + + window.ajax = { + get: request.bind(request, 'GET'), + post: request.bind(request, 'POST') + } +})(); + + +function lock(el) { + el.setAttribute('disabled', 'disabled'); +} + +function unlock(el) { + el.removeAttribute('disabled'); +} + +function initNetworkSettings() { + function setupField(el, value) { + if (value !== null) + el.value = value; + unlock(el); + } + + var doneRequestsCount = 0; + function onRequestDone() { + doneRequestsCount++; + if (doneRequestsCount === 2) { + hide(ge('loading_label')) + } + } + + var form = document.forms.network_settings; + form.addEventListener('submit', function(e) { + if (!form.hid.value.trim()) { + alert('Введите home id'); + return cancelEvent(e); + } + + if (form.psk.value.length < 8) { + alert('Неверный пароль (минимальная длина - 8 символов)'); + return cancelEvent(e); + } + + if (form.ssid.selectedIndex === -1) { + alert('Не выбрана точка доступа'); + return cancelEvent(e); + } + + lock(form.submit) + }) + form.show_psk.addEventListener('change', function(e) { + form.psk.setAttribute('type', e.target.checked ? 'text' : 'password'); + }); + form.ssid.addEventListener('change', function(e) { + var i = e.target.selectedIndex; + if (i !== -1) { + var opt = e.target.options[i]; + if (opt) + form.psk.value = ''; + } + }); + + ajax.get('/status', {}, function(error, response) { + try { + if (error) + throw error; + + setupField(form.hid, response.node_id || null); + setupField(form.psk, null); + setupField(form.submit, null); + + onRequestDone(); + } catch (error) { + alert(errorText(error)); + } + }); + + ajax.get('/scan', {}, function(error, response) { + try { + if (error) + throw error; + + form.ssid.innerHTML = ''; + for (var i = 0; i < response.list.length; i++) { + var ssid = response.list[i][0]; + var rssi = response.list[i][1]; + form.ssid.append(new Option(ssid + ' (' + rssi + ' dBm)', ssid)); + } + unlock(form.ssid); + + onRequestDone(); + } catch (error) { + alert(errorText(error)); + } + }); +} + +function initUpdateForm() { + var form = document.forms.update_settings; + form.addEventListener('submit', function(e) { + cancelEvent(e); + if (!form.file.files.length) { + alert('Файл обновления не выбран'); + return false; + } + + lock(form.submit); + + var xhr = new XMLHttpRequest(); + var fd = new FormData(); + fd.append('file', form.file.files[0]); + + xhr.upload.addEventListener('progress', function (e) { + var total = form.file.files[0].size; + var progress; + if (e.loaded < total) { + progress = Math.round(e.loaded / total * 100).toFixed(2); + } else { + progress = 100; + } + form.submit.innerHTML = progress + '%'; + }); + xhr.onreadystatechange = function() { + var errorMessage = 'Ошибка обновления'; + var successMessage = 'Обновление завершено, устройство перезагружается'; + if (xhr.readyState === 4) { + try { + var response = JSON.parse(xhr.responseText); + if (response.result === 1) { + alert(successMessage); + } else { + alert(errorMessage); + } + } catch (e) { + alert(successMessage); + } + } + }; + xhr.onerror = function(e) { + alert(errorText(e)); + }; + + xhr.open('POST', e.target.action); + xhr.send(fd); + + return false; + }); + form.file.addEventListener('change', function(e) { + if (e.target.files.length) { + var reader = new FileReader(); + reader.onload = function() { + var hash = window.md5(reader.result); + form.setAttribute('action', '/update?md5='+hash); + unlock(form.submit); + }; + reader.onerror = function() { + alert('Ошибка чтения файла'); + }; + reader.readAsBinaryString(e.target.files[0]); + } + }); +} + +window.initApp = function() { + initNetworkSettings(); + initUpdateForm(); +}
\ No newline at end of file |