From d33d55376a1805cb6438cbf02cf0081abdfbad76 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Tue, 20 Jul 2021 15:22:12 -0700 Subject: [PATCH] Put reply into its own view model. Otherwise, we re-render the reply message on every keystroke. --- src/domain/session/room/RoomViewModel.js | 60 ++++++++++++------- .../room/timeline/tiles/BaseMessageTile.js | 4 +- .../session/room/timeline/BaseMessageView.js | 2 +- 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/domain/session/room/RoomViewModel.js b/src/domain/session/room/RoomViewModel.js index aa1bde25..3b0d61e1 100644 --- a/src/domain/session/room/RoomViewModel.js +++ b/src/domain/session/room/RoomViewModel.js @@ -155,7 +155,7 @@ export class RoomViewModel extends ViewModel { this._room.join(); } - async _sendMessage(message, replyTo) { + async _sendMessage(message, replyingTo) { if (!this._room.isArchived && message) { try { let msgtype = "m.text"; @@ -164,8 +164,8 @@ export class RoomViewModel extends ViewModel { msgtype = "m.emote"; } const content = {msgtype, body: message}; - if (replyTo) { - content["m.relates_to"] = replyTo.reply(); + if (replyingTo) { + content["m.relates_to"] = replyingTo.reply(); } await this._room.sendEvent("m.room.message", content); } catch (err) { @@ -175,7 +175,6 @@ export class RoomViewModel extends ViewModel { this.emitChange("error"); return false; } - this.setReply(null); return true; } return false; @@ -301,8 +300,10 @@ export class RoomViewModel extends ViewModel { this.navigation.applyPath(path); } - setReply(entry) { - this._composerVM.setReply(entry); + startReply(entry) { + if (!this._room.isArchived) { + this._composerVM.startReply(entry); + } } } @@ -310,32 +311,23 @@ class ComposerViewModel extends ViewModel { constructor(roomVM) { super(); this._roomVM = roomVM; - this._replyTo = null; - this._isEmpty = true; + this._replyVM = new ReplyViewModel(roomVM); + } + + startReply(entry) { + this._replyVM.setReplyingTo(entry); } get isEncrypted() { return this._roomVM.isEncrypted; } - setReply(entry) { - this._replyTo = entry; - this.emitChange("replyTo"); - } - - clearReply() { - this.setReply(null); - } - - get replyTo() { - return this._replyTo; - } - sendMessage(message) { - const success = this._roomVM._sendMessage(message, this._replyTo); + const success = this._roomVM._sendMessage(message, this._replyVM.replyingTo); if (success) { this._isEmpty = true; this.emitChange("canSend"); + this._replyVM.clearReply(); } return success; } @@ -372,6 +364,30 @@ class ComposerViewModel extends ViewModel { } } +class ReplyViewModel extends ViewModel { + constructor(roomVM) { + super(); + this._roomVM = roomVM; + this._replyingTo = null; + } + + setReplyingTo(entry) { + const changed = this._replyingTo !== entry; + this._replyingTo = entry; + if (changed) { + this.emitChange("replyingTo"); + } + } + + clearReply() { + this.setReplyingTo(null); + } + + get replyingTo() { + return this._replyingTo; + } +} + function imageToInfo(image) { return { w: image.width, diff --git a/src/domain/session/room/timeline/tiles/BaseMessageTile.js b/src/domain/session/room/timeline/tiles/BaseMessageTile.js index 7090c514..01d32a9c 100644 --- a/src/domain/session/room/timeline/tiles/BaseMessageTile.js +++ b/src/domain/session/room/timeline/tiles/BaseMessageTile.js @@ -106,8 +106,8 @@ export class BaseMessageTile extends SimpleTile { return action; } - setReply() { - this._roomVM.setReply(this._entry); + startReply() { + this._roomVM.startReply(this._entry); } redact(reason, log) { diff --git a/src/platform/web/ui/session/room/timeline/BaseMessageView.js b/src/platform/web/ui/session/room/timeline/BaseMessageView.js index c91a5ed7..b17bd93a 100644 --- a/src/platform/web/ui/session/room/timeline/BaseMessageView.js +++ b/src/platform/web/ui/session/room/timeline/BaseMessageView.js @@ -113,7 +113,7 @@ export class BaseMessageView extends TemplateView { if (vm.canReact && vm.shape !== "redacted") { options.push(new QuickReactionsMenuOption(vm)); } - options.push(Menu.option(vm.i18n`Reply`, () => vm.setReply())); + options.push(Menu.option(vm.i18n`Reply`, () => vm.startReply())); if (vm.canAbortSending) { options.push(Menu.option(vm.i18n`Cancel`, () => vm.abortSending())); } else if (vm.canRedact) {