blob: 2036a868017ce4bdebf58a260825cfe65719494b [file] [log] [blame]
/*
* Copyright (c) 2020 Alexander Kozhinov <AlexanderKozhinov@yandex.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
var connected
var first_run
var ws
var LogMsgType = {
TEXT: 'text',
BINARY: 'binary'
}
var LogMsgSender = {
SYSTEM: 'system',
LOCAL: 'local',
REMOTE: 'remote',
CONSOLE: 'console'
}
var MAX_LOG_SIZE = 10
var SECOND = 1000
var MINUTE = SECOND * 60
var HOUR = MINUTE * 60
var DAY = HOUR * 24
var MONTH = DAY * 30
var YEAR = MONTH * 12
var TIME_UP_PERIOD_SEC = 5
function init() {
addLogEntry(LogMsgSender.CONSOLE,
LogMsgType.TEXT, 'establishing connection to the server...')
ws = new WebSocket(location.origin.replace("http", "ws") + "/ws")
first_run = "true"
connected = "false"
ws.onopen = function() {
addLogEntry(LogMsgSender.CONSOLE, LogMsgType.TEXT,
'connection opened')
addLogEntry(LogMsgSender.SYSTEM, LogMsgType.TEXT,
"The connection was established successfully (in " +
(Date.now() - ws.__openTime)+ " ms).\n" +
(ws.extensions ? 'Negotiated Extensions: ' +
ws.extensions : '') +
(ws.protocol ? 'Negotiated Protocol: ' +
ws.protocol : ''))
connected = "true"
}
ws.onmessage = function(e) {
addLogEntry(LogMsgSender.REMOTE,
LogMsgType.TEXT, 'data received: ' + e.data)
}
ws.onclose = function() {
addLogEntry(LogMsgSender.CONSOLE, LogMsgType.TEXT,
'connection closed')
connected = "false"
}
ws.onerror = function(e) {
addLogEntry(LogMsgSender.CONSOLE, LogMsgType.TEXT,
'data error: ' + e.data)
console.log(e)
}
var sendText = function(text) {
addLogEntry(LogMsgSender.LOCAL, LogMsgType.TEXT, text)
ws.send(text)
}
document.getElementById('btn_send').onclick = function(event) {
event.preventDefault()
var text2send = document.getElementById('message_text').value
sendText(text2send)
scrollLogToBottom()
}
document.getElementById('btn_clear_log').onclick = function(event) {
event.preventDefault()
clearLog()
}
window.setInterval(updateTimestamps, TIME_UP_PERIOD_SEC * SECOND)
}
function updateTimestamps() {
var entries = document.getElementsByClassName('entries')
var now = Date.now()
var timestamp = null
var entry = null
var old_time = null
for (var i = 0; i < entries[0].childElementCount; i++) {
entry = entries[0].children[i]
old_time = Number(entry.getAttribute('timestamp'))
timestamp = entry.getElementsByClassName('timestamp')[0]
timestamp.innerHTML = formatTimeDifference(now, old_time)
}
}
function formatTimeDifference(now, then) {
var difference = Math.abs(now - then)
if (difference < TIME_UP_PERIOD_SEC * SECOND) {
return 'just now'
}
if (difference < MINUTE) {
return '< 1 min ago'
}
if (difference < HOUR) {
return Math.round(difference / MINUTE) + ' min ago'
}
if (difference < DAY) {
return Math.round(difference / HOUR) + ' hr ago'
}
if (difference < MONTH) {
return Math.round(difference / DAY) + ' day ago'
}
return Math.round(difference / YEAR) + ' yr ago'
}
function blobToHex(blob) {
// TODO: Implement (seems to be non-trivial).
return ''
}
function logIsScrolledToBottom() {
var j = document.getElementsByClassName('log')
var e = j[0]
return e.scrollTop + j.height +
10 /* padding */ >= e.scrollHeight - 10 /* some tolerance */
}
function scrollLogToBottom() {
var e = document.getElementsByClassName('log')[0]
e.scrollTop = e.scrollHeight
}
function pruneLog() {
var e = document.getElementsByClassName('entries')
if (e.length == 0) {
return
}
if (e[0].children.length == MAX_LOG_SIZE) {
e[0].children[0].remove()
}
}
function addLogEntry(sender, type, data) {
pruneLog()
if (type == LogMsgType.BINARY) {
data = '(BINARY MESSAGE: ' + data.size + ' bytes)\n' +
blobToHex(data)
} else {
data = data || '(empty message)'
}
var entries = document.getElementsByClassName('entries')
var entry = entries[0].appendChild(document.createElement('div'))
entry.classList += 'entry'
var publisher = entry.appendChild(document.createElement('div'))
publisher.classList += 'publisher'
publisher.classList += ' ' + sender
var content = entry.appendChild(document.createElement('div'))
content.classList += 'content'
content.classList += ' ' + type
var timestamp = publisher.appendChild(document.createElement('div'))
timestamp.classList += 'timestamp'
entry.setAttribute('timestamp', '' + Date.now())
content.innerHTML = data
timestamp.innerHTML = 'just now'
var scroll = logIsScrolledToBottom()
if (scroll) {
scrollLogToBottom()
}
}
function clearLog() {
var entries = document.getElementsByClassName('entries')[0]
while (entries.firstChild) entries.removeChild(entries.firstChild)
}