thelounge/client/js/chat.js

410 lines
8.2 KiB
JavaScript
Raw Normal View History

2014-06-30 01:20:54 +00:00
$(function() {
var socket = io();
var commands = [
"/close",
"/connect",
"/deop",
"/devoice",
"/disconnect",
"/invite",
"/join",
"/kick",
"/leave",
"/mode",
"/msg",
"/nick",
"/notice",
"/op",
"/part",
"/query",
"/quit",
"/raw",
"/say",
"/send",
"/server",
"/slap",
"/topic",
"/voice",
"/whois"
];
2014-07-17 13:58:43 +00:00
2014-07-07 00:44:31 +00:00
var sidebar = $("#sidebar");
2014-06-30 01:20:54 +00:00
var chat = $("#chat");
2014-07-17 13:58:43 +00:00
2014-07-07 23:13:12 +00:00
var pop = new Audio();
pop.src = "/audio/pop.ogg";
2014-07-17 13:58:43 +00:00
2014-07-09 22:40:51 +00:00
$("#play").on("click", function() { pop.play(); });
2014-07-17 13:58:43 +00:00
$("#footer button").tooltip();
2014-07-07 23:13:12 +00:00
var favico = new Favico({
animation: "none"
});
2014-07-17 13:58:43 +00:00
2014-06-30 01:20:54 +00:00
var tpl = [];
function render(name, data) {
tpl[name] = tpl[name] || Handlebars.compile($("#templates ." + name).html());
return tpl[name](data);
}
2014-07-17 13:58:43 +00:00
2014-07-07 23:13:12 +00:00
Handlebars.registerHelper(
"partial", function(id) {
return new Handlebars.SafeString(render(id, this));
}
);
2014-06-30 01:20:54 +00:00
socket.on("auth", function(data) {
console.log(data);
});
2014-07-17 13:58:43 +00:00
2014-06-30 01:20:54 +00:00
socket.on("init", function(data) {
2014-07-08 20:50:41 +00:00
if (data.networks.length === 0) {
$("#footer").find(".connect").trigger("click");
return;
}
2014-07-17 13:58:43 +00:00
2014-07-08 20:50:41 +00:00
sidebar.find(".networks").append(
2014-06-30 01:20:54 +00:00
render("networks", {
networks: data.networks
})
2014-07-07 12:42:46 +00:00
);
2014-07-08 20:50:41 +00:00
var channels = $.map(data.networks, function(n) {
return n.channels;
});
2014-07-07 12:42:46 +00:00
chat.html(
render("chat", {
channels: channels
})
);
2014-07-17 13:58:43 +00:00
2014-07-07 12:42:46 +00:00
var id = $.cookie("target");
2014-07-08 20:50:41 +00:00
var target = sidebar.find("[data-target=" + id + "]").trigger("click");
if (target.length === 0) {
var first = sidebar.find(".chan")
2014-07-07 12:42:46 +00:00
.eq(0)
.trigger("click");
2014-07-08 20:50:41 +00:00
if (first.length === 0) {
$("#footer").find(".connect").trigger("click");
}
2014-07-07 00:44:31 +00:00
}
2014-06-30 01:20:54 +00:00
});
2014-07-17 13:58:43 +00:00
2014-06-30 01:20:54 +00:00
socket.on("join", function(data) {
2014-07-07 00:44:31 +00:00
var id = data.network;
2014-07-07 12:42:46 +00:00
var network = sidebar.find("#network-" + id);
2014-06-30 01:20:54 +00:00
network.append(
render("channels", {
channels: [data.chan]
})
);
2014-07-07 12:42:46 +00:00
chat.append(
render("chat", {
channels: [data.chan]
})
);
sidebar.find(".chan")
2014-07-05 00:31:20 +00:00
.last()
.trigger("click");
2014-06-30 01:20:54 +00:00
});
2014-07-17 13:58:43 +00:00
2014-06-30 01:20:54 +00:00
socket.on("msg", function(data) {
2014-07-09 22:40:51 +00:00
var target = data.chan;
if (data.msg.type == "error") {
target = chat.find(".active").data("id");
}
target = "#chan-" + target;
2014-07-07 23:13:12 +00:00
chat.find(target)
2014-07-07 12:42:46 +00:00
.find(".messages")
2014-07-07 23:13:12 +00:00
.append(render("messages", {messages: [data.msg]}))
.trigger("msg", [
target,
data.msg
]);
2014-06-30 01:20:54 +00:00
});
2014-07-17 13:58:43 +00:00
2014-06-30 01:20:54 +00:00
socket.on("network", function(data) {
2014-07-08 20:50:41 +00:00
sidebar.find(".empty").hide();
2014-07-07 12:42:46 +00:00
sidebar.find(".networks").append(
2014-06-30 01:20:54 +00:00
render("networks", {
networks: [data.network]
})
);
2014-07-08 20:50:41 +00:00
chat.append(
render("chat", {
channels: data.network.channels
})
);
2014-07-07 12:42:46 +00:00
sidebar.find(".chan")
2014-07-07 00:44:31 +00:00
.last()
.trigger("click");
2014-07-09 22:40:51 +00:00
connect.find(".btn")
.prop("disabled", false)
.end()
.find("input")
.val("");
2014-06-30 01:20:54 +00:00
});
2014-07-17 13:58:43 +00:00
2014-06-30 01:20:54 +00:00
socket.on("nick", function(data) {
console.log(data);
});
2014-07-17 13:58:43 +00:00
2014-06-30 01:20:54 +00:00
socket.on("part", function(data) {
2014-07-07 00:44:31 +00:00
var id = data.chan;
2014-07-07 12:42:46 +00:00
sidebar.find("[data-target=#chan-" + id + "]")
2014-07-04 23:32:40 +00:00
.remove()
.end()
.find(".chan")
.eq(0)
.trigger("click");
2014-06-30 01:20:54 +00:00
});
2014-07-17 13:58:43 +00:00
2014-06-30 01:20:54 +00:00
socket.on("quit", function(data) {
2014-07-07 00:44:31 +00:00
var id = data.network;
2014-07-07 12:42:46 +00:00
sidebar.find("#network-" + id)
2014-07-04 23:32:40 +00:00
.remove()
.end()
.find(".chan")
.eq(0)
.trigger("click");
2014-06-30 01:20:54 +00:00
});
2014-07-17 13:58:43 +00:00
2014-06-30 01:20:54 +00:00
socket.on("users", function(data) {
2014-07-07 12:42:46 +00:00
chat.find("#chan-" + data.chan)
.find(".users")
.html(render("users", data));
2014-06-30 01:20:54 +00:00
});
2014-07-17 13:58:43 +00:00
2014-07-09 22:40:51 +00:00
$.cookie.json = true;
var settings = $("#settings");
var options = $.extend({
join: true,
mode: true,
nick: true,
notification: true,
part: true,
quit: true,
}, $.cookie("settings"));
2014-07-17 13:58:43 +00:00
2014-07-09 22:40:51 +00:00
for (var i in options) {
if (options[i]) {
settings.find("input[name=" + i + "]").prop("checked", true);
}
}
2014-07-17 13:58:43 +00:00
2014-07-09 22:40:51 +00:00
settings.on("change", "input", function() {
var self = $(this);
var name = self.attr("name");
options[name] = self.prop("checked");
$.cookie("settings", options);
if ([
"join",
"nick",
"part",
"mode",
"quit",
].indexOf(name) !== -1) {
chat.toggleClass("hide-" + name, !self.prop("checked"));
}
}).find("input")
.eq(0)
.trigger("change");
2014-07-17 13:58:43 +00:00
2014-07-07 21:44:49 +00:00
var viewport = $("#viewport");
$("#rt, #lt").on("click", function(e) {
var self = $(this);
viewport.toggleClass(self.attr("id"));
if (viewport.is(".lt, .rt")) {
e.stopPropagation();
chat.find(".chat").one("click", function() {
viewport.removeClass("lt rt");
});
}
});
2014-07-17 13:58:43 +00:00
2014-07-06 15:58:57 +00:00
var input = $("#input")
.history()
.tab(complete, {hint: false});
2014-07-17 13:58:43 +00:00
2014-06-30 01:20:54 +00:00
var form = $("#form").on("submit", function(e) {
e.preventDefault();
2014-07-07 21:44:49 +00:00
var text = input.val();
2014-06-30 01:20:54 +00:00
input.val("");
socket.emit("input", {
2014-07-07 12:42:46 +00:00
target: chat.data("id"),
2014-07-07 21:44:49 +00:00
text: text
2014-06-30 01:20:54 +00:00
});
});
2014-07-17 13:58:43 +00:00
2014-07-07 12:42:46 +00:00
var top = 1;
2014-07-07 00:44:31 +00:00
sidebar.on("click", "button:not(.active)", function() {
2014-07-07 12:42:46 +00:00
var self = $(this);
var target = self.data("target");
if (!target) {
return;
}
2014-07-17 13:58:43 +00:00
2014-07-07 12:42:46 +00:00
$.cookie("target", target);
chat.data(
"id",
self.data("id")
);
2014-07-17 13:58:43 +00:00
2014-07-07 00:44:31 +00:00
sidebar.find(".active").removeClass("active");
2014-07-07 12:42:46 +00:00
self.addClass("active")
.find(".badge")
.removeClass("highlight")
.empty();
2014-07-17 13:58:43 +00:00
2014-07-07 23:13:12 +00:00
if (sidebar.find(".highlight").length == 0) {
favico.badge("");
}
2014-07-17 13:58:43 +00:00
2014-07-07 21:44:49 +00:00
$("#rt").toggle(self.hasClass("chan"));
$("#header").find("h1").html(self.data("title"));
viewport.removeClass();
2014-07-17 13:58:43 +00:00
2014-07-07 23:13:12 +00:00
$("#windows .active").removeClass("active");
2014-07-07 12:42:46 +00:00
var chan = $(target)
.css("z-index", top++)
2014-07-07 23:13:12 +00:00
.addClass("active")
2014-07-07 12:42:46 +00:00
.find(".chat")
.sticky();
2014-07-02 22:00:11 +00:00
});
2014-07-17 13:58:43 +00:00
2014-07-09 17:11:07 +00:00
sidebar.on("click", ".close", function() {
var cmd = "/close";
var chan = $(this).closest(".chan");
if (chan.hasClass("lobby")) {
cmd = "/quit";
var server = chan
.clone()
.remove("span")
.text()
.trim();
if (!confirm("Disconnect from " + server + "?")) {
return false;
}
}
socket.emit("input", {
target: chan.data("id"),
text: cmd
});
chan.css({
transition: "none",
opacity: .4
});
return false;
});
2014-07-17 13:58:43 +00:00
2014-07-07 12:42:46 +00:00
chat.on("input", ".search", function() {
2014-07-07 21:44:49 +00:00
var value = $(this).val();
2014-07-07 12:42:46 +00:00
var names = $(this).closest(".users").find(".names");
names.find("button").each(function() {
2014-07-04 23:32:40 +00:00
var btn = $(this);
2014-07-08 20:50:41 +00:00
var name = btn.text().toLowerCase().replace(/[+%@~]/, "");
if (name.indexOf(value) === 0) {
2014-07-04 23:32:40 +00:00
btn.show();
} else {
btn.hide();
}
});
});
2014-07-17 13:58:43 +00:00
2014-07-07 00:44:31 +00:00
chat.on("click", ".user", function() {
2014-07-07 21:44:49 +00:00
var user = $(this).html().trim().replace(/[+%@~]/, "");
2014-07-07 00:44:31 +00:00
if (user.indexOf("#") !== -1) {
return;
}
2014-07-07 21:44:49 +00:00
var text = "/whois " + user;
2014-07-07 00:44:31 +00:00
socket.emit("input", {
2014-07-07 21:44:49 +00:00
target: chat.data("id"),
text: text
2014-07-07 00:44:31 +00:00
});
});
2014-07-17 13:58:43 +00:00
2014-07-07 23:13:12 +00:00
chat.on("msg", ".messages", function(e, target, msg) {
var type = msg.type;
var highlight = type.contains("highlight");
if (highlight) {
pop.play();
if (document.hidden || !$(target).hasClass("active")) {
favico.badge("!");
}
}
2014-07-17 13:58:43 +00:00
2014-07-07 23:13:12 +00:00
var btn = sidebar.find(".chan[data-target=" + target + "]:not(.active)");
if (btn.length === 0) {
return;
}
2014-07-17 13:58:43 +00:00
2014-07-07 23:13:12 +00:00
var ignore = [
"join",
"part",
"quit",
"nick"
];
if ($.inArray(type, ignore) !== -1){
return;
}
2014-07-17 13:58:43 +00:00
2014-07-07 23:13:12 +00:00
var badge = btn.find(".badge");
if (badge.length !== 0) {
var i = (parseInt(badge.html()) || 0) + 1;
badge.html(i);
if (highlight) {
badge.addClass("highlight");
}
}
});
2014-07-17 13:58:43 +00:00
2014-07-08 20:50:41 +00:00
var connect = $("#connect");
connect.on("submit", "form", function(e) {
e.preventDefault();
var form = $(this)
.find(".btn")
.attr("disabled", true)
.end();
2014-07-17 13:58:43 +00:00
2014-07-08 20:50:41 +00:00
var post = {};
var values = form.serializeArray();
2014-07-17 13:58:43 +00:00
2014-07-08 20:50:41 +00:00
$.each(values, function(i, obj) {
if (obj.value !== "") {
post[obj.name] = obj.value;
}
});
2014-07-17 13:58:43 +00:00
2014-07-08 20:50:41 +00:00
socket.emit("conn", post);
});
2014-07-17 13:58:43 +00:00
2014-06-30 01:20:54 +00:00
function complete(word) {
2014-07-09 16:54:16 +00:00
var words = commands.slice();
var users = chat.find(".active")
.find(".names")
.children()
.each(function() {
words.push($(this).text().replace(/[+%@~]/, ""));
});
2014-07-09 22:47:38 +00:00
var channels = sidebar.find(".channel")
.each(function() {
var chan = $(this).clone().remove("span").text().trim();
words.push(chan);
});
2014-06-30 01:20:54 +00:00
return $.grep(
2014-07-09 16:54:16 +00:00
words,
2014-06-30 01:20:54 +00:00
function(w) {
return !w.toLowerCase().indexOf(word.toLowerCase());
}
);
}
2014-07-17 13:58:43 +00:00
2014-07-07 23:13:12 +00:00
document.addEventListener(
"visibilitychange",
function() {
if (sidebar.find(".highlight").length == 0) {
favico.badge("");
2014-06-30 01:20:54 +00:00
}
}
);
});