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(",");