diff --git a/components/app.js b/components/app.js
index 3c86f41..852c3d3 100644
--- a/components/app.js
+++ b/components/app.js
@@ -762,7 +762,7 @@ export default class App extends Component {
// Open a new buffer if the message doesn't come from me or is a
// self-message
- if ((!client.isMyNick(msg.prefix.name) || client.isMyNick(bufName)) && (msg.command !== "PART" && msg.comand !== "QUIT" && msg.command !== irc.RPL_MONONLINE && msg.command !== irc.RPL_MONOFFLINE)) {
+ if ((!client.isMyNick(msg.prefix.name) || client.isMyNick(bufName)) && (msg.command !== "PART" && msg.command !== "QUIT" && msg.command !== irc.RPL_MONONLINE && msg.command !== irc.RPL_MONOFFLINE)) {
this.createBuffer(serverID, bufName);
}
@@ -1075,6 +1075,7 @@ export default class App extends Component {
case "ACK":
case "BOUNCER":
case "MARKREAD":
+ case "REDACT":
// Ignore these
return [];
default:
diff --git a/components/buffer.js b/components/buffer.js
index 007269b..9312acf 100644
--- a/components/buffer.js
+++ b/components/buffer.js
@@ -94,7 +94,7 @@ function canFoldMessage(msg) {
class LogLine extends Component {
shouldComponentUpdate(nextProps) {
- return this.props.message !== nextProps.message;
+ return this.props.message !== nextProps.message || this.props.redacted !== nextProps.redacted;
}
render() {
@@ -143,13 +143,18 @@ class LogLine extends Component {
`;
}
} else {
- lineClass = "talk";
let prefix = "<", suffix = ">";
if (msg.command === "NOTICE") {
lineClass += " notice";
prefix = suffix = "-";
}
- content = html`${prefix}${createNick(msg.prefix.name)}${suffix} ${linkify(stripANSI(text), onChannelClick)}`;
+ if (this.props.redacted) {
+ content = html`This message has been deleted.`;
+ } else {
+ content = html`${linkify(stripANSI(text), onChannelClick)}`;
+ lineClass += " talk";
+ }
+ content = html`${prefix}${createNick(msg.prefix.name)}${suffix} ${content}`;
}
let allowedPrefixes = server.statusMsg;
@@ -710,6 +715,7 @@ export default class Buffer extends Component {
message=${msg}
buffer=${buf}
server=${server}
+ redacted=${buf.redacted.has(msg.tags.msgid)}
onChannelClick=${onChannelClick}
onNickClick=${onNickClick}
onVerifyClick=${onVerifyClick}
diff --git a/lib/client.js b/lib/client.js
index cfbf23c..1cd5e28 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -21,6 +21,7 @@ const permanentCaps = [
"draft/account-registration",
"draft/chathistory",
"draft/extended-monitor",
+ "draft/message-redaction",
"draft/read-marker",
"soju.im/bouncer-networks",
diff --git a/state.js b/state.js
index 270e34b..a70c48e 100644
--- a/state.js
+++ b/state.js
@@ -361,6 +361,7 @@ export const State = {
hasInitialWho: false, // if channel
members: new irc.CaseMapMap(null, client.cm), // if channel
messages: [],
+ redacted: new Set(),
unread: Unread.NONE,
prevReadReceipt: null,
});
@@ -665,6 +666,14 @@ export const State = {
return { members };
});
+ case "REDACT":
+ target = msg.params[0];
+ if (client.isMyNick(target)) {
+ target = msg.prefix.name;
+ }
+ return updateBuffer(target, (buf) => {
+ return { redacted: new Set(buf.redacted).add(msg.params[1]) };
+ });
case irc.RPL_MONONLINE:
case irc.RPL_MONOFFLINE:
targets = msg.params[1].split(",");