diff --git a/app.js b/app.js index 207b1d41..a41d97ff 100644 --- a/app.js +++ b/app.js @@ -1,7 +1,4 @@ -var commander = require("commander") -var listen = require("./lib/server.js").listen; - -var argv = commander +var argv = require("commander") .option("-p, --port ", "port to use", parseInt) .parse(process.argv); @@ -10,4 +7,24 @@ if (argv.port) { PORT = argv.port; } -listen(PORT); +var server = + new (require("./lib/server.js"))() + .listen(PORT); + +// Temp + +var models = require("./lib/models.js"); +var network = new models.Network({host: "irc.network.org"}); + +server.networks.add(network); +network.get("channels").add(new models.Channel({ + name: "#foo", + messages: [ + new models.Message({user: "user", text: "Hi!"}), + new models.Message({user: "user", text: ".. Hello?"}), + ], + users: [ + new models.User({name: "user"}), + new models.User({name: "other_user"}), + ] +})); diff --git a/client/css/style.css b/client/css/style.css index 1acf668f..ed3441d3 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -27,13 +27,13 @@ h2 { border-right: 1px solid #ccc; float: left; height: 100%; - line-height: 36px; width: 199px; } #sidebar .channel { border-bottom: 1px solid transparent; color: #f00; cursor: pointer; + line-height: 1.8em; padding: 0 12px; } #sidebar .channel:first-child { @@ -43,9 +43,16 @@ h2 { #sidebar .channel:hover { text-decoration: underline; } -#sidebar .network:first-child .channel:first-child { +#sidebar .network { + margin-top: 1em; +} +#sidebar .network:first-child { + margin-top: 0; +} +#sidebar .network:first-child .channel { background: #eaeaea; border-bottom-color: #e5e5e5; + line-height: 36px; } #chat { bottom: 0; diff --git a/client/index.html b/client/index.html index f6630e3c..735b8b84 100644 --- a/client/index.html +++ b/client/index.html @@ -43,7 +43,7 @@ diff --git a/client/js/chat.js b/client/js/chat.js index 3e205036..06690798 100644 --- a/client/js/chat.js +++ b/client/js/chat.js @@ -1,7 +1,10 @@ $(function() { var socket = io.connect(""); - socket.on("event", function(event) { - render(event); + socket.on("event", function(data) { + render(data); + + // Debug + console.log(data); }); var chat = $("#chat"); @@ -13,49 +16,7 @@ $(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) { + function render(data) { chat.html(""); var partials = { users: users, @@ -80,60 +41,6 @@ $(function() { .focus(); } - var View = {}; - - View.refresh = function(event) { - var data = event.data; - sidebar.html( - Mustache.render(networks, { - networks: data - }) - ); - - chat.html(""); - var partials = { - users: users, - messages: messages - }; - data.forEach(function(network) { - chat.append(Mustache.render(channels, network, partials)); - }); - - 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(); - }; - - View.add = function(event) { - var target = $("[data-id='" + event.target + "'] "); - switch (event.type) { - - case "users": - target = target.find(".users"); - target.html(Mustache.render(users, {users: event.data})); - break; - - case "messages": - var keepAtBottom = target.isScrollBottom(); - target = target.find(".messages"); - target.append(Mustache.render(messages, {messages: event.data})); - if (keepAtBottom) { - target.scrollToBottom(); - } - break; - - } - }; - - View.remove = function(event) { - $("[data-id='" + event.target + "']").remove(); - }; - chat.on("submit", "form", function() { var input = $(this).find(".input"); var text = input.val(); diff --git a/lib/models.js b/lib/models.js index a41641df..ea87818d 100644 --- a/lib/models.js +++ b/lib/models.js @@ -1,66 +1,67 @@ -var _ = require("lodash"); +var Backbone = require("backbone"); var moment = require("moment"); -var models = exports; +var models = + module.exports = + {}; + var id = 1; -models.Network = function(attr) { - attr = attr || {}; - _.extend(this, _.defaults(attr, { - id: id++, - address: "", - nick: "", - channels: [] - })); -}; +models.User = Backbone.Model.extend({ + defaults: { + mode: "", + name: "user" + } +}); -models.Network.prototype.toJSON = function() { - return _.omit(this, "client"); -}; +models.Message = Backbone.Model.extend({ + defaults: { + time: moment().format("HH:mm"), + user: "user", + text: "text" + } +}); -models.Channel = function(attr) { - attr = attr || {}; - _.extend(this, _.defaults(attr, { - id: id++, - name: "", +models.Channel = Backbone.Model.extend({ + defaults: { type: "channel", + name: "", topic: "", users: [], messages: [] - })); -}; + }, + initialize: function() { + this.set({ + id: id++ + }); + } +}); -models.User = function(attr) { - attr = attr || {}; - _.extend(this, _.defaults(attr, { - id: id++, - name: "" - })); -}; +models.ChannelCollection = Backbone.Collection.extend({ + model: models.Channel +}); -models.Message = function(attr) { - attr = attr || {}; - _.extend(this, _.defaults(attr, { - time: moment().format("HH:mm"), - user: "", - text: "" - })); -}; +models.Network = Backbone.Model.extend({ + defaults: { + host: "", + }, + initialize: function() { + this.set({ + id: id++, + channels: new models.ChannelCollection() + }); + this.get("channels").add(new models.Channel({ + type: "network", + name: this.get("host") + })); + } +}); -models.Event = function(attr) { - attr = attr || {}; - _.extend(this, _.defaults(attr, { - action: "", - data: "", - target: "", - type: "" - })); -}; - -models.Target = function(attr) { - attr = attr || {}; - _.extend(this, _.defaults(attr, { - network: "", - channel: "" - })); -}; +models.NetworkCollection = Backbone.Collection.extend({ + model: models.Network, + initialize: function() { + this.add(new models.Network({ + host: "Lobby" + })); + } +}); diff --git a/lib/server.js b/lib/server.js index f264f939..70b1c19d 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,130 +1,33 @@ var connect = require("connect"); -var models = require("./models.js"); -var _ = require("lodash"); -var irc = require("irc"); var io = require("socket.io"); -exports.listen = listen; +// Local library +var models = require("./models.js"); -var sockets = false;; -var networks = []; +module.exports = Server; -addToServer( - "NETWORK", - new models.Network({address: "Start"}) -); +function Server() { + this.sockets = false; + this.networks = new models.NetworkCollection; +} -function listen(port) { +Server.prototype.listen = function(port) { + var self = this; var http = connect() .use(connect.static("client")) .listen(port); - sockets = io - .listen(http) - .on("connection", initSocket) - .sockets; -} - -function initSocket(socket) { - socket.on("input", handleUserInput); - refresh(); -} - -function sendEvent(params) { - if (sockets) { - sockets.emit("event", new models.Event(params)); - } -} - -function refresh() { - sendEvent({action: "RENDER", type: "NETWORK", data: networks}); -} - -function addToServer(type, model, target) { - switch (type) { - case "NETWORK": - var channel = new models.Channel({ - name: model.address, - type: "network" - }); - - model.channels.push(channel); - networks.push(model); - - refresh(); - break; - - case "CHANNEL": - target.network.channels.push(model); - refresh(); - break; - - 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; - - 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; - - case "MESSAGE": - addToServer( - "MESSAGE", - new models.Message({text: input.text}), - getTarget(id) - ); - break; - - } -} - -function getTarget(id) { - var find; - _.each(networks, function(n) { - find = {network: n, channel: _.findWhere(n.channels, {id: id})}; - if (find.channel) - return; + this.sockets = io.listen(http).sockets; + this.sockets.on("connection", function(socket) { + init.call(self, socket); }); - if (find.channel) { - return new models.Target(find); - } + + return this; +}; + +function init(socket) { + socket.emit( + "event", + this.networks + ) } diff --git a/package.json b/package.json index a0b739a8..7200af5c 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,10 @@ "email": "mattias@mattiaserming.com" }, "dependencies": { + "backbone": "1.1.2", "commander": "2.1.0", "connect": "2.13.0", "irc": "0.3.6", - "lodash": "2.4.1", "moment": "2.5.1", "socket.io": "0.9.16" },