bring insert method inline with transform callback, add docs
before the insertPartsAt method would call the update callback on its own, but now we have the concept of a transformation session, so lets bring the API in line
This commit is contained in:
parent
8e66d382de
commit
d8bb9ecedf
3 changed files with 31 additions and 11 deletions
|
@ -279,22 +279,33 @@ export default class SendMessageComposer extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
_insertMention(userId) {
|
_insertMention(userId) {
|
||||||
|
const {model} = this;
|
||||||
|
const {partCreator} = model;
|
||||||
const member = this.props.room.getMember(userId);
|
const member = this.props.room.getMember(userId);
|
||||||
const displayName = member ?
|
const displayName = member ?
|
||||||
member.rawDisplayName : userId;
|
member.rawDisplayName : userId;
|
||||||
const userPillPart = this.model.partCreator.userPill(displayName, userId);
|
const userPillPart = partCreator.userPill(displayName, userId);
|
||||||
this.model.insertPartsAt([userPillPart], this._editorRef.getCaret());
|
const caret = this._editorRef.getCaret();
|
||||||
|
const position = model.positionForOffset(caret.offset, caret.atNodeEnd);
|
||||||
|
model.transform(() => {
|
||||||
|
const addedLen = model.insert([userPillPart], position);
|
||||||
|
return model.positionForOffset(caret.offset + addedLen, true);
|
||||||
|
});
|
||||||
// refocus on composer, as we just clicked "Mention"
|
// refocus on composer, as we just clicked "Mention"
|
||||||
this._editorRef && this._editorRef.focus();
|
this._editorRef && this._editorRef.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
_insertQuotedMessage(event) {
|
_insertQuotedMessage(event) {
|
||||||
const {partCreator} = this.model;
|
const {model} = this;
|
||||||
|
const {partCreator} = model;
|
||||||
const quoteParts = parseEvent(event, partCreator, { isQuotedMessage: true });
|
const quoteParts = parseEvent(event, partCreator, { isQuotedMessage: true });
|
||||||
// add two newlines
|
// add two newlines
|
||||||
quoteParts.push(partCreator.newline());
|
quoteParts.push(partCreator.newline());
|
||||||
quoteParts.push(partCreator.newline());
|
quoteParts.push(partCreator.newline());
|
||||||
this.model.insertPartsAt(quoteParts, {offset: 0});
|
model.transform(() => {
|
||||||
|
const addedLen = model.insert(quoteParts, model.positionForOffset(0));
|
||||||
|
return model.positionForOffset(addedLen, true);
|
||||||
|
});
|
||||||
// refocus on composer, as we just clicked "Quote"
|
// refocus on composer, as we just clicked "Quote"
|
||||||
this._editorRef && this._editorRef.focus();
|
this._editorRef && this._editorRef.focus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,8 +158,14 @@ export default class EditorModel {
|
||||||
this._updateCallback(caret, inputType);
|
this._updateCallback(caret, inputType);
|
||||||
}
|
}
|
||||||
|
|
||||||
insertPartsAt(parts, caret) {
|
/**
|
||||||
const position = this.positionForOffset(caret.offset, caret.atNodeEnd);
|
* Inserts the given parts at the given position.
|
||||||
|
* Should be run inside a `model.transform()` callback.
|
||||||
|
* @param {Part[]} parts the parts to replace the range with
|
||||||
|
* @param {DocumentPosition} position the position to start inserting at
|
||||||
|
* @return {Number} the amount of characters added
|
||||||
|
*/
|
||||||
|
insert(parts, position) {
|
||||||
const insertIndex = this._splitAt(position);
|
const insertIndex = this._splitAt(position);
|
||||||
let newTextLength = 0;
|
let newTextLength = 0;
|
||||||
for (let i = 0; i < parts.length; ++i) {
|
for (let i = 0; i < parts.length; ++i) {
|
||||||
|
@ -167,10 +173,7 @@ export default class EditorModel {
|
||||||
newTextLength += part.text.length;
|
newTextLength += part.text.length;
|
||||||
this._insertPart(insertIndex + i, part);
|
this._insertPart(insertIndex + i, part);
|
||||||
}
|
}
|
||||||
// put caret after new part
|
return newTextLength;
|
||||||
const lastPartIndex = insertIndex + parts.length - 1;
|
|
||||||
const newPosition = new DocumentPosition(lastPartIndex, newTextLength);
|
|
||||||
this._updateCallback(newPosition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update(newValue, inputType, caret) {
|
update(newValue, inputType, caret) {
|
||||||
|
@ -403,7 +406,7 @@ export default class EditorModel {
|
||||||
return new Range(this, position);
|
return new Range(this, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from Range.replace
|
//mostly internal, called from Range.replace
|
||||||
replaceRange(startPosition, endPosition, parts) {
|
replaceRange(startPosition, endPosition, parts) {
|
||||||
const newStartPartIndex = this._splitAt(startPosition);
|
const newStartPartIndex = this._splitAt(startPosition);
|
||||||
const idxDiff = newStartPartIndex - startPosition.index;
|
const idxDiff = newStartPartIndex - startPosition.index;
|
||||||
|
|
|
@ -41,6 +41,12 @@ export default class Range {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Splits the model at the range boundaries and replaces with the given parts.
|
||||||
|
* Should be run inside a `model.transform()` callback.
|
||||||
|
* @param {Part[]} parts the parts to replace the range with
|
||||||
|
* @return {Number} the net amount of characters added, can be negative.
|
||||||
|
*/
|
||||||
replace(parts) {
|
replace(parts) {
|
||||||
const newLength = parts.reduce((sum, part) => sum + part.text.length, 0);
|
const newLength = parts.reduce((sum, part) => sum + part.text.length, 0);
|
||||||
let oldLength = 0;
|
let oldLength = 0;
|
||||||
|
|
Loading…
Reference in a new issue