diff --git a/src/components/views/elements/MessageEditor.js b/src/components/views/elements/MessageEditor.js index ff0a705111..c863f8baf4 100644 --- a/src/components/views/elements/MessageEditor.js +++ b/src/components/views/elements/MessageEditor.js @@ -44,7 +44,11 @@ export default class MessageEditor extends React.Component { () => this._autocompleteRef, query => this.setState({query}), ); - this.model = new EditorModel(parseEvent(this.props.event), partCreator); + this.model = new EditorModel( + parseEvent(this.props.event), + partCreator, + this._updateEditorState, + ); const room = this.context.matrixClient.getRoom(this.props.event.getRoomId()); this.state = { autoComplete: null, @@ -54,20 +58,25 @@ export default class MessageEditor extends React.Component { this._autocompleteRef = null; } - _onInput = (event) => { - const caretOffset = getCaretOffset(this._editorRef); - const caret = this.model.update(this._editorRef.textContent, event.inputType, caretOffset); - // const parts = this.model.serializeParts(); - const shouldRerender = event.inputType === "insertFromDrop" || event.inputType === "insertFromPaste"; + _updateEditorState = (caret) => { + const shouldRerender = false; //event.inputType === "insertFromDrop" || event.inputType === "insertFromPaste"; if (shouldRerender) { rerenderModel(this._editorRef, this.model); } else { renderModel(this._editorRef, this.model); } - setCaretPosition(this._editorRef, caret); + if (caret) { + setCaretPosition(this._editorRef, caret); + } this.setState({autoComplete: this.model.autoComplete}); - this._updateModelOutput(); + const modelOutput = this._editorRef.parentElement.querySelector(".model"); + modelOutput.textContent = JSON.stringify(this.model.serializeParts(), undefined, 2); + } + + _onInput = (event) => { + const caretOffset = getCaretOffset(this._editorRef); + this.model.update(this._editorRef.textContent, event.inputType, caretOffset); } _onKeyDown = (event) => { @@ -109,25 +118,14 @@ export default class MessageEditor extends React.Component { _onAutoCompleteConfirm = (completion) => { this.model.autoComplete.onComponentConfirm(completion); - renderModel(this._editorRef, this.model); - this._updateModelOutput(); } _onAutoCompleteSelectionChange = (completion) => { this.model.autoComplete.onComponentSelectionChange(completion); - renderModel(this._editorRef, this.model); - this._updateModelOutput(); - } - - _updateModelOutput() { - const modelOutput = this._editorRef.parentElement.querySelector(".model"); - modelOutput.textContent = JSON.stringify(this.model.serializeParts(), undefined, 2); } componentDidMount() { - const editor = this._editorRef; - rerenderModel(editor, this.model); - this._updateModelOutput(); + this._updateEditorState(); } render() { diff --git a/src/editor/model.js b/src/editor/model.js index fb1e4801ba..999d37efca 100644 --- a/src/editor/model.js +++ b/src/editor/model.js @@ -17,12 +17,13 @@ limitations under the License. import {diffAtCaret, diffDeletion} from "./diff"; export default class EditorModel { - constructor(parts, partCreator) { + constructor(parts, partCreator, updateCallback) { this._parts = parts; this._partCreator = partCreator; this._activePartIdx = null; this._autoComplete = null; this._autoCompletePartIdx = null; + this._updateCallback = updateCallback; } _insertPart(index, part) { @@ -90,7 +91,7 @@ export default class EditorModel { const caretOffset = diff.at + (diff.added ? diff.added.length : 0); const newPosition = this._positionForOffset(caretOffset, true); this._setActivePart(newPosition); - return newPosition; + this._updateCallback(newPosition); } _setActivePart(pos) { @@ -116,10 +117,12 @@ export default class EditorModel { _onAutoComplete = ({replacePart, replaceCaret, close}) => { this._replacePart(this._autoCompletePartIdx, replacePart); + const index = this._autoCompletePartIdx; if (close) { this._autoComplete = null; this._autoCompletePartIdx = null; } + this._updateCallback(new DocumentPosition(index, replaceCaret)); } /*