mirror of https://github.com/vector-im/riot-web
Fix autocomplete not resetting properly on message send (#10741)
parent
0d1020c66f
commit
f819853cad
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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", () => {
|
||||
|
|
Loading…
Reference in New Issue