2014-03-06 15:11:25 +00:00
|
|
|
$(function() {
|
|
|
|
var socket = io.connect("");
|
2014-03-24 13:44:41 +00:00
|
|
|
$.each(["networks", "channels", "messages", "users"], function(i, type) {
|
2014-03-19 17:30:06 +00:00
|
|
|
socket.on(type, function(json) {
|
|
|
|
event(type, json);
|
2014-03-12 13:10:53 +00:00
|
|
|
});
|
2014-03-07 03:18:53 +00:00
|
|
|
});
|
2014-03-06 15:11:25 +00:00
|
|
|
|
|
|
|
var chat = $("#chat");
|
|
|
|
var sidebar = $("#sidebar");
|
2014-03-14 19:21:00 +00:00
|
|
|
|
2014-03-19 17:30:06 +00:00
|
|
|
var tpl = [];
|
2014-03-22 21:42:02 +00:00
|
|
|
function render(id, json) {
|
|
|
|
tpl[id] = tpl[id] || Handlebars.compile($(id).html());
|
|
|
|
return tpl[id](json);
|
2014-03-19 17:30:06 +00:00
|
|
|
}
|
2014-03-22 23:42:07 +00:00
|
|
|
|
2014-03-19 17:30:06 +00:00
|
|
|
function event(type, json) {
|
2014-03-12 13:10:53 +00:00
|
|
|
switch (type) {
|
2014-03-17 16:24:32 +00:00
|
|
|
|
2014-03-24 13:44:41 +00:00
|
|
|
case "networks":
|
2014-03-18 23:08:11 +00:00
|
|
|
var html = "";
|
2014-03-19 17:30:06 +00:00
|
|
|
json.forEach(function(network) {
|
2014-03-22 21:42:02 +00:00
|
|
|
html += render("#window", network);
|
2014-03-12 13:10:53 +00:00
|
|
|
});
|
2014-03-18 23:08:11 +00:00
|
|
|
$("#windows")[0].innerHTML = html;
|
|
|
|
|
2014-03-16 20:07:27 +00:00
|
|
|
sidebar.find("#list").html(
|
2014-03-22 21:42:02 +00:00
|
|
|
render("#network", {networks: json})
|
2014-03-17 16:24:32 +00:00
|
|
|
).find(".channel")
|
|
|
|
.first()
|
2014-03-14 19:21:00 +00:00
|
|
|
.addClass("active");
|
2014-03-12 13:10:53 +00:00
|
|
|
|
2014-03-19 23:24:45 +00:00
|
|
|
chat.find(".messages").scrollGlue({animate: 400}).scrollToBottom();
|
2014-03-12 13:10:53 +00:00
|
|
|
chat.find(".window")
|
2014-03-17 16:24:32 +00:00
|
|
|
.first()
|
2014-03-14 19:21:00 +00:00
|
|
|
.bringToTop();
|
2014-03-12 13:10:53 +00:00
|
|
|
break;
|
|
|
|
|
2014-03-24 13:44:41 +00:00
|
|
|
case "channels":
|
2014-03-19 17:30:06 +00:00
|
|
|
var target = json.target;
|
|
|
|
if (json.action == "remove") {
|
|
|
|
$("[data-id='" + json.data.id + "']").remove();
|
2014-03-17 16:24:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-18 23:08:11 +00:00
|
|
|
var network = sidebar
|
|
|
|
.find(".network")
|
|
|
|
.find(".channel")
|
|
|
|
.removeClass("active")
|
|
|
|
.end();
|
|
|
|
|
2014-03-19 17:30:06 +00:00
|
|
|
network = network.filter("[data-id='" + json.target + "']").append(
|
|
|
|
render("#channel", {channels: json.data})
|
2014-03-18 23:08:11 +00:00
|
|
|
).find(".channel")
|
|
|
|
.last()
|
|
|
|
.addClass("active");
|
|
|
|
|
|
|
|
$("#windows").append(
|
2014-03-19 17:30:06 +00:00
|
|
|
render("#window", {channels: json.data})
|
2014-03-18 23:08:11 +00:00
|
|
|
).find(".window")
|
|
|
|
.last()
|
|
|
|
.bringToTop()
|
|
|
|
.find(".messages")
|
2014-03-19 23:24:45 +00:00
|
|
|
.scrollGlue({animate: 400});
|
2014-03-17 16:24:32 +00:00
|
|
|
break;
|
|
|
|
|
2014-03-24 13:44:41 +00:00
|
|
|
case "users":
|
2014-03-17 16:24:32 +00:00
|
|
|
var target;
|
2014-03-19 17:30:06 +00:00
|
|
|
if (typeof json.target !== "undefined") {
|
|
|
|
target = chat.find(".window[data-id='" + json.target + "']");
|
2014-03-17 16:24:32 +00:00
|
|
|
}
|
|
|
|
|
2014-03-12 13:10:53 +00:00
|
|
|
target = target.find(".users");
|
2014-03-19 17:30:06 +00:00
|
|
|
target.html(render("#user", {users: json.data}));
|
2014-03-12 13:10:53 +00:00
|
|
|
break;
|
|
|
|
|
2014-03-24 13:44:41 +00:00
|
|
|
case "messages":
|
2014-03-17 16:24:32 +00:00
|
|
|
var target;
|
2014-03-19 17:30:06 +00:00
|
|
|
if (typeof json.target !== "undefined") {
|
|
|
|
target = chat.find(".window[data-id='" + json.target + "']");
|
2014-03-17 16:24:32 +00:00
|
|
|
}
|
|
|
|
|
2014-03-19 17:30:06 +00:00
|
|
|
var message = json.data;
|
2014-03-17 16:24:32 +00:00
|
|
|
if (message.type == "error") {
|
2014-03-15 16:14:05 +00:00
|
|
|
target = target.parent().find(".active");
|
|
|
|
}
|
2014-03-17 16:24:32 +00:00
|
|
|
|
2014-03-12 13:10:53 +00:00
|
|
|
target = target.find(".messages");
|
2014-03-19 17:30:06 +00:00
|
|
|
target.append(render("#message", {messages: message}));
|
2014-03-12 13:10:53 +00:00
|
|
|
break;
|
2014-03-17 16:24:32 +00:00
|
|
|
|
2014-03-12 13:10:53 +00:00
|
|
|
}
|
2014-03-07 03:18:53 +00:00
|
|
|
}
|
|
|
|
|
2014-03-15 15:51:21 +00:00
|
|
|
sidebar.on("click", ".channel", function(e) {
|
|
|
|
e.preventDefault();
|
2014-03-16 20:07:27 +00:00
|
|
|
sidebar.find("#list .active").removeClass("active");
|
2014-03-17 00:54:58 +00:00
|
|
|
$("#viewport").removeClass();
|
2014-03-15 15:51:21 +00:00
|
|
|
var item = $(this)
|
|
|
|
.addClass("active")
|
|
|
|
.find(".badge")
|
|
|
|
.html("")
|
|
|
|
.end();
|
|
|
|
var id = item.data("id");
|
|
|
|
chat.find(".window[data-id='" + id + "']")
|
|
|
|
.bringToTop();
|
|
|
|
});
|
2014-03-19 23:24:45 +00:00
|
|
|
|
2014-03-16 20:07:27 +00:00
|
|
|
sidebar.find("input[type=checkbox]").each(function() {
|
|
|
|
var input = $(this);
|
|
|
|
var value = input.val();
|
2014-03-22 19:23:48 +00:00
|
|
|
|
|
|
|
var checked = true;
|
|
|
|
if (($.cookie("hidden") || []).indexOf(value) !== -1) {
|
|
|
|
checked = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
input.prop("checked", checked)
|
|
|
|
.wrap("<label>")
|
|
|
|
.parent()
|
|
|
|
.append(value);
|
|
|
|
|
|
|
|
if (checked) {
|
|
|
|
chat.addClass("show-" + value);
|
|
|
|
}
|
|
|
|
|
2014-03-16 20:07:27 +00:00
|
|
|
input.on("change", function() {
|
2014-03-22 19:23:48 +00:00
|
|
|
var hidden = $.cookie("hidden") || "";
|
|
|
|
if (input.prop("checked")) {
|
|
|
|
hidden = hidden.replace(value, "");
|
|
|
|
} else {
|
|
|
|
hidden += value;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save the cookie with the new values.
|
|
|
|
$.cookie("hidden", hidden);
|
|
|
|
|
2014-03-16 20:07:27 +00:00
|
|
|
chat.toggleClass(
|
2014-03-22 19:23:48 +00:00
|
|
|
"show-" + value,
|
|
|
|
input.prop("checked")
|
2014-03-16 20:07:27 +00:00
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2014-03-17 00:54:58 +00:00
|
|
|
chat.on("click touchstart", ".toggle a", function(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
$("#viewport").toggleClass($(this).attr("class"));
|
|
|
|
});
|
|
|
|
|
2014-03-06 15:11:25 +00:00
|
|
|
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
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2014-03-15 15:51:21 +00:00
|
|
|
|
2014-03-18 23:08:11 +00:00
|
|
|
chat.on("focus", "input[type=text]", function() {
|
|
|
|
$(this).closest(".window").find(".messages").scrollToBottom();
|
|
|
|
});
|
|
|
|
|
2014-03-14 21:57:54 +00:00
|
|
|
chat.on("click", ".close", function() {
|
|
|
|
var btn = $(this);
|
|
|
|
btn.prop("disabled", true);
|
|
|
|
socket.emit("input", {
|
|
|
|
id: btn.closest(".window").data("id"),
|
2014-03-15 15:51:21 +00:00
|
|
|
text: "/LEAVE"
|
2014-03-14 21:57:54 +00:00
|
|
|
});
|
|
|
|
});
|
2014-03-15 15:51:21 +00:00
|
|
|
|
2014-03-15 15:07:49 +00:00
|
|
|
chat.on("append", ".window", function() {
|
|
|
|
var id = $(this).data("id");
|
|
|
|
var badge = sidebar.find(".channel[data-id='" + id + "']:not(.active) .badge");
|
|
|
|
badge.html((parseInt(badge.html()) + 1) || "1");
|
|
|
|
});
|
2014-03-15 15:51:21 +00:00
|
|
|
|
|
|
|
chat.on("click", ".user", function(e) {
|
2014-03-14 21:57:54 +00:00
|
|
|
e.preventDefault();
|
2014-03-15 15:51:21 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
chat.on("dblclick", ".user", function() {
|
|
|
|
var user = $(this);
|
|
|
|
var id = user.closest(".window").data("id");
|
|
|
|
var name = user.attr("href");
|
|
|
|
|
|
|
|
var channel = sidebar
|
|
|
|
.find(".channel[data-id='" + id + "']")
|
|
|
|
.siblings(".channel[data-name='" + name + "']");
|
|
|
|
if (channel.size() != 0) {
|
|
|
|
channel.trigger("click");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
socket.emit("input", {
|
|
|
|
id: id,
|
|
|
|
text: "/QUERY " + name
|
|
|
|
});
|
2014-03-06 15:11:25 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
var highest = 1;
|
|
|
|
$.fn.bringToTop = function() {
|
2014-03-14 19:21:00 +00:00
|
|
|
return this.css('z-index', highest++)
|
|
|
|
.addClass("active")
|
2014-03-19 00:52:09 +00:00
|
|
|
.find(".input")
|
|
|
|
.focus()
|
|
|
|
.end()
|
2014-03-14 19:21:00 +00:00
|
|
|
.siblings()
|
|
|
|
.removeClass("active")
|
|
|
|
.end();
|
2014-03-06 15:11:25 +00:00
|
|
|
};
|
2014-03-22 23:42:07 +00:00
|
|
|
});
|
|
|
|
|
2014-03-23 01:48:40 +00:00
|
|
|
Handlebars.registerHelper("link", function(text) {
|
2014-03-22 23:42:07 +00:00
|
|
|
var text = Handlebars.Utils.escapeExpression(text);
|
|
|
|
return URI.withinString(text, function(url) {
|
|
|
|
return "<a href='" + url + "' target='_blank'>" + url + "</a>";
|
|
|
|
});
|
|
|
|
});
|
2014-03-23 01:48:40 +00:00
|
|
|
|
|
|
|
Handlebars.registerHelper("color", function(text) {
|
|
|
|
return get_color(text);
|
|
|
|
});
|
|
|
|
|
|
|
|
// colornicks
|
|
|
|
// https://github.com/avidal
|
|
|
|
|
|
|
|
function clean_nick(nick) {
|
|
|
|
// attempts to clean up a nickname
|
|
|
|
// by removing alternate characters from the end
|
|
|
|
// nc_ becomes nc, avidal` becomes avidal
|
|
|
|
|
|
|
|
nick = nick.toLowerCase();
|
|
|
|
|
|
|
|
// typically ` and _ are used on the end alone
|
|
|
|
nick = nick.replace(/[`_]+$/, '');
|
|
|
|
|
|
|
|
// remove |<anything> from the end
|
|
|
|
nick = nick.replace(/|.*$/, '');
|
|
|
|
|
|
|
|
return nick;
|
|
|
|
}
|
|
|
|
|
|
|
|
function hash(nick) {
|
|
|
|
var cleaned = clean_nick(nick);
|
|
|
|
var h = 0;
|
|
|
|
|
|
|
|
for(var i = 0; i < cleaned.length; i++) {
|
|
|
|
h = cleaned.charCodeAt(i) + (h << 6) + (h << 16) - h;
|
|
|
|
}
|
|
|
|
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_color(nick) {
|
|
|
|
var nickhash = hash(nick);
|
|
|
|
|
|
|
|
// get a random value for the hue
|
|
|
|
var h = nickhash % 360;
|
|
|
|
|
|
|
|
var l = 50;
|
|
|
|
var s = 100;
|
|
|
|
|
|
|
|
// playing around with some numbers
|
|
|
|
h = 360 + (h % 40);
|
|
|
|
|
|
|
|
return "hsl(" + h + "," + s + "%," + l + "%)";
|
|
|
|
}
|