Fix autocomplete not resetting properly on message send (#10741)

pull/28217/head
Michael Telatynski 2023-04-28 14:31:02 +01:00 committed by GitHub
parent 0d1020c66f
commit f819853cad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 13 deletions

View File

@ -99,10 +99,10 @@ export default class EditorModel {
private insertPart(index: number, part: Part): void {
this._parts.splice(index, 0, part);
if (this.activePartIdx && this.activePartIdx >= index) {
if (this.activePartIdx !== null && this.activePartIdx >= index) {
++this.activePartIdx;
}
if (this.autoCompletePartIdx && this.autoCompletePartIdx >= index) {
if (this.autoCompletePartIdx !== null && this.autoCompletePartIdx >= index) {
++this.autoCompletePartIdx;
}
}
@ -111,12 +111,12 @@ export default class EditorModel {
this._parts.splice(index, 1);
if (index === this.activePartIdx) {
this.activePartIdx = null;
} else if (this.activePartIdx && this.activePartIdx > index) {
} else if (this.activePartIdx !== null && this.activePartIdx > index) {
--this.activePartIdx;
}
if (index === this.autoCompletePartIdx) {
this.autoCompletePartIdx = null;
} else if (this.autoCompletePartIdx && this.autoCompletePartIdx > index) {
} else if (this.autoCompletePartIdx !== null && this.autoCompletePartIdx > index) {
--this.autoCompletePartIdx;
}
}

View File

@ -21,7 +21,7 @@ import { Caret } from "../../src/editor/caret";
import { PillPart, Part, PartCreator } from "../../src/editor/parts";
import DocumentPosition from "../../src/editor/position";
class MockAutoComplete {
export class MockAutoComplete {
public _updateCallback;
public _partCreator;
public _completions;
@ -44,7 +44,7 @@ class MockAutoComplete {
});
if (matches.length === 1 && this._part && this._part.text.length > 1) {
const match = matches[0];
let pill;
let pill: PillPart;
if (match.resourceId[0] === "@") {
pill = this._partCreator.userPill(match.text, match.resourceId);
} else {

View File

@ -15,7 +15,7 @@ limitations under the License.
*/
import EditorModel from "../../src/editor/model";
import { createPartCreator, createRenderer } from "./mock";
import { createPartCreator, createRenderer, MockAutoComplete } from "./mock";
import DocumentOffset from "../../src/editor/offset";
import { PillPart } from "../../src/editor/parts";
import DocumentPosition from "../../src/editor/position";
@ -186,8 +186,7 @@ describe("editor/model", function () {
expect(model.parts[1].text).toBe("@a");
// this is a hacky mock function
// @ts-ignore
model.autoComplete.tryComplete(); // see MockAutoComplete
(model.autoComplete as unknown as MockAutoComplete).tryComplete();
expect(renderer.count).toBe(2);
expect((renderer.caret as DocumentPosition).index).toBe(1);
@ -216,8 +215,7 @@ describe("editor/model", function () {
expect(model.parts[1].text).toBe("#r");
// this is a hacky mock function
// @ts-ignore
model.autoComplete.tryComplete(); // see MockAutoComplete
(model.autoComplete as unknown as MockAutoComplete).tryComplete();
expect(renderer.count).toBe(2);
expect((renderer.caret as DocumentPosition).index).toBe(1);
@ -236,8 +234,7 @@ describe("editor/model", function () {
model.update("hello #r", "insertText", new DocumentOffset(8, true));
// this is a hacky mock function
// @ts-ignore
model.autoComplete.tryComplete(); // see MockAutoComplete
(model.autoComplete as unknown as MockAutoComplete).tryComplete();
model.update("hello #riot-dev!!", "insertText", new DocumentOffset(17, true));
expect(renderer.count).toBe(3);
@ -314,6 +311,45 @@ describe("editor/model", function () {
expect(model.parts[0].type).toBe("plain");
expect(model.parts[0].text).toBe("foo@a");
});
it("should allow auto-completing multiple times with resets between them", () => {
const renderer = createRenderer();
const pc = createPartCreator([{ resourceId: "#riot-dev" } as PillPart]);
const model = new EditorModel([pc.plain("")], pc, renderer);
model.update("#r", "insertText", new DocumentOffset(8, true));
expect(renderer.count).toBe(1);
expect((renderer.caret as DocumentPosition).index).toBe(0);
expect((renderer.caret as DocumentPosition).offset).toBe(2);
expect(model.parts.length).toBe(1);
expect(model.parts[0].type).toBe("pill-candidate");
expect(model.parts[0].text).toBe("#r");
// this is a hacky mock function
(model.autoComplete as unknown as MockAutoComplete).tryComplete();
expect(renderer.count).toBe(2);
expect((renderer.caret as DocumentPosition).index).toBe(0);
expect((renderer.caret as DocumentPosition).offset).toBe(9);
expect(model.parts.length).toBe(1);
expect(model.parts[0].type).toBe("room-pill");
expect(model.parts[0].text).toBe("#riot-dev");
model.reset([]);
model.update("#r", "insertText", new DocumentOffset(8, true));
expect(model.parts.length).toBe(1);
expect(model.parts[0].type).toBe("pill-candidate");
expect(model.parts[0].text).toBe("#r");
// this is a hacky mock function
(model.autoComplete as unknown as MockAutoComplete).tryComplete();
expect(model.parts.length).toBe(1);
expect(model.parts[0].type).toBe("room-pill");
expect(model.parts[0].text).toBe("#riot-dev");
});
});
describe("emojis", function () {
it("regional emojis should be separated to prevent them to be converted to flag", () => {