Add App.routeMessage

This splits handleMessage into two functions: one decides in which
buffers the message should be appended to, the other performs
message side-effects like auto-join.
This commit is contained in:
Simon Ser 2021-10-23 23:01:32 +02:00
parent c4a1f38b33
commit bf471abb1b

View file

@ -584,13 +584,164 @@ export default class App extends Component {
return null; return null;
} }
handleMessage(serverID, msg) { routeMessage(serverID, msg) {
let client = this.clients.get(serverID); let client = this.clients.get(serverID);
let chatHistoryBatch = irc.findBatchByType(msg, "chathistory"); let chatHistoryBatch = irc.findBatchByType(msg, "chathistory");
let target, channel, affectedBuffers;
switch (msg.command) {
case "MODE":
target = msg.params[0];
if (client.isChannel(target)) {
return [target];
}
return [];
case "NOTICE":
case "PRIVMSG":
target = msg.params[0];
if (client.isMyNick(target)) {
if (client.cm(msg.prefix.name) === client.cm(client.serverPrefix.name)) {
target = SERVER_BUFFER;
} else {
target = msg.prefix.name;
}
}
if (msg.command === "NOTICE" && !State.getBuffer(this.state, { server: serverID, name: target })) {
// Don't open a new buffer if this is just a NOTICE
target = SERVER_BUFFER;
}
let allowedPrefixes = client.isupport.get("STATUSMSG");
if (allowedPrefixes) {
let parts = irc.parseTargetPrefix(target, allowedPrefixes);
if (client.isChannel(parts.name)) {
target = parts.name;
}
}
return [target];
case "JOIN":
channel = msg.params[0];
if (!client.isMyNick(msg.prefix.name)) {
return [channel];
}
return [];
case "PART":
channel = msg.params[0];
return [channel];
case "KICK":
channel = msg.params[0];
return [channel];
case "QUIT":
affectedBuffers = [];
if (chatHistoryBatch) {
affectedBuffers.push(chatHistoryBatch.params[0]);
} else {
this.state.buffers.forEach((buf) => {
if (buf.server != serverID) {
return;
}
if (!buf.members.has(msg.prefix.name) && client.cm(buf.name) !== client.cm(msg.prefix.name)) {
return;
}
affectedBuffers.push(buf.name);
});
}
return affectedBuffers;
case "NICK":
let newNick = msg.params[0];
affectedBuffers = [];
if (chatHistoryBatch) {
affectedBuffers.push(chatHistoryBatch.params[0]);
} else {
this.state.buffers.forEach((buf) => {
if (buf.server != serverID) {
return;
}
if (!buf.members.has(msg.prefix.name)) {
return;
}
affectedBuffers.push(buf.name);
});
}
return affectedBuffers;
case "TOPIC":
channel = msg.params[0];
return [channel];
case "INVITE":
channel = msg.params[1];
// TODO: find a more reliable way to do this
let bufName = channel;
if (!State.getBuffer(this.state, { server: serverID, name: channel })) {
bufName = SERVER_BUFFER;
}
return [bufName];
case irc.RPL_CHANNELMODEIS:
case irc.RPL_CREATIONTIME:
case irc.RPL_INVITELIST:
case irc.RPL_ENDOFINVITELIST:
case irc.RPL_EXCEPTLIST:
case irc.RPL_ENDOFEXCEPTLIST:
case irc.RPL_BANLIST:
case irc.RPL_ENDOFBANLIST:
case irc.RPL_QUIETLIST:
case irc.RPL_ENDOFQUIETLIST:
channel = msg.params[1];
return [channel];
case irc.RPL_INVITING:
channel = msg.params[2];
return [channel];
case irc.RPL_WELCOME:
case irc.RPL_YOURHOST:
case irc.RPL_MYINFO:
case irc.RPL_ISUPPORT:
case irc.RPL_ENDOFMOTD:
case irc.ERR_NOMOTD:
case irc.RPL_NOTOPIC:
case irc.RPL_TOPIC:
case irc.RPL_TOPICWHOTIME:
case irc.RPL_NAMREPLY:
case irc.RPL_ENDOFNAMES:
case irc.RPL_MONONLINE:
case irc.RPL_MONOFFLINE:
case irc.RPL_SASLSUCCESS:
case "AWAY":
case "SETNAME":
case "CHGHOST":
case "ACCOUNT":
case "CAP":
case "AUTHENTICATE":
case "PING":
case "PONG":
case "BATCH":
case "TAGMSG":
case "CHATHISTORY":
case "ACK":
case "BOUNCER":
// Ignore these
return [];
default:
return [SERVER_BUFFER];
}
}
handleMessage(serverID, msg) {
let client = this.clients.get(serverID);
var destBuffers = this.routeMessage(serverID, msg);
if (irc.findBatchByType(msg, "chathistory")) {
destBuffers.forEach((bufName) => {
this.addMessage(serverID, bufName, msg);
});
return;
}
this.setState((state) => State.handleMessage(state, msg, serverID, client)); this.setState((state) => State.handleMessage(state, msg, serverID, client));
let target, channel, affectedBuffers; let target, channel;
switch (msg.command) { switch (msg.command) {
case irc.RPL_WELCOME: case irc.RPL_WELCOME:
let lastReceipt = this.latestReceipt(ReceiptType.DELIVERED); let lastReceipt = this.latestReceipt(ReceiptType.DELIVERED);
@ -636,44 +787,11 @@ export default class App extends Component {
params: [join.join(",")], params: [join.join(",")],
}); });
} }
case "MODE":
target = msg.params[0];
if (client.isChannel(target)) {
this.addMessage(serverID, target, msg);
}
break;
case "NOTICE":
case "PRIVMSG":
target = msg.params[0];
if (client.isMyNick(target)) {
if (client.cm(msg.prefix.name) === client.cm(client.serverPrefix.name)) {
target = SERVER_BUFFER;
} else {
target = msg.prefix.name;
}
}
if (msg.command === "NOTICE" && !State.getBuffer(this.state, { server: serverID, name: target })) {
// Don't open a new buffer if this is just a NOTICE
target = SERVER_BUFFER;
}
let allowedPrefixes = client.isupport.get("STATUSMSG");
if (allowedPrefixes) {
let parts = irc.parseTargetPrefix(target, allowedPrefixes);
if (client.isChannel(parts.name)) {
target = parts.name;
}
}
this.addMessage(serverID, target, msg);
break;
case "JOIN": case "JOIN":
channel = msg.params[0]; channel = msg.params[0];
if (client.isMyNick(msg.prefix.name)) { if (client.isMyNick(msg.prefix.name)) {
this.syncBufferUnread(serverID, channel); this.syncBufferUnread(serverID, channel);
} else {
this.addMessage(serverID, channel, msg);
} }
if (channel == this.switchToChannel) { if (channel == this.switchToChannel) {
this.switchBuffer({ server: serverID, name: channel }); this.switchBuffer({ server: serverID, name: channel });
@ -683,84 +801,46 @@ export default class App extends Component {
case "PART": case "PART":
channel = msg.params[0]; channel = msg.params[0];
this.addMessage(serverID, channel, msg); if (client.isMyNick(msg.prefix.name)) {
if (!chatHistoryBatch && client.isMyNick(msg.prefix.name)) {
this.receipts.delete(channel); this.receipts.delete(channel);
this.saveReceipts(); this.saveReceipts();
} }
break; break;
case "KICK":
channel = msg.params[0];
this.addMessage(serverID, channel, msg);
break;
case "QUIT": case "QUIT":
affectedBuffers = []; this.setState((state) => {
if (chatHistoryBatch) { let buffers = new Map(state.buffers);
affectedBuffers.push(chatHistoryBatch.params[0]); state.buffers.forEach((buf) => {
} else { if (buf.server != serverID) {
this.setState((state) => { return;
let buffers = new Map(state.buffers); }
state.buffers.forEach((buf) => { if (!buf.members.has(msg.prefix.name)) {
if (buf.server != serverID) { return;
return; }
} let members = new irc.CaseMapMap(buf.members);
if (!buf.members.has(msg.prefix.name) && client.cm(buf.name) !== client.cm(msg.prefix.name)) { members.delete(msg.prefix.name);
return; buffers.set(buf.id, { ...buf, members });
}
let members = new irc.CaseMapMap(buf.members);
members.delete(msg.prefix.name);
buffers.set(buf.id, { ...buf, members });
affectedBuffers.push(buf.name);
});
return { buffers };
}); });
} return { buffers };
});
affectedBuffers.forEach((name) => this.addMessage(serverID, name, msg));
break; break;
case "NICK": case "NICK":
let newNick = msg.params[0]; let newNick = msg.params[0];
this.setState((state) => {
affectedBuffers = []; let buffers = new Map(state.buffers);
if (chatHistoryBatch) { state.buffers.forEach((buf) => {
affectedBuffers.push(chatHistoryBatch.params[0]); if (buf.server != serverID) {
} else { return;
this.setState((state) => { }
let buffers = new Map(state.buffers); if (!buf.members.has(msg.prefix.name)) {
state.buffers.forEach((buf) => { return;
if (buf.server != serverID) { }
return; let members = new irc.CaseMapMap(buf.members);
} members.set(newNick, members.get(msg.prefix.name));
if (!buf.members.has(msg.prefix.name)) { members.delete(msg.prefix.name);
return; buffers.set(buf.id, { ...buf, members });
}
let members = new irc.CaseMapMap(buf.members);
members.set(newNick, members.get(msg.prefix.name));
members.delete(msg.prefix.name);
buffers.set(buf.id, { ...buf, members });
affectedBuffers.push(buf.name);
});
return { buffers };
}); });
} return { buffers };
});
affectedBuffers.forEach((name) => this.addMessage(serverID, name, msg));
break;
case "TOPIC":
channel = msg.params[0];
this.addMessage(serverID, channel, msg);
break;
case "INVITE":
channel = msg.params[1];
// TODO: find a more reliable way to do this
let bufName = channel;
if (!State.getBuffer(this.state, { server: serverID, name: channel })) {
bufName = SERVER_BUFFER;
}
this.addMessage(serverID, bufName, msg);
break; break;
case "BOUNCER": case "BOUNCER":
if (msg.params[0] !== "NETWORK") { if (msg.params[0] !== "NETWORK") {
@ -768,7 +848,7 @@ export default class App extends Component {
} }
if (client.isupport.has("BOUNCER_NETID")) { if (client.isupport.has("BOUNCER_NETID")) {
// This cn happen if the user has specified a network to bind // This can happen if the user has specified a network to bind
// to via other means, e.g. "<username>/<network>". // to via other means, e.g. "<username>/<network>".
break; break;
} }
@ -805,55 +885,16 @@ export default class App extends Component {
} }
}); });
break; break;
case irc.RPL_CHANNELMODEIS:
case irc.RPL_CREATIONTIME:
case irc.RPL_INVITELIST:
case irc.RPL_ENDOFINVITELIST:
case irc.RPL_EXCEPTLIST:
case irc.RPL_ENDOFEXCEPTLIST:
case irc.RPL_BANLIST:
case irc.RPL_ENDOFBANLIST:
case irc.RPL_QUIETLIST:
case irc.RPL_ENDOFQUIETLIST:
channel = msg.params[1];
this.addMessage(serverID, channel, msg);
break;
case irc.RPL_INVITING:
channel = msg.params[2];
this.addMessage(serverID, channel, msg);
break;
case irc.RPL_YOURHOST:
case irc.RPL_MYINFO:
case irc.RPL_ISUPPORT:
case irc.RPL_NOTOPIC:
case irc.RPL_TOPIC:
case irc.RPL_TOPICWHOTIME:
case irc.RPL_NAMREPLY:
case irc.RPL_ENDOFNAMES:
case irc.RPL_MONONLINE:
case irc.RPL_MONOFFLINE:
case irc.RPL_SASLSUCCESS:
case "AWAY":
case "SETNAME":
case "CHGHOST":
case "ACCOUNT":
case "CAP":
case "AUTHENTICATE":
case "PING":
case "PONG":
case "BATCH":
case "TAGMSG":
case "CHATHISTORY":
case "ACK":
// Ignore these
break;
default: default:
if (irc.isError(msg.command) && msg.command != irc.ERR_NOMOTD) { if (irc.isError(msg.command) && msg.command != irc.ERR_NOMOTD) {
let description = msg.params[msg.params.length - 1]; let description = msg.params[msg.params.length - 1];
this.setState({ error: description }); this.setState({ error: description });
} }
this.addMessage(serverID, SERVER_BUFFER, msg);
} }
destBuffers.forEach((bufName) => {
this.addMessage(serverID, bufName, msg);
});
} }
handleConnectSubmit(connectParams) { handleConnectSubmit(connectParams) {