diff --git a/src/components/views/context_menus/MessageContextMenu.tsx b/src/components/views/context_menus/MessageContextMenu.tsx index c7fcf32260..22dd3ac438 100644 --- a/src/components/views/context_menus/MessageContextMenu.tsx +++ b/src/components/views/context_menus/MessageContextMenu.tsx @@ -34,8 +34,7 @@ import ForwardDialog from "../dialogs/ForwardDialog"; import { Action } from "../../../dispatcher/actions"; import ReportEventDialog from '../dialogs/ReportEventDialog'; import ViewSource from '../../structures/ViewSource'; -import ConfirmRedactDialog from '../dialogs/ConfirmRedactDialog'; -import ErrorDialog from '../dialogs/ErrorDialog'; +import { createRedactEventDialog } from '../dialogs/ConfirmRedactDialog'; import ShareDialog from '../dialogs/ShareDialog'; import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks"; import { IPosition, ChevronFace } from '../../structures/ContextMenu'; @@ -140,34 +139,11 @@ export default class MessageContextMenu extends React.Component }; private onRedactClick = (): void => { - Modal.createTrackedDialog('Confirm Redact Dialog', '', ConfirmRedactDialog, { - onFinished: async (proceed: boolean, reason?: string) => { - if (!proceed) return; - - const cli = MatrixClientPeg.get(); - try { - this.props.onCloseDialog?.(); - await cli.redactEvent( - this.props.mxEvent.getRoomId(), - this.props.mxEvent.getId(), - undefined, - reason ? { reason } : {}, - ); - } catch (e) { - const code = e.errcode || e.statusCode; - // only show the dialog if failing for something other than a network error - // (e.g. no errcode or statusCode) as in that case the redactions end up in the - // detached queue and we show the room status bar to allow retry - if (typeof code !== "undefined") { - // display error message stating you couldn't delete this. - Modal.createTrackedDialog('You cannot delete this message', '', ErrorDialog, { - title: _t('Error'), - description: _t('You cannot delete this message. (%(code)s)', { code }), - }); - } - } - }, - }, 'mx_Dialog_confirmredact'); + const { mxEvent, onCloseDialog } = this.props; + createRedactEventDialog({ + mxEvent, + onCloseDialog, + }); this.closeMenu(); }; diff --git a/src/components/views/dialogs/ConfirmRedactDialog.tsx b/src/components/views/dialogs/ConfirmRedactDialog.tsx index b346d2d44c..74b3320fdf 100644 --- a/src/components/views/dialogs/ConfirmRedactDialog.tsx +++ b/src/components/views/dialogs/ConfirmRedactDialog.tsx @@ -14,9 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { MatrixEvent } from 'matrix-js-sdk/src/models/event'; import React from 'react'; import { _t } from '../../../languageHandler'; +import { MatrixClientPeg } from '../../../MatrixClientPeg'; +import Modal from '../../../Modal'; import { replaceableComponent } from "../../../utils/replaceableComponent"; +import ErrorDialog from './ErrorDialog'; import TextInputDialog from "./TextInputDialog"; interface IProps { @@ -42,3 +46,40 @@ export default class ConfirmRedactDialog extends React.Component { ); } } + +export function createRedactEventDialog({ + mxEvent, + onCloseDialog = () => {}, +}: { + mxEvent: MatrixEvent; + onCloseDialog?: () => void; +}) { + Modal.createTrackedDialog('Confirm Redact Dialog', '', ConfirmRedactDialog, { + onFinished: async (proceed: boolean, reason?: string) => { + if (!proceed) return; + + const cli = MatrixClientPeg.get(); + try { + onCloseDialog?.(); + await cli.redactEvent( + mxEvent.getRoomId(), + mxEvent.getId(), + undefined, + reason ? { reason } : {}, + ); + } catch (e) { + const code = e.errcode || e.statusCode; + // only show the dialog if failing for something other than a network error + // (e.g. no errcode or statusCode) as in that case the redactions end up in the + // detached queue and we show the room status bar to allow retry + if (typeof code !== "undefined") { + // display error message stating you couldn't delete this. + Modal.createTrackedDialog('You cannot delete this message', '', ErrorDialog, { + title: _t('Error'), + description: _t('You cannot delete this message. (%(code)s)', { code }), + }); + } + } + }, + }, 'mx_Dialog_confirmredact'); +} diff --git a/src/components/views/rooms/EditMessageComposer.tsx b/src/components/views/rooms/EditMessageComposer.tsx index f2f80b7670..33273f1f95 100644 --- a/src/components/views/rooms/EditMessageComposer.tsx +++ b/src/components/views/rooms/EditMessageComposer.tsx @@ -42,6 +42,7 @@ import ErrorDialog from "../dialogs/ErrorDialog"; import QuestionDialog from "../dialogs/QuestionDialog"; import { ActionPayload } from "../../../dispatcher/payloads"; import AccessibleButton from '../elements/AccessibleButton'; +import { createRedactEventDialog } from '../dialogs/ConfirmRedactDialog'; import SettingsStore from "../../../settings/SettingsStore"; import { logger } from "matrix-js-sdk/src/logger"; @@ -331,6 +332,14 @@ export default class EditMessageComposer extends React.Component let shouldSend = true; + if (newContent?.body === '') { + this.cancelPreviousPendingEdit(); + createRedactEventDialog({ + mxEvent: editedEvent, + }); + return; + } + // If content is modified then send an updated event into the room if (this.isContentModified(newContent)) { const roomId = editedEvent.getRoomId(); diff --git a/src/editor/serialize.ts b/src/editor/serialize.ts index 38a73cc945..9822046a0d 100644 --- a/src/editor/serialize.ts +++ b/src/editor/serialize.ts @@ -185,7 +185,7 @@ export function startsWith(model: EditorModel, prefix: string, caseSensitive = t const firstPart = model.parts[0]; // part type will be "plain" while editing, // and "command" while composing a message. - let text = firstPart && firstPart.text; + let text = firstPart?.text || ''; if (!caseSensitive) { prefix = prefix.toLowerCase(); text = text.toLowerCase();