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;
|
module.exports = User;
|
||||||
|
|
||||||
function User(attr) {
|
function User(attr, prefixLookup) {
|
||||||
// TODO: Remove this
|
|
||||||
attr.name = attr.name || attr.nick;
|
|
||||||
attr.mode = attr.mode || (attr.modes && attr.modes[0]) || "";
|
|
||||||
|
|
||||||
_.merge(this, _.extend({
|
_.merge(this, _.extend({
|
||||||
mode: "",
|
modes: [],
|
||||||
name: ""
|
nick: ""
|
||||||
}, attr));
|
}, 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: chan
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
chan.users.push(new User({nick: data.nick, modes: ""}));
|
chan.users.push(new User({nick: data.nick}));
|
||||||
chan.sortUsers(irc);
|
chan.sortUsers(irc);
|
||||||
client.emit("users", {
|
client.emit("users", {
|
||||||
chan: chan.id
|
chan: chan.id
|
||||||
|
@ -17,17 +17,19 @@ module.exports = function(irc, network) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var usersUpdated;
|
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++) {
|
for (var i = 0; i < data.modes.length; i++) {
|
||||||
var mode = data.modes[i];
|
var mode = data.modes[i];
|
||||||
var text = mode.mode;
|
var text = mode.mode;
|
||||||
|
|
||||||
if (mode.param) {
|
if (mode.param) {
|
||||||
text += " " + mode.param;
|
text += " " + mode.param;
|
||||||
|
|
||||||
var user = _.find(targetChan.users, {name: mode.param});
|
|
||||||
if (typeof user !== "undefined") {
|
|
||||||
usersUpdated = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg = new Msg({
|
var msg = new Msg({
|
||||||
@ -39,11 +41,51 @@ module.exports = function(irc, network) {
|
|||||||
self: data.nick === irc.user.nick
|
self: data.nick === irc.user.nick
|
||||||
});
|
});
|
||||||
targetChan.pushMessage(client, msg);
|
targetChan.pushMessage(client, msg);
|
||||||
|
|
||||||
|
if (!mode.param) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
if (!usersUpdated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!supportsMultiPrefix) {
|
||||||
// TODO: This is horrible
|
// TODO: This is horrible
|
||||||
irc.raw("NAMES", data.target);
|
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") {
|
if (typeof chan === "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
chan.users = [];
|
|
||||||
_.each(data.users, function(u) {
|
|
||||||
var user = new User(u);
|
|
||||||
|
|
||||||
// irc-framework sets characater mode, but lounge works with symbols
|
chan.users = [];
|
||||||
if (user.mode) {
|
|
||||||
user.mode = network.prefixLookup[user.mode];
|
_.each(data.users, function(u) {
|
||||||
}
|
var user = new User(u, network.prefixLookup);
|
||||||
|
|
||||||
chan.users.push(user);
|
chan.users.push(user);
|
||||||
});
|
});
|
||||||
|
|
||||||
chan.sortUsers(irc);
|
chan.sortUsers(irc);
|
||||||
|
|
||||||
client.emit("users", {
|
client.emit("users", {
|
||||||
chan: chan.id
|
chan: chan.id
|
||||||
});
|
});
|
||||||
|
@ -1,36 +1,48 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var _ = require("lodash");
|
||||||
var expect = require("chai").expect;
|
var expect = require("chai").expect;
|
||||||
|
|
||||||
var Chan = require("../../src/models/chan");
|
var Chan = require("../../src/models/chan");
|
||||||
var User = require("../../src/models/user");
|
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("Chan", function() {
|
||||||
describe("#sortUsers(irc)", function() {
|
describe("#sortUsers(irc)", function() {
|
||||||
var fullNetworkPrefix = [
|
var network = {
|
||||||
{symbol: "~", mode: "q"},
|
network: {
|
||||||
{symbol: "&", mode: "a"},
|
options: {
|
||||||
{symbol: "@", mode: "o"},
|
PREFIX: [
|
||||||
{symbol: "%", mode: "h"},
|
{symbol: "~", mode: "q"},
|
||||||
{symbol: "+", mode: "v"}
|
{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() {
|
it("should sort a simple user list", function() {
|
||||||
var chan = new Chan({users: [
|
var chan = new Chan({users: [
|
||||||
"JocelynD", "YaManicKill", "astorije", "xPaw", "Max-P"
|
"JocelynD", "YaManicKill", "astorije", "xPaw", "Max-P"
|
||||||
].map(makeUser)});
|
].map(makeUser)});
|
||||||
chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}});
|
chan.sortUsers(network);
|
||||||
|
|
||||||
expect(getUserNames(chan)).to.deep.equal([
|
expect(getUserNames(chan)).to.deep.equal([
|
||||||
"astorije", "JocelynD", "Max-P", "xPaw", "YaManicKill"
|
"astorije", "JocelynD", "Max-P", "xPaw", "YaManicKill"
|
||||||
@ -39,13 +51,13 @@ describe("Chan", function() {
|
|||||||
|
|
||||||
it("should group users by modes", function() {
|
it("should group users by modes", function() {
|
||||||
var chan = new Chan({users: [
|
var chan = new Chan({users: [
|
||||||
new User({name: "JocelynD", mode: "&"}),
|
new User({nick: "JocelynD", modes: ["a", "o"]}, prefixLookup),
|
||||||
new User({name: "YaManicKill", mode: "+"}),
|
new User({nick: "YaManicKill", modes: ["v"]}, prefixLookup),
|
||||||
new User({name: "astorije", mode: "%"}),
|
new User({nick: "astorije", modes: ["h"]}, prefixLookup),
|
||||||
new User({name: "xPaw", mode: "~"}),
|
new User({nick: "xPaw", modes: ["q"]}, prefixLookup),
|
||||||
new User({name: "Max-P", mode: "@"}),
|
new User({nick: "Max-P", modes: ["o"]}, prefixLookup),
|
||||||
]});
|
]});
|
||||||
chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}});
|
chan.sortUsers(network);
|
||||||
|
|
||||||
expect(getUserNames(chan)).to.deep.equal([
|
expect(getUserNames(chan)).to.deep.equal([
|
||||||
"xPaw", "JocelynD", "Max-P", "astorije", "YaManicKill"
|
"xPaw", "JocelynD", "Max-P", "astorije", "YaManicKill"
|
||||||
@ -54,13 +66,13 @@ describe("Chan", function() {
|
|||||||
|
|
||||||
it("should sort a mix of users and modes", function() {
|
it("should sort a mix of users and modes", function() {
|
||||||
var chan = new Chan({users: [
|
var chan = new Chan({users: [
|
||||||
new User({name: "JocelynD"}),
|
new User({nick: "JocelynD"}, prefixLookup),
|
||||||
new User({name: "YaManicKill", mode: "@"}),
|
new User({nick: "YaManicKill", modes: ["o"]}, prefixLookup),
|
||||||
new User({name: "astorije"}),
|
new User({nick: "astorije"}, prefixLookup),
|
||||||
new User({name: "xPaw"}),
|
new User({nick: "xPaw"}, prefixLookup),
|
||||||
new User({name: "Max-P", mode: "@"}),
|
new User({nick: "Max-P", modes: ["o"]}, prefixLookup),
|
||||||
]});
|
]});
|
||||||
chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}});
|
chan.sortUsers(network);
|
||||||
|
|
||||||
expect(getUserNames(chan)).to.deep.equal(
|
expect(getUserNames(chan)).to.deep.equal(
|
||||||
["Max-P", "YaManicKill", "astorije", "JocelynD", "xPaw"]
|
["Max-P", "YaManicKill", "astorije", "JocelynD", "xPaw"]
|
||||||
@ -69,7 +81,7 @@ describe("Chan", function() {
|
|||||||
|
|
||||||
it("should be case-insensitive", function() {
|
it("should be case-insensitive", function() {
|
||||||
var chan = new Chan({users: ["aB", "Ad", "AA", "ac"].map(makeUser)});
|
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"]);
|
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}", "<foo>", "_foo", "@foo", "^foo",
|
||||||
"&foo", "!foo", "+foo", "Foo"
|
"&foo", "!foo", "+foo", "Foo"
|
||||||
].map(makeUser)});
|
].map(makeUser)});
|
||||||
chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}});
|
chan.sortUsers(network);
|
||||||
|
|
||||||
expect(getUserNames(chan)).to.deep.equal([
|
expect(getUserNames(chan)).to.deep.equal([
|
||||||
"!foo", "&foo", "(foo)", "+foo", "<foo>", "@foo", "[foo", "]foo",
|
"!foo", "&foo", "(foo)", "+foo", "<foo>", "@foo", "[foo", "]foo",
|
||||||
|
Loading…
Reference in New Issue
Block a user