Commit f26d4778 authored by Mike Greiling's avatar Mike Greiling

dynamically import emoji helpers for AwardsHandler class

parent 3f3993c3
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
/* global Flash */ /* global Flash */
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import * as Emoji from './emoji';
const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd'; const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';
const transitionEndEventString = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd'; const transitionEndEventString = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd';
...@@ -24,27 +23,9 @@ const categoryLabelMap = { ...@@ -24,27 +23,9 @@ const categoryLabelMap = {
flags: 'Flags', flags: 'Flags',
}; };
function renderCategory(name, emojiList, opts = {}) { class AwardsHandler {
return ` constructor(emoji) {
<h5 class="emoji-menu-title"> this.emoji = emoji;
${name}
</h5>
<ul class="clearfix emoji-menu-list ${opts.menuListClass || ''}">
${emojiList.map(emojiName => `
<li class="emoji-menu-list-item">
<button class="emoji-menu-btn text-center js-emoji-btn" type="button">
${Emoji.glEmojiTag(emojiName, {
sprite: true,
})}
</button>
</li>
`).join('\n')}
</ul>
`;
}
export default class AwardsHandler {
constructor() {
this.eventListeners = []; this.eventListeners = [];
// If the user shows intent let's pre-build the menu // If the user shows intent let's pre-build the menu
this.registerEventListener('one', $(document), 'mouseenter focus', '.js-add-award', 'mouseenter focus', () => { this.registerEventListener('one', $(document), 'mouseenter focus', '.js-add-award', 'mouseenter focus', () => {
...@@ -78,10 +59,10 @@ export default class AwardsHandler { ...@@ -78,10 +59,10 @@ export default class AwardsHandler {
const $target = $(e.currentTarget); const $target = $(e.currentTarget);
const $glEmojiElement = $target.find('gl-emoji'); const $glEmojiElement = $target.find('gl-emoji');
const $spriteIconElement = $target.find('.icon'); const $spriteIconElement = $target.find('.icon');
const emoji = ($glEmojiElement.length ? $glEmojiElement : $spriteIconElement).data('name'); const emojiName = ($glEmojiElement.length ? $glEmojiElement : $spriteIconElement).data('name');
$target.closest('.js-awards-block').addClass('current'); $target.closest('.js-awards-block').addClass('current');
this.addAward(this.getVotesBlock(), this.getAwardUrl(), emoji); this.addAward(this.getVotesBlock(), this.getAwardUrl(), emojiName);
}); });
} }
...@@ -139,16 +120,16 @@ export default class AwardsHandler { ...@@ -139,16 +120,16 @@ export default class AwardsHandler {
this.isCreatingEmojiMenu = true; this.isCreatingEmojiMenu = true;
// Render the first category // Render the first category
const categoryMap = Emoji.getEmojiCategoryMap(); const categoryMap = this.emoji.getEmojiCategoryMap();
const categoryNameKey = Object.keys(categoryMap)[0]; const categoryNameKey = Object.keys(categoryMap)[0];
const emojisInCategory = categoryMap[categoryNameKey]; const emojisInCategory = categoryMap[categoryNameKey];
const firstCategory = renderCategory(categoryLabelMap[categoryNameKey], emojisInCategory); const firstCategory = this.renderCategory(categoryLabelMap[categoryNameKey], emojisInCategory);
// Render the frequently used // Render the frequently used
const frequentlyUsedEmojis = this.getFrequentlyUsedEmojis(); const frequentlyUsedEmojis = this.getFrequentlyUsedEmojis();
let frequentlyUsedCatgegory = ''; let frequentlyUsedCatgegory = '';
if (frequentlyUsedEmojis.length > 0) { if (frequentlyUsedEmojis.length > 0) {
frequentlyUsedCatgegory = renderCategory('Frequently used', frequentlyUsedEmojis, { frequentlyUsedCatgegory = this.renderCategory('Frequently used', frequentlyUsedEmojis, {
menuListClass: 'frequent-emojis', menuListClass: 'frequent-emojis',
}); });
} }
...@@ -179,7 +160,7 @@ export default class AwardsHandler { ...@@ -179,7 +160,7 @@ export default class AwardsHandler {
} }
this.isAddingRemainingEmojiMenuCategories = true; this.isAddingRemainingEmojiMenuCategories = true;
const categoryMap = Emoji.getEmojiCategoryMap(); const categoryMap = this.emoji.getEmojiCategoryMap();
// Avoid the jank and render the remaining categories separately // Avoid the jank and render the remaining categories separately
// This will take more time, but makes UI more responsive // This will take more time, but makes UI more responsive
...@@ -191,7 +172,7 @@ export default class AwardsHandler { ...@@ -191,7 +172,7 @@ export default class AwardsHandler {
promiseChain.then(() => promiseChain.then(() =>
new Promise((resolve) => { new Promise((resolve) => {
const emojisInCategory = categoryMap[categoryNameKey]; const emojisInCategory = categoryMap[categoryNameKey];
const categoryMarkup = renderCategory( const categoryMarkup = this.renderCategory(
categoryLabelMap[categoryNameKey], categoryLabelMap[categoryNameKey],
emojisInCategory, emojisInCategory,
); );
...@@ -216,6 +197,25 @@ export default class AwardsHandler { ...@@ -216,6 +197,25 @@ export default class AwardsHandler {
}); });
} }
renderCategory(name, emojiList, opts = {}) {
return `
<h5 class="emoji-menu-title">
${name}
</h5>
<ul class="clearfix emoji-menu-list ${opts.menuListClass || ''}">
${emojiList.map(emojiName => `
<li class="emoji-menu-list-item">
<button class="emoji-menu-btn text-center js-emoji-btn" type="button">
${this.emoji.glEmojiTag(emojiName, {
sprite: true,
})}
</button>
</li>
`).join('\n')}
</ul>
`;
}
positionMenu($menu, $addBtn) { positionMenu($menu, $addBtn) {
const position = $addBtn.data('position'); const position = $addBtn.data('position');
// The menu could potentially be off-screen or in a hidden overflow element // The menu could potentially be off-screen or in a hidden overflow element
...@@ -234,7 +234,7 @@ export default class AwardsHandler { ...@@ -234,7 +234,7 @@ export default class AwardsHandler {
} }
addAward(votesBlock, awardUrl, emoji, checkMutuality, callback) { addAward(votesBlock, awardUrl, emoji, checkMutuality, callback) {
const normalizedEmoji = Emoji.normalizeEmojiName(emoji); const normalizedEmoji = this.emoji.normalizeEmojiName(emoji);
const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent(); const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent();
this.postEmoji($emojiButton, awardUrl, normalizedEmoji, () => { this.postEmoji($emojiButton, awardUrl, normalizedEmoji, () => {
this.addAwardToEmojiBar(votesBlock, normalizedEmoji, checkMutuality); this.addAwardToEmojiBar(votesBlock, normalizedEmoji, checkMutuality);
...@@ -249,7 +249,7 @@ export default class AwardsHandler { ...@@ -249,7 +249,7 @@ export default class AwardsHandler {
this.checkMutuality(votesBlock, emoji); this.checkMutuality(votesBlock, emoji);
} }
this.addEmojiToFrequentlyUsedList(emoji); this.addEmojiToFrequentlyUsedList(emoji);
const normalizedEmoji = Emoji.normalizeEmojiName(emoji); const normalizedEmoji = this.emoji.normalizeEmojiName(emoji);
const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent(); const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent();
if ($emojiButton.length > 0) { if ($emojiButton.length > 0) {
if (this.isActive($emojiButton)) { if (this.isActive($emojiButton)) {
...@@ -374,7 +374,7 @@ export default class AwardsHandler { ...@@ -374,7 +374,7 @@ export default class AwardsHandler {
createAwardButtonForVotesBlock(votesBlock, emojiName) { createAwardButtonForVotesBlock(votesBlock, emojiName) {
const buttonHtml = ` const buttonHtml = `
<button class="btn award-control js-emoji-btn has-tooltip active" title="You" data-placement="bottom"> <button class="btn award-control js-emoji-btn has-tooltip active" title="You" data-placement="bottom">
${Emoji.glEmojiTag(emojiName)} ${this.emoji.glEmojiTag(emojiName)}
<span class="award-control-text js-counter">1</span> <span class="award-control-text js-counter">1</span>
</button> </button>
`; `;
...@@ -440,7 +440,7 @@ export default class AwardsHandler { ...@@ -440,7 +440,7 @@ export default class AwardsHandler {
} }
addEmojiToFrequentlyUsedList(emoji) { addEmojiToFrequentlyUsedList(emoji) {
if (Emoji.isEmojiNameValid(emoji)) { if (this.emoji.isEmojiNameValid(emoji)) {
this.frequentlyUsedEmojis = _.uniq(this.getFrequentlyUsedEmojis().concat(emoji)); this.frequentlyUsedEmojis = _.uniq(this.getFrequentlyUsedEmojis().concat(emoji));
Cookies.set('frequently_used_emojis', this.frequentlyUsedEmojis.join(','), { expires: 365 }); Cookies.set('frequently_used_emojis', this.frequentlyUsedEmojis.join(','), { expires: 365 });
} }
...@@ -450,7 +450,7 @@ export default class AwardsHandler { ...@@ -450,7 +450,7 @@ export default class AwardsHandler {
return this.frequentlyUsedEmojis || (() => { return this.frequentlyUsedEmojis || (() => {
const frequentlyUsedEmojis = _.uniq((Cookies.get('frequently_used_emojis') || '').split(',')); const frequentlyUsedEmojis = _.uniq((Cookies.get('frequently_used_emojis') || '').split(','));
this.frequentlyUsedEmojis = frequentlyUsedEmojis.filter( this.frequentlyUsedEmojis = frequentlyUsedEmojis.filter(
inputName => Emoji.isEmojiNameValid(inputName), inputName => this.emoji.isEmojiNameValid(inputName),
); );
return this.frequentlyUsedEmojis; return this.frequentlyUsedEmojis;
...@@ -493,7 +493,7 @@ export default class AwardsHandler { ...@@ -493,7 +493,7 @@ export default class AwardsHandler {
} }
findMatchingEmojiElements(query) { findMatchingEmojiElements(query) {
const emojiMatches = Emoji.filterEmojiNamesByAlias(query); const emojiMatches = this.emoji.filterEmojiNamesByAlias(query);
const $emojiElements = $('.emoji-menu-list:not(.frequent-emojis) [data-name]'); const $emojiElements = $('.emoji-menu-list:not(.frequent-emojis) [data-name]');
const $matchingElements = $emojiElements const $matchingElements = $emojiElements
.filter((i, elm) => emojiMatches.indexOf(elm.dataset.name) >= 0); .filter((i, elm) => emojiMatches.indexOf(elm.dataset.name) >= 0);
...@@ -507,3 +507,12 @@ export default class AwardsHandler { ...@@ -507,3 +507,12 @@ export default class AwardsHandler {
$('.emoji-menu').remove(); $('.emoji-menu').remove();
} }
} }
let awardsHandlerPromise = null;
export default function loadAwardsHandler(reload = false) {
if (!awardsHandlerPromise || reload) {
awardsHandlerPromise = import(/* webpackChunkName: 'emoji' */ './emoji')
.then(Emoji => new AwardsHandler(Emoji));
}
return awardsHandlerPromise;
}
...@@ -70,7 +70,7 @@ import './ajax_loading_spinner'; ...@@ -70,7 +70,7 @@ import './ajax_loading_spinner';
import './api'; import './api';
import './aside'; import './aside';
import './autosave'; import './autosave';
import AwardsHandler from './awards_handler'; import loadAwardsHandler from './awards_handler';
import './breakpoints'; import './breakpoints';
import './broadcast_message'; import './broadcast_message';
import './build'; import './build';
...@@ -363,7 +363,7 @@ $(function () { ...@@ -363,7 +363,7 @@ $(function () {
$window.off('resize.app').on('resize.app', function () { $window.off('resize.app').on('resize.app', function () {
return fitSidebarForSize(); return fitSidebarForSize();
}); });
gl.awardsHandler = new AwardsHandler(); loadAwardsHandler();
new Aside(); new Aside();
gl.utils.initTimeagoTimeout(); gl.utils.initTimeagoTimeout();
......
...@@ -18,6 +18,7 @@ import 'vendor/jquery.caret'; // required by jquery.atwho ...@@ -18,6 +18,7 @@ import 'vendor/jquery.caret'; // required by jquery.atwho
import 'vendor/jquery.atwho'; import 'vendor/jquery.atwho';
import AjaxCache from '~/lib/utils/ajax_cache'; import AjaxCache from '~/lib/utils/ajax_cache';
import CommentTypeToggle from './comment_type_toggle'; import CommentTypeToggle from './comment_type_toggle';
import loadAwardsHandler from './awards_handler';
import './autosave'; import './autosave';
import './dropzone_input'; import './dropzone_input';
import './task_list'; import './task_list';
...@@ -291,8 +292,13 @@ export default class Notes { ...@@ -291,8 +292,13 @@ export default class Notes {
if ('emoji_award' in noteEntity.commands_changes) { if ('emoji_award' in noteEntity.commands_changes) {
votesBlock = $('.js-awards-block').eq(0); votesBlock = $('.js-awards-block').eq(0);
gl.awardsHandler.addAwardToEmojiBar(votesBlock, noteEntity.commands_changes.emoji_award);
return gl.awardsHandler.scrollToAwards(); loadAwardsHandler().then((awardsHandler) => {
awardsHandler.addAwardToEmojiBar(votesBlock, noteEntity.commands_changes.emoji_award);
awardsHandler.scrollToAwards();
}).catch(() => {
// ignore
});
} }
} }
} }
......
/* eslint-disable space-before-function-paren, no-var, one-var, one-var-declaration-per-line, no-unused-expressions, comma-dangle, new-parens, no-unused-vars, quotes, jasmine/no-spec-dupes, prefer-template, max-len */ /* eslint-disable space-before-function-paren, no-var, one-var, one-var-declaration-per-line, no-unused-expressions, comma-dangle, new-parens, no-unused-vars, quotes, jasmine/no-spec-dupes, prefer-template, max-len */
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import AwardsHandler from '~/awards_handler'; import loadAwardsHandler from '~/awards_handler';
import '~/lib/utils/common_utils'; import '~/lib/utils/common_utils';
...@@ -26,14 +26,13 @@ import '~/lib/utils/common_utils'; ...@@ -26,14 +26,13 @@ import '~/lib/utils/common_utils';
describe('AwardsHandler', function() { describe('AwardsHandler', function() {
preloadFixtures('issues/issue_with_comment.html.raw'); preloadFixtures('issues/issue_with_comment.html.raw');
beforeEach(function() { beforeEach(function(done) {
loadFixtures('issues/issue_with_comment.html.raw'); loadFixtures('issues/issue_with_comment.html.raw');
awardsHandler = new AwardsHandler; loadAwardsHandler(true).then((obj) => {
spyOn(awardsHandler, 'postEmoji').and.callFake((function(_this) { awardsHandler = obj;
return function(button, url, emoji, cb) { spyOn(awardsHandler, 'postEmoji').and.callFake((button, url, emoji, cb) => cb());
return cb(); done();
}; }).catch(fail);
})(this));
let isEmojiMenuBuilt = false; let isEmojiMenuBuilt = false;
openAndWaitForEmojiMenu = function() { openAndWaitForEmojiMenu = function() {
......
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