thelounge/src/plugins/irc-events/message.js
Al McKinlay 5ce67ba093 Insert channel/user into channel list at alphabetically sorted point, not just the end
Don't sort queries/users after special chans


Set all users in tests to be of type query


Add test for not inserting infront of lobby


Break after finding the index, otherwise it always adds it to the end


Add checking for lobby in first test


Fix off-by-one error on the frontend


Fix utterly idiotic issue adding a duplicate of the channel we are on rather than the new user when we query


Check that we always insert before first special chan
2018-03-12 12:42:59 +00:00

159 lines
4.1 KiB
JavaScript

"use strict";
const Chan = require("../../models/chan");
const Msg = require("../../models/msg");
const LinkPrefetch = require("./link");
const cleanIrcMessage = require("../../../client/js/libs/handlebars/ircmessageparser/cleanIrcMessage");
const nickRegExp = /(?:\x03[0-9]{1,2}(?:,[0-9]{1,2})?)?([\w[\]\\`^{|}-]+)/g;
module.exports = function(irc, network) {
const client = this;
irc.on("notice", function(data) {
// Some servers send notices without any nickname
if (!data.nick) {
data.from_server = true;
data.nick = network.host;
}
data.type = Msg.Type.NOTICE;
handleMessage(data);
});
irc.on("action", function(data) {
data.type = Msg.Type.ACTION;
handleMessage(data);
});
irc.on("privmsg", function(data) {
data.type = Msg.Type.MESSAGE;
handleMessage(data);
});
irc.on("wallops", function(data) {
data.from_server = true;
data.type = Msg.Type.NOTICE;
handleMessage(data);
});
function handleMessage(data) {
let chan;
let from;
let highlight = false;
let showInActive = false;
const self = data.nick === irc.user.nick;
// Server messages go to server window, no questions asked
if (data.from_server) {
chan = network.channels[0];
from = chan.getUser(data.nick);
} else {
let target = data.target;
// If the message is targeted at us, use sender as target instead
if (target.toLowerCase() === irc.user.nick.toLowerCase()) {
target = data.nick;
}
chan = network.getChannel(target);
if (typeof chan === "undefined") {
// Send notices that are not targeted at us into the server window
if (data.type === Msg.Type.NOTICE) {
showInActive = true;
chan = network.channels[0];
} else {
chan = new Chan({
type: Chan.Type.QUERY,
name: target,
});
client.emit("join", {
network: network.id,
chan: chan.getFilteredClone(true),
index: network.addChannel(chan),
});
client.save();
chan.loadMessages(client, network);
}
}
from = chan.getUser(data.nick);
// Query messages (unless self) always highlight
if (chan.type === Chan.Type.QUERY) {
highlight = !self;
} else if (chan.type === Chan.Type.CHANNEL) {
from.lastMessage = data.time || Date.now();
}
}
// msg is constructed down here because `from` is being copied in the constructor
const msg = new Msg({
type: data.type,
time: data.time,
text: data.message,
self: self,
from: from,
highlight: highlight,
users: [],
});
if (showInActive) {
msg.showInActive = true;
}
// Self messages in channels are never highlighted
// Non-self messages are highlighted as soon as the nick is detected
if (!msg.highlight && !msg.self) {
msg.highlight = network.highlightRegex.test(data.message);
}
let match;
while ((match = nickRegExp.exec(data.message))) {
if (chan.findUser(match[1])) {
msg.users.push(match[1]);
}
}
// No prefetch URLs unless are simple MESSAGE or ACTION types
if ([Msg.Type.MESSAGE, Msg.Type.ACTION].includes(data.type)) {
LinkPrefetch(client, chan, msg);
}
chan.pushMessage(client, msg, !msg.self);
// Do not send notifications for messages older than 15 minutes (znc buffer for example)
if (msg.highlight && (!data.time || data.time > Date.now() - 900000)) {
let title = chan.name;
let body = cleanIrcMessage(data.message);
if (msg.type === Msg.Type.ACTION) {
// For actions, do not include colon in the message
body = `${data.nick} ${body}`;
} else if (chan.type !== Chan.Type.QUERY) {
// In channels, prepend sender nickname to the message
body = `${data.nick}: ${body}`;
}
// If a channel is active on any client, highlight won't increment and notification will say (0 mention)
if (chan.highlight > 0) {
title += ` (${chan.highlight} ${chan.type === Chan.Type.QUERY ? "new message" : "mention"}${chan.highlight > 1 ? "s" : ""})`;
}
if (chan.highlight > 1) {
body += `\n\n… and ${chan.highlight - 1} other message${chan.highlight > 2 ? "s" : ""}`;
}
client.manager.webPush.push(client, {
type: "notification",
chanId: chan.id,
timestamp: data.time || Date.now(),
title: title,
body: body,
}, true);
}
}
};