From ce7147e463e0b2b887272f0f2ef54598ea3b0ff3 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 26 May 2021 13:07:56 +0200 Subject: [PATCH] put redactions in their own view, and allow aborting while still queued --- .../room/timeline/tiles/RedactedTile.js | 25 ++++++++---- .../room/timeline/entries/BaseEventEntry.js | 39 +++++++++++++++---- .../web/ui/session/room/TimelineList.js | 4 +- .../ui/session/room/timeline/RedactedView.js | 27 +++++++++++++ 4 files changed, 79 insertions(+), 16 deletions(-) create mode 100644 src/platform/web/ui/session/room/timeline/RedactedView.js diff --git a/src/domain/session/room/timeline/tiles/RedactedTile.js b/src/domain/session/room/timeline/tiles/RedactedTile.js index 81b286a5..2363f91c 100644 --- a/src/domain/session/room/timeline/tiles/RedactedTile.js +++ b/src/domain/session/room/timeline/tiles/RedactedTile.js @@ -14,20 +14,31 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {BaseTextTile} from "./BaseTextTile.js"; +import {BaseMessageTile} from "./BaseMessageTile.js"; -export class RedactedTile extends BaseTextTile { +export class RedactedTile extends BaseMessageTile { get shape() { return "redacted"; } - _getBodyAsString() { + get description() { const {redactionReason} = this._entry; - if (redactionReason) { - return this.i18n`This message has been deleted (${redactionReason}).`; - + if (this.isRedacting) { + return this.i18n`This message is being deleted …`; } else { - return this.i18n`This message has been deleted.`; + if (redactionReason) { + return this.i18n`This message has been deleted (${redactionReason}).`; + } else { + return this.i18n`This message has been deleted.`; + } } } + + get isRedacting() { + return this._entry.isRedacting; + } + + abortPendingRedaction() { + return this._entry.abortPendingRedaction(); + } } diff --git a/src/matrix/room/timeline/entries/BaseEventEntry.js b/src/matrix/room/timeline/entries/BaseEventEntry.js index c895f538..4706f5f2 100644 --- a/src/matrix/room/timeline/entries/BaseEventEntry.js +++ b/src/matrix/room/timeline/entries/BaseEventEntry.js @@ -20,11 +20,17 @@ import {REDACTION_TYPE} from "../../common.js"; export class BaseEventEntry extends BaseEntry { constructor(fragmentIdComparer) { super(fragmentIdComparer); - this._localRedactCount = 0; + this._pendingRedactions = null; + } + + get isRedacting() { + return !!this._pendingRedactions; } get isRedacted() { - return this._localRedactCount > 0; + return this.isRedacting; + } + } /** @@ -33,8 +39,11 @@ export class BaseEventEntry extends BaseEntry { */ addLocalRelation(entry) { if (entry.eventType === REDACTION_TYPE) { - this._localRedactCount += 1; - if (this._localRedactCount === 1) { + if (!this._pendingRedactions) { + this._pendingRedactions = []; + } + this._pendingRedactions.push(entry); + if (this._pendingRedactions.length === 1) { return "isRedacted"; } } @@ -45,11 +54,25 @@ export class BaseEventEntry extends BaseEntry { @return [string] returns the name of the field that has changed, if any */ removeLocalRelation(entry) { - if (entry.eventType === REDACTION_TYPE) { - this._localRedactCount -= 1; - if (this._localRedactCount === 0) { - return "isRedacted"; + if (entry.eventType === REDACTION_TYPE && this._pendingRedactions) { + const countBefore = this._pendingRedactions.length; + this._pendingRedactions = this._pendingRedactions.filter(e => e !== entry); + if (this._pendingRedactions.length === 0) { + this._pendingRedactions = null; + if (countBefore !== 0) { + return "isRedacted"; + } } } } + + async abortPendingRedaction() { + if (this._pendingRedactions) { + for (const pee of this._pendingRedactions) { + await pee.pendingEvent.abort(); + } + // removing the pending events will call removeLocalRelation, + // so don't clear _pendingRedactions here + } + } } \ No newline at end of file diff --git a/src/platform/web/ui/session/room/TimelineList.js b/src/platform/web/ui/session/room/TimelineList.js index b55c2450..81763c05 100644 --- a/src/platform/web/ui/session/room/TimelineList.js +++ b/src/platform/web/ui/session/room/TimelineList.js @@ -22,6 +22,7 @@ import {VideoView} from "./timeline/VideoView.js"; import {FileView} from "./timeline/FileView.js"; import {MissingAttachmentView} from "./timeline/MissingAttachmentView.js"; import {AnnouncementView} from "./timeline/AnnouncementView.js"; +import {RedactedView} from "./timeline/RedactedView.js"; function viewClassForEntry(entry) { switch (entry.shape) { @@ -29,12 +30,13 @@ function viewClassForEntry(entry) { case "announcement": return AnnouncementView; case "message": case "message-status": - case "redacted": return TextMessageView; case "image": return ImageView; case "video": return VideoView; case "file": return FileView; case "missing-attachment": return MissingAttachmentView; + case "redacted": + return RedactedView; } } diff --git a/src/platform/web/ui/session/room/timeline/RedactedView.js b/src/platform/web/ui/session/room/timeline/RedactedView.js new file mode 100644 index 00000000..6e9bf105 --- /dev/null +++ b/src/platform/web/ui/session/room/timeline/RedactedView.js @@ -0,0 +1,27 @@ +/* +Copyright 2020 Bruno Windels + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import {TemplateView} from "../../../general/TemplateView.js"; +import {renderMessage} from "./common.js"; + +export class RedactedView extends TemplateView { + render(t, vm) { + const cancelButton = t.if(vm => vm.isRedacting, t => t.button({onClick: () => vm.abortPendingRedaction()}, "Cancel")); + return renderMessage(t, vm, + [t.p([vm => vm.description, " ", cancelButton, t.time({className: {hidden: !vm.date}}, vm.date + " " + vm.time)])] + ); + } +} \ No newline at end of file