$(function() { var chat = $("#chat"); var sidebar = $("#sidebar"); var commands = [ "/connect", "/deop", "/devoice", "/disconnect", "/join", "/kick", "/leave", "/mode", "/nick", "/op", "/part", "/query", "/quit", "/server", "/topic", "/voice", "/whois", ]; var socket = io.connect(""); $.each(["network", "channel", "user", "message"], function(i, event) { socket.on(event, function(json) { handleEvent(event, json); }); }); var tpl = []; function render(id, json) { tpl[id] = tpl[id] || Handlebars.compile($(id).html()); return tpl[id](json); } Handlebars.registerHelper( "partial", function(id) { return new Handlebars.SafeString(render(id, this)); } ); function handleEvent(event, json) { var data = json.data; switch (event) { case "network": var html = ""; data.forEach(function(n) { html += render("#windows", {windows: n.channels}); }); chat[0].innerHTML = html; sidebar.find("#list").html( render("#networks", {networks: data}) ).find(".channel") .first() .addClass("active") .end(); chat.find(".messages") .scrollGlue({animate: 400}) .scrollToBottom() .end(); chat.find(".window") .find("input") .tabComplete({after: " ", list: commands}) .inputHistory({submit: true}) .end() .first() .bringToTop() .end(); break; case "channel": var id = data.id; if (json.action == "remove") { $("#channel-" + id + ", #window-" + id).remove(); 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"); } return; } sidebar.find(".channel").removeClass("active"); $("#network-" + json.target).append( render("#channels", {channels: [data]}) ).find(".channel") .last() .addClass("active"); chat.append( render("#windows", {windows: [data]}) ).find(".window") .last() .find("input") .tabComplete({after: " ", list: commands}) .inputHistory({submit: true}) .end() .bringToTop() .find(".messages") .scrollGlue({animate: 400}) .end(); break; case "user": var html = render("#users", {users: data}); var target = chat.find("#window-" + json.target + " .users").html(html); break; case "message": var target = $("#window-" + json.target); if (target.size() == 0) { return; } if (data.type == "error") { target = target.parent().find(".active"); } var msg = $(render("#messages", {messages: [data]})); target = target.find(".messages"); target.append(msg); break; } } sidebar.on("click", ".channel", function(e) { e.preventDefault(); sidebar.find("#list .active").removeClass("active"); $("#viewport").removeClass(); var item = $(this) .addClass("active") .find(".badge") .html("") .end(); $("#window-" + item.attr("id").replace("channel-", "")) .bringToTop(); }); sidebar.find("input[type=checkbox]").each(function() { var input = $(this); var value = input.val(); var checked = true; if (($.cookie("hidden") || []).indexOf(value) !== -1) { checked = false; } input.prop("checked", checked) .wrap("