X-Git-Url: https://git.rvb.name/esp-clock.git/blobdiff_plain/dab14a20e37e760a82b72f50f765caa26fff556e..6d3be4253d91ef9289fa4f3b7e280b2258fabaf1:/data/web/script.js diff --git a/data/web/script.js b/data/web/script.js index 025339e..247126c 100644 --- a/data/web/script.js +++ b/data/web/script.js @@ -1,61 +1,27 @@ -(function (window, document) { - - // we fetch the elements each time because docusaurus removes the previous - // element references on page navigation - function getElements() { - return { - layout: document.getElementById('layout'), - menu: document.getElementById('menu'), - menuLink: document.getElementById('menuLink') - }; - } - - function toggleClass(element, className) { - var classes = element.className.split(/\s+/); - var length = classes.length; - var i = 0; - - for (; i < length; i++) { - if (classes[i] === className) { - classes.splice(i, 1); - break; - } - } - // The className is not found - if (length === classes.length) { - classes.push(className); - } - - element.className = classes.join(' '); - } - - function toggleAll() { - var active = 'active'; - var elements = getElements(); - - toggleClass(elements.layout, active); - toggleClass(elements.menu, active); - toggleClass(elements.menuLink, active); - } - - function handleEvent(e) { - var elements = getElements(); - - if (e.target.id === elements.menuLink.id) { - toggleAll(); - e.preventDefault(); - } else if (elements.menu.className.indexOf('active') !== -1) { - toggleAll(); - } - } - - document.addEventListener('click', handleEvent); - -}(this, this.document)); - var pages var parameters = {} var daynames = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'] +var msgT + +function toggleMenu(e) { + active = (document.getElementById('menuLink').className.indexOf('active') !== -1) + if (active || e.target.id == 'menuLink' || e.target.id == 'menuBtn') { + elements = [ document.getElementById('layout'), document.getElementById('menu'), document.getElementById('menuLink') ] + for (const element of elements) { + if (!active) { + element.classList.add('active') + } else { + element.classList.remove('active') + } + } + if (e.target.id == 'menuLink' || e.target.id == 'menuBtn') { + e.preventDefault() + } + e.stopPropagation() + } +} + +document.getElementById('layout').addEventListener('click', toggleMenu) function encode(r){ r = String(r) @@ -63,22 +29,22 @@ function encode(r){ } function getAnchor() { - return window.location.hash; + return window.location.hash.slice(1); } -function DrawHeader(project) { +function drawHeader(project) { var menu_header = document.getElementById('_ui_menu_header') menu_header.innerHTML = project.name document.title = project.name + '/' + project.version } -function ParseJsonQ(url, callback) { +function parseJsonQ(url, callback) { var req = new XMLHttpRequest(); req.onreadystatechange = function () { if (this.readyState != 4) return; if (this.status != 200 && this.status != 500 && this.status != 404) { - setTimeout(ParseJsonQ(url, callback),30000); + setTimeout(parseJsonQ(url, callback),30000); return; } var json = JSON.parse(this.responseText) @@ -90,7 +56,7 @@ function ParseJsonQ(url, callback) { } -function UpdateElement(id, value) { +function updateElement(id, value) { var element = document.getElementById("_ui_element_"+id) if (!element) return; var ui_class = element.dataset.ui_class; @@ -122,17 +88,17 @@ function UpdateElement(id, value) { } } -function UpdateValues(json) { +function updateValues(json) { for (var key in json) { var obj = document.getElementById("_ui_element_"+key) if (obj) { - UpdateElement(key, json[key]) + updateElement(key, json[key]) } parameters[key] = json[key] } var notification = document.getElementById('_ui_notification'); if (parameters['_changed']) { - notification.innerHTML = '' + notification.innerHTML = '' notification.removeAttribute('hidden') } else { notification.innerHTML = '' @@ -149,35 +115,39 @@ function sendUpdate(id) { case 'number': case 'range': if (input.checkValidity() && input.value != parameters[id]) { - ParseJsonQ('/config/set?name=' + id + '&value=' + encodeURIComponent(input.value), function(json) { - UpdateValues(json) + parseJsonQ('/config/set?name=' + id + '&value=' + encodeURIComponent(input.value), function(json) { + updateValues(json) }) } break case 'select': - ParseJsonQ('/config/set?name=' + id + '&value=' + encodeURIComponent(input.selectedOptions[0].value), function(json) { - UpdateValues(json) + parseJsonQ('/config/set?name=' + id + '&value=' + encodeURIComponent(input.selectedOptions[0].value), function(json) { + updateValues(json) }) break; case 'checkbox': - ParseJsonQ('/config/set?name=' + id + '&value=' + (input.checked?'true':'false'), function(json) { - UpdateValues(json) + parseJsonQ('/config/set?name=' + id + '&value=' + (input.checked?'true':'false'), function(json) { + updateValues(json) }) break; case 'week': - ParseJsonQ('/config/set?name=' + id + '&value=' + input.dataset.value, function(json) { - UpdateValues(json) + parseJsonQ('/config/set?name=' + id + '&value=' + input.dataset.value, function(json) { + updateValues(json) }) break; } } -function sendAction(name) { - ParseJsonQ('/action?name=' + name, function(json) { +function sendAction(name, params = {}) { + var url = '/action?name=' + name + for (var param in params) { + url += '&'+param+'='+encodeURIComponent(params[param]) + } + parseJsonQ(url, function(json) { if (json.result == 'FAILED') { alert(json.message) if (json.page) { - DrawPage(json.page) + drawPage(json.page) } } else { location.reload() @@ -185,7 +155,7 @@ function sendAction(name) { }) } -function ShowPwd(id) { +function showPwd(id) { var x = document.getElementById('_ui_element_' + id) if (x.type === "password") { x.type = "text"; @@ -194,20 +164,41 @@ function ShowPwd(id) { } } -function OpenSelect(id) { +function openSelect(id) { var selector = document.getElementById('_ui_elemmodal_'+id); selector.removeAttribute("hidden") } -function CloseSelect(id) { +function closeSelect(id) { var selector = document.getElementById('_ui_elemmodal_'+id); selector.hidden = true } -function SelectWiFi(id, ssid) { - CloseSelect(id); +function closeMsg() { + document.getElementById("_ui_message").hidden = true; +} + +function fadeMsg() { + var msg = document.getElementById('_ui_message'); + msg.classList.add("fadeout") + msgT = setTimeout(()=> { closeMsg() }, 5000); +} + +function openMsg(msgText) { + document.getElementById("_ui_message_text").innerText = msgText; + document.getElementById("_ui_message").classList.remove("fadeout"); + document.getElementById("_ui_message").removeAttribute('hidden'); + + if (msgT) { + window.clearTimeout(msgT); + } + msgT = setTimeout(()=> { fadeMsg(); }, 5000); +} + +function selectWiFi(id, ssid) { + closeSelect(id); var x = document.getElementById('_ui_element_' + id) - UpdateElement(x,ssid); + updateElement(x,ssid); sendUpdate(id) } @@ -223,13 +214,13 @@ function getWiFi(id) { return; } var json = JSON.parse(this.responseText) - var table = '' + var table = '
SSIDBSSIDRSSIКаналЗащита
' if (!json.length) { setTimeout(getWiFi(id),5000); } for (idx in json) { - var encryption = json[idx].secure == 2? "TKIP" : json[idx].secure == 5? "WEP" : json[idx].secure == 4? "CCMP" : json[idx].secure == 7? "нет" : json[idx].secure == 8? "Автоматически" : "Не определено"; - table += '' + var encryption = json[idx].secure == 2? "TKIP" : json[idx].secure == 5? "WEP" : json[idx].secure == 4? "CCMP" : json[idx].secure == 7? "нет" : json[idx].secure == 8? "Авто" : "Неизв."; + table += '' } table += '
SSIDBSSIDRSSIКаналЗащита
'+json[idx].ssid+''+json[idx].bssid+''+json[idx].rssi+''+json[idx].channel+''+encryption+'
'+json[idx].ssid+''+json[idx].bssid+''+json[idx].rssi+''+json[idx].channel+''+encryption+'
' @@ -238,10 +229,9 @@ function getWiFi(id) { req.open("GET", "/wifi/scan", true); req.send() - } -function ClickDay(id, day) { +function clickDay(id, day) { value = parameters[id].split('') day_value = value[day] day_value = (day_value=='0')?'1':'0' @@ -252,7 +242,35 @@ function ClickDay(id, day) { sendUpdate(id); } -function ElementHTML(element) { +function sendTime(id) { + var value = document.getElementById('_ui_element_' + id).value + if (value) { + var date = new Date(value) + var timestamp = Math.floor(date.getTime()/1000); + sendAction('time',{"timestamp":timestamp}) + } +} + +function downloadFile(url, name) { + const a = document.createElement('a') + a.href = url + a.download = name?name:url.split('/').pop() + document.body.appendChild(a) + a.click() + document.body.removeChild(a) +} + +function uploadConfig() { + var elem = document.getElementById('_config_file') + if (elem.value) { + var data = elem.files[0] + console.log(data) + fetch('/config/put', {method:'PUT',body:data}); + elem.value = null + } +} + +function elementHTML(element) { var value if (parameters[element.id] || !isNaN(parameters[element.id])) { value = parameters[element.id] @@ -265,13 +283,13 @@ function ElementHTML(element) { case 'hr': return '

