diff --git a/src/components/views/rooms/BasicMessageComposer.tsx b/src/components/views/rooms/BasicMessageComposer.tsx index d317aa409b..3258674cf6 100644 --- a/src/components/views/rooms/BasicMessageComposer.tsx +++ b/src/components/views/rooms/BasicMessageComposer.tsx @@ -711,6 +711,7 @@ export default class BasicMessageEditor extends React.Component } public insertMention(userId: string): void { + this.modifiedFlag = true; const { model } = this.props; const { partCreator } = model; const member = this.props.room.getMember(userId); @@ -729,6 +730,7 @@ export default class BasicMessageEditor extends React.Component } public insertQuotedMessage(event: MatrixEvent): void { + this.modifiedFlag = true; const { model } = this.props; const { partCreator } = model; const quoteParts = parseEvent(event, partCreator, { isQuotedMessage: true }); @@ -744,6 +746,7 @@ export default class BasicMessageEditor extends React.Component } public insertPlaintext(text: string): void { + this.modifiedFlag = true; const { model } = this.props; const { partCreator } = model; const caret = this.getCaret(); diff --git a/src/components/views/rooms/EditMessageComposer.tsx b/src/components/views/rooms/EditMessageComposer.tsx index 4e51a0105b..fea6499dd8 100644 --- a/src/components/views/rooms/EditMessageComposer.tsx +++ b/src/components/views/rooms/EditMessageComposer.tsx @@ -131,11 +131,12 @@ export default class EditMessageComposer extends React.Component super(props); this.context = context; // otherwise React will only set it prior to render due to type def above + const isRestored = this.createEditorModel(); + const ev = this.props.editState.getEvent(); this.state = { - saveDisabled: true, + saveDisabled: !isRestored || !this.isContentModified(createEditContent(this.model, ev)["m.new_content"]), }; - this.createEditorModel(); window.addEventListener("beforeunload", this.saveStoredEditorState); this.dispatcherRef = dis.register(this.onAction); } @@ -230,12 +231,12 @@ export default class EditMessageComposer extends React.Component } } - private saveStoredEditorState(): void { + private saveStoredEditorState = (): void => { const item = SendHistoryManager.createItem(this.model); this.clearPreviousEdit(); localStorage.setItem(this.editorRoomKey, this.props.editState.getEvent().getId()); localStorage.setItem(this.editorStateKey, JSON.stringify(item)); - } + }; private isSlashCommand(): boolean { const parts = this.model.parts; @@ -256,10 +257,9 @@ export default class EditMessageComposer extends React.Component private isContentModified(newContent: IContent): boolean { // if nothing has changed then bail const oldContent = this.props.editState.getEvent().getContent(); - if (!this.editorRef.current?.isModified() || - (oldContent["msgtype"] === newContent["msgtype"] && oldContent["body"] === newContent["body"] && + if (oldContent["msgtype"] === newContent["msgtype"] && oldContent["body"] === newContent["body"] && oldContent["format"] === newContent["format"] && - oldContent["formatted_body"] === newContent["formatted_body"])) { + oldContent["formatted_body"] === newContent["formatted_body"]) { return false; } return true; @@ -410,36 +410,27 @@ export default class EditMessageComposer extends React.Component dis.unregister(this.dispatcherRef); } - private createEditorModel(): void { + private createEditorModel(): boolean { const { editState } = this.props; const room = this.getRoom(); const partCreator = new CommandPartCreator(room, this.context); + let parts; + let isRestored = false; if (editState.hasEditorState()) { // if restoring state from a previous editor, // restore serialized parts from the state parts = editState.getSerializedParts().map(p => partCreator.deserializePart(p)); } else { - //otherwise, either restore serialized parts from localStorage or parse the body of the event - parts = this.restoreStoredEditorState(partCreator) || parseEvent(editState.getEvent(), partCreator); + // otherwise, either restore serialized parts from localStorage or parse the body of the event + const restoredParts = this.restoreStoredEditorState(partCreator); + parts = restoredParts || parseEvent(editState.getEvent(), partCreator); + isRestored = !!restoredParts; } this.model = new EditorModel(parts, partCreator); this.saveStoredEditorState(); - } - private getInitialCaretPosition(): CaretPosition { - const { editState } = this.props; - let caretPosition; - if (editState.hasEditorState() && editState.getCaret()) { - // if restoring state from a previous editor, - // restore caret position from the state - const caret = editState.getCaret(); - caretPosition = this.model.positionForOffset(caret.offset, caret.atNodeEnd); - } else { - // otherwise, set it at the end - caretPosition = this.model.getPositionAtEnd(); - } - return caretPosition; + return isRestored; } private onChange = (): void => {