$(function() { var socket = io.connect(""); $.each([ "NETWORKS", "CHANNELS", "MESSAGES", "USERS" ], function(i, type) { socket.on(type, function(data) { render(type, data); }); }); var chat = $("#chat"); var sidebar = $("#sidebar"); // Templates var networks = $("#networks").html(); var channels = $("#channels").html(); var messages = $("#messages").html(); var users = $("#users").html() function render(type, data) { var target; if (typeof data.target !== "undefined") { target = $(".window[data-id='" + data.target + "']"); } switch (type) { case "NETWORKS": var partials = { users: users, messages: messages }; var windows = chat .find("#windows") .html(""); data.forEach(function(network) { windows.append(Mustache.render(channels, network, partials)); }); sidebar.find("#list").html( Mustache.render(networks, { networks: data }) ); sidebar.find(".channel") .last() .addClass("active"); chat.find(".messages").sticky().scrollToBottom(); chat.find(".window") // Sort windows by `data-id` value. .sort(function(a, b) { return ($(a).data("id") - $(b).data("id")); }) .last() .bringToTop(); break; case "USERS": target = target.find(".users"); target.html(Mustache.render(users, {users: data.data})); break; case "MESSAGES": var message = data.data; if (message.type == "error" || message.type == "notice") { target = target.parent().find(".active"); } target = target.find(".messages"); target.append(Mustache.render(messages, {messages: message})); 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(); var id = item.data("id"); chat.find(".window[data-id='" + id + "']") .bringToTop(); }); sidebar.find("input[type=checkbox]").each(function() { var input = $(this); var value = input.val(); input.prop("checked", true).wrap("