From 6a026c6439fb015fa145d50d729c44701126b3b9 Mon Sep 17 00:00:00 2001 From: Chris Svenningsen Date: Mon, 26 Oct 2020 17:13:49 -0700 Subject: [PATCH] Fix emoji completion; don't show when typing times * Do not pop picker in timestamps * Fix timestamp triggering emoji picker Co-authored-by: Sidney Keese --- ts/quill/emoji/completion.tsx | 7 ++- ts/test/quill/emoji/completion_test.tsx | 58 +++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/ts/quill/emoji/completion.tsx b/ts/quill/emoji/completion.tsx index f84bc3dcc18e..85a92bea0744 100644 --- a/ts/quill/emoji/completion.tsx +++ b/ts/quill/emoji/completion.tsx @@ -1,6 +1,7 @@ import Quill from 'quill'; import Delta from 'quill-delta'; import React from 'react'; +import _ from 'lodash'; import { Popper } from 'react-popper'; import classNames from 'classnames'; @@ -91,7 +92,7 @@ export class EmojiCompletion { this.quill.keyboard.addBinding({ key: 39 }, clearResults); // 39 = Right this.quill.keyboard.addBinding({ key: 40 }, changeIndex(1)); // 40 = Down - this.quill.on('text-change', this.onTextChange.bind(this)); + this.quill.on('text-change', _.debounce(this.onTextChange.bind(this), 100)); } destroy(): void { @@ -127,7 +128,9 @@ export class EmojiCompletion { const [leftLeafText, rightLeafText] = this.getCurrentLeafTextPartitions(); - const leftTokenTextMatch = /:([-+0-9a-z_]*)(:?)$/.exec(leftLeafText); + const leftTokenTextMatch = /(?<=^|\s):([-+0-9a-z_]*)(:?)$/.exec( + leftLeafText + ); const rightTokenTextMatch = /^([-+0-9a-z_]*):/.exec(rightLeafText); if (!leftTokenTextMatch) { diff --git a/ts/test/quill/emoji/completion_test.tsx b/ts/test/quill/emoji/completion_test.tsx index 2e1218efa453..1dc9c8ff6035 100644 --- a/ts/test/quill/emoji/completion_test.tsx +++ b/ts/test/quill/emoji/completion_test.tsx @@ -116,6 +116,27 @@ describe('emojiCompletion', () => { }); }); + describe('given a colon in a string (but not an emoji)', () => { + beforeEach(function beforeEach() { + mockQuill.getSelection.returns({ + index: 5, + length: 0, + }); + + const blot = { + text: '10:30', + }; + mockQuill.getLeaf.returns([blot, 5]); + + emojiCompletion.onTextChange(); + }); + + it('resets the completion', () => { + assert.equal(emojiCompletion.results.length, 0); + assert.equal(emojiCompletion.index, 0); + }); + }); + describe('given an emoji is starting but does not have 2 characters', () => { beforeEach(function beforeEach() { mockQuill.getSelection.returns({ @@ -213,6 +234,43 @@ describe('emojiCompletion', () => { }); }); + describe('and given it matches a short name inside a larger string', () => { + const text = 'have a :smile: nice day'; + + beforeEach(function beforeEach() { + const blot = { + text, + }; + mockQuill.getSelection.returns({ + index: 13, + length: 0, + }); + mockQuill.getLeaf.returns([blot, 13]); + + emojiCompletion.onTextChange(); + }); + + it('inserts the emoji at the current cursor position', () => { + const [emoji, index, range] = insertEmojiStub.args[0]; + + assert.equal(emoji.short_name, 'smile'); + assert.equal(index, 7); + assert.equal(range, 7); + }); + + it('resets the completion', () => { + assert.equal(emojiCompletion.results.length, 0); + assert.equal(emojiCompletion.index, 0); + }); + + it('sets the quill selection to the right cursor position', () => { + const [index, range] = mockQuill.setSelection.args[0]; + + assert.equal(index, 8); + assert.equal(range, 0); + }); + }); + describe('and given it does not match a short name', () => { const text = ':smyle:';