' case 'button': - return '
' + return '
' case 'password': return '
' - + '' - + '
👁
' + + '
' + + '
' case 'input': var pattern = "" if (element.pattern) { @@ -286,15 +304,15 @@ function ElementHTML(element) { pattern = ' pattern="' + encode(element.pattern) + '"' } return '
' - + '' - + '
📶
' + + '
' + + '
' + '' + + '
' + + '
' case 'checkbox': return '
' + case 'config': + return '
' + + '
' + + '' + + '' + + '' + + '
' case 'table': default: - return '
' 
-        + encode(element.label)+ '
' + encode(value) + '
' + return '
' + + encode(element.label)+ '' + encode(value) + '
' } } -function DrawPage(id) { +function drawPage(id) { var idx =0, i=0 for (const page of pages) { var menu_link = document.getElementById('_ui_pglink_' + page.id) @@ -359,37 +391,66 @@ function DrawPage(id) { var page_content = document.getElementById("_ui_page_content"); var content = '' for (const element of pages[idx].elements) { - content = content + ElementHTML(element) + content = content + elementHTML(element) + '\n' } page_content.innerHTML = content - window.location.hash = '#'+id + window.location.hash = id } -function DrawNavigator(project, pages) { +function drawNavigator(project, pages) { var menu = document.getElementById('_ui_menu_list'); var list = '' for (const page of pages) { list = list + '' } menu.innerHTML = list } -function DrawUI(ui) { - DrawHeader(ui.project) +function drawContacts(contacts) { + if (!contacts) return; + var contact_list = '

