(function () {
var current_channel = {};
- var users_per_id = {}, current_user_id = 0;
+ var users_per_id = null;
+ var channels_per_id = null;
- function add_msg(sender, msg) {
- var p = document.createElement("P");
+ function clear_children(element) {
+ while (element.firstChild) {
+ element.removeChild(element.firstChild);
+ }
+ }
+
+ function get_data_id(element) {
+ var attr = element.getAttribute("data-id");
+ if (attr === null)
+ return null;
+ return Number(attr);
+ }
+
+ function get_current_user_id() {
+ return get_data_id(document.getElementsByClassName("user")[0].children[0]);
+ }
+
+ function set_msg(p, sender, msg) {
+ clear_children(p);
+ if (typeof sender === 'number') {
+ sender = users_per_id[sender].username;
+ }
p.appendChild(document.createTextNode(sender));
p.appendChild(document.createTextNode(": "));
p.appendChild(document.createTextNode(msg));
+ }
+
+ function add_msg(msg_id, sender, msg) {
+ var p = document.createElement("P");
+ p.setAttribute("data-id", msg_id);
+ set_msg(p, sender, msg);
document.getElementsByClassName("messages")[0].appendChild(p);
}
+ function find_existing_message(msg_id, callback) {
+ var i, messages = document.getElementsByClassName("messages")[0];
+ for (i = 0; i < messages.children.length; i++) {
+ if (get_data_id(messages.children[i]) === msg_id) {
+ fetch_data(current_channel.url + msg_id + "/", callback);
+ return;
+ }
+ }
+ }
+
+ function delete_existing_message(msg_id) {
+ var i, messages = document.getElementsByClassName("messages")[0];
+ for (i = 0; i < messages.children.length; i++) {
+ if (get_data_id(messages.children[i]) === msg_id) {
+ messages.removeChild(messages.children[i]);
+ return;
+ }
+ }
+ }
+
function ws_receive(msg) {
- add_msg("ws", msg.data);
+ var data = JSON.parse(msg.data);
+ add_msg(null, "ws", msg.data);
+ if (
+ current_channel.url === "/api/privatemessage/"
+ && data.table === "chat_privatemessage"
+ ) {
+ if (
+ (
+ data.new.sender_id === get_current_user_id()
+ && data.new.recipient_id === current_channel.data.recipient
+ ) || (
+ data.new.sender_id === current_channel.data.recipient
+ && data.new.recipient_id === get_current_user_id()
+ )
+ ) {
+ if (data.op === "INSERT") {
+ fetch_data(
+ current_channel.url + data.new.id + "/", add_privatemessage
+ );
+ } else if (data.op === "UPDATE") {
+ find_existing_message(data.new.id, update_privatemessage);
+ } else if (data.op === "DELETE") {
+ delete_existing_message(data.old.id);
+ } else if (data.op === "TRUNCATE") {
+ clear_children(document.getElementsByClassName("messages")[0]);
+ }
+ }
+ } else if (
+ current_channel.url === "/api/channelmessage/"
+ && data.table === "chat_channelmessage"
+ ) {
+ if (data.new.channel_id === current_channel.data.channel) {
+ if (data.op === "INSERT") {
+ fetch_data(
+ current_channel.url + data.new.id + "/", add_channelmessage
+ );
+ } else if (data.op === "UPDATE") {
+ find_existing_message(data.new.id, update_channelmessage);
+ } else if (data.op === "DELETE") {
+ delete_existing_message(data.old.id);
+ } else if (data.op === "TRUNCATE") {
+ clear_children(document.getElementsByClassName("messages")[0]);
+ }
+ }
+ } else if (data.table === "chat_user") {
+ reload_users();
+ } else if (data.table === "chat_channel") {
+ reload_channels();
+ }
+ }
+
+ function reload_users() {
+ clear_children(document.getElementsByClassName("users")[0].children[0]);
+ fetch_data("/api/user/", setup_user_callback);
+ }
+
+ function reload_channels() {
+ clear_children(document.getElementsByClassName("channels")[0].children[0]);
+ fetch_data("/api/channel/", setup_channel_callback);
}
function xhr_error(msg) {
console.log(msg);
- add_msg("xhr_error", msg);
+ add_msg(null, "xhr_error", msg);
+ }
+
+ function xhr_abort(msg) {
+ console.log(msg);
+ add_msg(null, "xhr_abort", msg);
}
function fetch_data(url, callback) {
function post_data(url, data, callback) {
var xhr = new XMLHttpRequest();
- xhr.addEventListener("load", callback);
+ if (callback !== null) {
+ xhr.addEventListener("load", callback);
+ }
xhr.addEventListener("error", xhr_error);
+ xhr.addEventListener("abort", xhr_abort);
xhr.open("post", url);
xhr.send(data);
}
+ function add_privatemessage() {
+ var msg = JSON.parse(this.responseText);
+ add_msg(msg.id, msg.sender, msg.text);
+ }
+
+ function update_privatemessage() {
+ var msg = JSON.parse(this.responseText);
+ var i, messages = document.getElementsByClassName("messages")[0];
+ for (i = 0; i < messages.children.length; i++) {
+ if (get_data_id(messages.children[i]) === msg.id) {
+ set_msg(messages.children[i], msg.sender, msg.text);
+ return;
+ }
+ }
+ }
+
function add_privatemessages() {
var msgs = JSON.parse(this.responseText), i;
for (i = 0; i < msgs.result.length; i += 1) {
- add_msg(users_per_id[msgs.result[i].sender].username, msgs.result[i].text);
+ add_msg(msgs.result[i].id, msgs.result[i].sender, msgs.result[i].text);
}
}
"url": "/api/privatemessage/",
"data": {"recipient": user_id},
}
- while(messages.firstChild) {
- messages.removeChild(messages.firstChild);
- }
+ clear_children(messages);
fetch_data(
"/api/privatemessage/?other=" + user_id.toString(), add_privatemessages
);
}
function setup_user_callback() {
- var data = JSON.parse(this.responseText), ul, li, a;
+ var data = JSON.parse(this.responseText), ul, li, a, p;
ul = document.getElementsByClassName("users")[0].children[0];
+ users_per_id = {};
for (i = 0; i < data.result.length; i += 1) {
users_per_id[data.result[i].id] = data.result[i];
if (data.result[i].is_current) {
- current_user_id = data.result[i].id;
+ p = document.createElement("P");
+ p.setAttribute("data-id", data.result[i].id);
+ p.appendChild(document.createTextNode(data.result[i].username));
+ document.getElementsByClassName("user")[0].appendChild(p);
}
li = document.createElement("li");
+ li.setAttribute("data-id", data.result[i].id);
a = document.createElement("a");
a.setAttribute("href", "#");
a.appendChild(
}
}
+ function add_channelmessage() {
+ var msg = JSON.parse(this.responseText);
+ add_msg(msg.id, msg.user, msg.text);
+ }
+
+ function update_channelmessage() {
+ var msg = JSON.parse(this.responseText);
+ var i, messages = document.getElementsByClassName("messages")[0];
+ for (i = 0; i < messages.children.length; i++) {
+ if (get_data_id(messages.children[i]) === msg.id) {
+ set_msg(messages.children[i], msg.user, msg.text);
+ return;
+ }
+ }
+ }
+
function add_channelmessages() {
var msgs = JSON.parse(this.responseText), i;
for (i = 0; i < msgs.result.length; i += 1) {
- add_msg(users_per_id[msgs.result[i].user].username, msgs.result[i].text);
+ add_msg(msgs.result[i].id, msgs.result[i].user, msgs.result[i].text);
}
}
"url": "/api/channelmessage/",
"data": {"channel": channel_id},
}
- while(messages.firstChild) {
- messages.removeChild(messages.firstChild);
- }
+ clear_children(messages);
fetch_data(
"/api/channelmessage/?channel=" + channel_id.toString(), add_channelmessages
);
function setup_channel_callback() {
var data = JSON.parse(this.responseText), ul, li, a;
ul = document.getElementsByClassName("channels")[0].children[0];
+ channels_per_id = {};
for (i = 0; i < data.result.length; i += 1) {
+ channels_per_id[data.result[i].id] = data.result[i];
li = document.createElement("li");
+ li.setAttribute("data-id", data.result[i].id);
a = document.createElement("a");
a.setAttribute("href", "#");
a.appendChild(document.createTextNode(data.result[i].name));
data[name] = current_channel.data[name];
}
}
- post_data(
- current_channel.url,
- JSON.stringify(data), function () { add_msg("send", "success"); }
- );
+ post_data(current_channel.url, JSON.stringify(data), null);
ta.value = "";
}
- window.addEventListener("load", function(e) {
- var ws, schema;
- e = e || window.event;
- if (e.target.readyState !== "complete") {
- return;
+ function input_onkeydown(event) {
+ var keycode;
+ event = event || window.event;
+ keycode = event.code || event.key;
+ if (keycode === "Enter" || keycode === "NumpadEnter") {
+ // todo: make it possible to add newlines using ctrl+enter
+ send();
+ event.preventDefault();
+ event.stopPropagation();
}
- // setup ws
- schema = {"http:": "ws:", "https:": "wss:"}[window.location.protocol];
- ws = new WebSocket(schema + "//" + window.location.host + "/");
- ws.addEventListener("message", ws_receive);
- fetch_data("/api/user/", setup_user_callback);
- fetch_data("/api/channel/", setup_channel_callback);
- document.getElementsByClassName("input")[0].children[1].addEventListener(
- "click", send
- );
- });
+ }
+
+ window.addEventListener(
+ "load",
+ function (event) {
+ var ws, schema, input;
+ event = event || window.event;
+ if (event.target.readyState !== "complete") {
+ return;
+ }
+ schema = {"http:": "ws:", "https:": "wss:"}[window.location.protocol];
+ ws = new WebSocket(schema + "//" + window.location.host + "/");
+ ws.addEventListener("message", ws_receive);
+ input = document.getElementsByClassName("input")[0];
+ input.children[0].addEventListener("keydown", input_onkeydown);
+ input.children[0].value = "";
+ input.children[1].addEventListener("click", send);
+ reload_users();
+ reload_channels();
+ }
+ );
}());