diff --git a/package.json b/package.json index dba8def040..af7bbb7d5b 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "classnames": "^2.1.2", "commonmark": "^0.28.1", "counterpart": "^0.18.0", + "diff-match-patch": "^1.0.4", "emojibase-data": "^4.0.0", "emojibase-regex": "^3.0.0", "file-saver": "^1.3.3", diff --git a/res/css/views/dialogs/_MessageEditHistoryDialog.scss b/res/css/views/dialogs/_MessageEditHistoryDialog.scss index 38188974ac..3f54cc2e82 100644 --- a/res/css/views/dialogs/_MessageEditHistoryDialog.scss +++ b/res/css/views/dialogs/_MessageEditHistoryDialog.scss @@ -39,6 +39,20 @@ limitations under the License. padding: 0; color: $primary-fg-color; + span.mx_EditHistoryMessage_deletion, span.mx_EditHistoryMessage_insertion { + padding: 0px 2px; + } + + span.mx_EditHistoryMessage_deletion { + color: rgb(255, 76, 85); + background-color: rgba(255, 76, 85, 0.1); + } + + span.mx_EditHistoryMessage_insertion { + color: rgb(26, 169, 123); + background-color: rgba(26, 169, 123, 0.1); + } + .mx_EventTile_line, .mx_EventTile_content { margin-right: 0px; } diff --git a/src/components/views/dialogs/MessageEditHistoryDialog.js b/src/components/views/dialogs/MessageEditHistoryDialog.js index 56e208e464..6014cb941c 100644 --- a/src/components/views/dialogs/MessageEditHistoryDialog.js +++ b/src/components/views/dialogs/MessageEditHistoryDialog.js @@ -108,7 +108,7 @@ export default class MessageEditHistoryDialog extends React.PureComponent { allEvents = allEvents.concat(this.state.originalEvent); } const baseEventId = this.props.mxEvent.getId(); - allEvents.forEach(e => { + allEvents.forEach((e, i) => { if (!lastEvent || wantsDateSeparator(lastEvent.getDate(), e.getDate())) { nodes.push(
  • ); } @@ -116,6 +116,7 @@ export default class MessageEditHistoryDialog extends React.PureComponent { nodes.push(( { + // not using del and ins tags here as del is used for strikethrough + if (modifier < 0) { + return ({text}); + } else if (modifier > 0) { + return ({text}); + } else { + return text; + } + }); + } + render() { const {mxEvent} = this.props; - const originalContent = mxEvent.getOriginalContent(); - const content = originalContent["m.new_content"] || originalContent; + const content = getReplacedContent(mxEvent); let contentContainer; if (mxEvent.isRedacted()) { const UnknownBody = sdk.getComponent('messages.UnknownBody'); contentContainer = ; } else { - const contentElements = HtmlUtils.bodyToHtml(content, null, {stripReplyFallback: true}); + let contentElements; + if (isPlainMessage(mxEvent) && this.props.previousEdit && isPlainMessage(this.props.previousEdit)) { + contentElements = this._diffIt(getReplacedContent(this.props.previousEdit).body, content.body); + } else { + contentElements = HtmlUtils.bodyToHtml(content, null, {stripReplyFallback: true}); + } if (mxEvent.getContent().msgtype === "m.emote") { const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); contentContainer = ( diff --git a/yarn.lock b/yarn.lock index 2ee2604b28..8f6f24d5e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2464,6 +2464,11 @@ di@^0.0.1: resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= +diff-match-patch@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.4.tgz#6ac4b55237463761c4daf0dc603eb869124744b1" + integrity sha512-Uv3SW8bmH9nAtHKaKSanOQmj2DnlH65fUpcrMdfdaOxUG02QQ4YGZ8AE7kKOMisF7UqvOlGKVYWRvezdncW9lg== + diff-sequences@^24.3.0: version "24.3.0" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975"