Emoji picker: make sure search results get properly updated

This commit is contained in:
JC Brand 2020-07-13 09:55:01 +02:00
parent 43ccc09cf2
commit 756a85fb53
2 changed files with 28 additions and 9 deletions

View File

@ -1,9 +1,10 @@
/*global mock */
/*global mock, converse */
const { Promise, $msg, $pres, sizzle } = converse.env;
const u = converse.env.utils;
const original_timeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
describe("Emojis", function () {
describe("The emoji picker", function () {
@ -98,7 +99,7 @@ describe("Emojis", function () {
done();
}));
it("allows you to search for particular emojis",
fit("allows you to search for particular emojis",
mock.initConverse(
['rosterGroupsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
@ -131,6 +132,15 @@ describe("Emojis", function () {
input.dispatchEvent(new KeyboardEvent('keydown', enter_event));
expect(input.value).toBe('smiley');
// Check that search results update when chars are deleted
input.value = 'sm';
input.dispatchEvent(new KeyboardEvent('keydown', event));
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden)', view.el).length === 25, 1000);
input.value = 'smiley';
input.dispatchEvent(new KeyboardEvent('keydown', event));
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden)', view.el).length === 2, 1000);
// Test that TAB autocompletes the to first match
const tab_event = Object.assign({}, event, {'keyCode': 9, 'key': 'Tab'});
input.dispatchEvent(new KeyboardEvent('keydown', tab_event));

View File

@ -33,13 +33,22 @@ export default class EmojiPicker extends CustomElement {
constructor () {
super();
this.search_results = [];
this._search_results = [];
this.debouncedFilter = debounce(input => this.model.set({'query': input.value}), 250);
this.onGlobalKeyDown = ev => this._onGlobalKeyDown(ev);
const body = document.querySelector('body');
body.addEventListener('keydown', this.onGlobalKeyDown);
}
get search_results () {
return this._search_results;
}
set search_results (value) {
this._search_results = value;
this.requestUpdate();
}
render () {
return tpl_emoji_picker({
'chatview': this.chatview,
@ -59,7 +68,7 @@ export default class EmojiPicker extends CustomElement {
}
updated (changed) {
changed.has('query') && this.updateSearchResults();
changed.has('query') && this.updateSearchResults(changed);
changed.has('current_category') && this.setScrollPosition();
}
@ -82,22 +91,22 @@ export default class EmojiPicker extends CustomElement {
}
}
updateSearchResults () {
updateSearchResults (changed) {
const old_query = changed.get('query');
const contains = _converse.FILTER_CONTAINS;
if (this.query) {
if (this.query === this.old_query) {
if (this.query === old_query) {
return this.search_results;
} else if (this.old_query && this.query.includes(this.old_query)) {
} else if (old_query && this.query.includes(old_query)) {
this.search_results = this.search_results.filter(e => contains(e.sn, this.query));
} else {
this.search_results = converse.emojis.list.filter(e => contains(e.sn, this.query));
}
this.old_query = this.query;
} else if (this.search_results.length) {
// Avoid re-rendering by only setting to new empty array if it wasn't empty before
this.search_results = [];
}
return this.search_results;
this.requestUpdate();
}
disconnectedCallback() {