Commit 22b2875b authored by JC Brand's avatar JC Brand

emoji-picker: Move picker content into another component

to avoid re-rendering them when non-relevant properties change
parent bec476b6
...@@ -54,11 +54,11 @@ describe("Emojis", function () { ...@@ -54,11 +54,11 @@ describe("Emojis", function () {
} }
view.onKeyDown(tab_event); view.onKeyDown(tab_event);
await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists'))); await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists')));
let picker = await u.waitUntil(() => view.el.querySelector('.emoji-picker__container')); const picker = await u.waitUntil(() => view.el.querySelector('.emoji-picker__container'));
const input = picker.querySelector('.emoji-search'); const input = picker.querySelector('.emoji-search');
expect(input.value).toBe(':gri'); expect(input.value).toBe(':gri');
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji', picker).length === 3, 1000);
let visible_emojis = sizzle('.emojis-lists__container--search .insert-emoji', picker); let visible_emojis = sizzle('.emojis-lists__container--search .insert-emoji', picker);
expect(visible_emojis.length).toBe(3);
expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':grimacing:'); expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':grimacing:');
expect(visible_emojis[1].getAttribute('data-emoji')).toBe(':grin:'); expect(visible_emojis[1].getAttribute('data-emoji')).toBe(':grin:');
expect(visible_emojis[2].getAttribute('data-emoji')).toBe(':grinning:'); expect(visible_emojis[2].getAttribute('data-emoji')).toBe(':grinning:');
...@@ -66,8 +66,8 @@ describe("Emojis", function () { ...@@ -66,8 +66,8 @@ describe("Emojis", function () {
// Test that TAB autocompletes the to first match // Test that TAB autocompletes the to first match
input.dispatchEvent(new KeyboardEvent('keydown', tab_event)); input.dispatchEvent(new KeyboardEvent('keydown', tab_event));
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji', picker).length === 1); await u.waitUntil(() => sizzle(".emojis-lists__container--search .insert-emoji:not('.hidden')", picker).length === 1, 1000);
visible_emojis = sizzle('.emojis-lists__container--search .insert-emoji', picker); visible_emojis = sizzle(".emojis-lists__container--search .insert-emoji:not('.hidden')", picker);
expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':grimacing:'); expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':grimacing:');
expect(input.value).toBe(':grimacing:'); expect(input.value).toBe(':grimacing:');
...@@ -95,8 +95,7 @@ describe("Emojis", function () { ...@@ -95,8 +95,7 @@ describe("Emojis", function () {
textarea.value = ':use'; textarea.value = ':use';
view.onKeyDown(tab_event); view.onKeyDown(tab_event);
await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists'))); await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists')));
picker = await u.waitUntil(() => view.el.querySelector('.emoji-picker__container')); await u.waitUntil(() => input.value === ':use');
expect(input.value).toBe(':use');
visible_emojis = sizzle('.insert-emoji:not(.hidden)', picker); visible_emojis = sizzle('.insert-emoji:not(.hidden)', picker);
expect(visible_emojis.length).toBe(0); expect(visible_emojis.length).toBe(0);
done(); done();
...@@ -129,8 +128,8 @@ describe("Emojis", function () { ...@@ -129,8 +128,8 @@ describe("Emojis", function () {
input.dispatchEvent(new KeyboardEvent('keydown', event)); input.dispatchEvent(new KeyboardEvent('keydown', event));
await u.waitUntil(() => view.emoji_picker_view.model.get('query') === 'smiley', 1000); await u.waitUntil(() => view.emoji_picker_view.model.get('query') === 'smiley', 1000);
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji', picker).length === 2, 1000);
let visible_emojis = sizzle('.emojis-lists__container--search .insert-emoji', picker); let visible_emojis = sizzle('.emojis-lists__container--search .insert-emoji', picker);
expect(visible_emojis.length).toBe(2);
expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':smiley:'); expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':smiley:');
expect(visible_emojis[1].getAttribute('data-emoji')).toBe(':smiley_cat:'); expect(visible_emojis[1].getAttribute('data-emoji')).toBe(':smiley_cat:');
...@@ -144,8 +143,8 @@ describe("Emojis", function () { ...@@ -144,8 +143,8 @@ describe("Emojis", function () {
input.dispatchEvent(new KeyboardEvent('keydown', tab_event)); input.dispatchEvent(new KeyboardEvent('keydown', tab_event));
await u.waitUntil(() => input.value === ':smiley:'); await u.waitUntil(() => input.value === ':smiley:');
visible_emojis = sizzle('.emojis-lists__container--search .insert-emoji', picker); await u.waitUntil(() => sizzle(".emojis-lists__container--search .insert-emoji:not('.hidden')", picker).length === 1);
expect(visible_emojis.length).toBe(1); visible_emojis = sizzle(".emojis-lists__container--search .insert-emoji:not('.hidden')", picker);
expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':smiley:'); expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':smiley:');
// Check that ENTER now inserts the match // Check that ENTER now inserts the match
......
This diff is collapsed.
...@@ -18,26 +18,26 @@ const emoji_category = (o) => { ...@@ -18,26 +18,26 @@ const emoji_category = (o) => {
<a class="pick-category" <a class="pick-category"
@click=${o.onCategoryPicked} @click=${o.onCategoryPicked}
href="#emoji-picker-${o.category}" href="#emoji-picker-${o.category}"
data-category="${o.category}">${o.transformCategory(o.emoji_categories[o.category])} </a> data-category="${o.category}">${o.emoji} </a>
</li> </li>
`; `;
} }
const emoji_picker_header = (o) => html` const emoji_picker_header = (o) => {
<ul> const cats = api.settings.get('emoji_categories');
${ Object.keys(o.emoji_categories).map(category => (o.emoji_categories[category] ? emoji_category(Object.assign({category}, o)) : '')) } const transform = c => cats[c] ? emoji_category(Object.assign({'category': c, 'emoji': o.sn2Emoji(cats[c])}, o)) : '';
</ul> return html`<ul>${ Object.keys(cats).map(transform) }</ul>`;
`; }
const emoji_item = (o) => { const emoji_item = (o) => {
return html` return html`
<li class="emoji insert-emoji ${o.shouldBeHidden(o.emoji.sn) ? 'hidden' : ''}" data-emoji="${o.emoji.sn}" title="${o.emoji.sn}"> <li class="emoji insert-emoji ${o.shouldBeHidden(o.emoji.sn) ? 'hidden' : ''}" data-emoji="${o.emoji.sn}" title="${o.emoji.sn}">
<a href="#" @click=${o.onEmojiPicked} data-emoji="${o.emoji.sn}">${u.shortnamesToEmojis(o.emoji.sn)}</a> <a href="#" @click=${o.insertEmoji} data-emoji="${o.emoji.sn}">${u.shortnamesToEmojis(o.emoji.sn)}</a>
</li> </li>
`; `;
} }
const search_results = (o) => html` export const tpl_search_results = (o) => html`
<span ?hidden=${!o.query} class="emoji-lists__container emojis-lists__container--search"> <span ?hidden=${!o.query} class="emoji-lists__container emojis-lists__container--search">
<a id="emoji-picker-search-results" class="emoji-category__heading">${i18n_search_results}</a> <a id="emoji-picker-search-results" class="emoji-category__heading">${i18n_search_results}</a>
<ul class="emoji-picker"> <ul class="emoji-picker">
...@@ -46,33 +46,33 @@ const search_results = (o) => html` ...@@ -46,33 +46,33 @@ const search_results = (o) => html`
</span> </span>
`; `;
const emojis_for_category = (o) => html` const emojis_for_category = (o) => {
<a id="emoji-picker-${o.category}" class="emoji-category__heading" data-category="${o.category}">${ __(api.settings.get('emoji_category_labels')[o.category]) }</a> const emojis_by_category = _converse.emojis.json;
<ul class="emoji-picker" data-category="${o.category}"> return html`
${ Object.values(o.emojis_by_category[o.category]).map(emoji => emoji_item(Object.assign({emoji}, o))) } <a id="emoji-picker-${o.category}" class="emoji-category__heading" data-category="${o.category}">${ __(api.settings.get('emoji_category_labels')[o.category]) }</a>
</ul> <ul class="emoji-picker" data-category="${o.category}">
`; ${ Object.values(emojis_by_category[o.category]).map(emoji => emoji_item(Object.assign({emoji}, o))) }
</ul>`;
}
export const tpl_all_emojis = (o) => {
const cats = api.settings.get('emoji_categories');
return html`
<span ?hidden=${o.query} class="emoji-lists__container emoji-lists__container--browse">
${Object.keys(cats).map(c => (cats[c] ? emojis_for_category(Object.assign({'category': c}, o)) : ''))}
</span>`;
}
const skintone_emoji = (o) => { const skintone_emoji = (o) => {
return html` return html`
<li data-skintone="${o.skintone}" class="emoji-skintone ${(o.current_skintone === o.skintone) ? 'picked' : ''}"> <li data-skintone="${o.skintone}" class="emoji-skintone ${(o.current_skintone === o.skintone) ? 'picked' : ''}">
<a class="pick-skintone" href="#" data-skintone="${o.skintone}" @click=${o.onSkintonePicked}>${u.shortnamesToEmojis(':'+o.skintone+':')}</a> <a class="pick-skintone" href="#" data-skintone="${o.skintone}" @click=${o.onSkintonePicked}>${u.shortnamesToEmojis(':'+o.skintone+':')}</a>
</li> </li>`;
`;
} }
const all_emojis = (o) => html`
<span ?hidden=${o.query} class="emoji-lists__container emoji-lists__container--browse">
${Object.keys(o.emoji_categories).map(category => (o.emoji_categories[category] ? emojis_for_category(Object.assign({category}, o)) : ''))}
</span>
`;
export default (o) => {
o.emoji_categories = api.settings.get('emoji_categories');
o.emojis_by_category = _converse.emojis.json;
o.toned_emojis = _converse.emojis.toned;
export const tpl_emoji_picker = (o) => {
return html` return html`
<div class="emoji-picker__header"> <div class="emoji-picker__header">
<input class="form-control emoji-search" name="emoji-search" placeholder="${i18n_search}" <input class="form-control emoji-search" name="emoji-search" placeholder="${i18n_search}"
...@@ -82,10 +82,14 @@ export default (o) => { ...@@ -82,10 +82,14 @@ export default (o) => {
@focus=${o.onSearchInputFocus}> @focus=${o.onSearchInputFocus}>
${ o.query ? '' : emoji_picker_header(o) } ${ o.query ? '' : emoji_picker_header(o) }
</div> </div>
<div class="emoji-picker__lists"> <converse-emoji-picker-content
${search_results(o)} .chatview=${o.chatview}
${all_emojis(o)} .model=${o.model}
</div> .search_results="${o.search_results}"
current_skintone="${o.current_skintone}"
query="${o.query}"
></converse-emoji-picker-content>
<div class="emoji-skintone-picker"> <div class="emoji-skintone-picker">
<label>Skin tone</label> <label>Skin tone</label>
<ul>${ skintones.map(skintone => skintone_emoji(Object.assign({skintone}, o))) }</ul> <ul>${ skintones.map(skintone => skintone_emoji(Object.assign({skintone}, o))) }</ul>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment