Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Fix autocomplete not resetting properly on message send #10741

Merged
merged 1 commit into from
Apr 28, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/editor/model.ts
Original file line number Diff line number Diff line change
@@ -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;
}
}
4 changes: 2 additions & 2 deletions test/editor/mock.ts
Original file line number Diff line number Diff line change
@@ -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 {
50 changes: 43 additions & 7 deletions test/editor/model-test.ts
Original file line number Diff line number Diff line change
@@ -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", () => {