const messages = new Map(); const users = new Map(); function xhttp_request(location) { var xhttp = new XMLHttpRequest(); var return_string; xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { // Typical action to be performed when the document is ready: return_string = xhttp.responseText; } }; xhttp.open("GET", "http://localhost/api/" + location, false); xhttp.send(); return JSON.parse(return_string); } function xhttp_post(location, json) { var xhttp = new XMLHttpRequest(); xhttp.open("POST", "http://localhost/api/" + location, false); xhttp.setRequestHeader("Content-Type", "application/json") var return_string; xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { return_string = xhttp.responseText; } }; xhttp.send(json); return JSON.parse(return_string); } function format_message(m) { var s; var sender = get_user_name(m.sender); if (m.deleted) { s = `${m.id}|${sender}: deleted` // s = "" + m.id + "|" + m.sender + ": /deleted/" + "" } else { s = `${m.id}|${sender}: ${m.message}` // s = "" + m.id + "|" + m.sender + ": " + m.message + "" } return s } function send() { var input = document.getElementById("input").value; let message = JSON.stringify({"sender": 0, "message": input}) var id = xhttp_post("send_message", message) get_message(id.Ok); document.getElementById("input").value = '' } function get_newest_cache_id() { let last = -1; for (k of messages.keys()) { if (k > last) { last = k } } return last } // Returns message list function get_newest_messages() { let newest_id = xhttp_request("get_message_id_newest").Ok; let newest_cache_id = get_newest_cache_id(); let final_array = []; if (newest_id == newest_cache_id) { return } if (newest_cache_id == -1) { get_message(0) return get_newest_messages() } if (newest_id > newest_cache_id) { let delta = newest_id - newest_cache_id ; if (delta > 25) { let oldest = newest_id - 25; let newest = delta; let list = get_message_list(oldest, newest); for (x of list.values()) { final_array.push(x) } newest_id = oldest; if (oldest - 25 < 0) { newest_cache_id = 0 } else { newest_cache_id = oldest - 25 } } } let list = get_message_list(newest_cache_id, newest_id) for (x of list.values()) { final_array.push(x) } // Insert all values into the message map for (x of final_array.values()) { messages.set(x.id, x) } chatwindow() } function get_message_list(oldest, newest) { let req = xhttp_request(`get_message_list/${oldest}/${newest}`).Ok return req } // Returns dom function get_message(id) { let cached = messages.get(id) if (cached != undefined) { return to_dom(cached) } // Get message let msg = xhttp_request("get_message/" + id).Ok; messages.set(msg.id, msg) let dom = to_dom(msg); chatwindow() return dom } function get_user_name(id) { let cached = users.get(id) if (cached != undefined) { return cached.username } let user = xhttp_request("get_user/" + id).Ok; users.set(user.id, user) return user.username } // Returns dom function to_dom(x) { let dom = new DOMParser().parseFromString(format_message(x), "text/xml").firstChild; return dom } function chatwindow() { let window = document.getElementById("chatwindow"); window.innerHTML = ""; let array = []; for (v of messages.values()) { array.push(v); } array.sort( function(a, b) { return a.id - b.id } ); for (v of array) { let dom = to_dom(v); window.append(dom) } window.scrollTop = window.scrollHeight } function inputkey(event) { let key = event.key let shift = event.shiftKey; if (key == "Enter" && shift) { send() } else if (key == "Enter" && !shift) { this.value += "\n" } } function onload() { let server_info = xhttp_request(""); document.getElementById("info").innerHTML += server_info.version + ", " + server_info.name + ", users: " + server_info.users; // Get all messages on startup // get_newest_messages(); const interval = setInterval(get_newest_messages, 1000); }