Merge pull request #632 from thelounge/xpaw/multi-prefix-support
Make use of multi-prefix cap and remove NAMES spam on mode changes
This commit is contained in:
commit
1e864e266e
@ -2,13 +2,16 @@ var _ = require("lodash");
|
||||
|
||||
module.exports = User;
|
||||
|
||||
function User(attr) {
|
||||
// TODO: Remove this
|
||||
attr.name = attr.name || attr.nick;
|
||||
attr.mode = attr.mode || (attr.modes && attr.modes[0]) || "";
|
||||
|
||||
function User(attr, prefixLookup) {
|
||||
_.merge(this, _.extend({
|
||||
mode: "",
|
||||
name: ""
|
||||
modes: [],
|
||||
nick: ""
|
||||
}, attr));
|
||||
|
||||
// irc-framework sets character mode, but lounge works with symbols
|
||||
this.modes = this.modes.map(mode => prefixLookup[mode]);
|
||||
|
||||
// TODO: Remove this
|
||||
this.name = this.nick;
|
||||
this.mode = (this.modes && this.modes[0]) || "";
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ module.exports = function(irc, network) {
|
||||
chan: chan
|
||||
});
|
||||
}
|
||||
chan.users.push(new User({nick: data.nick, modes: ""}));
|
||||
chan.users.push(new User({nick: data.nick}));
|
||||
chan.sortUsers(irc);
|
||||
client.emit("users", {
|
||||
chan: chan.id
|
||||
|
@ -17,17 +17,19 @@ module.exports = function(irc, network) {
|
||||
}
|
||||
|
||||
var usersUpdated;
|
||||
var supportsMultiPrefix = network.irc.network.cap.isEnabled("multi-prefix");
|
||||
var userModeSortPriority = {};
|
||||
|
||||
irc.network.options.PREFIX.forEach(function(prefix, index) {
|
||||
userModeSortPriority[prefix.symbol] = index;
|
||||
});
|
||||
|
||||
for (var i = 0; i < data.modes.length; i++) {
|
||||
var mode = data.modes[i];
|
||||
var text = mode.mode;
|
||||
|
||||
if (mode.param) {
|
||||
text += " " + mode.param;
|
||||
|
||||
var user = _.find(targetChan.users, {name: mode.param});
|
||||
if (typeof user !== "undefined") {
|
||||
usersUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
var msg = new Msg({
|
||||
@ -39,11 +41,51 @@ module.exports = function(irc, network) {
|
||||
self: data.nick === irc.user.nick
|
||||
});
|
||||
targetChan.pushMessage(client, msg);
|
||||
|
||||
if (!mode.param) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (usersUpdated) {
|
||||
var user = _.find(targetChan.users, {name: mode.param});
|
||||
if (!user) {
|
||||
continue;
|
||||
}
|
||||
|
||||
usersUpdated = true;
|
||||
|
||||
if (!supportsMultiPrefix) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var add = mode.mode[0] === "+";
|
||||
var changedMode = network.prefixLookup[mode.mode[1]];
|
||||
|
||||
if (!add) {
|
||||
_.pull(user.modes, changedMode);
|
||||
} else if (user.modes.indexOf(changedMode) === -1) {
|
||||
user.modes.push(changedMode);
|
||||
user.modes.sort(function(a, b) {
|
||||
return userModeSortPriority[a] - userModeSortPriority[b];
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: remove in future
|
||||
user.mode = (user.modes && user.modes[0]) || "";
|
||||
}
|
||||
|
||||
if (!usersUpdated) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!supportsMultiPrefix) {
|
||||
// TODO: This is horrible
|
||||
irc.raw("NAMES", data.target);
|
||||
} else {
|
||||
targetChan.sortUsers(irc);
|
||||
|
||||
client.emit("users", {
|
||||
chan: targetChan.id
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -8,18 +8,17 @@ module.exports = function(irc, network) {
|
||||
if (typeof chan === "undefined") {
|
||||
return;
|
||||
}
|
||||
chan.users = [];
|
||||
_.each(data.users, function(u) {
|
||||
var user = new User(u);
|
||||
|
||||
// irc-framework sets characater mode, but lounge works with symbols
|
||||
if (user.mode) {
|
||||
user.mode = network.prefixLookup[user.mode];
|
||||
}
|
||||
chan.users = [];
|
||||
|
||||
_.each(data.users, function(u) {
|
||||
var user = new User(u, network.prefixLookup);
|
||||
|
||||
chan.users.push(user);
|
||||
});
|
||||
|
||||
chan.sortUsers(irc);
|
||||
|
||||
client.emit("users", {
|
||||
chan: chan.id
|
||||
});
|
||||
|
@ -1,36 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require("lodash");
|
||||
var expect = require("chai").expect;
|
||||
|
||||
var Chan = require("../../src/models/chan");
|
||||
var User = require("../../src/models/user");
|
||||
|
||||
function makeUser(name) {
|
||||
// TODO Update/Fix this when User constructor gets reworked (see its TODO)
|
||||
return new User({nick: name, mode: ""});
|
||||
}
|
||||
|
||||
function getUserNames(chan) {
|
||||
return chan.users.map(function(u) {
|
||||
return u.name;
|
||||
});
|
||||
}
|
||||
|
||||
describe("Chan", function() {
|
||||
describe("#sortUsers(irc)", function() {
|
||||
var fullNetworkPrefix = [
|
||||
var network = {
|
||||
network: {
|
||||
options: {
|
||||
PREFIX: [
|
||||
{symbol: "~", mode: "q"},
|
||||
{symbol: "&", mode: "a"},
|
||||
{symbol: "@", mode: "o"},
|
||||
{symbol: "%", mode: "h"},
|
||||
{symbol: "+", mode: "v"}
|
||||
];
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var prefixLookup = {};
|
||||
|
||||
_.each(network.network.options.PREFIX, function(mode) {
|
||||
prefixLookup[mode.mode] = mode.symbol;
|
||||
});
|
||||
|
||||
var makeUser = function(nick) {
|
||||
return new User({nick: nick}, prefixLookup);
|
||||
};
|
||||
|
||||
var getUserNames = function(chan) {
|
||||
return chan.users.map(function(u) {
|
||||
return u.name;
|
||||
});
|
||||
};
|
||||
|
||||
it("should sort a simple user list", function() {
|
||||
var chan = new Chan({users: [
|
||||
"JocelynD", "YaManicKill", "astorije", "xPaw", "Max-P"
|
||||
].map(makeUser)});
|
||||
chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}});
|
||||
chan.sortUsers(network);
|
||||
|
||||
expect(getUserNames(chan)).to.deep.equal([
|
||||
"astorije", "JocelynD", "Max-P", "xPaw", "YaManicKill"
|
||||
@ -39,13 +51,13 @@ describe("Chan", function() {
|
||||
|
||||
it("should group users by modes", function() {
|
||||
var chan = new Chan({users: [
|
||||
new User({name: "JocelynD", mode: "&"}),
|
||||
new User({name: "YaManicKill", mode: "+"}),
|
||||
new User({name: "astorije", mode: "%"}),
|
||||
new User({name: "xPaw", mode: "~"}),
|
||||
new User({name: "Max-P", mode: "@"}),
|
||||
new User({nick: "JocelynD", modes: ["a", "o"]}, prefixLookup),
|
||||
new User({nick: "YaManicKill", modes: ["v"]}, prefixLookup),
|
||||
new User({nick: "astorije", modes: ["h"]}, prefixLookup),
|
||||
new User({nick: "xPaw", modes: ["q"]}, prefixLookup),
|
||||
new User({nick: "Max-P", modes: ["o"]}, prefixLookup),
|
||||
]});
|
||||
chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}});
|
||||
chan.sortUsers(network);
|
||||
|
||||
expect(getUserNames(chan)).to.deep.equal([
|
||||
"xPaw", "JocelynD", "Max-P", "astorije", "YaManicKill"
|
||||
@ -54,13 +66,13 @@ describe("Chan", function() {
|
||||
|
||||
it("should sort a mix of users and modes", function() {
|
||||
var chan = new Chan({users: [
|
||||
new User({name: "JocelynD"}),
|
||||
new User({name: "YaManicKill", mode: "@"}),
|
||||
new User({name: "astorije"}),
|
||||
new User({name: "xPaw"}),
|
||||
new User({name: "Max-P", mode: "@"}),
|
||||
new User({nick: "JocelynD"}, prefixLookup),
|
||||
new User({nick: "YaManicKill", modes: ["o"]}, prefixLookup),
|
||||
new User({nick: "astorije"}, prefixLookup),
|
||||
new User({nick: "xPaw"}, prefixLookup),
|
||||
new User({nick: "Max-P", modes: ["o"]}, prefixLookup),
|
||||
]});
|
||||
chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}});
|
||||
chan.sortUsers(network);
|
||||
|
||||
expect(getUserNames(chan)).to.deep.equal(
|
||||
["Max-P", "YaManicKill", "astorije", "JocelynD", "xPaw"]
|
||||
@ -69,7 +81,7 @@ describe("Chan", function() {
|
||||
|
||||
it("should be case-insensitive", function() {
|
||||
var chan = new Chan({users: ["aB", "Ad", "AA", "ac"].map(makeUser)});
|
||||
chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}});
|
||||
chan.sortUsers(network);
|
||||
|
||||
expect(getUserNames(chan)).to.deep.equal(["AA", "aB", "ac", "Ad"]);
|
||||
});
|
||||
@ -79,7 +91,7 @@ describe("Chan", function() {
|
||||
"[foo", "]foo", "(foo)", "{foo}", "<foo>", "_foo", "@foo", "^foo",
|
||||
"&foo", "!foo", "+foo", "Foo"
|
||||
].map(makeUser)});
|
||||
chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}});
|
||||
chan.sortUsers(network);
|
||||
|
||||
expect(getUserNames(chan)).to.deep.equal([
|
||||
"!foo", "&foo", "(foo)", "+foo", "<foo>", "@foo", "[foo", "]foo",
|
||||
|
Loading…
Reference in New Issue
Block a user