Add support for draft/event-playback

This commit is contained in:
Simon Ser 2021-06-04 19:45:51 +02:00
parent 651e255ddb
commit 34078d5da7
4 changed files with 65 additions and 34 deletions

View file

@ -488,6 +488,7 @@ export default class App extends Component {
handleMessage(serverID, msg) { handleMessage(serverID, msg) {
var client = this.clients.get(serverID); var client = this.clients.get(serverID);
var chatHistoryBatch = irc.findBatchByType(msg, "chathistory");
this.setState((state) => State.handleMessage(state, msg, serverID, client)); this.setState((state) => State.handleMessage(state, msg, serverID, client));
@ -520,7 +521,9 @@ export default class App extends Component {
if (client.isChannel(target)) { if (client.isChannel(target)) {
this.addMessage(serverID, target, msg); this.addMessage(serverID, target, msg);
} }
this.handleMode(serverID, msg); if (!chatHistoryBatch) {
this.handleMode(serverID, msg);
}
break; break;
case "NOTICE": case "NOTICE":
case "PRIVMSG": case "PRIVMSG":
@ -559,7 +562,7 @@ export default class App extends Component {
this.addMessage(serverID, channel, msg); 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();
} }
@ -570,46 +573,56 @@ export default class App extends Component {
break; break;
case "QUIT": case "QUIT":
var affectedBuffers = []; var affectedBuffers = [];
this.setState((state) => { if (chatHistoryBatch) {
var buffers = new Map(state.buffers); affectedBuffers.push(chatHistoryBatch.params[0]);
state.buffers.forEach((buf) => { } else {
if (buf.server != serverID) { this.setState((state) => {
return; var buffers = new Map(state.buffers);
} state.buffers.forEach((buf) => {
if (!buf.members.has(msg.prefix.name) && client.cm(buf.name) !== client.cm(msg.prefix.name)) { if (buf.server != serverID) {
return; return;
} }
var 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;
var offline = client.cm(buf.name) === client.cm(msg.prefix.name); }
buffers.set(buf.id, { ...buf, members, offline }); var members = new irc.CaseMapMap(buf.members);
affectedBuffers.push(buf.name); members.delete(msg.prefix.name);
var offline = client.cm(buf.name) === client.cm(msg.prefix.name);
buffers.set(buf.id, { ...buf, members, offline });
affectedBuffers.push(buf.name);
});
return { buffers };
}); });
return { buffers }; }
});
affectedBuffers.forEach((name) => this.addMessage(serverID, name, msg)); affectedBuffers.forEach((name) => this.addMessage(serverID, name, msg));
break; break;
case "NICK": case "NICK":
var newNick = msg.params[0]; var newNick = msg.params[0];
var affectedBuffers = []; var affectedBuffers = [];
this.setState((state) => { if (chatHistoryBatch) {
var buffers = new Map(state.buffers); affectedBuffers.push(chatHistoryBatch.params[0]);
state.buffers.forEach((buf) => { } else {
if (buf.server != serverID) { this.setState((state) => {
return; var buffers = new Map(state.buffers);
} state.buffers.forEach((buf) => {
if (!buf.members.has(msg.prefix.name)) { if (buf.server != serverID) {
return; return;
} }
var members = new irc.CaseMapMap(buf.members); if (!buf.members.has(msg.prefix.name)) {
members.set(newNick, members.get(msg.prefix.name)); return;
members.delete(msg.prefix.name); }
buffers.set(buf.id, { ...buf, members }); var members = new irc.CaseMapMap(buf.members);
affectedBuffers.push(buf.name); 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)); affectedBuffers.forEach((name) => this.addMessage(serverID, name, msg));
break; break;
case "TOPIC": case "TOPIC":

View file

@ -13,6 +13,7 @@ const permanentCaps = [
"setname", "setname",
"draft/chathistory", "draft/chathistory",
"draft/event-playback",
"soju.im/bouncer-networks", "soju.im/bouncer-networks",
]; ];
@ -160,6 +161,7 @@ export default class Client extends EventTarget {
msgBatch = this.batches.get(msg.tags["batch"]); msgBatch = this.batches.get(msg.tags["batch"]);
if (msgBatch) { if (msgBatch) {
msgBatch.messages.push(msg); msgBatch.messages.push(msg);
msg.batch = msgBatch;
} }
} }

View file

@ -533,3 +533,14 @@ export function parseMembershipModes(str) {
} }
return memberships; return memberships;
} }
export function findBatchByType(msg, type) {
var batch = msg.batch;
while (batch) {
if (batch.type === type) {
return batch;
}
batch = batch.parent;
}
return null;
}

View file

@ -249,6 +249,11 @@ export const State = {
return State.updateBuffer(state, { server: serverID, name }, updater); return State.updateBuffer(state, { server: serverID, name }, updater);
} }
// Don't update our internal state if it's a chat history message
if (irc.findBatchByType(msg, "chathistory")) {
return;
}
switch (msg.command) { switch (msg.command) {
case irc.RPL_MYINFO: case irc.RPL_MYINFO:
// TODO: parse available modes // TODO: parse available modes