Merge pull request #1194 from thelounge/xpaw/lazy-user-list
Lazily load user list in channels on init, keep autocompletion sort on server
This commit is contained in:
commit
ed9bfcf2fa
@ -81,7 +81,7 @@ function buildChatMessage(data) {
|
|||||||
renderPreview(preview, msg);
|
renderPreview(preview, msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
if ((type === "message" || type === "action") && chan.hasClass("channel")) {
|
if ((type === "message" || type === "action" || type === "notice") && chan.hasClass("channel")) {
|
||||||
const nicks = chan.find(".users").data("nicks");
|
const nicks = chan.find(".users").data("nicks");
|
||||||
if (nicks) {
|
if (nicks) {
|
||||||
const find = nicks.indexOf(data.msg.from);
|
const find = nicks.indexOf(data.msg.from);
|
||||||
@ -143,22 +143,10 @@ function renderChannelMessages(data) {
|
|||||||
|
|
||||||
function renderChannelUsers(data) {
|
function renderChannelUsers(data) {
|
||||||
const users = chat.find("#chan-" + data.id).find(".users");
|
const users = chat.find("#chan-" + data.id).find(".users");
|
||||||
let nicks = users.data("nicks") || [];
|
const nicks = data.users
|
||||||
const oldSortOrder = {};
|
.concat() // Make a copy of the user list, sort is applied in-place
|
||||||
|
.sort((a, b) => b.lastMessage - a.lastMessage)
|
||||||
for (const i in nicks) {
|
.map((a) => a.nick);
|
||||||
oldSortOrder[nicks[i]] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
nicks = [];
|
|
||||||
|
|
||||||
for (const i in data.users) {
|
|
||||||
nicks.push(data.users[i].nick);
|
|
||||||
}
|
|
||||||
|
|
||||||
nicks = nicks.sort(function(a, b) {
|
|
||||||
return (oldSortOrder[a] || Number.MAX_VALUE) - (oldSortOrder[b] || Number.MAX_VALUE);
|
|
||||||
});
|
|
||||||
|
|
||||||
const search = users
|
const search = users
|
||||||
.find(".search")
|
.find(".search")
|
||||||
@ -191,7 +179,13 @@ function renderNetworks(data) {
|
|||||||
channels: channels
|
channels: channels
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
channels.forEach(renderChannel);
|
channels.forEach((channel) => {
|
||||||
|
renderChannel(channel);
|
||||||
|
|
||||||
|
if (channel.type === "channel") {
|
||||||
|
chat.find("#chan-" + channel.id).data("needsNamesRefresh", true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
utils.confirmExit();
|
utils.confirmExit();
|
||||||
sorting();
|
sorting();
|
||||||
|
@ -93,8 +93,12 @@ Chan.prototype.sortUsers = function(irc) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Chan.prototype.findUser = function(nick) {
|
||||||
|
return _.find(this.users, {nick: nick});
|
||||||
|
};
|
||||||
|
|
||||||
Chan.prototype.getMode = function(name) {
|
Chan.prototype.getMode = function(name) {
|
||||||
var user = _.find(this.users, {nick: name});
|
var user = this.findUser(name);
|
||||||
if (user) {
|
if (user) {
|
||||||
return user.mode;
|
return user.mode;
|
||||||
}
|
}
|
||||||
@ -104,6 +108,7 @@ Chan.prototype.getMode = function(name) {
|
|||||||
|
|
||||||
Chan.prototype.toJSON = function() {
|
Chan.prototype.toJSON = function() {
|
||||||
var clone = _.clone(this);
|
var clone = _.clone(this);
|
||||||
|
clone.users = []; // Do not send user list, the client will explicitly request it when needed
|
||||||
clone.messages = clone.messages.slice(-100);
|
clone.messages = clone.messages.slice(-100);
|
||||||
return clone;
|
return clone;
|
||||||
};
|
};
|
||||||
|
@ -8,20 +8,24 @@ function User(attr, prefixLookup) {
|
|||||||
_.defaults(this, attr, {
|
_.defaults(this, attr, {
|
||||||
modes: [],
|
modes: [],
|
||||||
mode: "",
|
mode: "",
|
||||||
nick: ""
|
nick: "",
|
||||||
|
lastMessage: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
// irc-framework sets character mode, but lounge works with symbols
|
this.setModes(this.modes, prefixLookup);
|
||||||
this.modes = this.modes.map((mode) => prefixLookup[mode]);
|
|
||||||
|
|
||||||
if (this.modes[0]) {
|
|
||||||
this.mode = this.modes[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
User.prototype.setModes = function(modes, prefixLookup) {
|
||||||
|
// irc-framework sets character mode, but lounge works with symbols
|
||||||
|
this.modes = modes.map((mode) => prefixLookup[mode]);
|
||||||
|
|
||||||
|
this.mode = this.modes[0] || "";
|
||||||
|
};
|
||||||
|
|
||||||
User.prototype.toJSON = function() {
|
User.prototype.toJSON = function() {
|
||||||
return {
|
return {
|
||||||
nick: this.nick,
|
nick: this.nick,
|
||||||
mode: this.mode,
|
mode: this.mode,
|
||||||
|
lastMessage: this.lastMessage,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -11,10 +11,12 @@ module.exports = function(irc, network) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const user = chan.findUser(data.kicked);
|
||||||
|
|
||||||
if (data.kicked === irc.user.nick) {
|
if (data.kicked === irc.user.nick) {
|
||||||
chan.users = [];
|
chan.users = [];
|
||||||
} else {
|
} else {
|
||||||
chan.users = _.without(chan.users, _.find(chan.users, {nick: data.kicked}));
|
chan.users = _.without(chan.users, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
client.emit("users", {
|
client.emit("users", {
|
||||||
@ -24,7 +26,7 @@ module.exports = function(irc, network) {
|
|||||||
var msg = new Msg({
|
var msg = new Msg({
|
||||||
type: Msg.Type.KICK,
|
type: Msg.Type.KICK,
|
||||||
time: data.time,
|
time: data.time,
|
||||||
mode: chan.getMode(data.nick),
|
mode: user.mode,
|
||||||
from: data.nick,
|
from: data.nick,
|
||||||
target: data.kicked,
|
target: data.kicked,
|
||||||
text: data.message || "",
|
text: data.message || "",
|
||||||
|
@ -71,6 +71,12 @@ module.exports = function(irc, network) {
|
|||||||
// Query messages (unless self) always highlight
|
// Query messages (unless self) always highlight
|
||||||
if (chan.type === Chan.Type.QUERY) {
|
if (chan.type === Chan.Type.QUERY) {
|
||||||
highlight = !self;
|
highlight = !self;
|
||||||
|
} else if (chan.type === Chan.Type.CHANNEL) {
|
||||||
|
const user = chan.findUser(data.nick);
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
user.lastMessage = data.time || Date.now();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ module.exports = function(irc, network) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = _.find(targetChan.users, {nick: mode.param});
|
const user = targetChan.findUser(mode.param);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,39 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var User = require("../../models/user");
|
const User = require("../../models/user");
|
||||||
|
|
||||||
module.exports = function(irc, network) {
|
module.exports = function(irc, network) {
|
||||||
var client = this;
|
const client = this;
|
||||||
|
|
||||||
irc.on("userlist", function(data) {
|
irc.on("userlist", function(data) {
|
||||||
var chan = network.getChannel(data.channel);
|
const chan = network.getChannel(data.channel);
|
||||||
if (typeof chan === "undefined") {
|
if (typeof chan === "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
chan.users = data.users.map((user) => new User({
|
// Create lookup map of current users,
|
||||||
nick: user.nick,
|
// as we need to keep certain properties
|
||||||
modes: user.modes,
|
// and we can recycle existing User objects
|
||||||
}, network.prefixLookup));
|
const oldUsers = new Map();
|
||||||
|
|
||||||
|
chan.users.forEach((user) => {
|
||||||
|
oldUsers.set(user.nick, user);
|
||||||
|
});
|
||||||
|
|
||||||
|
chan.users = data.users.map((user) => {
|
||||||
|
const oldUser = oldUsers.get(user.nick);
|
||||||
|
|
||||||
|
// For existing users, we only need to update mode
|
||||||
|
if (oldUser) {
|
||||||
|
oldUser.setModes(user.modes, network.prefixLookup);
|
||||||
|
return oldUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new User({
|
||||||
|
nick: user.nick,
|
||||||
|
modes: user.modes,
|
||||||
|
}, network.prefixLookup);
|
||||||
|
});
|
||||||
|
|
||||||
chan.sortUsers(irc);
|
chan.sortUsers(irc);
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var _ = require("lodash");
|
|
||||||
var Msg = require("../../models/msg");
|
var Msg = require("../../models/msg");
|
||||||
|
|
||||||
module.exports = function(irc, network) {
|
module.exports = function(irc, network) {
|
||||||
@ -25,7 +24,7 @@ module.exports = function(irc, network) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
network.channels.forEach((chan) => {
|
network.channels.forEach((chan) => {
|
||||||
var user = _.find(chan.users, {nick: data.nick});
|
const user = chan.findUser(data.nick);
|
||||||
if (typeof user === "undefined") {
|
if (typeof user === "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ module.exports = function(irc, network) {
|
|||||||
chan: chan.id
|
chan: chan.id
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var user = _.find(chan.users, {nick: from});
|
const user = chan.findUser(from);
|
||||||
chan.users = _.without(chan.users, user);
|
chan.users = _.without(chan.users, user);
|
||||||
client.emit("users", {
|
client.emit("users", {
|
||||||
chan: chan.id
|
chan: chan.id
|
||||||
|
@ -7,8 +7,7 @@ module.exports = function(irc, network) {
|
|||||||
var client = this;
|
var client = this;
|
||||||
irc.on("quit", function(data) {
|
irc.on("quit", function(data) {
|
||||||
network.channels.forEach((chan) => {
|
network.channels.forEach((chan) => {
|
||||||
var from = data.nick;
|
const user = chan.findUser(data.nick);
|
||||||
var user = _.find(chan.users, {nick: from});
|
|
||||||
if (typeof user === "undefined") {
|
if (typeof user === "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -22,7 +21,7 @@ module.exports = function(irc, network) {
|
|||||||
mode: user.mode || "",
|
mode: user.mode || "",
|
||||||
text: data.message || "",
|
text: data.message || "",
|
||||||
hostmask: data.ident + "@" + data.hostname,
|
hostmask: data.ident + "@" + data.hostname,
|
||||||
from: from
|
from: data.nick
|
||||||
});
|
});
|
||||||
chan.pushMessage(client, msg);
|
chan.pushMessage(client, msg);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user