thelounge/client/js/chat.js
2014-03-07 22:28:30 +01:00

177 lines
3.5 KiB
JavaScript

$(function() {
var socket = io.connect("");
socket.on("event", function(event) {
render(event);
});
var chat = $("#chat");
var sidebar = $("#sidebar");
// Templates
var networks = $("#networks").html();
var channels = $("#channels").html();
var messages = $("#messages").html();
var users = $("#users").html()
function render(event) {
var type = event.type;
var data = event.data;
var action = event.action;
var target = event.target;
if (action == "REMOVE") {
remove(target);
return;
}
if (target != "") {
target = $("[data-id='" + target + "']");
}
switch (type) {
case "NETWORK":
case "CHANNEL":
refresh(data);
break;
case "USER":
target = target.find(".users");
target.html(Mustache.render(users, {users: event.data}));
break;
case "MESSAGE":
var keepAtBottom = target.isScrollBottom();
target = target.find(".messages");
target.append(Mustache.render(messages, {messages: event.data}));
if (keepAtBottom) {
target.scrollToBottom();
}
break;
}
}
function remove(id) {
$("[data-id='" + id + "']").remove();
}
function refresh(data) {
chat.html("");
var partials = {
users: users,
messages: messages
};
data.forEach(function(network) {
chat.append(Mustache.render(channels, network, partials));
});
sidebar.html(
Mustache.render(networks, {
networks: data
})
);
chat.find(".messages").scrollToBottom();
chat.find(".window")
// Sort windows by `data-id` value.
.sort(function(a, b) { return ($(a).data("id") - $(b).data("id")); })
.last()
.bringToTop()
.find(".input")
.focus();
}
var View = {};
View.refresh = function(event) {
var data = event.data;
sidebar.html(
Mustache.render(networks, {
networks: data
})
);
chat.html("");
var partials = {
users: users,
messages: messages
};
data.forEach(function(network) {
chat.append(Mustache.render(channels, network, partials));
});
chat.find(".messages").scrollToBottom();
chat.find(".window")
// Sort windows by `data-id` value.
.sort(function(a, b) { return ($(a).data("id") - $(b).data("id")); })
.last()
.bringToTop()
.find(".input")
.focus();
};
View.add = function(event) {
var target = $("[data-id='" + event.target + "'] ");
switch (event.type) {
case "users":
target = target.find(".users");
target.html(Mustache.render(users, {users: event.data}));
break;
case "messages":
var keepAtBottom = target.isScrollBottom();
target = target.find(".messages");
target.append(Mustache.render(messages, {messages: event.data}));
if (keepAtBottom) {
target.scrollToBottom();
}
break;
}
};
View.remove = function(event) {
$("[data-id='" + event.target + "']").remove();
};
chat.on("submit", "form", function() {
var input = $(this).find(".input");
var text = input.val();
if (text != "") {
input.val("");
socket.emit("input", {
id: input.data("target"),
text: text
});
}
});
sidebar.on("click", ".channel", function() {
chat.find(".window[data-id='" + $(this).data("id") + "']")
.bringToTop();
});
});
(function() {
var highest = 1;
$.fn.bringToTop = function() {
return this
.css('z-index', highest++)
.find("input")
.focus();
};
$.fn.scrollToBottom = function() {
return this.scrollTop(this.prop("scrollHeight"));
};
$.fn.isScrollBottom = function() {
var height = this.outerHeight();
var scroll = this.scrollTop();
if ((scroll + height + 5) >= this.prop("scrollHeight")) {
return true;
}
};
})();