rerender through callback instead of after modifying model

this way rendering is centralized and we can better rerender
from interaction in the autocompleter
(we didn't have access to caret before)
This commit is contained in:
Bruno Windels 2019-05-09 15:58:32 +02:00
parent aa1b4bb91e
commit 64b171198c
2 changed files with 23 additions and 22 deletions

View File

@ -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() {

View File

@ -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));
}
/*