2014-03-06 15:11:25 +00:00
|
|
|
$(function() {
|
2014-04-19 21:40:36 +00:00
|
|
|
var chat = $("#chat");
|
|
|
|
var sidebar = $("#sidebar");
|
|
|
|
|
2014-04-07 21:19:20 +00:00
|
|
|
var commands = [
|
|
|
|
"/connect",
|
|
|
|
"/deop",
|
|
|
|
"/devoice",
|
|
|
|
"/disconnect",
|
|
|
|
"/join",
|
|
|
|
"/kick",
|
|
|
|
"/leave",
|
|
|
|
"/mode",
|
|
|
|
"/nick",
|
|
|
|
"/op",
|
|
|
|
"/part",
|
|
|
|
"/query",
|
|
|
|
"/quit",
|
|
|
|
"/server",
|
|
|
|
"/topic",
|
|
|
|
"/voice",
|
|
|
|
"/whois",
|
|
|
|
];
|
|
|
|
|
2014-03-06 15:11:25 +00:00
|
|
|
var socket = io.connect("");
|
2014-04-19 21:40:36 +00:00
|
|
|
$.each(["network", "channel", "user", "message"], function(i, event) {
|
|
|
|
socket.on(event, function(json) {
|
|
|
|
handleEvent(event, json);
|
2014-03-12 13:10:53 +00:00
|
|
|
});
|
2014-03-07 03:18:53 +00:00
|
|
|
});
|
2014-04-08 14:18:06 +00:00
|
|
|
|
2014-03-19 17:30:06 +00:00
|
|
|
var tpl = [];
|
2014-04-01 18:09:08 +00:00
|
|
|
function render(id, json, partials) {
|
|
|
|
tpl[id] = tpl[id] || $(id).html();
|
|
|
|
if (!json) {
|
|
|
|
// If no data is supplied, return the template instead.
|
|
|
|
// Handy when fetching partials.
|
|
|
|
return tpl[id];
|
|
|
|
}
|
|
|
|
return Mustache.render(
|
|
|
|
tpl[id],
|
|
|
|
json,
|
|
|
|
partials || {}
|
|
|
|
);
|
2014-03-19 17:30:06 +00:00
|
|
|
}
|
2014-03-22 23:42:07 +00:00
|
|
|
|
2014-04-19 21:40:36 +00:00
|
|
|
function handleEvent(event, json) {
|
|
|
|
var data = json.data;
|
|
|
|
switch (event) {
|
2014-03-29 15:36:12 +00:00
|
|
|
|
2014-03-24 15:47:29 +00:00
|
|
|
case "network":
|
2014-03-18 23:08:11 +00:00
|
|
|
var html = "";
|
2014-04-01 18:09:08 +00:00
|
|
|
var partials = {
|
2014-04-19 21:40:36 +00:00
|
|
|
users: render("#users"),
|
|
|
|
messages: render("#messages"),
|
2014-04-01 18:09:08 +00:00
|
|
|
};
|
2014-04-19 21:40:36 +00:00
|
|
|
data.forEach(function(n) {
|
2014-04-14 00:39:34 +00:00
|
|
|
html += render(
|
2014-04-19 21:40:36 +00:00
|
|
|
"#windows", {windows: n.channels}, partials
|
2014-04-14 00:39:34 +00:00
|
|
|
);
|
2014-03-12 13:10:53 +00:00
|
|
|
});
|
2014-04-19 21:40:36 +00:00
|
|
|
chat[0].innerHTML = html;
|
2014-03-18 23:08:11 +00:00
|
|
|
|
2014-03-16 20:07:27 +00:00
|
|
|
sidebar.find("#list").html(
|
2014-04-19 21:40:36 +00:00
|
|
|
render("#networks", {networks: data}, {channels: render("#channels")})
|
2014-03-17 16:24:32 +00:00
|
|
|
).find(".channel")
|
|
|
|
.first()
|
2014-04-14 00:39:34 +00:00
|
|
|
.addClass("active")
|
|
|
|
.end();
|
2014-03-12 13:10:53 +00:00
|
|
|
|
2014-04-10 21:58:08 +00:00
|
|
|
chat.find(".messages")
|
|
|
|
.scrollGlue({animate: 400})
|
|
|
|
.scrollToBottom()
|
|
|
|
.end();
|
2014-03-12 13:10:53 +00:00
|
|
|
chat.find(".window")
|
2014-04-07 21:19:20 +00:00
|
|
|
.find("input")
|
2014-04-13 23:49:22 +00:00
|
|
|
.tabComplete({after: " ", list: commands})
|
2014-04-14 00:47:59 +00:00
|
|
|
.inputHistory({submit: true})
|
2014-04-07 21:19:20 +00:00
|
|
|
.end()
|
2014-03-17 16:24:32 +00:00
|
|
|
.first()
|
2014-04-07 21:19:20 +00:00
|
|
|
.bringToTop()
|
|
|
|
.end();
|
2014-03-12 13:10:53 +00:00
|
|
|
break;
|
|
|
|
|
2014-03-24 15:47:29 +00:00
|
|
|
case "channel":
|
2014-04-19 21:40:36 +00:00
|
|
|
var id = data.id;
|
2014-03-19 17:30:06 +00:00
|
|
|
if (json.action == "remove") {
|
2014-03-31 22:02:28 +00:00
|
|
|
$("#channel-" + id + ", #window-" + id).remove();
|
2014-04-14 12:54:17 +00:00
|
|
|
var highest = 0;
|
|
|
|
var next = null;
|
|
|
|
$(".window").each(function() {
|
|
|
|
var z = $(this).css("z-index");
|
|
|
|
if (z > highest) {
|
|
|
|
highest = z;
|
|
|
|
next = $(this);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if (next != null) {
|
|
|
|
next.addClass("active");
|
|
|
|
}
|
2014-03-17 16:24:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-31 22:02:28 +00:00
|
|
|
sidebar.find(".channel").removeClass("active");
|
|
|
|
|
|
|
|
$("#network-" + json.target).append(
|
2014-04-19 21:40:36 +00:00
|
|
|
render("#channels", {channels: data})
|
2014-03-18 23:08:11 +00:00
|
|
|
).find(".channel")
|
|
|
|
.last()
|
|
|
|
.addClass("active");
|
|
|
|
|
2014-04-19 21:40:36 +00:00
|
|
|
chat.append(
|
|
|
|
render("#windows", {windows: data})
|
2014-03-18 23:08:11 +00:00
|
|
|
).find(".window")
|
|
|
|
.last()
|
2014-04-07 21:19:20 +00:00
|
|
|
.find("input")
|
2014-04-13 23:49:22 +00:00
|
|
|
.tabComplete({after: " ", list: commands})
|
2014-04-14 00:47:59 +00:00
|
|
|
.inputHistory({submit: true})
|
2014-04-07 21:19:20 +00:00
|
|
|
.end()
|
2014-03-18 23:08:11 +00:00
|
|
|
.bringToTop()
|
|
|
|
.find(".messages")
|
2014-04-07 21:19:20 +00:00
|
|
|
.scrollGlue({animate: 400})
|
|
|
|
.end();
|
2014-03-17 16:24:32 +00:00
|
|
|
break;
|
|
|
|
|
2014-03-24 15:47:29 +00:00
|
|
|
case "user":
|
2014-04-14 15:18:18 +00:00
|
|
|
var target = chat.find("#window-" + json.target).find(".users");
|
2014-04-19 21:40:36 +00:00
|
|
|
target.html(render("#users", {users: data}));
|
2014-03-12 13:10:53 +00:00
|
|
|
break;
|
|
|
|
|
2014-03-24 15:47:29 +00:00
|
|
|
case "message":
|
2014-04-01 18:09:08 +00:00
|
|
|
var target = $("#window-" + json.target);
|
|
|
|
if (target.size() == 0) {
|
|
|
|
return;
|
2014-03-17 16:24:32 +00:00
|
|
|
}
|
2014-03-29 15:36:12 +00:00
|
|
|
|
2014-04-19 21:40:36 +00:00
|
|
|
if (data.type == "error") {
|
2014-03-15 16:14:05 +00:00
|
|
|
target = target.parent().find(".active");
|
|
|
|
}
|
2014-04-10 21:58:08 +00:00
|
|
|
|
2014-04-19 21:40:36 +00:00
|
|
|
var msg = $(render("#messages", {messages: data}))
|
2014-04-10 21:58:08 +00:00
|
|
|
|
2014-03-12 13:10:53 +00:00
|
|
|
target = target.find(".messages");
|
2014-04-10 21:58:08 +00:00
|
|
|
target.append(msg);
|
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();
|
2014-03-31 22:02:28 +00:00
|
|
|
$("#window-" + item.attr("id").replace("channel-", ""))
|
2014-03-15 15:51:21 +00:00
|
|
|
.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;
|
|
|
|
}
|
2014-04-19 21:40:36 +00:00
|
|
|
$.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-31 22:02:28 +00:00
|
|
|
|
2014-03-30 21:53:01 +00:00
|
|
|
chat.on("append", ".messages", function(e) {
|
|
|
|
var item = $(this);
|
|
|
|
var last = item.find(".message:last");
|
|
|
|
var type = last[0].classList[1];
|
|
|
|
if (type && !chat.hasClass("show-" + type)) {
|
|
|
|
return;
|
|
|
|
}
|
2014-03-31 22:02:28 +00:00
|
|
|
var id = item.parent()
|
|
|
|
.attr("id")
|
|
|
|
.replace("window-", "");
|
2014-03-30 21:53:01 +00:00
|
|
|
var badge = sidebar
|
2014-03-31 22:02:28 +00:00
|
|
|
.find("#channel-" + id + ":not(.active)")
|
2014-03-30 21:53:01 +00:00
|
|
|
.find(".badge");
|
|
|
|
var num = (parseInt(badge.html()) + 1) || "1";
|
|
|
|
badge.html(num);
|
2014-03-15 15:07:49 +00:00
|
|
|
});
|
2014-03-15 15:51:21 +00:00
|
|
|
|
2014-03-31 22:02:28 +00:00
|
|
|
chat.on("click touchstart", ".toggle a", function(e) {
|
|
|
|
$("#viewport").toggleClass($(this).attr("class"));
|
|
|
|
return false;
|
2014-03-15 15:51:21 +00:00
|
|
|
});
|
|
|
|
|
2014-03-31 22:02:28 +00:00
|
|
|
chat.on("submit", "form", function() {
|
|
|
|
var input = $(this).find(".input");
|
|
|
|
var text = input.val();
|
|
|
|
if (text == "") {
|
|
|
|
return false;
|
2014-03-15 15:51:21 +00:00
|
|
|
}
|
2014-03-31 22:02:28 +00:00
|
|
|
input.val("");
|
2014-03-15 15:51:21 +00:00
|
|
|
socket.emit("input", {
|
2014-03-31 22:02:28 +00:00
|
|
|
id: input.data("target"),
|
2014-04-06 20:53:07 +00:00
|
|
|
text: text,
|
2014-03-15 15:51:21 +00:00
|
|
|
});
|
2014-03-06 15:11:25 +00:00
|
|
|
});
|
|
|
|
|
2014-04-06 20:53:07 +00:00
|
|
|
chat.on("click", ".close", function() {
|
|
|
|
var id = parseInt($(this).closest(".window").attr("id").replace("window-", ""));
|
|
|
|
socket.emit("input", {
|
|
|
|
id: id,
|
|
|
|
text: "/part",
|
|
|
|
});
|
2014-03-31 22:02:28 +00:00
|
|
|
});
|
2014-04-06 20:53:07 +00:00
|
|
|
|
2014-04-10 21:34:53 +00:00
|
|
|
chat.on("mousedown", ".user", function(e) {
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2014-04-09 20:54:04 +00:00
|
|
|
chat.on("dblclick", ".user", function() {
|
|
|
|
var link = $(this);
|
|
|
|
var id = parseInt(link.closest(".window").attr("id").replace("window-", ""));
|
2014-04-10 21:34:53 +00:00
|
|
|
var name = link.text().trim();
|
|
|
|
if (name == "-!-" || name.indexOf(".") != -1) {
|
|
|
|
return;
|
|
|
|
}
|
2014-04-09 20:54:04 +00:00
|
|
|
socket.emit("input", {
|
|
|
|
id: id,
|
2014-04-09 22:35:04 +00:00
|
|
|
text: "/whois " + link.text().trim(),
|
2014-04-09 20:54:04 +00:00
|
|
|
});
|
2014-03-31 22:02:28 +00:00
|
|
|
});
|
|
|
|
|
2014-04-06 20:53:07 +00:00
|
|
|
chat.on("focus", "input[type=text]", function() {
|
|
|
|
$(this).closest(".window").find(".messages").scrollToBottom();
|
|
|
|
});
|
2014-04-14 00:39:34 +00:00
|
|
|
|
|
|
|
chat.on("mouseover", ".text", function() {
|
|
|
|
var self = $(this);
|
|
|
|
if (!self.hasClass("parsed")) {
|
|
|
|
self.addClass("parsed").html(uri(self.html()));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
function uri(text) {
|
|
|
|
return URI.withinString(text, function(url) {
|
|
|
|
return "<a href='" + url + "' target='_blank'>" + url + "</a>";
|
|
|
|
});
|
|
|
|
}
|
2014-04-06 20:53:07 +00:00
|
|
|
|
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
|
|
|
});
|