mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-16 21:24:59 +08:00
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:
parent
aa1b4bb91e
commit
64b171198c
@ -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() {
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user