Merge pull request #3361 from matrix-org/bwindels/autocomplete-colon
New composer: append colon to completed user pill when at start of message
This commit is contained in:
commit
ec0d048cf0
3 changed files with 26 additions and 23 deletions
|
@ -27,8 +27,7 @@ export default class AutocompleteWrapperModel {
|
||||||
onEscape(e) {
|
onEscape(e) {
|
||||||
this._getAutocompleterComponent().onEscape(e);
|
this._getAutocompleterComponent().onEscape(e);
|
||||||
this._updateCallback({
|
this._updateCallback({
|
||||||
replacePart: this._partCreator.plain(this._queryPart.text),
|
replaceParts: [this._partCreator.plain(this._queryPart.text)],
|
||||||
caretOffset: this._queryOffset,
|
|
||||||
close: true,
|
close: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -66,30 +65,29 @@ export default class AutocompleteWrapperModel {
|
||||||
this._getAutocompleterComponent().moveSelection(+1);
|
this._getAutocompleterComponent().moveSelection(+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
onPartUpdate(part, offset) {
|
onPartUpdate(part, pos) {
|
||||||
// cache the typed value and caret here
|
// cache the typed value and caret here
|
||||||
// so we can restore it in onComponentSelectionChange when the value is undefined (meaning it should be the typed text)
|
// so we can restore it in onComponentSelectionChange when the value is undefined (meaning it should be the typed text)
|
||||||
this._queryPart = part;
|
this._queryPart = part;
|
||||||
this._queryOffset = offset;
|
this._partIndex = pos.index;
|
||||||
return this._updateQuery(part.text);
|
return this._updateQuery(part.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
onComponentSelectionChange(completion) {
|
onComponentSelectionChange(completion) {
|
||||||
if (!completion) {
|
if (!completion) {
|
||||||
this._updateCallback({
|
this._updateCallback({
|
||||||
replacePart: this._queryPart,
|
replaceParts: [this._queryPart],
|
||||||
caretOffset: this._queryOffset,
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this._updateCallback({
|
this._updateCallback({
|
||||||
replacePart: this._partForCompletion(completion),
|
replaceParts: this._partForCompletion(completion),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onComponentConfirm(completion) {
|
onComponentConfirm(completion) {
|
||||||
this._updateCallback({
|
this._updateCallback({
|
||||||
replacePart: this._partForCompletion(completion),
|
replaceParts: this._partForCompletion(completion),
|
||||||
close: true,
|
close: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -101,16 +99,18 @@ export default class AutocompleteWrapperModel {
|
||||||
switch (firstChr) {
|
switch (firstChr) {
|
||||||
case "@": {
|
case "@": {
|
||||||
if (completionId === "@room") {
|
if (completionId === "@room") {
|
||||||
return this._partCreator.atRoomPill(completionId);
|
return [this._partCreator.atRoomPill(completionId)];
|
||||||
} else {
|
} else {
|
||||||
return this._partCreator.userPill(text, completionId);
|
const pill = this._partCreator.userPill(text, completionId);
|
||||||
|
const postfix = this._partCreator.plain(this._partIndex === 0 ? ": " : " ");
|
||||||
|
return [pill, postfix];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "#":
|
case "#":
|
||||||
return this._partCreator.roomPill(completionId);
|
return [this._partCreator.roomPill(completionId)];
|
||||||
// used for emoji and command completion replacement
|
// used for emoji and command completion replacement
|
||||||
default:
|
default:
|
||||||
return this._partCreator.plain(text);
|
return [this._partCreator.plain(text)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ export default class EditorModel {
|
||||||
this._activePartIdx = null;
|
this._activePartIdx = null;
|
||||||
this._autoComplete = null;
|
this._autoComplete = null;
|
||||||
this._autoCompletePartIdx = null;
|
this._autoCompletePartIdx = null;
|
||||||
|
this._autoCompletePartCount = 0;
|
||||||
this._transformCallback = null;
|
this._transformCallback = null;
|
||||||
this.setUpdateCallback(updateCallback);
|
this.setUpdateCallback(updateCallback);
|
||||||
}
|
}
|
||||||
|
@ -218,34 +219,36 @@ export default class EditorModel {
|
||||||
// make sure that react picks up the difference between both acs
|
// make sure that react picks up the difference between both acs
|
||||||
this._autoComplete = ac;
|
this._autoComplete = ac;
|
||||||
this._autoCompletePartIdx = index;
|
this._autoCompletePartIdx = index;
|
||||||
|
this._autoCompletePartCount = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// not _autoComplete, only there if active part is autocomplete part
|
// not _autoComplete, only there if active part is autocomplete part
|
||||||
if (this.autoComplete) {
|
if (this.autoComplete) {
|
||||||
return this.autoComplete.onPartUpdate(part, pos.offset);
|
return this.autoComplete.onPartUpdate(part, pos);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this._activePartIdx = null;
|
this._activePartIdx = null;
|
||||||
this._autoComplete = null;
|
this._autoComplete = null;
|
||||||
this._autoCompletePartIdx = null;
|
this._autoCompletePartIdx = null;
|
||||||
|
this._autoCompletePartCount = 0;
|
||||||
}
|
}
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onAutoComplete = ({replacePart, caretOffset, close}) => {
|
_onAutoComplete = ({replaceParts, close}) => {
|
||||||
let pos;
|
let pos;
|
||||||
if (replacePart) {
|
if (replaceParts) {
|
||||||
this._replacePart(this._autoCompletePartIdx, replacePart);
|
this._parts.splice(this._autoCompletePartIdx, this._autoCompletePartCount, ...replaceParts);
|
||||||
const index = this._autoCompletePartIdx;
|
this._autoCompletePartCount = replaceParts.length;
|
||||||
if (caretOffset === undefined) {
|
const lastPart = replaceParts[replaceParts.length - 1];
|
||||||
caretOffset = replacePart.text.length;
|
const lastPartIndex = this._autoCompletePartIdx + replaceParts.length - 1;
|
||||||
}
|
pos = new DocumentPosition(lastPartIndex, lastPart.text.length);
|
||||||
pos = new DocumentPosition(index, caretOffset);
|
|
||||||
}
|
}
|
||||||
if (close) {
|
if (close) {
|
||||||
this._autoComplete = null;
|
this._autoComplete = null;
|
||||||
this._autoCompletePartIdx = null;
|
this._autoCompletePartIdx = null;
|
||||||
|
this._autoCompletePartCount = 0;
|
||||||
}
|
}
|
||||||
// rerender even if editor contents didn't change
|
// rerender even if editor contents didn't change
|
||||||
// to make sure the MessageEditor checks
|
// to make sure the MessageEditor checks
|
||||||
|
|
|
@ -40,12 +40,12 @@ class MockAutoComplete {
|
||||||
} else {
|
} else {
|
||||||
pill = this._partCreator.roomPill(match.resourceId);
|
pill = this._partCreator.roomPill(match.resourceId);
|
||||||
}
|
}
|
||||||
this._updateCallback({replacePart: pill, close});
|
this._updateCallback({replaceParts: [pill], close});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// called by EditorModel when typing into pill-candidate part
|
// called by EditorModel when typing into pill-candidate part
|
||||||
onPartUpdate(part, offset) {
|
onPartUpdate(part, pos) {
|
||||||
this._part = part;
|
this._part = part;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue