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 = [
|
2014-05-18 16:18:19 +00:00
|
|
|
"/ame",
|
|
|
|
"/amsg",
|
2014-05-15 21:58:50 +00:00
|
|
|
"/close",
|
2014-04-07 21:19:20 +00:00
|
|
|
"/connect",
|
|
|
|
"/deop",
|
|
|
|
"/devoice",
|
|
|
|
"/disconnect",
|
2014-05-17 22:17:50 +00:00
|
|
|
"/invite",
|
2014-04-07 21:19:20 +00:00
|
|
|
"/join",
|
|
|
|
"/kick",
|
|
|
|
"/leave",
|
|
|
|
"/mode",
|
2014-04-23 18:44:44 +00:00
|
|
|
"/msg",
|
2014-04-07 21:19:20 +00:00
|
|
|
"/nick",
|
2014-05-03 17:21:11 +00:00
|
|
|
"/notice",
|
2014-04-07 21:19:20 +00:00
|
|
|
"/op",
|
|
|
|
"/part",
|
2014-05-16 13:12:57 +00:00
|
|
|
"/partall",
|
2014-04-07 21:19:20 +00:00
|
|
|
"/query",
|
|
|
|
"/quit",
|
2014-05-15 21:58:50 +00:00
|
|
|
"/raw",
|
2014-05-15 21:56:23 +00:00
|
|
|
"/say",
|
2014-05-07 19:30:14 +00:00
|
|
|
"/send",
|
2014-04-07 21:19:20 +00:00
|
|
|
"/server",
|
2014-05-30 01:07:38 +00:00
|
|
|
"/slap",
|
2014-04-07 21:19:20 +00:00
|
|
|
"/topic",
|
|
|
|
"/voice",
|
2014-06-12 12:11:12 +00:00
|
|
|
"/whoami",
|
2014-04-07 21:19:20 +00:00
|
|
|
"/whois",
|
|
|
|
];
|
|
|
|
|
2014-03-06 15:11:25 +00:00
|
|
|
var socket = io.connect("");
|
2014-04-23 18:44:44 +00:00
|
|
|
var events = [
|
|
|
|
"join",
|
2014-06-02 21:08:03 +00:00
|
|
|
"messages",
|
2014-04-23 18:44:44 +00:00
|
|
|
"msg",
|
|
|
|
"networks",
|
|
|
|
"nick",
|
|
|
|
"part",
|
|
|
|
"users",
|
|
|
|
].forEach(function(e) {
|
|
|
|
socket.on(e, function(data) {
|
|
|
|
event(e, data);
|
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-05-02 17:46:18 +00:00
|
|
|
function render(name, data) {
|
|
|
|
tpl[name] = tpl[name] || Handlebars.compile($("#templates ." + name).html());
|
|
|
|
return tpl[name](data);
|
2014-03-19 17:30:06 +00:00
|
|
|
}
|
2014-03-22 23:42:07 +00:00
|
|
|
|
2014-04-23 18:44:44 +00:00
|
|
|
function event(e, data) {
|
|
|
|
switch (e) {
|
|
|
|
case "join":
|
2014-05-02 17:46:18 +00:00
|
|
|
chat.append(render("windows", {windows: [data.chan]}))
|
2014-05-13 22:47:35 +00:00
|
|
|
.find(".window")
|
2014-04-23 18:44:44 +00:00
|
|
|
.last()
|
|
|
|
.find(".input")
|
2014-06-14 20:28:17 +00:00
|
|
|
.tabcomplete(complete, {hint: false})
|
2014-06-14 21:21:09 +00:00
|
|
|
.history()
|
|
|
|
.end()
|
|
|
|
.find(".chat")
|
|
|
|
.sticky();
|
2014-05-02 17:46:18 +00:00
|
|
|
|
2014-04-26 15:26:30 +00:00
|
|
|
$("#network-" + data.id)
|
2014-05-02 17:46:18 +00:00
|
|
|
.append(render("channels", {channels: [data.chan]}))
|
2014-05-28 20:57:39 +00:00
|
|
|
.find("a")
|
2014-03-18 23:08:11 +00:00
|
|
|
.last()
|
2014-05-03 17:54:51 +00:00
|
|
|
.trigger("click");
|
2014-04-23 18:44:44 +00:00
|
|
|
break;
|
|
|
|
|
2014-06-02 21:08:03 +00:00
|
|
|
case "messages":
|
2014-04-23 18:44:44 +00:00
|
|
|
case "msg":
|
2014-06-13 11:22:03 +00:00
|
|
|
var target = (data.id ? $("#window-" + data.id) : $("#chat .active"))
|
|
|
|
.find(".messages");
|
2014-06-02 21:08:03 +00:00
|
|
|
var html = render(
|
|
|
|
"messages",
|
|
|
|
{messages: toArray(data.msg)}
|
|
|
|
);
|
|
|
|
switch (e) {
|
|
|
|
case "messages":
|
|
|
|
target.prepend(html);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "msg":
|
|
|
|
target.append(html);
|
|
|
|
break;
|
|
|
|
}
|
2014-04-23 18:44:44 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case "networks":
|
2014-04-26 15:26:30 +00:00
|
|
|
var channels = $.map(data.networks, function(n) { return n.channels; });
|
2014-05-02 17:46:18 +00:00
|
|
|
chat.html(render("windows", {windows: channels}))
|
2014-06-14 20:28:17 +00:00
|
|
|
.find(".input")
|
|
|
|
.tabcomplete(complete, {hint: false})
|
2014-06-14 21:21:09 +00:00
|
|
|
.history()
|
|
|
|
.end()
|
|
|
|
.find(".chat")
|
|
|
|
.sticky();
|
2014-04-26 15:26:30 +00:00
|
|
|
|
2014-05-07 14:01:46 +00:00
|
|
|
var networks = $("#networks")
|
2014-05-28 20:57:39 +00:00
|
|
|
.html(render("networks", {networks: data.networks}))
|
|
|
|
.find("a")
|
|
|
|
.last()
|
|
|
|
.trigger("click");
|
2014-03-17 16:24:32 +00:00
|
|
|
break;
|
2014-04-23 18:44:44 +00:00
|
|
|
|
|
|
|
case "part":
|
2014-04-26 15:26:30 +00:00
|
|
|
$("#channel-" + data.id)
|
|
|
|
.add("#window-" + data.id)
|
|
|
|
.remove();
|
2014-04-23 18:44:44 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case "users":
|
2014-06-09 19:39:19 +00:00
|
|
|
var target = $("#window-" + data.id);
|
2014-06-13 11:22:03 +00:00
|
|
|
var json = {name: target.find("h1").html(), users: data.users};
|
2014-06-09 19:39:19 +00:00
|
|
|
target.find(".meta")
|
|
|
|
.replaceWith(render("meta", json))
|
2014-06-09 19:45:38 +00:00
|
|
|
.end();
|
|
|
|
target.find(".users")
|
2014-06-09 19:39:19 +00:00
|
|
|
.html(render("users", json))
|
|
|
|
.end();
|
2014-03-12 13:10:53 +00:00
|
|
|
break;
|
|
|
|
}
|
2014-03-07 03:18:53 +00:00
|
|
|
}
|
2014-04-23 18:44:44 +00:00
|
|
|
|
2014-05-31 14:03:58 +00:00
|
|
|
var viewport = $("#viewport");
|
2014-05-31 16:40:44 +00:00
|
|
|
var touchDevice = (window.screen.width <= 768);
|
2014-05-31 14:03:58 +00:00
|
|
|
|
2014-05-02 17:46:18 +00:00
|
|
|
var z = 1;
|
2014-05-30 00:23:23 +00:00
|
|
|
sidebar.on("click", "a", function(e) {
|
|
|
|
e.preventDefault();
|
2014-05-28 20:57:39 +00:00
|
|
|
var link = $(this);
|
|
|
|
var target = link.attr("href");
|
2014-05-08 22:12:16 +00:00
|
|
|
if (!target) {
|
|
|
|
return;
|
|
|
|
}
|
2014-05-31 14:03:58 +00:00
|
|
|
viewport.removeClass();
|
2014-05-02 17:46:18 +00:00
|
|
|
sidebar.find(".active").removeClass("active");
|
2014-05-28 20:57:39 +00:00
|
|
|
link.addClass("active")
|
2014-05-03 17:54:51 +00:00
|
|
|
.find(".badge")
|
2014-05-04 11:05:06 +00:00
|
|
|
.removeClass("highlight")
|
2014-05-03 17:54:51 +00:00
|
|
|
.empty();
|
2014-05-07 14:01:46 +00:00
|
|
|
var window = $(target)
|
2014-05-30 00:23:23 +00:00
|
|
|
.siblings()
|
|
|
|
.removeClass("active")
|
|
|
|
.end()
|
|
|
|
.css("z-index", z++)
|
2014-05-31 14:03:58 +00:00
|
|
|
.addClass("active");
|
|
|
|
|
|
|
|
if (!touchDevice) {
|
|
|
|
window.find("input").focus();
|
|
|
|
}
|
2014-05-03 17:54:51 +00:00
|
|
|
});
|
|
|
|
|
2014-05-24 21:56:28 +00:00
|
|
|
sidebar.on("click", ".close", function() {
|
2014-05-28 20:57:39 +00:00
|
|
|
var channel = $(this).closest("a");
|
2014-05-24 21:56:28 +00:00
|
|
|
var id = parseInt(channel.attr("id").split("-")[1]);
|
2014-05-25 19:39:17 +00:00
|
|
|
var cmd = "/close";
|
|
|
|
if (channel.hasClass("lobby")) {
|
|
|
|
cmd = "/quit";
|
2014-05-25 23:20:16 +00:00
|
|
|
var server = channel
|
|
|
|
.clone()
|
|
|
|
.remove("span")
|
|
|
|
.text()
|
|
|
|
.trim();
|
|
|
|
if (!confirm("Disconnect from " + server + "?")) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-05-25 19:39:17 +00:00
|
|
|
}
|
2014-05-24 21:56:28 +00:00
|
|
|
socket.emit("input", {
|
|
|
|
id: id,
|
2014-05-25 19:39:17 +00:00
|
|
|
text: cmd,
|
|
|
|
});
|
|
|
|
channel.css({
|
|
|
|
transition: "none",
|
|
|
|
opacity: .4
|
2014-05-24 21:56:28 +00:00
|
|
|
});
|
|
|
|
return false;
|
2014-05-08 22:12:16 +00:00
|
|
|
});
|
|
|
|
|
2014-05-03 17:54:51 +00:00
|
|
|
chat.on("append", ".messages", function() {
|
|
|
|
var messages = $(this);
|
2014-05-14 01:36:51 +00:00
|
|
|
var id = messages.closest(".window").find(".form").data("target");
|
2014-06-13 16:52:36 +00:00
|
|
|
|
|
|
|
var link = $("#channel-" + id + ":not(.active)");
|
|
|
|
if (link.length == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
link.addClass("pulse");
|
|
|
|
setTimeout(function() {
|
|
|
|
link.removeClass("pulse");
|
|
|
|
}, 500);
|
|
|
|
|
|
|
|
var last = messages.find(".row:last-child");
|
|
|
|
var type = last.attr("class");
|
|
|
|
|
|
|
|
var ignore = [
|
|
|
|
"join",
|
|
|
|
"part",
|
|
|
|
"quit",
|
|
|
|
"nick",
|
|
|
|
];
|
|
|
|
for (var i = 0; i < ignore.length; i++) {
|
|
|
|
if (type.indexOf(ignore[i]) !== -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var badge = link.find(".badge");
|
2014-05-03 19:22:14 +00:00
|
|
|
if (badge.length != 0) {
|
|
|
|
var i = (parseInt(badge.html()) || 0) + 1;
|
|
|
|
badge.html(i);
|
2014-05-04 11:05:06 +00:00
|
|
|
if (messages.children().last().hasClass("highlight")) {
|
|
|
|
badge.addClass("highlight");
|
|
|
|
}
|
2014-05-03 17:54:51 +00:00
|
|
|
}
|
2014-03-06 15:11:25 +00:00
|
|
|
});
|
2014-04-23 18:44:44 +00:00
|
|
|
|
2014-06-02 21:08:03 +00:00
|
|
|
chat.on("click", ".show-more", function() {
|
|
|
|
var btn = $(this);
|
|
|
|
var messages = btn.closest(".chat").find(".messages").children();
|
|
|
|
socket.emit("fetch", {
|
|
|
|
id: btn.data("id"),
|
|
|
|
count: messages.length,
|
|
|
|
});
|
|
|
|
btn.attr("disabled", true);
|
2014-04-23 18:44:44 +00:00
|
|
|
});
|
|
|
|
|
2014-05-30 00:23:23 +00:00
|
|
|
chat.on("click", ".user", function(e) {
|
|
|
|
e.preventDefault();
|
2014-04-23 18:44:44 +00:00
|
|
|
var user = $(this);
|
2014-06-02 21:08:03 +00:00
|
|
|
var id = user
|
|
|
|
.closest(".window")
|
|
|
|
.data("id");
|
|
|
|
|
2014-06-13 10:16:47 +00:00
|
|
|
// Strip modes.
|
|
|
|
var name = user.html().trim().replace(/[+%@~]/, "");
|
2014-05-03 17:54:51 +00:00
|
|
|
if (name.match(/[#.]|-!-/) != null) {
|
2014-04-10 21:34:53 +00:00
|
|
|
return;
|
|
|
|
}
|
2014-06-02 21:08:03 +00:00
|
|
|
|
2014-04-09 20:54:04 +00:00
|
|
|
socket.emit("input", {
|
|
|
|
id: id,
|
2014-04-23 18:44:44 +00:00
|
|
|
text: "/whois " + name,
|
2014-04-09 20:54:04 +00:00
|
|
|
});
|
2014-03-31 22:02:28 +00:00
|
|
|
});
|
2014-04-23 22:03:35 +00:00
|
|
|
|
2014-05-02 21:54:31 +00:00
|
|
|
chat.on("focus", ".input", function() {
|
2014-05-28 20:57:39 +00:00
|
|
|
$(this).closest(".window").find(".chat").scrollToBottom();
|
2014-05-02 21:54:31 +00:00
|
|
|
});
|
|
|
|
|
2014-05-28 20:57:39 +00:00
|
|
|
chat.on("submit", "form", function(e) {
|
|
|
|
e.preventDefault();
|
2014-05-02 17:46:18 +00:00
|
|
|
var form = $(this);
|
2014-05-13 22:47:35 +00:00
|
|
|
var input = form.find(".input:not(.hint)");
|
2014-05-02 17:46:18 +00:00
|
|
|
var text = input.val();
|
|
|
|
if (text == "") {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
input.val("");
|
2014-05-18 16:18:19 +00:00
|
|
|
input.prev(".hint").val("");
|
2014-04-23 22:03:35 +00:00
|
|
|
socket.emit("input", {
|
2014-05-02 17:46:18 +00:00
|
|
|
id: form.data("target"),
|
|
|
|
text: text,
|
2014-04-23 22:03:35 +00:00
|
|
|
});
|
|
|
|
});
|
2014-04-23 18:44:44 +00:00
|
|
|
|
2014-05-30 21:31:47 +00:00
|
|
|
var toggle = "click";
|
2014-05-31 14:03:58 +00:00
|
|
|
if (touchDevice) {
|
2014-05-30 21:31:47 +00:00
|
|
|
toggle = "touchstart";
|
|
|
|
}
|
2014-06-13 14:23:37 +00:00
|
|
|
|
|
|
|
chat.on(toggle, ".lt, .rt", function(e) {
|
2014-05-30 21:31:47 +00:00
|
|
|
var btn = $(this);
|
|
|
|
viewport.toggleClass(btn.attr("class"));
|
2014-06-13 14:23:37 +00:00
|
|
|
if (viewport.hasClass("lt")) {
|
|
|
|
e.stopPropagation();
|
|
|
|
viewport.find("#main").one(toggle, function(e) {
|
|
|
|
viewport.removeClass("lt");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-05-30 21:31:47 +00:00
|
|
|
});
|
|
|
|
|
2014-06-14 20:28:17 +00:00
|
|
|
function complete(word) {
|
2014-06-15 14:36:22 +00:00
|
|
|
var words = commands.slice();
|
2014-06-14 21:21:09 +00:00
|
|
|
var users = $(this).closest(".window")
|
|
|
|
.find(".users .user")
|
|
|
|
.each(function() {
|
|
|
|
words.push(this.getAttribute("href").slice(1));
|
|
|
|
});
|
2014-06-14 20:28:17 +00:00
|
|
|
return $.grep(
|
2014-06-14 21:21:09 +00:00
|
|
|
words,
|
2014-06-14 20:28:17 +00:00
|
|
|
function(cmd) {
|
|
|
|
return !cmd.indexOf(word);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2014-06-02 21:08:03 +00:00
|
|
|
function toArray(val) {
|
|
|
|
return Array.isArray(val) ? val : [val];
|
|
|
|
}
|
|
|
|
|
2014-05-28 20:57:39 +00:00
|
|
|
function escape(text) {
|
|
|
|
var e = {
|
|
|
|
"<": "<",
|
|
|
|
">": ">"
|
|
|
|
};
|
|
|
|
return text.replace(/[<>]/g, function (c) {
|
|
|
|
return e[c];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-06-14 20:28:17 +00:00
|
|
|
Handlebars.registerHelper(
|
|
|
|
"equal", function(a, b, opt) {
|
|
|
|
a = parseInt(a);
|
|
|
|
b = parseInt(b);
|
|
|
|
if (a == b) {
|
|
|
|
return opt.fn(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2014-05-28 20:57:39 +00:00
|
|
|
Handlebars.registerHelper(
|
|
|
|
"uri", function(text) {
|
|
|
|
text = escape(text);
|
|
|
|
return URI.withinString(text, function(url) {
|
|
|
|
return "<a href='" + url.replace(/^www/, "//www") + "' target='_blank'>" + url + "</a>";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2014-05-02 17:46:18 +00:00
|
|
|
Handlebars.registerHelper(
|
|
|
|
"partial", function(id) {
|
2014-04-21 10:27:43 +00:00
|
|
|
return new Handlebars.SafeString(render(id, this));
|
2014-05-02 17:46:18 +00:00
|
|
|
}
|
|
|
|
);
|
2014-03-22 23:42:07 +00:00
|
|
|
});
|