mirror of
https://github.com/thelounge/thelounge
synced 2024-11-22 12:03:11 +00:00
Removing Backbone dependency. Closes #6
This commit is contained in:
parent
8ad659d7fa
commit
2852942241
13 changed files with 538 additions and 448 deletions
|
@ -11,6 +11,7 @@ These are the commands currently implemented:
|
|||
- `/kick`
|
||||
- `/leave`
|
||||
- `/mode`
|
||||
- `/msg`
|
||||
- `/nick`
|
||||
- `/op`
|
||||
- `/part`
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
|
||||
<title>Chat</title>
|
||||
<title>Shout — The modern IRC client</title>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||
|
@ -21,25 +21,23 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/x-handlebars-template" id="networks">
|
||||
<script type="text/html" id="networks">
|
||||
{{#each networks}}
|
||||
<ul id="network-{{id}}" class="network">
|
||||
<div id="network-{{id}}" data-nick="{{nick}}" class="network">
|
||||
{{partial "#channels"}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/x-handlebars-template" id="channels">
|
||||
<script type="text/html" id="channels">
|
||||
{{#each channels}}
|
||||
<li>
|
||||
<button id="channel-{{id}}" class="channel">
|
||||
{{name}}
|
||||
</button>
|
||||
</li>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/x-handlebars-template" id="windows">
|
||||
<script type="text/html" id="windows">
|
||||
{{#each windows}}
|
||||
<div id="window-{{id}}" class="window {{type}}">
|
||||
<div class="title">
|
||||
|
@ -59,7 +57,7 @@
|
|||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/x-handlebars-template" id="users">
|
||||
<script type="text/html" id="users">
|
||||
<div class="count">
|
||||
Users: {{users.length}}
|
||||
</div>
|
||||
|
@ -70,9 +68,9 @@
|
|||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/x-handlebars-template" id="messages">
|
||||
<script type="text/html" id="messages">
|
||||
{{#each messages}}
|
||||
<div class="{{type}}">
|
||||
<div class="msg {{type}}">
|
||||
<span class="time">
|
||||
{{time}}
|
||||
</span>
|
||||
|
|
|
@ -11,6 +11,7 @@ $(function() {
|
|||
"/kick",
|
||||
"/leave",
|
||||
"/mode",
|
||||
"/msg",
|
||||
"/nick",
|
||||
"/op",
|
||||
"/part",
|
||||
|
@ -23,133 +24,98 @@ $(function() {
|
|||
];
|
||||
|
||||
var socket = io.connect("");
|
||||
$.each(["network", "channel", "user", "message"], function(i, event) {
|
||||
socket.on(event, function(json) {
|
||||
handleEvent(event, json);
|
||||
var events = [
|
||||
"join",
|
||||
"msg",
|
||||
"networks",
|
||||
"nick",
|
||||
"part",
|
||||
"users",
|
||||
].forEach(function(e) {
|
||||
socket.on(e, function(data) {
|
||||
event(e, data);
|
||||
});
|
||||
});
|
||||
|
||||
var tpl = [];
|
||||
function render(id, json) {
|
||||
tpl[id] = tpl[id] || Handlebars.compile($(id).html());
|
||||
return tpl[id](json);
|
||||
function render(id, data) {
|
||||
tpl[id] = tpl[id] || Handlebars.compile($(id).remove().html());
|
||||
return tpl[id](data);
|
||||
}
|
||||
|
||||
function handleEvent(event, json) {
|
||||
var data = [].concat(json.data);
|
||||
switch (event) {
|
||||
function event(e, data) {
|
||||
// Debug
|
||||
console.log(arguments);
|
||||
|
||||
case "network":
|
||||
var html = "";
|
||||
data.forEach(function(n) {
|
||||
html += render("#windows", {windows: n.channels});
|
||||
});
|
||||
chat[0].innerHTML = html;
|
||||
|
||||
sidebar.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[0].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 == "auto") z = 0;
|
||||
if (z > highest) {
|
||||
highest = z;
|
||||
next = $(this);
|
||||
}
|
||||
});
|
||||
if (next != null) {
|
||||
$("#channel-" + next.attr("id").replace("window-", "")).addClass("active");
|
||||
next.bringToTop();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sidebar.find(".channel").removeClass("active");
|
||||
|
||||
$("#network-" + json.target).append(
|
||||
render("#channels", {channels: data})
|
||||
).find(".channel")
|
||||
switch (e) {
|
||||
case "join":
|
||||
chat.append(render("#windows", {
|
||||
windows: [data.chan],
|
||||
})).find(".window")
|
||||
.last()
|
||||
.addClass("active");
|
||||
|
||||
chat.append(
|
||||
render("#windows", {windows: data})
|
||||
).find(".window")
|
||||
.last()
|
||||
.find("input")
|
||||
.find(".input")
|
||||
.tabComplete({after: " ", list: commands})
|
||||
.inputHistory({submit: true})
|
||||
.end()
|
||||
.bringToTop()
|
||||
.find(".messages")
|
||||
.scrollGlue({animate: 400})
|
||||
.scrollGlue({speed: 400})
|
||||
.end();
|
||||
$("#network-" + data.id).append(render("#channels", {
|
||||
channels: [data.chan],
|
||||
})).find(".channel")
|
||||
.last()
|
||||
.uniqueClass("active")
|
||||
.end();
|
||||
break;
|
||||
|
||||
case "user":
|
||||
var html = render("#users", {users: data});
|
||||
var target = chat.find("#window-" + json.target + " .users").html(html);
|
||||
|
||||
case "msg":
|
||||
$("#window-" + data.id).find(".messages").append(render("#messages", {
|
||||
messages: [data.msg],
|
||||
}));
|
||||
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);
|
||||
|
||||
case "networks":
|
||||
chat.html(render("#windows", {
|
||||
windows: $.map(data.networks, function(n) { return n.channels; }),
|
||||
})).find(".window")
|
||||
.find(".input")
|
||||
.tabComplete({after: " ", list: commands})
|
||||
.inputHistory({submit: true})
|
||||
.end()
|
||||
.find(".messages")
|
||||
.scrollGlue({speed: 400})
|
||||
.end()
|
||||
.last()
|
||||
.bringToTop()
|
||||
.end();
|
||||
sidebar.html(render("#networks", {
|
||||
networks: data.networks,
|
||||
})).find(".channel")
|
||||
.last()
|
||||
.addClass("active")
|
||||
.end();
|
||||
break;
|
||||
|
||||
case "nick":
|
||||
// Not yet implemented.
|
||||
break;
|
||||
|
||||
case "part":
|
||||
$("#channel-" + data.id + ", #window-" + data.id).remove();
|
||||
break;
|
||||
|
||||
case "users":
|
||||
$("#window-" + data.id).find(".users").html(render("#users", {
|
||||
users: data.users,
|
||||
}));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sidebar.on("click", ".channel", function(e) {
|
||||
e.preventDefault();
|
||||
sidebar.find(".active").removeClass("active");
|
||||
$("#viewport").removeClass();
|
||||
var item = $(this)
|
||||
.addClass("active")
|
||||
.find(".badge")
|
||||
.html("")
|
||||
.end();
|
||||
$("#window-" + item.attr("id").replace("channel-", ""))
|
||||
.bringToTop();
|
||||
});
|
||||
|
||||
|
||||
chat.on("submit", "form", function() {
|
||||
var input = $(this).find(".input");
|
||||
var text = input.val();
|
||||
var text = input.val();
|
||||
if (text == "") {
|
||||
return false;
|
||||
}
|
||||
|
@ -159,39 +125,36 @@ $(function() {
|
|||
text: text,
|
||||
});
|
||||
});
|
||||
|
||||
chat.on("dblclick", ".user", function() {
|
||||
var link = $(this);
|
||||
var id = parseInt(link.closest(".window").attr("id").replace("window-", ""));
|
||||
var name = link.text().trim();
|
||||
|
||||
chat.on("focus", ".input", function() {
|
||||
var input = $(this).parents().eq(1).find(".messages").scrollToBottom();
|
||||
});
|
||||
|
||||
chat.on("click", ".user", function(e) {
|
||||
e.preventDefault();
|
||||
var user = $(this);
|
||||
var id = parseInt(user.closest(".window").attr("id").replace("window-", ""));
|
||||
var name = user.text().trim();
|
||||
if (name == "-!-" || name.indexOf(".") != -1) {
|
||||
return;
|
||||
}
|
||||
socket.emit("input", {
|
||||
id: id,
|
||||
text: "/whois " + link.text().trim(),
|
||||
text: "/whois " + name,
|
||||
});
|
||||
});
|
||||
|
||||
chat.on("focus", "input[type=text]", function() {
|
||||
$(this).closest(".window").find(".messages").scrollToBottom();
|
||||
sidebar.on("click", ".channel", function(e) {
|
||||
e.preventDefault();
|
||||
$("#window-" + $(this).attr("id").replace("channel-", ""))
|
||||
.bringToTop();
|
||||
});
|
||||
|
||||
var highest = 1;
|
||||
$.fn.bringToTop = function() {
|
||||
return this.css('z-index', highest++)
|
||||
.addClass("active")
|
||||
.find(".input")
|
||||
.focus()
|
||||
.end()
|
||||
.siblings()
|
||||
.removeClass("active")
|
||||
.end();
|
||||
};
|
||||
|
||||
// Utils
|
||||
|
||||
function uri(text) {
|
||||
return URI.withinString(text, function(url) {
|
||||
return "<a href='" + url + "' target='_blank'>" + url + "</a>";
|
||||
return "<a href='" + url.replace(/^www/, "//www") + "' target='_blank'>" + url + "</a>";
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -205,6 +168,8 @@ $(function() {
|
|||
});
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
Handlebars.registerHelper(
|
||||
"uri",
|
||||
function(text) {
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
/*!
|
||||
* uniqueClass
|
||||
* https://gist.github.com/erming/11212325
|
||||
*/
|
||||
(function($) {
|
||||
$.fn.uniqueClass = function(name) {
|
||||
return this.addClass(name).siblings().removeClass(name).end();
|
||||
};
|
||||
})(jQuery);
|
||||
|
||||
/*!
|
||||
* bringToTop
|
||||
* https://gist.github.com/erming/11193183
|
||||
*/
|
||||
(function($) {
|
||||
var highest = 1;
|
||||
$.fn.bringToTop = function() {
|
||||
return this.css('z-index', highest++).uniqueClass('active')
|
||||
.find(".input")
|
||||
.focus()
|
||||
.end();
|
||||
};
|
||||
})(jQuery);
|
||||
|
||||
/*!
|
||||
* inputHistory
|
||||
* https://github.com/erming/inputHistory
|
||||
|
@ -7,7 +31,6 @@
|
|||
*
|
||||
* Version 0.1.1
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
$.fn.inputHistory = function(options) {
|
||||
var settings = $.extend({
|
||||
|
@ -72,13 +95,13 @@
|
|||
* Copyright (c) 2014 Mattias Erming <mattias@mattiaserming.com>
|
||||
* Licensed under the MIT License.
|
||||
*
|
||||
* Version 0.2.1
|
||||
* Version 0.2.2
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
$.fn.scrollGlue = function(options) {
|
||||
var settings = $.extend({
|
||||
speed: 0
|
||||
speed: 0,
|
||||
scrollToBottom: true,
|
||||
}, options);
|
||||
|
||||
var self = this;
|
||||
|
@ -87,6 +110,10 @@
|
|||
$(this).scrollGlue(options);
|
||||
});
|
||||
}
|
||||
|
||||
if (settings.scrollToBottom) {
|
||||
self.scrollToBottom();
|
||||
}
|
||||
|
||||
$(window).on('resize', function() {
|
||||
self.finish();
|
||||
|
@ -147,7 +174,6 @@
|
|||
*
|
||||
* Version 0.2.2
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
$.fn.tabComplete = function(options) {
|
||||
var settings = $.extend({
|
||||
|
|
|
@ -49,10 +49,12 @@ li {
|
|||
#sidebar .network {
|
||||
margin: 20px;
|
||||
}
|
||||
#sidebar li {
|
||||
#sidebar .channel {
|
||||
display: block;
|
||||
margin: 5px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
#sidebar li:first-child {
|
||||
#sidebar .channel:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
#chat {
|
||||
|
@ -83,11 +85,11 @@ li {
|
|||
padding: 0 10px;
|
||||
width: 100%;
|
||||
}
|
||||
#chat .network .users {
|
||||
#chat .lobby .users {
|
||||
display: none;
|
||||
}
|
||||
#chat .network .title,
|
||||
#chat .network .messages {
|
||||
#chat .lobby .title,
|
||||
#chat .lobby .messages {
|
||||
right: 0;
|
||||
}
|
||||
#chat .window {
|
||||
|
@ -141,9 +143,15 @@ li {
|
|||
#chat .notice,
|
||||
#chat .part,
|
||||
#chat .quit,
|
||||
#chat .topic {
|
||||
#chat .topic,
|
||||
#chat .whois {
|
||||
color: #999;
|
||||
}
|
||||
#chat .motd .type,
|
||||
#chat .notice .type,
|
||||
#chat .whois .type {
|
||||
display: none;
|
||||
}
|
||||
#chat .users {
|
||||
background: #fff;
|
||||
border-left: 1px solid #ddd;
|
||||
|
|
12
config.js
12
config.js
|
@ -1,11 +1,13 @@
|
|||
module.exports = {
|
||||
port: 9000,
|
||||
defaults: {
|
||||
nick: "t_user",
|
||||
realname: "Temp User",
|
||||
nick: "j_doe",
|
||||
realname: "John Doe",
|
||||
},
|
||||
servers: [{
|
||||
networks: [{
|
||||
host: "irc.freenode.org",
|
||||
channels: ["#t_chan"],
|
||||
port: 6667,
|
||||
channels: [
|
||||
"#t_chan",
|
||||
],
|
||||
}]
|
||||
};
|
||||
|
|
131
lib/models.js
131
lib/models.js
|
@ -1,131 +0,0 @@
|
|||
var _ = require("lodash");
|
||||
var Backbone = require("backbone");
|
||||
|
||||
var id = 1;
|
||||
var models =
|
||||
module.exports =
|
||||
{};
|
||||
|
||||
models.User = Backbone.Model.extend({
|
||||
defaults: {
|
||||
mode: "",
|
||||
name: "",
|
||||
}
|
||||
});
|
||||
|
||||
models.Users = Backbone.Collection.extend({
|
||||
model: models.User,
|
||||
sort: function() {
|
||||
this.models = _.sortBy(
|
||||
this.models,
|
||||
function(user) {
|
||||
return user.get("name").toLowerCase();
|
||||
}
|
||||
);
|
||||
this.trigger("sort", {}, this);
|
||||
}
|
||||
});
|
||||
|
||||
models.Message = Backbone.Model.extend({
|
||||
defaults: {
|
||||
type: "",
|
||||
time: "",
|
||||
from: "-!-",
|
||||
text: "",
|
||||
},
|
||||
initialize: function() {
|
||||
this.set("time", require("moment")().format("HH:mm"));
|
||||
}
|
||||
});
|
||||
|
||||
models.Messages = Backbone.Collection.extend({
|
||||
model: models.Message
|
||||
});
|
||||
|
||||
models.Channel = Backbone.Model.extend({
|
||||
defaults: {
|
||||
type: "channel",
|
||||
name: "",
|
||||
},
|
||||
initialize: function() {
|
||||
var users = new models.Users;
|
||||
users.on("all", function(action, data) {
|
||||
this.trigger("user", {
|
||||
action: action,
|
||||
target: this.get("id"),
|
||||
data: users,
|
||||
});
|
||||
}, this);
|
||||
|
||||
var messages = new models.Messages;
|
||||
messages.on("all", function(action, data) {
|
||||
this.trigger("message", {
|
||||
action: action,
|
||||
target: this.get("id"),
|
||||
data: data,
|
||||
});
|
||||
}, this);
|
||||
|
||||
this.set({
|
||||
id: id++,
|
||||
users: users,
|
||||
messages: messages,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
models.Channels = Backbone.Collection.extend({
|
||||
model: models.Channel
|
||||
});
|
||||
|
||||
models.Network = Backbone.Model.extend({
|
||||
defaults: {
|
||||
host: "",
|
||||
client: null,
|
||||
},
|
||||
initialize: function() {
|
||||
this.set({
|
||||
id: id++,
|
||||
channels: new models.Channels,
|
||||
});
|
||||
|
||||
this.get("channels").on("all", function(action, data) {
|
||||
if (action == "message"
|
||||
|| action == "user") {
|
||||
return this.trigger(action, data);
|
||||
}
|
||||
this.trigger("channel", {
|
||||
action: action,
|
||||
target: this.get("id"),
|
||||
data: data,
|
||||
});
|
||||
}, this);
|
||||
|
||||
this.get("channels").add({
|
||||
type: "network",
|
||||
name: this.get("host")
|
||||
});
|
||||
},
|
||||
toJSON: function() {
|
||||
return _.omit(this.attributes, "client");
|
||||
}
|
||||
});
|
||||
|
||||
models.Networks = Backbone.Collection.extend({
|
||||
model: models.Network,
|
||||
initialize: function() {
|
||||
this.add({host: "Status"});
|
||||
},
|
||||
find: function(id) {
|
||||
var i = this.models.length;
|
||||
while (i--) {
|
||||
var find = this.models[i].get("channels").findWhere({id: id});
|
||||
if (find) {
|
||||
return {
|
||||
network: this.models[i],
|
||||
channel: find
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
13
lib/models/chan.js
Normal file
13
lib/models/chan.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
var _ = require("lodash");
|
||||
|
||||
module.exports = Chan;
|
||||
|
||||
function Chan(attr) {
|
||||
_.merge(this, _.extend({
|
||||
id: global.id = ++global.id || 1,
|
||||
name: "",
|
||||
type: "",
|
||||
messages: [],
|
||||
users: [],
|
||||
}, attr));
|
||||
};
|
13
lib/models/msg.js
Normal file
13
lib/models/msg.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
var _ = require("lodash");
|
||||
var moment = require("moment");
|
||||
|
||||
module.exports = Msg;
|
||||
|
||||
function Msg(attr) {
|
||||
_.merge(this, _.extend({
|
||||
time: moment().format("HH:mm"),
|
||||
type: "",
|
||||
from: "",
|
||||
text: "",
|
||||
}, attr));
|
||||
};
|
25
lib/models/network.js
Normal file
25
lib/models/network.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
var _ = require("lodash");
|
||||
var Chan = require("./chan");
|
||||
|
||||
module.exports = Network;
|
||||
|
||||
function Network(attr) {
|
||||
_.merge(this, _.extend({
|
||||
id: global.id = ++global.id || 1,
|
||||
client: null,
|
||||
host: "",
|
||||
nick: "",
|
||||
channels: [],
|
||||
}, attr));
|
||||
|
||||
// Add lobby
|
||||
this.channels.unshift(
|
||||
new Chan({name: this.host, type: "lobby"})
|
||||
);
|
||||
};
|
||||
|
||||
Network.prototype = {
|
||||
toJSON: function() {
|
||||
return _.omit(this, "client");
|
||||
}
|
||||
};
|
10
lib/models/user.js
Normal file
10
lib/models/user.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
var _ = require("lodash");
|
||||
|
||||
module.exports = User;
|
||||
|
||||
function User(attr) {
|
||||
_.merge(this, _.extend({
|
||||
mode: "",
|
||||
name: "",
|
||||
}, attr));
|
||||
};
|
485
lib/server.js
485
lib/server.js
|
@ -1,13 +1,21 @@
|
|||
var models = require(__dirname + "/models.js");
|
||||
var config = require(__dirname + "/../config.js");
|
||||
var http = require("connect");
|
||||
var io = require("socket.io");
|
||||
var irc = require("slate-irc");
|
||||
var net = require("net");
|
||||
var _ = require("lodash");
|
||||
var config = require("../config");
|
||||
var http = require("connect");
|
||||
var io = require("socket.io");
|
||||
var irc = require("slate-irc");
|
||||
var net = require("net");
|
||||
var _ = require("lodash");
|
||||
|
||||
var sockets = null;
|
||||
var networks = new models.Networks;
|
||||
// Models
|
||||
|
||||
var Chan = require("./models/chan");
|
||||
var Msg = require("./models/msg");
|
||||
var Network = require("./models/network");
|
||||
var User = require("./models/user");
|
||||
|
||||
var sockets = null;
|
||||
var networks = [
|
||||
new Network({host: "Status"})
|
||||
];
|
||||
|
||||
var events = [
|
||||
"join",
|
||||
|
@ -25,26 +33,25 @@ var events = [
|
|||
"whois",
|
||||
];
|
||||
|
||||
module.exports = function listen() {
|
||||
module.exports = listen;
|
||||
|
||||
function listen() {
|
||||
var app = http()
|
||||
.use(http.static("client"))
|
||||
.listen(9000);
|
||||
|
||||
var self = this;
|
||||
sockets = io.listen(app, {log: 0}).sockets.on("connection", function(s) {
|
||||
s.on("input", input);
|
||||
sockets.emit("network", {
|
||||
data: networks,
|
||||
s.emit("networks", {
|
||||
networks: networks
|
||||
});
|
||||
});
|
||||
|
||||
networks.on("all", function() {
|
||||
sockets.emit.apply(sockets, arguments);
|
||||
config.networks.forEach(function(n) {
|
||||
connect(n);
|
||||
});
|
||||
|
||||
config.servers.forEach(function(s) {
|
||||
connect(s);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function connect(params) {
|
||||
params = _.extend(
|
||||
|
@ -53,7 +60,7 @@ function connect(params) {
|
|||
);
|
||||
|
||||
var host = params.host;
|
||||
var port = params.port || 6667;
|
||||
var port = params.port;
|
||||
|
||||
var stream = net.connect({
|
||||
port: port,
|
||||
|
@ -65,18 +72,20 @@ function connect(params) {
|
|||
});
|
||||
|
||||
var client = irc(stream);
|
||||
var network = networks.add({
|
||||
var network = new Network({
|
||||
host: host,
|
||||
client: client,
|
||||
}, {silent: true});
|
||||
|
||||
networks.trigger("network", {data: networks});
|
||||
});
|
||||
|
||||
networks.push(network);
|
||||
sockets.emit("networks", {
|
||||
networks: networks
|
||||
});
|
||||
|
||||
client.nick(params.nick);
|
||||
client.user(params.nick, params.realname);
|
||||
|
||||
client.once("welcome", function() {
|
||||
params.channels.forEach(function(c) {
|
||||
(params.channels || []).forEach(function(c) {
|
||||
client.join(c);
|
||||
});
|
||||
});
|
||||
|
@ -88,41 +97,53 @@ function connect(params) {
|
|||
});
|
||||
}
|
||||
|
||||
function input(json) {
|
||||
var target = networks.find(json.id);
|
||||
function input(data) {
|
||||
// Debug
|
||||
console.log(arguments);
|
||||
|
||||
var target = find(data.id);
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var network = target.network;
|
||||
var channel = target.channel;
|
||||
var chan = target.chan;
|
||||
|
||||
var client = network.get("client");
|
||||
|
||||
var id = json.id;
|
||||
var text = json.text;
|
||||
var client = network.client;
|
||||
|
||||
var id = data.id;
|
||||
var text = data.text;
|
||||
|
||||
var args = text.replace(/^\//, '').split(" ");
|
||||
var cmd = text.charAt(0) == "/" ? args[0].toLowerCase() : "";
|
||||
var cmd = text.charAt(0) == "/" ? args[0].toLowerCase() : "";
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case "":
|
||||
args.unshift(
|
||||
"msg",
|
||||
channel.get("name")
|
||||
chan.name
|
||||
);
|
||||
console.log(args);
|
||||
case "msg":
|
||||
var user;
|
||||
var message = _.tail(args, 2).join(" ");
|
||||
var text = _.tail(args, 2).join(" ");
|
||||
if (cmd == "msg") console.log(args);
|
||||
if (client) {
|
||||
user = client.me;
|
||||
client.send(args[1], message);
|
||||
client.send(args[1], text);
|
||||
}
|
||||
var chan = _.findWhere(network.channels, {name: args[1]});
|
||||
if (typeof chan !== "undefined") {
|
||||
var msg = new Msg({
|
||||
from: user,
|
||||
text: text,
|
||||
});
|
||||
chan.messages.push(msg)
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
}
|
||||
channel.get("messages").add({
|
||||
from: user,
|
||||
text: message,
|
||||
});
|
||||
break;
|
||||
|
||||
case "server":
|
||||
|
@ -141,21 +162,23 @@ function input(json) {
|
|||
|
||||
case "leave":
|
||||
case "part":
|
||||
if (channel.get("type") == "query") {
|
||||
network.get("channels").remove(channel);
|
||||
var id = chan.id;
|
||||
if (chan.type == "query" || !chan.users.length) {
|
||||
remove(id);
|
||||
sockets.emit("part", {
|
||||
id: id,
|
||||
});
|
||||
} else if (client) {
|
||||
client.part(channel.get("name"));
|
||||
client.part(chan.name);
|
||||
}
|
||||
break;
|
||||
|
||||
case "topic":
|
||||
var chan = channel.get("name");
|
||||
if (client) {
|
||||
var str = "TOPIC " + chan;
|
||||
if (args[1]) {
|
||||
str += " :" + args.slice(1).join(" ");
|
||||
}
|
||||
client.write(str);
|
||||
var msg = "TOPIC";
|
||||
msg += " " + chan.name;
|
||||
msg += args[1] ? " :" + args.slice(1).join(" ") : "";
|
||||
client.write(msg);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -168,7 +191,7 @@ function input(json) {
|
|||
|
||||
case "kick":
|
||||
if (client && args[1]) {
|
||||
client.kick(channel.get("name"), args[1]);
|
||||
client.kick(chan.name, args[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -180,7 +203,6 @@ function input(json) {
|
|||
if (!client || !args[1]) {
|
||||
break;
|
||||
}
|
||||
|
||||
var mode;
|
||||
var user;
|
||||
if (cmd != "mode") {
|
||||
|
@ -197,9 +219,8 @@ function input(json) {
|
|||
mode = args[1];
|
||||
user = args[2];
|
||||
}
|
||||
|
||||
client.mode(
|
||||
channel.get("name"),
|
||||
chan.name,
|
||||
mode,
|
||||
user
|
||||
);
|
||||
|
@ -207,191 +228,331 @@ function input(json) {
|
|||
|
||||
case "quit":
|
||||
case "disconnect":
|
||||
networks.remove(network);
|
||||
networks.trigger("network", {data: networks});
|
||||
if (client) {
|
||||
client.quit();
|
||||
networks = _.without(networks, network);
|
||||
sockets.emit("networks", {
|
||||
networks: networks
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function event(event, data) {
|
||||
var channels = this.get("channels");
|
||||
function event(e, data) {
|
||||
// Debug
|
||||
console.log(arguments);
|
||||
|
||||
switch (event) {
|
||||
var data = _.last(data);
|
||||
var channels = this.channels;
|
||||
|
||||
switch (e) {
|
||||
case "join":
|
||||
var chan = channels.findWhere({name: data[0].channel}) || channels.add({name: data[0].channel});
|
||||
var users = chan.get("users");
|
||||
users.add({name: data[0].nick}, {silent: true});
|
||||
if (data[0].nick != this.get("client").me) {
|
||||
users.sort();
|
||||
var chan = _.findWhere(channels, {name: data.channel});
|
||||
if (typeof chan === "undefined") {
|
||||
chan = new Chan({
|
||||
name: data.channel,
|
||||
});
|
||||
channels.push(chan);
|
||||
sockets.emit("join", {
|
||||
id: this.id,
|
||||
chan: chan,
|
||||
});
|
||||
}
|
||||
chan.get("messages").add({
|
||||
from: data[0].nick,
|
||||
var users = chan.users;
|
||||
users.push(new User({name: data.nick}));
|
||||
sockets.emit("users", {
|
||||
id: chan.id,
|
||||
users: users,
|
||||
});
|
||||
var msg = new Msg({
|
||||
from: data.nick,
|
||||
type: "join",
|
||||
});
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
break;
|
||||
|
||||
case "kick":
|
||||
var chan = channels.findWhere({name: data[0].channel});
|
||||
var users = chan.get("users");
|
||||
|
||||
if (data[0].client != this.get("client").me) {
|
||||
users.remove(users.findWhere({name: data[0].client}));
|
||||
var chan = _.findWhere(channels, {name: data.channel});
|
||||
if (data.client == this.client.me) {
|
||||
chan.users = [];
|
||||
} else {
|
||||
users.reset();
|
||||
chan.users = _.without(chan.users, _.findWhere(chan.users, {name: data.client}));
|
||||
}
|
||||
|
||||
chan.get("messages").add({
|
||||
from: data[0].nick,
|
||||
text: data[0].client,
|
||||
sockets.emit("users", {
|
||||
id: chan.id,
|
||||
users: chan.users,
|
||||
});
|
||||
var msg = new Msg({
|
||||
type: "kick",
|
||||
from: data.nick,
|
||||
text: data.client,
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
break;
|
||||
|
||||
case "mode":
|
||||
var chan = channels.findWhere({name: data[0].target});
|
||||
var chan = _.findWhere(channels, {name: data.target});
|
||||
if (typeof chan !== "undefined") {
|
||||
chan.get("messages").add({
|
||||
from: data[0].nick,
|
||||
text: data[0].mode + " " + data[0].client,
|
||||
var msg = new Msg({
|
||||
type: "mode",
|
||||
from: data.nick,
|
||||
text: data.mode + " " + data.client,
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "motd":
|
||||
var messages = data[0].motd;
|
||||
messages.forEach(function(msg) {
|
||||
channels.first().get("messages").add({text: msg});
|
||||
var chan = channels[0];
|
||||
data.motd.forEach(function(m) {
|
||||
var msg = new Msg({
|
||||
type: "motd",
|
||||
from: "-!-",
|
||||
text: m,
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
||||
case "message":
|
||||
var chan = channels.findWhere({name: data[0].to}) || channels.add({type: "query", name: data[0].from});
|
||||
var chan = _.findWhere(channels, {name: data.to});
|
||||
if (typeof chan === "undefined") {
|
||||
chan = new Chan({
|
||||
name: data.from,
|
||||
type: "query",
|
||||
});
|
||||
channels.push(chan);
|
||||
sockets.emit("join", {
|
||||
id: this.id,
|
||||
chan: chan,
|
||||
});
|
||||
}
|
||||
var type = "";
|
||||
var text = data[0].message;
|
||||
var text = data.message;
|
||||
var network = this;
|
||||
text.split(" ").forEach(function(w) {
|
||||
if (w == network.get("client").me) type = "highlight";
|
||||
if (w == network.client.me) type = "highlight";
|
||||
});
|
||||
chan.get("messages").add({
|
||||
var msg = new Msg({
|
||||
type: type,
|
||||
from: data[0].from,
|
||||
from: data.from,
|
||||
text: text,
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
break;
|
||||
|
||||
case "names":
|
||||
var chan = channels.findWhere({name: data[0].channel});
|
||||
var users = chan.get("users");
|
||||
users.reset(
|
||||
_.map(data[0].names, function(n) { return {name: n}; }),
|
||||
{silent: true}
|
||||
);
|
||||
users.sort();
|
||||
var chan = _.findWhere(channels, {name: data.channel});
|
||||
chan.users = [];
|
||||
data.names.forEach(function(n) {
|
||||
chan.users.push(new User({name: n}));
|
||||
});
|
||||
sockets.emit("users", {
|
||||
id: chan.id,
|
||||
users: chan.users,
|
||||
});
|
||||
break;
|
||||
|
||||
case "nick":
|
||||
if (data[0].new == this.get("client").me) {
|
||||
channels.first().get("messages").add({
|
||||
text: "You're now known as " + data[0]["new"],
|
||||
if (data["new"] == this.client.me) {
|
||||
var chan = channels[0];
|
||||
var msg = new Msg({
|
||||
from: "-!-",
|
||||
text: "You're now known as " + data["new"],
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
}
|
||||
channels.each(function(chan) {
|
||||
var users = chan.get("users");
|
||||
var user = users.findWhere({name: data[0].nick});
|
||||
channels.forEach(function(chan) {
|
||||
var user = _.findWhere(chan.users, {name: data.nick});
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
|
||||
user.set("name", data[0]["new"]);
|
||||
users.sort();
|
||||
|
||||
chan.get("messages").add({
|
||||
from: data[0].nick,
|
||||
text: data[0]["new"],
|
||||
user.name = data["new"];
|
||||
sockets.emit("users", {
|
||||
id: chan.id,
|
||||
users: chan.users,
|
||||
});
|
||||
var msg = new Msg({
|
||||
type: "nick",
|
||||
from: data.nick,
|
||||
text: data["new"],
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
||||
case "notice":
|
||||
if (data[0].to = "*") {
|
||||
data[0].from = "-!-";
|
||||
}
|
||||
channels.first().get("messages").add({
|
||||
case "notice":
|
||||
var chan = channels[0];
|
||||
var msg = new Msg({
|
||||
type: "notice",
|
||||
from: data[0].from,
|
||||
text: data[0].message,
|
||||
from: data.to == "*" ? "-!-" : data.from,
|
||||
text: data.message,
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
break;
|
||||
|
||||
case "part":
|
||||
var chan = channels.findWhere({name: data[0].channels[0]});
|
||||
if (data[0].nick == this.get("client").me) {
|
||||
channels.remove(chan);
|
||||
return;
|
||||
var chan = _.findWhere(channels, {name: data.channels[0]});
|
||||
if (data.nick == this.client.me) {
|
||||
remove(chan.id);
|
||||
sockets.emit("part", {
|
||||
id: chan.id,
|
||||
});
|
||||
} else {
|
||||
chan.users = _.without(chan.users, _.findWhere(chan.users, {name: data.nick}));
|
||||
sockets.emit("users", {
|
||||
id: chan.id,
|
||||
users: chan.users,
|
||||
});
|
||||
var msg = new Msg({
|
||||
type: "part",
|
||||
from: data.nick,
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
}
|
||||
var users = chan.get("users");
|
||||
users.remove(users.findWhere({name: data[0].nick}));
|
||||
users.sort();
|
||||
chan.get("messages").add({
|
||||
from: data[0].nick,
|
||||
type: "part",
|
||||
});
|
||||
break;
|
||||
|
||||
case "quit":
|
||||
channels.each(function(chan) {
|
||||
var users = chan.get("users");
|
||||
var user = users.findWhere({name: data[0].nick});
|
||||
if (user) {
|
||||
users.remove(user);
|
||||
users.sort();
|
||||
chan.get("messages").add({
|
||||
from: data[0].nick,
|
||||
type: "quit",
|
||||
});
|
||||
channels.forEach(function(chan) {
|
||||
var user = _.findWhere(chan.users, {name: data.nick});
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
chan.users = _.without(chan.users, user);
|
||||
sockets.emit("users", {
|
||||
id: chan.id,
|
||||
users: chan.users,
|
||||
});
|
||||
var msg = new Msg({
|
||||
type: "quit",
|
||||
from: data.nick,
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
||||
case "topic":
|
||||
var chan = channels.findWhere({name: data[0].channel});
|
||||
var from = data[0].nick || chan.get("name");
|
||||
chan.get("messages").add({
|
||||
from: from,
|
||||
text: data[0].topic,
|
||||
var chan = _.findWhere(channels, {name: data.channel});
|
||||
var from = data.nick || chan.name;
|
||||
var msg = new Msg({
|
||||
type: "topic",
|
||||
from: from,
|
||||
text: data.topic,
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
break;
|
||||
|
||||
case "welcome":
|
||||
channels.first().get("messages").add([
|
||||
{text: "You're now connected to " + this.get("host")},
|
||||
{text: "You're now known as " + data[0]}
|
||||
]);
|
||||
// Leaving this empty for now.
|
||||
break;
|
||||
|
||||
case "whois":
|
||||
if (data[1] == null) {
|
||||
channels.first().get("messages").add({
|
||||
if (!data) {
|
||||
var chan = channels[0];
|
||||
var msg = new Msg({
|
||||
type: "error",
|
||||
text: data[0]
|
||||
text: "No such nick/channel.",
|
||||
});
|
||||
break;
|
||||
}
|
||||
var name = data[1].nickname;
|
||||
var chan = channels.findWhere({name: name}) || channels.add({type: "query", name: name});
|
||||
var i = 0;
|
||||
for (var k in data[1]) {
|
||||
if (i++ == 5) break;
|
||||
chan.get("messages").add({
|
||||
text: k + ": " + data[1][k]
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
} else {
|
||||
var chan = _.findWhere(channels, {name: data.nickname});
|
||||
if (typeof chan === "undefined") {
|
||||
chan = new Chan({
|
||||
type: "query",
|
||||
name: data.nickname,
|
||||
});
|
||||
channels.push(chan);
|
||||
sockets.emit("join", {
|
||||
id: this.id,
|
||||
chan: chan,
|
||||
});
|
||||
}
|
||||
var i = 0;
|
||||
for (var k in data) {
|
||||
if (i++ == 5) break;
|
||||
var msg = new Msg({
|
||||
type: "whois",
|
||||
from: "-!-",
|
||||
text: k + ": " + data[k],
|
||||
});
|
||||
chan.messages.push(msg);
|
||||
sockets.emit("msg", {
|
||||
id: chan.id,
|
||||
msg: msg,
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Utils
|
||||
|
||||
function find(id) {
|
||||
var result = false;
|
||||
networks.forEach(function(n) {
|
||||
result = {
|
||||
network: n,
|
||||
chan: _.findWhere(n.channels, {id: id}),
|
||||
};
|
||||
if (!result.chan) {
|
||||
result = false;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function remove(id) {
|
||||
networks.forEach(function(n) {
|
||||
n.channels = _.without(n.channels, _.findWhere(n.channels, {id: id}));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"lodash": "~2.4.1",
|
||||
"backbone": "~1.1.2",
|
||||
"slate-irc": "~0.5.0",
|
||||
"moment": "~2.5.1",
|
||||
"connect": "~2.14.3",
|
||||
|
|
Loading…
Reference in a new issue