Improved the event/render flow
This commit is contained in:
parent
acfeac27f4
commit
efa3fcd7ab
|
@ -36,10 +36,6 @@ h2 {
|
|||
cursor: pointer;
|
||||
padding: 0 12px;
|
||||
}
|
||||
#sidebar .channel[data-id='0'] {
|
||||
background: #eaeaea;
|
||||
border-bottom-color: #e5e5e5;
|
||||
}
|
||||
#sidebar .channel:first-child {
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
|
@ -47,6 +43,10 @@ h2 {
|
|||
#sidebar .channel:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
#sidebar .network:first-child .channel:first-child {
|
||||
background: #eaeaea;
|
||||
border-bottom-color: #e5e5e5;
|
||||
}
|
||||
#chat {
|
||||
bottom: 0;
|
||||
left: 200px;
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
$(function() {
|
||||
var socket = io.connect("");
|
||||
socket.on(
|
||||
"event",
|
||||
function(event) {
|
||||
console.log(event);
|
||||
View[event.action](event);
|
||||
}
|
||||
);
|
||||
socket.on("event", function(event) {
|
||||
render(event);
|
||||
});
|
||||
|
||||
var chat = $("#chat");
|
||||
var sidebar = $("#sidebar");
|
||||
|
@ -17,11 +13,77 @@ $(function() {
|
|||
var messages = $("#messages").html();
|
||||
var users = $("#users").html()
|
||||
|
||||
function render(event) {
|
||||
var type = event.type;
|
||||
var data = event.data;
|
||||
var action = event.action;
|
||||
var target = event.target;
|
||||
|
||||
if (action == "REMOVE") {
|
||||
remove(target);
|
||||
return;
|
||||
}
|
||||
if (target != "") {
|
||||
target = $("[data-id='" + target + "']");
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
|
||||
case "NETWORK":
|
||||
case "CHANNEL":
|
||||
refresh(data);
|
||||
break;
|
||||
|
||||
case "USER":
|
||||
target = target.find(".users");
|
||||
target.html(Mustache.render(users, {users: event.data}));
|
||||
break;
|
||||
|
||||
case "MESSAGE":
|
||||
var keepAtBottom = target.isScrollBottom();
|
||||
target = target.find(".messages");
|
||||
target.append(Mustache.render(messages, {messages: event.data}));
|
||||
if (keepAtBottom) {
|
||||
target.scrollToBottom();
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function remove(id) {
|
||||
$("[data-id='" + id + "']").remove();
|
||||
}
|
||||
|
||||
function refresh(data) {
|
||||
chat.html("");
|
||||
var partials = {
|
||||
users: users,
|
||||
messages: messages
|
||||
};
|
||||
data.forEach(function(network) {
|
||||
chat.append(Mustache.render(channels, network, partials));
|
||||
});
|
||||
sidebar.html(
|
||||
Mustache.render(networks, {
|
||||
networks: data
|
||||
})
|
||||
);
|
||||
|
||||
chat.find(".messages").scrollToBottom();
|
||||
chat.find(".window")
|
||||
// Sort windows by `data-id` value.
|
||||
.sort(function(a, b) { return ($(a).data("id") - $(b).data("id")); })
|
||||
.last()
|
||||
.bringToTop()
|
||||
.find(".input")
|
||||
.focus();
|
||||
}
|
||||
|
||||
var View = {};
|
||||
|
||||
View.refresh = function(event) {
|
||||
var data = event.data;
|
||||
|
||||
sidebar.html(
|
||||
Mustache.render(networks, {
|
||||
networks: data
|
||||
|
@ -48,32 +110,23 @@ $(function() {
|
|||
};
|
||||
|
||||
View.add = function(event) {
|
||||
var target = "";
|
||||
var render = "";
|
||||
|
||||
var target = $("[data-id='" + event.target + "'] ");
|
||||
switch (event.type) {
|
||||
case "user":
|
||||
target = ".users";
|
||||
render = Mustache.render(
|
||||
users, {users: event.data}
|
||||
);
|
||||
|
||||
case "users":
|
||||
target = target.find(".users");
|
||||
target.html(Mustache.render(users, {users: event.data}));
|
||||
break;
|
||||
|
||||
case "message":
|
||||
target = ".messages";
|
||||
render = Mustache.render(
|
||||
messages, {messages: event.data}
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
if (target != "") {
|
||||
target = $("[data-id='" + event.target + "'] " + target);
|
||||
case "messages":
|
||||
var keepAtBottom = target.isScrollBottom();
|
||||
target.append(render);
|
||||
target = target.find(".messages");
|
||||
target.append(Mustache.render(messages, {messages: event.data}));
|
||||
if (keepAtBottom) {
|
||||
target.scrollToBottom();
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -81,10 +134,6 @@ $(function() {
|
|||
$("[data-id='" + event.target + "']").remove();
|
||||
};
|
||||
|
||||
View.change = function(event) {
|
||||
// ..
|
||||
};
|
||||
|
||||
chat.on("submit", "form", function() {
|
||||
var input = $(this).find(".input");
|
||||
var text = input.val();
|
||||
|
@ -107,7 +156,10 @@ $(function() {
|
|||
(function() {
|
||||
var highest = 1;
|
||||
$.fn.bringToTop = function() {
|
||||
return this.css('z-index', highest++);
|
||||
return this
|
||||
.css('z-index', highest++)
|
||||
.find("input")
|
||||
.focus();
|
||||
};
|
||||
|
||||
$.fn.scrollToBottom = function() {
|
||||
|
|
|
@ -2,7 +2,7 @@ var _ = require("lodash");
|
|||
var moment = require("moment");
|
||||
|
||||
var models = exports;
|
||||
var id = 0;
|
||||
var id = 1;
|
||||
|
||||
models.Network = function(attr) {
|
||||
attr = attr || {};
|
||||
|
@ -56,3 +56,11 @@ models.Event = function(attr) {
|
|||
type: ""
|
||||
}));
|
||||
};
|
||||
|
||||
models.Target = function(attr) {
|
||||
attr = attr || {};
|
||||
_.extend(this, _.defaults(attr, {
|
||||
network: "",
|
||||
channel: ""
|
||||
}));
|
||||
};
|
||||
|
|
207
lib/server.js
207
lib/server.js
|
@ -1,149 +1,130 @@
|
|||
var _ = require("lodash");
|
||||
var connect = require("connect");
|
||||
var models = require("./models.js");
|
||||
var _ = require("lodash");
|
||||
var irc = require("irc");
|
||||
var io = require("socket.io");
|
||||
var models = require("./models.js");
|
||||
var io = require("socket.io");
|
||||
|
||||
exports.listen = listen;
|
||||
|
||||
var sockets;
|
||||
var sockets = false;;
|
||||
var networks = [];
|
||||
|
||||
addNetwork("Lobby", false);
|
||||
addToServer(
|
||||
"NETWORK",
|
||||
new models.Network({address: "Start"})
|
||||
);
|
||||
|
||||
function listen(port) {
|
||||
var http = connect()
|
||||
.use(connect.static("client"))
|
||||
.listen(port);
|
||||
sockets = io.listen(http).sockets;
|
||||
sockets.on("connection", function(socket) {
|
||||
init(socket);
|
||||
});
|
||||
sockets = io
|
||||
.listen(http)
|
||||
.on("connection", initSocket)
|
||||
.sockets;
|
||||
}
|
||||
|
||||
function init(socket) {
|
||||
function initSocket(socket) {
|
||||
socket.on("input", handleUserInput);
|
||||
refresh();
|
||||
socket.on(
|
||||
"input",
|
||||
function(input) {
|
||||
handleUserInput(input)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function sendEvent(params) {
|
||||
if (sockets) {
|
||||
sockets.emit("event", new models.Event(params));
|
||||
}
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
if (typeof sockets === "undefined") {
|
||||
return;
|
||||
}
|
||||
sockets.emit("event", new models.Event({
|
||||
action: "refresh",
|
||||
data: networks
|
||||
}));
|
||||
sendEvent({action: "RENDER", type: "NETWORK", data: networks});
|
||||
}
|
||||
|
||||
function handleUserInput(input) {
|
||||
var text = input.text;
|
||||
var target = getChannel(input.id);
|
||||
function addToServer(type, model, target) {
|
||||
switch (type) {
|
||||
|
||||
if (text.charAt(0) != "/") {
|
||||
return addMessage(target, text);
|
||||
}
|
||||
case "NETWORK":
|
||||
var channel = new models.Channel({
|
||||
name: model.address,
|
||||
type: "network"
|
||||
});
|
||||
|
||||
var args = text.substr(1).split(" ");
|
||||
var cmd = args[0].toUpperCase();
|
||||
model.channels.push(channel);
|
||||
networks.push(model);
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case "SERVER":
|
||||
case "CONNECT":
|
||||
if (args[1]) {
|
||||
addNetwork(args[1], true);
|
||||
}
|
||||
break;
|
||||
|
||||
case "JOIN":
|
||||
if (args[1]) {
|
||||
target.network.channels.push(
|
||||
new models.Channel({
|
||||
name: args[1]
|
||||
})
|
||||
);
|
||||
refresh();
|
||||
}
|
||||
refresh();
|
||||
break;
|
||||
|
||||
case "PART":
|
||||
target.network.channels =
|
||||
_.without(target.network.channels, target.channel);
|
||||
case "CHANNEL":
|
||||
target.network.channels.push(model);
|
||||
refresh();
|
||||
break;
|
||||
|
||||
default:
|
||||
addMessage(
|
||||
target,
|
||||
"Command '/" + args[0] + "' does not exist."
|
||||
case "MESSAGE":
|
||||
target.channel.messages
|
||||
.push(model);
|
||||
sendEvent({
|
||||
action: "RENDER",
|
||||
type: "MESSAGE",
|
||||
target: target.channel.id,
|
||||
data: model
|
||||
});
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function handleUserInput(input) {
|
||||
var id = input.id;
|
||||
var text = input.text;
|
||||
|
||||
var args = text.substr(1).split(' ');
|
||||
var cmd = text.charAt(0) == "/" ? args[0].toUpperCase()
|
||||
: "MESSAGE";
|
||||
|
||||
var target = getTarget(id);
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case "SERVER":
|
||||
case "CONNECT":
|
||||
addToServer(
|
||||
"NETWORK",
|
||||
new models.Network({address: args[1]})
|
||||
);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function addNetwork(addr, bool) {
|
||||
bool = bool || false;
|
||||
|
||||
var chan = new models.Channel({
|
||||
name: addr,
|
||||
type: "network"
|
||||
});
|
||||
var network = new models.Network({
|
||||
channels: [chan]
|
||||
});
|
||||
|
||||
networks.push(network);
|
||||
refresh();
|
||||
|
||||
if (addr == "Lobby") {
|
||||
return;
|
||||
}
|
||||
|
||||
network.client = new irc.Client(addr, "default_user");
|
||||
network.client.addListener("raw", function() {
|
||||
handleEvent(
|
||||
network, arguments
|
||||
case "JOIN":
|
||||
addToServer(
|
||||
"CHANNEL",
|
||||
new models.Channel({name: args[1]}),
|
||||
target
|
||||
);
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "PART":
|
||||
target.network.channels = _.reject(target.network.channels, {id: id});
|
||||
refresh();
|
||||
break;
|
||||
|
||||
function handleEvent(network) {
|
||||
var args = arguments;
|
||||
var target = {
|
||||
network: network,
|
||||
channel: network.channels[0]
|
||||
};
|
||||
case "MESSAGE":
|
||||
addToServer(
|
||||
"MESSAGE",
|
||||
new models.Message({text: input.text}),
|
||||
getTarget(id)
|
||||
);
|
||||
break;
|
||||
|
||||
console.log(args[1]);
|
||||
addMessage(target, args[1][0].args);
|
||||
}
|
||||
|
||||
function addMessage(target, text) {
|
||||
var message = _.extend(new models.Message, {text: text});
|
||||
target.channel.messages.push(message);
|
||||
sockets.emit("event", new models.Event({
|
||||
action: "add",
|
||||
type: "message",
|
||||
target: target.channel.id,
|
||||
data: message
|
||||
}));
|
||||
}
|
||||
|
||||
function getChannel(id) {
|
||||
for (var i = 0; i < networks.length; i++) {
|
||||
var find = {
|
||||
network: networks[i],
|
||||
channel: _.findWhere(networks[i].channels, {id: id})
|
||||
};
|
||||
if (typeof find.channel !== "undefined") {
|
||||
return find;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTarget(id) {
|
||||
var find;
|
||||
_.each(networks, function(n) {
|
||||
find = {network: n, channel: _.findWhere(n.channels, {id: id})};
|
||||
if (find.channel)
|
||||
return;
|
||||
});
|
||||
if (find.channel) {
|
||||
return new models.Target(find);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue