Преглед на файлове

Emoji picker: properly insert emoji upon click

JC Brand преди 5 години
родител
ревизия
e6d8634194
променени са 4 файла, в които са добавени 58 реда и са изтрити 12 реда
  1. 45 1
      spec/emojis.js
  2. 1 4
      src/components/emoji-picker-content.js
  3. 3 1
      src/components/emoji-picker.js
  4. 9 6
      src/converse-chatview.js

+ 45 - 1
spec/emojis.js

@@ -99,7 +99,51 @@ describe("Emojis", function () {
             done();
             done();
         }));
         }));
 
 
-        fit("allows you to search for particular emojis",
+        it("properly inserts emojis into the chat 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 = ':gri';
+
+            // Press tab
+            const tab_event = {
+                'target': textarea,
+                'preventDefault': function preventDefault () {},
+                'stopPropagation': function stopPropagation () {},
+                'keyCode': 9,
+                'key': 'Tab'
+            }
+            textarea.value = ':';
+            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');
+            input.dispatchEvent(new KeyboardEvent('keydown', tab_event));
+            await u.waitUntil(() => input.value === ':100:');
+            const enter_event = Object.assign({}, tab_event, {'keyCode': 13, 'key': 'Enter', 'target': input});
+            input.dispatchEvent(new KeyboardEvent('keydown', enter_event));
+            expect(textarea.value).toBe(':100:');
+
+            textarea.value = ':';
+            view.onKeyDown(tab_event);
+            await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists')));
+            input.dispatchEvent(new KeyboardEvent('keydown', tab_event));
+            await u.waitUntil(() => input.value === ':100:');
+            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();
+            emoji.click();
+            expect(textarea.value).toBe(':100:');
+            done();
+        }));
+
+
+        it("allows you to search for particular emojis",
             mock.initConverse(
             mock.initConverse(
                 ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {

+ 1 - 4
src/components/emoji-picker-content.js

@@ -77,10 +77,7 @@ export default class EmojiPickerContent extends CustomElement {
       ev.preventDefault();
       ev.preventDefault();
       ev.stopPropagation();
       ev.stopPropagation();
       const target = ev.target.nodeName === 'IMG' ? ev.target.parentElement : ev.target;
       const target = ev.target.nodeName === 'IMG' ? ev.target.parentElement : ev.target;
-      const replace = this.model.get('autocompleting');
-      const position = this.model.get('position');
-      this.model.set({'autocompleting': null, 'position': null, 'query': ''});
-      this.chatview.insertIntoTextArea(target.getAttribute('data-emoji'), replace, false, position);
+      this.parentElement.insertIntoTextArea(target.getAttribute('data-emoji'));
   }
   }
 
 
   shouldBeHidden (shortname) {
   shouldBeHidden (shortname) {

+ 3 - 1
src/components/emoji-picker.js

@@ -140,7 +140,7 @@ export default class EmojiPicker extends CustomElement {
 
 
     insertIntoTextArea (value) {
     insertIntoTextArea (value) {
         this.chatview.onEmojiReceivedFromPicker(value);
         this.chatview.onEmojiReceivedFromPicker(value);
-        this.model.set({'query': ''});
+        this.model.set({'autocompleting': null, 'query': '', 'ac_position': null});
     }
     }
 
 
     chooseSkinTone (ev) {
     chooseSkinTone (ev) {
@@ -279,6 +279,8 @@ export class EmojiDropdown extends BaseDropdown {
                 this.model = new _converse.EmojiPicker({'id': id});
                 this.model = new _converse.EmojiPicker({'id': id});
                 this.model.browserStorage = _converse.createStore(id);
                 this.model.browserStorage = _converse.createStore(id);
                 await new Promise(resolve => this.model.fetch({'success': resolve, 'error': resolve}));
                 await new Promise(resolve => this.model.fetch({'success': resolve, 'error': resolve}));
+                // We never want still be in the autocompleting state upon page load
+                this.model.set({'autocompleting': null, 'ac_position': null});
             })();
             })();
         }
         }
         return this.init_promise;
         return this.init_promise;

+ 9 - 6
src/converse-chatview.js

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