Контакты

' + for (contact of contacts) { + const url = new URL(contact) + var ref + switch (url.protocol) { + case 'http': + case 'https:': + ref = ''+url.hostname + break + case 'mailto:': + ref = ''+url.pathname + break + case 'tg:': + ref = ''+url.pathname + contact = 'tg://resolve?domain='+url.pathname + break + default: + ref = ''+url.pathname + } + contact_list += ''+ref+'' + } + var footer = document.getElementById('_ui_contacts'); + footer.innerHTML = contact_list +} + +function drawUI(ui) { + drawHeader(ui.project) pages = ui.pages - DrawNavigator(ui.project, pages) + drawNavigator(ui.project, pages) + drawContacts(ui.project.contacts) var anchor = getAnchor() if (anchor) { - DrawPage(anchor) + drawPage(anchor) } else { - DrawPage(pages[0].id) + drawPage(pages[0].id) } } function GetUI() { - ParseJsonQ("/ui", DrawUI); + parseJsonQ("/ui", drawUI); } GetUI() @@ -397,31 +458,32 @@ GetUI() function initES() { if (!!window.EventSource) { var source = new EventSource('/events'); + openMsg('Соединение установлено') source.onerror = function(e) { if (source.readyState == 2) { + openMsg('Соединение прервано') setTimeout(initES, 5000); } }; - source.addEventListener('keepalive', function(e) { - UpdateValues(JSON.parse(e.data)); - }, false); - source.addEventListener('update', function(e) { - UpdateValues(JSON.parse(e.data)); + updateValues(JSON.parse(e.data)); + }, false); + source.addEventListener('message', function(e) { + openMsg(e.data); }, false); } } initES(); -function DrawConfig(cfg) { - UpdateValues(cfg) +function drawConfig(cfg) { + updateValues(cfg) } function GetCfg() { - ParseJsonQ("/config/get", DrawConfig); + parseJsonQ("/config/get", drawConfig); } GetCfg()