Emoji picker fixes

- Don't replace entire textarea when entering a second emoji
- Focus emoji picker on tab completion when it's already opened
This commit is contained in:
JC Brand 2020-07-14 10:51:16 +02:00
parent 4de9816f24
commit 282ffc622f
3 changed files with 57 additions and 9 deletions

View File

@ -74,7 +74,7 @@ describe("Emojis", function () {
input.dispatchEvent(new KeyboardEvent('keydown', enter_event)); input.dispatchEvent(new KeyboardEvent('keydown', enter_event));
await u.waitUntil(() => input.value === ''); await u.waitUntil(() => input.value === '');
await u.waitUntil(() => textarea.value === ':grimacing:'); await u.waitUntil(() => textarea.value === ':grimacing: ');
// Test that username starting with : doesn't cause issues // Test that username starting with : doesn't cause issues
const presence = $pres({ const presence = $pres({
@ -99,6 +99,56 @@ describe("Emojis", function () {
done(); done();
})); }));
it("is focused to autocomplete emojis in the textarea",
mock.initConverse(
['rosterGroupsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const view = _converse.chatboxviews.get(muc_jid);
const textarea = view.el.querySelector('textarea.chat-textarea');
textarea.value = ':';
// Press tab
const tab_event = {
'target': textarea,
'preventDefault': function preventDefault () {},
'stopPropagation': function stopPropagation () {},
'keyCode': 9,
'key': 'Tab'
}
view.onKeyDown(tab_event);
await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists')));
const picker = view.el.querySelector('converse-emoji-picker');
const input = picker.querySelector('.emoji-search');
expect(input.value).toBe(':');
input.value = ':gri';
const event = {
'target': input,
'preventDefault': function preventDefault () {},
'stopPropagation': function stopPropagation () {}
};
input.dispatchEvent(new KeyboardEvent('keydown', event));
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji', view.el).length === 3, 1000);
let emoji = sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden) a', view.el).pop();
emoji.click();
await u.waitUntil(() => textarea.value === ':grinning: ');
textarea.value = ':grinning: :';
view.onKeyDown(tab_event);
await u.waitUntil(() => input.value === ':');
input.value = ':grimacing';
input.dispatchEvent(new KeyboardEvent('keydown', event));
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji', view.el).length === 1, 1000);
emoji = sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden) a', view.el).pop();
emoji.click();
await u.waitUntil(() => textarea.value === ':grinning: :grimacing: ');
done();
}));
it("properly inserts emojis into the chat textarea", it("properly inserts emojis into the chat textarea",
mock.initConverse( mock.initConverse(
['rosterGroupsFetched', 'chatBoxesFetched'], {}, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
@ -128,7 +178,7 @@ describe("Emojis", function () {
await u.waitUntil(() => input.value === ':100:'); await u.waitUntil(() => input.value === ':100:');
const enter_event = Object.assign({}, tab_event, {'keyCode': 13, 'key': 'Enter', 'target': input}); const enter_event = Object.assign({}, tab_event, {'keyCode': 13, 'key': 'Enter', 'target': input});
input.dispatchEvent(new KeyboardEvent('keydown', enter_event)); input.dispatchEvent(new KeyboardEvent('keydown', enter_event));
expect(textarea.value).toBe(':100:'); expect(textarea.value).toBe(':100: ');
textarea.value = ':'; textarea.value = ':';
view.onKeyDown(tab_event); view.onKeyDown(tab_event);
@ -138,7 +188,7 @@ describe("Emojis", function () {
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden)', view.el).length === 1, 1000); await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden)', view.el).length === 1, 1000);
const emoji = sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden) a', view.el).pop(); const emoji = sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden) a', view.el).pop();
emoji.click(); emoji.click();
expect(textarea.value).toBe(':100:'); expect(textarea.value).toBe(':100: ');
done(); done();
})); }));

View File

@ -724,10 +724,10 @@ converse.plugins.add('converse-chatview', {
if (emoji_picker && emoji_dropdown) { if (emoji_picker && emoji_dropdown) {
emoji_picker.model.set({ emoji_picker.model.set({
'ac_position': input.selectionStart, 'ac_position': input.selectionStart,
'autocompleting': true, 'autocompleting': value,
'query': value 'query': value
}); });
emoji_dropdown.firstElementChild.click(); emoji_dropdown.showMenu();
return true; return true;
} }
}, },
@ -736,7 +736,7 @@ converse.plugins.add('converse-chatview', {
const model = this.el.querySelector('converse-emoji-picker').model; const model = this.el.querySelector('converse-emoji-picker').model;
const autocompleting = model.get('autocompleting'); const autocompleting = model.get('autocompleting');
const ac_position = model.get('ac_position'); const ac_position = model.get('ac_position');
this.insertIntoTextArea(emoji, !!autocompleting, false, ac_position); this.insertIntoTextArea(emoji, autocompleting, false, ac_position);
}, },
/** /**

View File

@ -498,9 +498,7 @@ converse.plugins.add('converse-minimize', {
}); });
function initMinimizedChats () { function initMinimizedChats () {
if (_converse.minimized_chats) { _converse.minimized_chats?.remove();
_converse.minimized_chats.remove();
}
_converse.minimized_chats = new _converse.MinimizedChats({model: _converse.chatboxes}); _converse.minimized_chats = new _converse.MinimizedChats({model: _converse.chatboxes});
/** /**
* Triggered once the _converse.MinimizedChats instance has been initialized * Triggered once the _converse.MinimizedChats instance has been initialized