dynamically import emoji helpers for AwardsHandler class
This commit is contained in:
parent
3f3993c3d3
commit
f26d477865
4 changed files with 61 additions and 47 deletions
|
@ -2,7 +2,6 @@
|
|||
/* global Flash */
|
||||
|
||||
import Cookies from 'js-cookie';
|
||||
import * as Emoji from './emoji';
|
||||
|
||||
const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';
|
||||
const transitionEndEventString = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd';
|
||||
|
@ -24,27 +23,9 @@ const categoryLabelMap = {
|
|||
flags: 'Flags',
|
||||
};
|
||||
|
||||
function 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">
|
||||
${Emoji.glEmojiTag(emojiName, {
|
||||
sprite: true,
|
||||
})}
|
||||
</button>
|
||||
</li>
|
||||
`).join('\n')}
|
||||
</ul>
|
||||
`;
|
||||
}
|
||||
|
||||
export default class AwardsHandler {
|
||||
constructor() {
|
||||
class AwardsHandler {
|
||||
constructor(emoji) {
|
||||
this.emoji = emoji;
|
||||
this.eventListeners = [];
|
||||
// If the user shows intent let's pre-build the menu
|
||||
this.registerEventListener('one', $(document), 'mouseenter focus', '.js-add-award', 'mouseenter focus', () => {
|
||||
|
@ -78,10 +59,10 @@ export default class AwardsHandler {
|
|||
const $target = $(e.currentTarget);
|
||||
const $glEmojiElement = $target.find('gl-emoji');
|
||||
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');
|
||||
this.addAward(this.getVotesBlock(), this.getAwardUrl(), emoji);
|
||||
this.addAward(this.getVotesBlock(), this.getAwardUrl(), emojiName);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -139,16 +120,16 @@ export default class AwardsHandler {
|
|||
this.isCreatingEmojiMenu = true;
|
||||
|
||||
// Render the first category
|
||||
const categoryMap = Emoji.getEmojiCategoryMap();
|
||||
const categoryMap = this.emoji.getEmojiCategoryMap();
|
||||
const categoryNameKey = Object.keys(categoryMap)[0];
|
||||
const emojisInCategory = categoryMap[categoryNameKey];
|
||||
const firstCategory = renderCategory(categoryLabelMap[categoryNameKey], emojisInCategory);
|
||||
const firstCategory = this.renderCategory(categoryLabelMap[categoryNameKey], emojisInCategory);
|
||||
|
||||
// Render the frequently used
|
||||
const frequentlyUsedEmojis = this.getFrequentlyUsedEmojis();
|
||||
let frequentlyUsedCatgegory = '';
|
||||
if (frequentlyUsedEmojis.length > 0) {
|
||||
frequentlyUsedCatgegory = renderCategory('Frequently used', frequentlyUsedEmojis, {
|
||||
frequentlyUsedCatgegory = this.renderCategory('Frequently used', frequentlyUsedEmojis, {
|
||||
menuListClass: 'frequent-emojis',
|
||||
});
|
||||
}
|
||||
|
@ -179,7 +160,7 @@ export default class AwardsHandler {
|
|||
}
|
||||
this.isAddingRemainingEmojiMenuCategories = true;
|
||||
|
||||
const categoryMap = Emoji.getEmojiCategoryMap();
|
||||
const categoryMap = this.emoji.getEmojiCategoryMap();
|
||||
|
||||
// Avoid the jank and render the remaining categories separately
|
||||
// This will take more time, but makes UI more responsive
|
||||
|
@ -191,7 +172,7 @@ export default class AwardsHandler {
|
|||
promiseChain.then(() =>
|
||||
new Promise((resolve) => {
|
||||
const emojisInCategory = categoryMap[categoryNameKey];
|
||||
const categoryMarkup = renderCategory(
|
||||
const categoryMarkup = this.renderCategory(
|
||||
categoryLabelMap[categoryNameKey],
|
||||
emojisInCategory,
|
||||
);
|
||||
|
@ -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) {
|
||||
const position = $addBtn.data('position');
|
||||
// The menu could potentially be off-screen or in a hidden overflow element
|
||||
|
@ -234,7 +234,7 @@ export default class AwardsHandler {
|
|||
}
|
||||
|
||||
addAward(votesBlock, awardUrl, emoji, checkMutuality, callback) {
|
||||
const normalizedEmoji = Emoji.normalizeEmojiName(emoji);
|
||||
const normalizedEmoji = this.emoji.normalizeEmojiName(emoji);
|
||||
const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent();
|
||||
this.postEmoji($emojiButton, awardUrl, normalizedEmoji, () => {
|
||||
this.addAwardToEmojiBar(votesBlock, normalizedEmoji, checkMutuality);
|
||||
|
@ -249,7 +249,7 @@ export default class AwardsHandler {
|
|||
this.checkMutuality(votesBlock, emoji);
|
||||
}
|
||||
this.addEmojiToFrequentlyUsedList(emoji);
|
||||
const normalizedEmoji = Emoji.normalizeEmojiName(emoji);
|
||||
const normalizedEmoji = this.emoji.normalizeEmojiName(emoji);
|
||||
const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent();
|
||||
if ($emojiButton.length > 0) {
|
||||
if (this.isActive($emojiButton)) {
|
||||
|
@ -374,7 +374,7 @@ export default class AwardsHandler {
|
|||
createAwardButtonForVotesBlock(votesBlock, emojiName) {
|
||||
const buttonHtml = `
|
||||
<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>
|
||||
</button>
|
||||
`;
|
||||
|
@ -440,7 +440,7 @@ export default class AwardsHandler {
|
|||
}
|
||||
|
||||
addEmojiToFrequentlyUsedList(emoji) {
|
||||
if (Emoji.isEmojiNameValid(emoji)) {
|
||||
if (this.emoji.isEmojiNameValid(emoji)) {
|
||||
this.frequentlyUsedEmojis = _.uniq(this.getFrequentlyUsedEmojis().concat(emoji));
|
||||
Cookies.set('frequently_used_emojis', this.frequentlyUsedEmojis.join(','), { expires: 365 });
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ export default class AwardsHandler {
|
|||
return this.frequentlyUsedEmojis || (() => {
|
||||
const frequentlyUsedEmojis = _.uniq((Cookies.get('frequently_used_emojis') || '').split(','));
|
||||
this.frequentlyUsedEmojis = frequentlyUsedEmojis.filter(
|
||||
inputName => Emoji.isEmojiNameValid(inputName),
|
||||
inputName => this.emoji.isEmojiNameValid(inputName),
|
||||
);
|
||||
|
||||
return this.frequentlyUsedEmojis;
|
||||
|
@ -493,7 +493,7 @@ export default class AwardsHandler {
|
|||
}
|
||||
|
||||
findMatchingEmojiElements(query) {
|
||||
const emojiMatches = Emoji.filterEmojiNamesByAlias(query);
|
||||
const emojiMatches = this.emoji.filterEmojiNamesByAlias(query);
|
||||
const $emojiElements = $('.emoji-menu-list:not(.frequent-emojis) [data-name]');
|
||||
const $matchingElements = $emojiElements
|
||||
.filter((i, elm) => emojiMatches.indexOf(elm.dataset.name) >= 0);
|
||||
|
@ -507,3 +507,12 @@ export default class AwardsHandler {
|
|||
$('.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';
|
|||
import './api';
|
||||
import './aside';
|
||||
import './autosave';
|
||||
import AwardsHandler from './awards_handler';
|
||||
import loadAwardsHandler from './awards_handler';
|
||||
import './breakpoints';
|
||||
import './broadcast_message';
|
||||
import './build';
|
||||
|
@ -363,7 +363,7 @@ $(function () {
|
|||
$window.off('resize.app').on('resize.app', function () {
|
||||
return fitSidebarForSize();
|
||||
});
|
||||
gl.awardsHandler = new AwardsHandler();
|
||||
loadAwardsHandler();
|
||||
new Aside();
|
||||
|
||||
gl.utils.initTimeagoTimeout();
|
||||
|
|
|
@ -18,6 +18,7 @@ import 'vendor/jquery.caret'; // required by jquery.atwho
|
|||
import 'vendor/jquery.atwho';
|
||||
import AjaxCache from '~/lib/utils/ajax_cache';
|
||||
import CommentTypeToggle from './comment_type_toggle';
|
||||
import loadAwardsHandler from './awards_handler';
|
||||
import './autosave';
|
||||
import './dropzone_input';
|
||||
import './task_list';
|
||||
|
@ -291,8 +292,13 @@ export default class Notes {
|
|||
|
||||
if ('emoji_award' in noteEntity.commands_changes) {
|
||||
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
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* 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 AwardsHandler from '~/awards_handler';
|
||||
import loadAwardsHandler from '~/awards_handler';
|
||||
|
||||
import '~/lib/utils/common_utils';
|
||||
|
||||
|
@ -26,14 +26,13 @@ import '~/lib/utils/common_utils';
|
|||
|
||||
describe('AwardsHandler', function() {
|
||||
preloadFixtures('issues/issue_with_comment.html.raw');
|
||||
beforeEach(function() {
|
||||
beforeEach(function(done) {
|
||||
loadFixtures('issues/issue_with_comment.html.raw');
|
||||
awardsHandler = new AwardsHandler;
|
||||
spyOn(awardsHandler, 'postEmoji').and.callFake((function(_this) {
|
||||
return function(button, url, emoji, cb) {
|
||||
return cb();
|
||||
};
|
||||
})(this));
|
||||
loadAwardsHandler(true).then((obj) => {
|
||||
awardsHandler = obj;
|
||||
spyOn(awardsHandler, 'postEmoji').and.callFake((button, url, emoji, cb) => cb());
|
||||
done();
|
||||
}).catch(fail);
|
||||
|
||||
let isEmojiMenuBuilt = false;
|
||||
openAndWaitForEmojiMenu = function() {
|
||||
|
|
Loading…
Reference in a new issue