Shuo/client/js/chat.js

285 lines
5.9 KiB
JavaScript
Raw Normal View History

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-20 21:48:05 +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-04-19 21:40:36 +00:00
function handleEvent(event, json) {
2014-04-21 11:20:20 +00:00
var data = [].concat(json.data);
2014-04-19 21:40:36 +00:00
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-19 21:40:36 +00:00
data.forEach(function(n) {
2014-04-20 21:48:05 +00:00
html += render("#windows", {windows: n.channels});
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-20 21:48:05 +00:00
render("#networks", {networks: data})
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-21 11:20:20 +00:00
var id = data[0].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");
2014-04-21 21:04:16 +00:00
if (z == "auto") z = 0;
2014-04-14 12:54:17 +00:00
if (z > highest) {
highest = z;
next = $(this);
}
});
if (next != null) {
2014-04-21 21:04:16 +00:00
$("#channel-" + next.attr("id").replace("window-", "")).addClass("active");
next.bringToTop();
2014-04-14 12:54:17 +00:00
}
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-21 11:20:20 +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(
2014-04-21 11:20:20 +00:00
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-20 21:48:05 +00:00
var html = render("#users", {users: data});
var target = chat.find("#window-" + json.target + " .users").html(html);
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-21 11:20:20 +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-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-04-21 10:27:43 +00:00
function uri(text) {
return URI.withinString(text, function(url) {
return "<a href='" + url + "' target='_blank'>" + url + "</a>";
});
}
function escape(string) {
var e = {
"<": "&lt;",
">": "&gt;",
};
return string.replace(/[<>]/g, function (s) {
return e[s];
});
}
Handlebars.registerHelper(
"uri",
function(text) {
return uri(escape(text));
}
);
Handlebars.registerHelper(
"partial",
function(id) {
return new Handlebars.SafeString(render(id, this));
}
);
2014-03-22 23:42:07 +00:00
});