Commit bf0b3d83 authored by Jacob Schatz's avatar Jacob Schatz

Merge branch 'awards-handler-class-syntax' into 'master'

Refactor AwardsHandler into ES class syntax

See merge request !12239
parents 826d5b7b 3b4c07ac
/* eslint-disable class-methods-use-this */
/* global Flash */ /* global Flash */
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
...@@ -68,141 +69,140 @@ function renderCategory(name, emojiList, opts = {}) { ...@@ -68,141 +69,140 @@ function renderCategory(name, emojiList, opts = {}) {
`; `;
} }
function AwardsHandler() { export default class AwardsHandler {
this.eventListeners = []; constructor() {
this.aliases = emojiAliases; this.eventListeners = [];
// If the user shows intent let's pre-build the menu this.aliases = emojiAliases;
this.registerEventListener('one', $(document), 'mouseenter focus', '.js-add-award', 'mouseenter focus', () => { // If the user shows intent let's pre-build the menu
const $menu = $('.emoji-menu'); this.registerEventListener('one', $(document), 'mouseenter focus', '.js-add-award', 'mouseenter focus', () => {
if ($menu.length === 0) { const $menu = $('.emoji-menu');
requestAnimationFrame(() => { if ($menu.length === 0) {
this.createEmojiMenu(); requestAnimationFrame(() => {
}); this.createEmojiMenu();
} });
// Prebuild the categoryMap }
categoryMap = categoryMap || buildCategoryMap(); // Prebuild the categoryMap
}); categoryMap = categoryMap || buildCategoryMap();
this.registerEventListener('on', $(document), 'click', '.js-add-award', (e) => { });
e.stopPropagation(); this.registerEventListener('on', $(document), 'click', '.js-add-award', (e) => {
e.preventDefault(); e.stopPropagation();
this.showEmojiMenu($(e.currentTarget)); e.preventDefault();
}); this.showEmojiMenu($(e.currentTarget));
});
this.registerEventListener('on', $('html'), 'click', (e) => { this.registerEventListener('on', $('html'), 'click', (e) => {
const $target = $(e.target); const $target = $(e.target);
if (!$target.closest('.emoji-menu-content').length) { if (!$target.closest('.emoji-menu-content').length) {
$('.js-awards-block.current').removeClass('current'); $('.js-awards-block.current').removeClass('current');
}
if (!$target.closest('.emoji-menu').length) {
if ($('.emoji-menu').is(':visible')) {
$('.js-add-award.is-active').removeClass('is-active');
$('.emoji-menu').removeClass('is-visible');
} }
} if (!$target.closest('.emoji-menu').length) {
}); if ($('.emoji-menu').is(':visible')) {
this.registerEventListener('on', $(document), 'click', '.js-emoji-btn', (e) => { $('.js-add-award.is-active').removeClass('is-active');
e.preventDefault(); $('.emoji-menu').removeClass('is-visible');
const $target = $(e.currentTarget); }
const $glEmojiElement = $target.find('gl-emoji'); }
const $spriteIconElement = $target.find('.icon'); });
const emoji = ($glEmojiElement.length ? $glEmojiElement : $spriteIconElement).data('name'); this.registerEventListener('on', $(document), 'click', '.js-emoji-btn', (e) => {
e.preventDefault();
$target.closest('.js-awards-block').addClass('current'); const $target = $(e.currentTarget);
this.addAward(this.getVotesBlock(), this.getAwardUrl(), emoji); const $glEmojiElement = $target.find('gl-emoji');
}); const $spriteIconElement = $target.find('.icon');
} const emoji = ($glEmojiElement.length ? $glEmojiElement : $spriteIconElement).data('name');
$target.closest('.js-awards-block').addClass('current');
this.addAward(this.getVotesBlock(), this.getAwardUrl(), emoji);
});
}
AwardsHandler.prototype.registerEventListener = function registerEventListener(method = 'on', element, ...args) { registerEventListener(method = 'on', element, ...args) {
element[method].call(element, ...args); element[method].call(element, ...args);
this.eventListeners.push({ this.eventListeners.push({
element, element,
args, args,
}); });
}; }
AwardsHandler.prototype.showEmojiMenu = function showEmojiMenu($addBtn) { showEmojiMenu($addBtn) {
if ($addBtn.hasClass('js-note-emoji')) { if ($addBtn.hasClass('js-note-emoji')) {
$addBtn.closest('.note').find('.js-awards-block').addClass('current'); $addBtn.closest('.note').find('.js-awards-block').addClass('current');
} else {
$addBtn.closest('.js-awards-block').addClass('current');
}
const $menu = $('.emoji-menu');
const $thumbsBtn = $menu.find('[data-name="thumbsup"], [data-name="thumbsdown"]').parent();
const $userAuthored = this.isUserAuthored($addBtn);
if ($menu.length) {
if ($menu.is('.is-visible')) {
$addBtn.removeClass('is-active');
$menu.removeClass('is-visible');
$('.js-emoji-menu-search').blur();
} else { } else {
$addBtn.addClass('is-active'); $addBtn.closest('.js-awards-block').addClass('current');
this.positionMenu($menu, $addBtn);
$menu.addClass('is-visible');
$('.js-emoji-menu-search').focus();
} }
} else {
$addBtn.addClass('is-loading is-active'); const $menu = $('.emoji-menu');
this.createEmojiMenu(() => { const $thumbsBtn = $menu.find('[data-name="thumbsup"], [data-name="thumbsdown"]').parent();
const $createdMenu = $('.emoji-menu'); const $userAuthored = this.isUserAuthored($addBtn);
$addBtn.removeClass('is-loading'); if ($menu.length) {
this.positionMenu($createdMenu, $addBtn); if ($menu.is('.is-visible')) {
return setTimeout(() => { $addBtn.removeClass('is-active');
$createdMenu.addClass('is-visible'); $menu.removeClass('is-visible');
$('.js-emoji-menu-search').blur();
} else {
$addBtn.addClass('is-active');
this.positionMenu($menu, $addBtn);
$menu.addClass('is-visible');
$('.js-emoji-menu-search').focus(); $('.js-emoji-menu-search').focus();
}, 200); }
}); } else {
$addBtn.addClass('is-loading is-active');
this.createEmojiMenu(() => {
const $createdMenu = $('.emoji-menu');
$addBtn.removeClass('is-loading');
this.positionMenu($createdMenu, $addBtn);
return setTimeout(() => {
$createdMenu.addClass('is-visible');
$('.js-emoji-menu-search').focus();
}, 200);
});
}
$thumbsBtn.toggleClass('disabled', $userAuthored);
} }
$thumbsBtn.toggleClass('disabled', $userAuthored); // Create the emoji menu with the first category of emojis.
}; // Then render the remaining categories of emojis one by one to avoid jank.
createEmojiMenu(callback) {
if (this.isCreatingEmojiMenu) {
return;
}
this.isCreatingEmojiMenu = true;
// Create the emoji menu with the first category of emojis. // Render the first category
// Then render the remaining categories of emojis one by one to avoid jank. categoryMap = categoryMap || buildCategoryMap();
AwardsHandler.prototype.createEmojiMenu = function createEmojiMenu(callback) { const categoryNameKey = Object.keys(categoryMap)[0];
if (this.isCreatingEmojiMenu) { const emojisInCategory = categoryMap[categoryNameKey];
return; const firstCategory = renderCategory(categoryLabelMap[categoryNameKey], emojisInCategory);
}
this.isCreatingEmojiMenu = true; // Render the frequently used
const frequentlyUsedEmojis = this.getFrequentlyUsedEmojis();
// Render the first category let frequentlyUsedCatgegory = '';
categoryMap = categoryMap || buildCategoryMap(); if (frequentlyUsedEmojis.length > 0) {
const categoryNameKey = Object.keys(categoryMap)[0]; frequentlyUsedCatgegory = renderCategory('Frequently used', frequentlyUsedEmojis, {
const emojisInCategory = categoryMap[categoryNameKey]; menuListClass: 'frequent-emojis',
const firstCategory = renderCategory(categoryLabelMap[categoryNameKey], emojisInCategory); });
}
// Render the frequently used
const frequentlyUsedEmojis = this.getFrequentlyUsedEmojis();
let frequentlyUsedCatgegory = '';
if (frequentlyUsedEmojis.length > 0) {
frequentlyUsedCatgegory = renderCategory('Frequently used', frequentlyUsedEmojis, {
menuListClass: 'frequent-emojis',
});
}
const emojiMenuMarkup = ` const emojiMenuMarkup = `
<div class="emoji-menu"> <div class="emoji-menu">
<input type="text" name="emoji-menu-search" value="" class="js-emoji-menu-search emoji-search search-input form-control" placeholder="Search emoji" /> <input type="text" name="emoji-menu-search" value="" class="js-emoji-menu-search emoji-search search-input form-control" placeholder="Search emoji" />
<div class="emoji-menu-content"> <div class="emoji-menu-content">
${frequentlyUsedCatgegory} ${frequentlyUsedCatgegory}
${firstCategory} ${firstCategory}
</div>
</div> </div>
</div> `;
`;
document.body.insertAdjacentHTML('beforeend', emojiMenuMarkup); document.body.insertAdjacentHTML('beforeend', emojiMenuMarkup);
this.addRemainingEmojiMenuCategories(); this.addRemainingEmojiMenuCategories();
this.setupSearch(); this.setupSearch();
if (callback) { if (callback) {
callback(); callback();
}
} }
};
AwardsHandler addRemainingEmojiMenuCategories() {
.prototype
.addRemainingEmojiMenuCategories = function addRemainingEmojiMenuCategories() {
if (this.isAddingRemainingEmojiMenuCategories) { if (this.isAddingRemainingEmojiMenuCategories) {
return; return;
} }
...@@ -243,176 +243,174 @@ AwardsHandler ...@@ -243,176 +243,174 @@ AwardsHandler
emojiContentElement.insertAdjacentHTML('beforeend', '<p>We encountered an error while adding the remaining categories</p>'); emojiContentElement.insertAdjacentHTML('beforeend', '<p>We encountered an error while adding the remaining categories</p>');
throw new Error(`Error occurred in addRemainingEmojiMenuCategories: ${err.message}`); throw new Error(`Error occurred in addRemainingEmojiMenuCategories: ${err.message}`);
}); });
}; }
AwardsHandler.prototype.positionMenu = function positionMenu($menu, $addBtn) {
const position = $addBtn.data('position');
// The menu could potentially be off-screen or in a hidden overflow element
// So we position the element absolute in the body
const css = {
top: `${$addBtn.offset().top + $addBtn.outerHeight()}px`,
};
if (position === 'right') {
css.left = `${($addBtn.offset().left - $menu.outerWidth()) + 20}px`;
$menu.addClass('is-aligned-right');
} else {
css.left = `${$addBtn.offset().left}px`;
$menu.removeClass('is-aligned-right');
}
return $menu.css(css);
};
AwardsHandler.prototype.addAward = function addAward(
votesBlock,
awardUrl,
emoji,
checkMutuality,
callback,
) {
const normalizedEmoji = this.normalizeEmojiName(emoji);
const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent();
this.postEmoji($emojiButton, awardUrl, normalizedEmoji, () => {
this.addAwardToEmojiBar(votesBlock, normalizedEmoji, checkMutuality);
return typeof callback === 'function' ? callback() : undefined;
});
$('.emoji-menu').removeClass('is-visible');
$('.js-add-award.is-active').removeClass('is-active');
};
AwardsHandler.prototype.addAwardToEmojiBar = function addAwardToEmojiBar( positionMenu($menu, $addBtn) {
votesBlock, const position = $addBtn.data('position');
emoji, // The menu could potentially be off-screen or in a hidden overflow element
checkForMutuality, // So we position the element absolute in the body
) { const css = {
if (checkForMutuality || checkForMutuality === null) { top: `${$addBtn.offset().top + $addBtn.outerHeight()}px`,
this.checkMutuality(votesBlock, emoji); };
} if (position === 'right') {
this.addEmojiToFrequentlyUsedList(emoji); css.left = `${($addBtn.offset().left - $menu.outerWidth()) + 20}px`;
const normalizedEmoji = this.normalizeEmojiName(emoji); $menu.addClass('is-aligned-right');
const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent();
if ($emojiButton.length > 0) {
if (this.isActive($emojiButton)) {
this.decrementCounter($emojiButton, normalizedEmoji);
} else { } else {
const counter = $emojiButton.find('.js-counter'); css.left = `${$addBtn.offset().left}px`;
counter.text(parseInt(counter.text(), 10) + 1); $menu.removeClass('is-aligned-right');
$emojiButton.addClass('active');
this.addYouToUserList(votesBlock, normalizedEmoji);
this.animateEmoji($emojiButton);
} }
} else { return $menu.css(css);
votesBlock.removeClass('hidden');
this.createEmoji(votesBlock, normalizedEmoji);
} }
};
AwardsHandler.prototype.getVotesBlock = function getVotesBlock() { addAward(
const currentBlock = $('.js-awards-block.current'); votesBlock,
let resultantVotesBlock = currentBlock; awardUrl,
if (currentBlock.length === 0) { emoji,
resultantVotesBlock = $('.js-awards-block').eq(0); checkMutuality,
callback,
) {
const normalizedEmoji = this.normalizeEmojiName(emoji);
const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent();
this.postEmoji($emojiButton, awardUrl, normalizedEmoji, () => {
this.addAwardToEmojiBar(votesBlock, normalizedEmoji, checkMutuality);
return typeof callback === 'function' ? callback() : undefined;
});
$('.emoji-menu').removeClass('is-visible');
$('.js-add-award.is-active').removeClass('is-active');
} }
return resultantVotesBlock; addAwardToEmojiBar(
}; votesBlock,
emoji,
checkForMutuality,
) {
if (checkForMutuality || checkForMutuality === null) {
this.checkMutuality(votesBlock, emoji);
}
this.addEmojiToFrequentlyUsedList(emoji);
const normalizedEmoji = this.normalizeEmojiName(emoji);
const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent();
if ($emojiButton.length > 0) {
if (this.isActive($emojiButton)) {
this.decrementCounter($emojiButton, normalizedEmoji);
} else {
const counter = $emojiButton.find('.js-counter');
counter.text(parseInt(counter.text(), 10) + 1);
$emojiButton.addClass('active');
this.addYouToUserList(votesBlock, normalizedEmoji);
this.animateEmoji($emojiButton);
}
} else {
votesBlock.removeClass('hidden');
this.createEmoji(votesBlock, normalizedEmoji);
}
}
AwardsHandler.prototype.getAwardUrl = function getAwardUrl() { getVotesBlock() {
return this.getVotesBlock().data('award-url'); const currentBlock = $('.js-awards-block.current');
}; let resultantVotesBlock = currentBlock;
if (currentBlock.length === 0) {
resultantVotesBlock = $('.js-awards-block').eq(0);
}
return resultantVotesBlock;
}
AwardsHandler.prototype.checkMutuality = function checkMutuality(votesBlock, emoji) { getAwardUrl() {
const awardUrl = this.getAwardUrl(); return this.getVotesBlock().data('award-url');
if (emoji === 'thumbsup' || emoji === 'thumbsdown') { }
const mutualVote = emoji === 'thumbsup' ? 'thumbsdown' : 'thumbsup';
const $emojiButton = votesBlock.find(`[data-name="${mutualVote}"]`).parent(); checkMutuality(votesBlock, emoji) {
const isAlreadyVoted = $emojiButton.hasClass('active'); const awardUrl = this.getAwardUrl();
if (isAlreadyVoted) { if (emoji === 'thumbsup' || emoji === 'thumbsdown') {
this.addAward(votesBlock, awardUrl, mutualVote, false); const mutualVote = emoji === 'thumbsup' ? 'thumbsdown' : 'thumbsup';
const $emojiButton = votesBlock.find(`[data-name="${mutualVote}"]`).parent();
const isAlreadyVoted = $emojiButton.hasClass('active');
if (isAlreadyVoted) {
this.addAward(votesBlock, awardUrl, mutualVote, false);
}
} }
} }
};
AwardsHandler.prototype.isActive = function isActive($emojiButton) { isActive($emojiButton) {
return $emojiButton.hasClass('active'); return $emojiButton.hasClass('active');
}; }
AwardsHandler.prototype.isUserAuthored = function isUserAuthored($button) { isUserAuthored($button) {
return $button.hasClass('js-user-authored'); return $button.hasClass('js-user-authored');
}; }
AwardsHandler.prototype.decrementCounter = function decrementCounter($emojiButton, emoji) { decrementCounter($emojiButton, emoji) {
const counter = $('.js-counter', $emojiButton); const counter = $('.js-counter', $emojiButton);
const counterNumber = parseInt(counter.text(), 10); const counterNumber = parseInt(counter.text(), 10);
if (counterNumber > 1) { if (counterNumber > 1) {
counter.text(counterNumber - 1); counter.text(counterNumber - 1);
this.removeYouFromUserList($emojiButton); this.removeYouFromUserList($emojiButton);
} else if (emoji === 'thumbsup' || emoji === 'thumbsdown') { } else if (emoji === 'thumbsup' || emoji === 'thumbsdown') {
$emojiButton.tooltip('destroy'); $emojiButton.tooltip('destroy');
counter.text('0'); counter.text('0');
this.removeYouFromUserList($emojiButton); this.removeYouFromUserList($emojiButton);
if ($emojiButton.parents('.note').length) { if ($emojiButton.parents('.note').length) {
this.removeEmoji($emojiButton);
}
} else {
this.removeEmoji($emojiButton); this.removeEmoji($emojiButton);
} }
} else { return $emojiButton.removeClass('active');
this.removeEmoji($emojiButton);
} }
return $emojiButton.removeClass('active');
};
AwardsHandler.prototype.removeEmoji = function removeEmoji($emojiButton) { removeEmoji($emojiButton) {
$emojiButton.tooltip('destroy'); $emojiButton.tooltip('destroy');
$emojiButton.remove(); $emojiButton.remove();
const $votesBlock = this.getVotesBlock(); const $votesBlock = this.getVotesBlock();
if ($votesBlock.find('.js-emoji-btn').length === 0) { if ($votesBlock.find('.js-emoji-btn').length === 0) {
$votesBlock.addClass('hidden'); $votesBlock.addClass('hidden');
}
} }
};
AwardsHandler.prototype.getAwardTooltip = function getAwardTooltip($awardBlock) {
return $awardBlock.attr('data-original-title') || $awardBlock.attr('data-title') || '';
};
AwardsHandler.prototype.toSentence = function toSentence(list) { getAwardTooltip($awardBlock) {
let sentence; return $awardBlock.attr('data-original-title') || $awardBlock.attr('data-title') || '';
if (list.length <= 2) {
sentence = list.join(' and ');
} else {
sentence = `${list.slice(0, -1).join(', ')}, and ${list[list.length - 1]}`;
} }
return sentence; toSentence(list) {
}; let sentence;
if (list.length <= 2) {
sentence = list.join(' and ');
} else {
sentence = `${list.slice(0, -1).join(', ')}, and ${list[list.length - 1]}`;
}
AwardsHandler.prototype.removeYouFromUserList = function removeYouFromUserList($emojiButton) { return sentence;
const awardBlock = $emojiButton; }
const originalTitle = this.getAwardTooltip(awardBlock);
const authors = originalTitle.split(FROM_SENTENCE_REGEX);
authors.splice(authors.indexOf('You'), 1);
return awardBlock
.closest('.js-emoji-btn')
.removeData('title')
.removeAttr('data-title')
.removeAttr('data-original-title')
.attr('title', this.toSentence(authors))
.tooltip('fixTitle');
};
AwardsHandler.prototype.addYouToUserList = function addYouToUserList(votesBlock, emoji) { removeYouFromUserList($emojiButton) {
const awardBlock = this.findEmojiIcon(votesBlock, emoji).parent(); const awardBlock = $emojiButton;
const origTitle = this.getAwardTooltip(awardBlock); const originalTitle = this.getAwardTooltip(awardBlock);
let users = []; const authors = originalTitle.split(FROM_SENTENCE_REGEX);
if (origTitle) { authors.splice(authors.indexOf('You'), 1);
users = origTitle.trim().split(FROM_SENTENCE_REGEX); return awardBlock
} .closest('.js-emoji-btn')
users.unshift('You'); .removeData('title')
return awardBlock .removeAttr('data-title')
.attr('title', this.toSentence(users)) .removeAttr('data-original-title')
.tooltip('fixTitle'); .attr('title', this.toSentence(authors))
}; .tooltip('fixTitle');
}
addYouToUserList(votesBlock, emoji) {
const awardBlock = this.findEmojiIcon(votesBlock, emoji).parent();
const origTitle = this.getAwardTooltip(awardBlock);
let users = [];
if (origTitle) {
users = origTitle.trim().split(FROM_SENTENCE_REGEX);
}
users.unshift('You');
return awardBlock
.attr('title', this.toSentence(users))
.tooltip('fixTitle');
}
AwardsHandler createAwardButtonForVotesBlock(votesBlock, emojiName) {
.prototype
.createAwardButtonForVotesBlock = function 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">
${glEmojiTag(emojiName)} ${glEmojiTag(emojiName)}
...@@ -424,144 +422,141 @@ AwardsHandler ...@@ -424,144 +422,141 @@ AwardsHandler
this.animateEmoji($emojiButton); this.animateEmoji($emojiButton);
$('.award-control').tooltip(); $('.award-control').tooltip();
votesBlock.removeClass('current'); votesBlock.removeClass('current');
}; }
AwardsHandler.prototype.animateEmoji = function animateEmoji($emoji) { animateEmoji($emoji) {
const className = 'pulse animated once short'; const className = 'pulse animated once short';
$emoji.addClass(className); $emoji.addClass(className);
this.registerEventListener('on', $emoji, animationEndEventString, (e) => { this.registerEventListener('on', $emoji, animationEndEventString, (e) => {
$(e.currentTarget).removeClass(className); $(e.currentTarget).removeClass(className);
}); });
}; }
AwardsHandler.prototype.createEmoji = function createEmoji(votesBlock, emoji) { createEmoji(votesBlock, emoji) {
if ($('.emoji-menu').length) { if ($('.emoji-menu').length) {
this.createAwardButtonForVotesBlock(votesBlock, emoji); this.createAwardButtonForVotesBlock(votesBlock, emoji);
}
this.createEmojiMenu(() => {
this.createAwardButtonForVotesBlock(votesBlock, emoji);
});
} }
this.createEmojiMenu(() => {
this.createAwardButtonForVotesBlock(votesBlock, emoji);
});
};
AwardsHandler.prototype.postEmoji = function postEmoji($emojiButton, awardUrl, emoji, callback) { postEmoji($emojiButton, awardUrl, emoji, callback) {
if (this.isUserAuthored($emojiButton)) { if (this.isUserAuthored($emojiButton)) {
this.userAuthored($emojiButton); this.userAuthored($emojiButton);
} else { } else {
$.post(awardUrl, { $.post(awardUrl, {
name: emoji, name: emoji,
}, (data) => { }, (data) => {
if (data.ok) { if (data.ok) {
callback(); callback();
} }
}).fail(() => new Flash('Something went wrong on our end.')); }).fail(() => new Flash('Something went wrong on our end.'));
}
} }
};
AwardsHandler.prototype.findEmojiIcon = function findEmojiIcon(votesBlock, emoji) { findEmojiIcon(votesBlock, emoji) {
return votesBlock.find(`.js-emoji-btn [data-name="${emoji}"]`); return votesBlock.find(`.js-emoji-btn [data-name="${emoji}"]`);
}; }
AwardsHandler.prototype.userAuthored = function userAuthored($emojiButton) { userAuthored($emojiButton) {
const oldTitle = this.getAwardTooltip($emojiButton); const oldTitle = this.getAwardTooltip($emojiButton);
const newTitle = 'You cannot vote on your own issue, MR and note'; const newTitle = 'You cannot vote on your own issue, MR and note';
gl.utils.updateTooltipTitle($emojiButton, newTitle).tooltip('show'); gl.utils.updateTooltipTitle($emojiButton, newTitle).tooltip('show');
// Restore tooltip back to award list // Restore tooltip back to award list
return setTimeout(() => { return setTimeout(() => {
$emojiButton.tooltip('hide'); $emojiButton.tooltip('hide');
gl.utils.updateTooltipTitle($emojiButton, oldTitle); gl.utils.updateTooltipTitle($emojiButton, oldTitle);
}, 2800); }, 2800);
}; }
AwardsHandler.prototype.scrollToAwards = function scrollToAwards() { scrollToAwards() {
const options = { const options = {
scrollTop: $('.awards').offset().top - 110, scrollTop: $('.awards').offset().top - 110,
}; };
return $('body, html').animate(options, 200); return $('body, html').animate(options, 200);
}; }
AwardsHandler.prototype.normalizeEmojiName = function normalizeEmojiName(emoji) { normalizeEmojiName(emoji) {
return Object.prototype.hasOwnProperty.call(this.aliases, emoji) ? this.aliases[emoji] : emoji; return Object.prototype.hasOwnProperty.call(this.aliases, emoji) ? this.aliases[emoji] : emoji;
}; }
AwardsHandler addEmojiToFrequentlyUsedList(emoji) {
.prototype
.addEmojiToFrequentlyUsedList = function addEmojiToFrequentlyUsedList(emoji) {
if (isEmojiNameValid(emoji)) { if (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 });
} }
}; }
AwardsHandler.prototype.getFrequentlyUsedEmojis = function getFrequentlyUsedEmojis() {
return this.frequentlyUsedEmojis || (() => {
const frequentlyUsedEmojis = _.uniq((Cookies.get('frequently_used_emojis') || '').split(','));
this.frequentlyUsedEmojis = frequentlyUsedEmojis.filter(
inputName => isEmojiNameValid(inputName),
);
return this.frequentlyUsedEmojis; getFrequentlyUsedEmojis() {
})(); return this.frequentlyUsedEmojis || (() => {
}; const frequentlyUsedEmojis = _.uniq((Cookies.get('frequently_used_emojis') || '').split(','));
this.frequentlyUsedEmojis = frequentlyUsedEmojis.filter(
inputName => isEmojiNameValid(inputName),
);
AwardsHandler.prototype.setupSearch = function setupSearch() { return this.frequentlyUsedEmojis;
const $search = $('.js-emoji-menu-search'); })();
}
this.registerEventListener('on', $search, 'input', (e) => { setupSearch() {
const term = $(e.target).val().trim(); const $search = $('.js-emoji-menu-search');
this.searchEmojis(term);
});
const $menu = $('.emoji-menu'); this.registerEventListener('on', $search, 'input', (e) => {
this.registerEventListener('on', $menu, transitionEndEventString, (e) => { const term = $(e.target).val().trim();
if (e.target === e.currentTarget) { this.searchEmojis(term);
// Clear the search });
this.searchEmojis('');
}
});
};
AwardsHandler.prototype.searchEmojis = function searchEmojis(term) { const $menu = $('.emoji-menu');
const $search = $('.js-emoji-menu-search'); this.registerEventListener('on', $menu, transitionEndEventString, (e) => {
$search.val(term); if (e.target === e.currentTarget) {
// Clear the search
// Clean previous search results this.searchEmojis('');
$('ul.emoji-menu-search, h5.emoji-search-title').remove(); }
if (term.length > 0) { });
// Generate a search result block
const h5 = $('<h5 class="emoji-search-title"/>').text('Search results');
const foundEmojis = this.findMatchingEmojiElements(term).show();
const ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(foundEmojis);
$('.emoji-menu-content ul, .emoji-menu-content h5').hide();
$('.emoji-menu-content').append(h5).append(ul);
} else {
$('.emoji-menu-content').children().show();
} }
};
AwardsHandler.prototype.findMatchingEmojiElements = function findMatchingEmojiElements(term) {
const safeTerm = term.toLowerCase();
const namesMatchingAlias = []; searchEmojis(term) {
Object.keys(emojiAliases).forEach((alias) => { const $search = $('.js-emoji-menu-search');
if (alias.indexOf(safeTerm) >= 0) { $search.val(term);
namesMatchingAlias.push(emojiAliases[alias]);
// Clean previous search results
$('ul.emoji-menu-search, h5.emoji-search-title').remove();
if (term.length > 0) {
// Generate a search result block
const h5 = $('<h5 class="emoji-search-title"/>').text('Search results');
const foundEmojis = this.findMatchingEmojiElements(term).show();
const ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(foundEmojis);
$('.emoji-menu-content ul, .emoji-menu-content h5').hide();
$('.emoji-menu-content').append(h5).append(ul);
} else {
$('.emoji-menu-content').children().show();
} }
}); }
const $matchingElements = namesMatchingAlias.concat(safeTerm)
.reduce(
($result, searchTerm) =>
$result.add($(`.emoji-menu-list:not(.frequent-emojis) [data-name*="${searchTerm}"]`)),
$([]),
);
return $matchingElements.closest('li').clone();
};
AwardsHandler.prototype.destroy = function destroy() { findMatchingEmojiElements(term) {
this.eventListeners.forEach((entry) => { const safeTerm = term.toLowerCase();
entry.element.off.call(entry.element, ...entry.args);
}); const namesMatchingAlias = [];
$('.emoji-menu').remove(); Object.keys(emojiAliases).forEach((alias) => {
}; if (alias.indexOf(safeTerm) >= 0) {
namesMatchingAlias.push(emojiAliases[alias]);
}
});
const $matchingElements = namesMatchingAlias.concat(safeTerm)
.reduce(
($result, searchTerm) =>
$result.add($(`.emoji-menu-list:not(.frequent-emojis) [data-name*="${searchTerm}"]`)),
$([]),
);
return $matchingElements.closest('li').clone();
}
export default AwardsHandler; destroy() {
this.eventListeners.forEach((entry) => {
entry.element.off.call(entry.element, ...entry.args);
});
$('.emoji-menu').remove();
}
}
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