diff options
| -rw-r--r-- | app/assets/javascripts/awards_handler.js | 753 | 
1 files changed, 374 insertions, 379 deletions
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js index adb45b0606d..ebe722061d7 100644 --- a/app/assets/javascripts/awards_handler.js +++ b/app/assets/javascripts/awards_handler.js @@ -1,3 +1,4 @@ +/* eslint-disable class-methods-use-this */  /* global Flash */  import Cookies from 'js-cookie'; @@ -68,141 +69,140 @@ function renderCategory(name, emojiList, opts = {}) {    `;  } -function AwardsHandler() { -  this.eventListeners = []; -  this.aliases = emojiAliases; -  // If the user shows intent let's pre-build the menu -  this.registerEventListener('one', $(document), 'mouseenter focus', '.js-add-award', 'mouseenter focus', () => { -    const $menu = $('.emoji-menu'); -    if ($menu.length === 0) { -      requestAnimationFrame(() => { -        this.createEmojiMenu(); -      }); -    } -    // Prebuild the categoryMap -    categoryMap = categoryMap || buildCategoryMap(); -  }); -  this.registerEventListener('on', $(document), 'click', '.js-add-award', (e) => { -    e.stopPropagation(); -    e.preventDefault(); -    this.showEmojiMenu($(e.currentTarget)); -  }); +export default class AwardsHandler { +  constructor() { +    this.eventListeners = []; +    this.aliases = emojiAliases; +    // If the user shows intent let's pre-build the menu +    this.registerEventListener('one', $(document), 'mouseenter focus', '.js-add-award', 'mouseenter focus', () => { +      const $menu = $('.emoji-menu'); +      if ($menu.length === 0) { +        requestAnimationFrame(() => { +          this.createEmojiMenu(); +        }); +      } +      // Prebuild the categoryMap +      categoryMap = categoryMap || buildCategoryMap(); +    }); +    this.registerEventListener('on', $(document), 'click', '.js-add-award', (e) => { +      e.stopPropagation(); +      e.preventDefault(); +      this.showEmojiMenu($(e.currentTarget)); +    }); -  this.registerEventListener('on', $('html'), 'click', (e) => { -    const $target = $(e.target); -    if (!$target.closest('.emoji-menu-content').length) { -      $('.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'); +    this.registerEventListener('on', $('html'), 'click', (e) => { +      const $target = $(e.target); +      if (!$target.closest('.emoji-menu-content').length) { +        $('.js-awards-block.current').removeClass('current');        } -    } -  }); -  this.registerEventListener('on', $(document), 'click', '.js-emoji-btn', (e) => { -    e.preventDefault(); -    const $target = $(e.currentTarget); -    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); -  }); -} +      if (!$target.closest('.emoji-menu').length) { +        if ($('.emoji-menu').is(':visible')) { +          $('.js-add-award.is-active').removeClass('is-active'); +          $('.emoji-menu').removeClass('is-visible'); +        } +      } +    }); +    this.registerEventListener('on', $(document), 'click', '.js-emoji-btn', (e) => { +      e.preventDefault(); +      const $target = $(e.currentTarget); +      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) { -  element[method].call(element, ...args); -  this.eventListeners.push({ -    element, -    args, -  }); -}; +  registerEventListener(method = 'on', element, ...args) { +    element[method].call(element, ...args); +    this.eventListeners.push({ +      element, +      args, +    }); +  } -AwardsHandler.prototype.showEmojiMenu = function showEmojiMenu($addBtn) { -  if ($addBtn.hasClass('js-note-emoji')) { -    $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(); +  showEmojiMenu($addBtn) { +    if ($addBtn.hasClass('js-note-emoji')) { +      $addBtn.closest('.note').find('.js-awards-block').addClass('current');      } else { -      $addBtn.addClass('is-active'); -      this.positionMenu($menu, $addBtn); -      $menu.addClass('is-visible'); -      $('.js-emoji-menu-search').focus(); +      $addBtn.closest('.js-awards-block').addClass('current');      } -  } 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'); + +    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 { +        $addBtn.addClass('is-active'); +        this.positionMenu($menu, $addBtn); +        $menu.addClass('is-visible');          $('.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. -// Then render the remaining categories of emojis one by one to avoid jank. -AwardsHandler.prototype.createEmojiMenu = function createEmojiMenu(callback) { -  if (this.isCreatingEmojiMenu) { -    return; -  } -  this.isCreatingEmojiMenu = true; - -  // Render the first category -  categoryMap = categoryMap || buildCategoryMap(); -  const categoryNameKey = Object.keys(categoryMap)[0]; -  const emojisInCategory = categoryMap[categoryNameKey]; -  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', -    }); -  } +    // Render the first category +    categoryMap = categoryMap || buildCategoryMap(); +    const categoryNameKey = Object.keys(categoryMap)[0]; +    const emojisInCategory = categoryMap[categoryNameKey]; +    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 = ` -    <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" /> +    const emojiMenuMarkup = ` +      <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" /> -      <div class="emoji-menu-content"> -        ${frequentlyUsedCatgegory} -        ${firstCategory} +        <div class="emoji-menu-content"> +          ${frequentlyUsedCatgegory} +          ${firstCategory} +        </div>        </div> -    </div> -  `; +    `; -  document.body.insertAdjacentHTML('beforeend', emojiMenuMarkup); +    document.body.insertAdjacentHTML('beforeend', emojiMenuMarkup); -  this.addRemainingEmojiMenuCategories(); -  this.setupSearch(); -  if (callback) { -    callback(); +    this.addRemainingEmojiMenuCategories(); +    this.setupSearch(); +    if (callback) { +      callback(); +    }    } -}; -AwardsHandler -  .prototype -  .addRemainingEmojiMenuCategories = function addRemainingEmojiMenuCategories() { +  addRemainingEmojiMenuCategories() {      if (this.isAddingRemainingEmojiMenuCategories) {        return;      } @@ -243,176 +243,174 @@ AwardsHandler        emojiContentElement.insertAdjacentHTML('beforeend', '<p>We encountered an error while adding the remaining categories</p>');        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( -  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); +  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 { -      const counter = $emojiButton.find('.js-counter'); -      counter.text(parseInt(counter.text(), 10) + 1); -      $emojiButton.addClass('active'); -      this.addYouToUserList(votesBlock, normalizedEmoji); -      this.animateEmoji($emojiButton); +      css.left = `${$addBtn.offset().left}px`; +      $menu.removeClass('is-aligned-right');      } -  } else { -    votesBlock.removeClass('hidden'); -    this.createEmoji(votesBlock, normalizedEmoji); +    return $menu.css(css);    } -}; -AwardsHandler.prototype.getVotesBlock = function getVotesBlock() { -  const currentBlock = $('.js-awards-block.current'); -  let resultantVotesBlock = currentBlock; -  if (currentBlock.length === 0) { -    resultantVotesBlock = $('.js-awards-block').eq(0); +  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');    } -  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() { -  return this.getVotesBlock().data('award-url'); -}; +  getVotesBlock() { +    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) { -  const awardUrl = this.getAwardUrl(); -  if (emoji === 'thumbsup' || emoji === 'thumbsdown') { -    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); +  getAwardUrl() { +    return this.getVotesBlock().data('award-url'); +  } + +  checkMutuality(votesBlock, emoji) { +    const awardUrl = this.getAwardUrl(); +    if (emoji === 'thumbsup' || emoji === 'thumbsdown') { +      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) { -  return $emojiButton.hasClass('active'); -}; +  isActive($emojiButton) { +    return $emojiButton.hasClass('active'); +  } -AwardsHandler.prototype.isUserAuthored = function isUserAuthored($button) { -  return $button.hasClass('js-user-authored'); -}; +  isUserAuthored($button) { +    return $button.hasClass('js-user-authored'); +  } -AwardsHandler.prototype.decrementCounter = function decrementCounter($emojiButton, emoji) { -  const counter = $('.js-counter', $emojiButton); -  const counterNumber = parseInt(counter.text(), 10); -  if (counterNumber > 1) { -    counter.text(counterNumber - 1); -    this.removeYouFromUserList($emojiButton); -  } else if (emoji === 'thumbsup' || emoji === 'thumbsdown') { -    $emojiButton.tooltip('destroy'); -    counter.text('0'); -    this.removeYouFromUserList($emojiButton); -    if ($emojiButton.parents('.note').length) { +  decrementCounter($emojiButton, emoji) { +    const counter = $('.js-counter', $emojiButton); +    const counterNumber = parseInt(counter.text(), 10); +    if (counterNumber > 1) { +      counter.text(counterNumber - 1); +      this.removeYouFromUserList($emojiButton); +    } else if (emoji === 'thumbsup' || emoji === 'thumbsdown') { +      $emojiButton.tooltip('destroy'); +      counter.text('0'); +      this.removeYouFromUserList($emojiButton); +      if ($emojiButton.parents('.note').length) { +        this.removeEmoji($emojiButton); +      } +    } else {        this.removeEmoji($emojiButton);      } -  } else { -    this.removeEmoji($emojiButton); +    return $emojiButton.removeClass('active');    } -  return $emojiButton.removeClass('active'); -}; -AwardsHandler.prototype.removeEmoji = function removeEmoji($emojiButton) { -  $emojiButton.tooltip('destroy'); -  $emojiButton.remove(); -  const $votesBlock = this.getVotesBlock(); -  if ($votesBlock.find('.js-emoji-btn').length === 0) { -    $votesBlock.addClass('hidden'); +  removeEmoji($emojiButton) { +    $emojiButton.tooltip('destroy'); +    $emojiButton.remove(); +    const $votesBlock = this.getVotesBlock(); +    if ($votesBlock.find('.js-emoji-btn').length === 0) { +      $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) { -  let sentence; -  if (list.length <= 2) { -    sentence = list.join(' and '); -  } else { -    sentence = `${list.slice(0, -1).join(', ')}, and ${list[list.length - 1]}`; +  getAwardTooltip($awardBlock) { +    return $awardBlock.attr('data-original-title') || $awardBlock.attr('data-title') || '';    } -  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) { -  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'); -}; +    return sentence; +  } -AwardsHandler.prototype.addYouToUserList = function 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'); -}; +  removeYouFromUserList($emojiButton) { +    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'); +  } + +  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 -  .prototype -  .createAwardButtonForVotesBlock = function createAwardButtonForVotesBlock(votesBlock, emojiName) { +  createAwardButtonForVotesBlock(votesBlock, emojiName) {      const buttonHtml = `        <button class="btn award-control js-emoji-btn has-tooltip active" title="You" data-placement="bottom">          ${glEmojiTag(emojiName)} @@ -424,144 +422,141 @@ AwardsHandler      this.animateEmoji($emojiButton);      $('.award-control').tooltip();      votesBlock.removeClass('current'); -  }; +  } -AwardsHandler.prototype.animateEmoji = function animateEmoji($emoji) { -  const className = 'pulse animated once short'; -  $emoji.addClass(className); +  animateEmoji($emoji) { +    const className = 'pulse animated once short'; +    $emoji.addClass(className); -  this.registerEventListener('on', $emoji, animationEndEventString, (e) => { -    $(e.currentTarget).removeClass(className); -  }); -}; +    this.registerEventListener('on', $emoji, animationEndEventString, (e) => { +      $(e.currentTarget).removeClass(className); +    }); +  } -AwardsHandler.prototype.createEmoji = function createEmoji(votesBlock, emoji) { -  if ($('.emoji-menu').length) { -    this.createAwardButtonForVotesBlock(votesBlock, emoji); +  createEmoji(votesBlock, emoji) { +    if ($('.emoji-menu').length) { +      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) { -  if (this.isUserAuthored($emojiButton)) { -    this.userAuthored($emojiButton); -  } else { -    $.post(awardUrl, { -      name: emoji, -    }, (data) => { -      if (data.ok) { -        callback(); -      } -    }).fail(() => new Flash('Something went wrong on our end.')); +  postEmoji($emojiButton, awardUrl, emoji, callback) { +    if (this.isUserAuthored($emojiButton)) { +      this.userAuthored($emojiButton); +    } else { +      $.post(awardUrl, { +        name: emoji, +      }, (data) => { +        if (data.ok) { +          callback(); +        } +      }).fail(() => new Flash('Something went wrong on our end.')); +    }    } -}; -AwardsHandler.prototype.findEmojiIcon = function findEmojiIcon(votesBlock, emoji) { -  return votesBlock.find(`.js-emoji-btn [data-name="${emoji}"]`); -}; +  findEmojiIcon(votesBlock, emoji) { +    return votesBlock.find(`.js-emoji-btn [data-name="${emoji}"]`); +  } -AwardsHandler.prototype.userAuthored = function userAuthored($emojiButton) { -  const oldTitle = this.getAwardTooltip($emojiButton); -  const newTitle = 'You cannot vote on your own issue, MR and note'; -  gl.utils.updateTooltipTitle($emojiButton, newTitle).tooltip('show'); -  // Restore tooltip back to award list -  return setTimeout(() => { -    $emojiButton.tooltip('hide'); -    gl.utils.updateTooltipTitle($emojiButton, oldTitle); -  }, 2800); -}; +  userAuthored($emojiButton) { +    const oldTitle = this.getAwardTooltip($emojiButton); +    const newTitle = 'You cannot vote on your own issue, MR and note'; +    gl.utils.updateTooltipTitle($emojiButton, newTitle).tooltip('show'); +    // Restore tooltip back to award list +    return setTimeout(() => { +      $emojiButton.tooltip('hide'); +      gl.utils.updateTooltipTitle($emojiButton, oldTitle); +    }, 2800); +  } -AwardsHandler.prototype.scrollToAwards = function scrollToAwards() { -  const options = { -    scrollTop: $('.awards').offset().top - 110, -  }; -  return $('body, html').animate(options, 200); -}; +  scrollToAwards() { +    const options = { +      scrollTop: $('.awards').offset().top - 110, +    }; +    return $('body, html').animate(options, 200); +  } -AwardsHandler.prototype.normalizeEmojiName = function normalizeEmojiName(emoji) { -  return Object.prototype.hasOwnProperty.call(this.aliases, emoji) ? this.aliases[emoji] : emoji; -}; +  normalizeEmojiName(emoji) { +    return Object.prototype.hasOwnProperty.call(this.aliases, emoji) ? this.aliases[emoji] : emoji; +  } -AwardsHandler -  .prototype -  .addEmojiToFrequentlyUsedList = function addEmojiToFrequentlyUsedList(emoji) { +  addEmojiToFrequentlyUsedList(emoji) {      if (isEmojiNameValid(emoji)) {        this.frequentlyUsedEmojis = _.uniq(this.getFrequentlyUsedEmojis().concat(emoji));        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() { -  const $search = $('.js-emoji-menu-search'); +      return this.frequentlyUsedEmojis; +    })(); +  } -  this.registerEventListener('on', $search, 'input', (e) => { -    const term = $(e.target).val().trim(); -    this.searchEmojis(term); -  }); +  setupSearch() { +    const $search = $('.js-emoji-menu-search'); -  const $menu = $('.emoji-menu'); -  this.registerEventListener('on', $menu, transitionEndEventString, (e) => { -    if (e.target === e.currentTarget) { -      // Clear the search -      this.searchEmojis(''); -    } -  }); -}; +    this.registerEventListener('on', $search, 'input', (e) => { +      const term = $(e.target).val().trim(); +      this.searchEmojis(term); +    }); -AwardsHandler.prototype.searchEmojis = function searchEmojis(term) { -  const $search = $('.js-emoji-menu-search'); -  $search.val(term); - -  // 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 $menu = $('.emoji-menu'); +    this.registerEventListener('on', $menu, transitionEndEventString, (e) => { +      if (e.target === e.currentTarget) { +        // Clear the search +        this.searchEmojis(''); +      } +    });    } -}; - -AwardsHandler.prototype.findMatchingEmojiElements = function findMatchingEmojiElements(term) { -  const safeTerm = term.toLowerCase(); -  const namesMatchingAlias = []; -  Object.keys(emojiAliases).forEach((alias) => { -    if (alias.indexOf(safeTerm) >= 0) { -      namesMatchingAlias.push(emojiAliases[alias]); +  searchEmojis(term) { +    const $search = $('.js-emoji-menu-search'); +    $search.val(term); + +    // 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() { -  this.eventListeners.forEach((entry) => { -    entry.element.off.call(entry.element, ...entry.args); -  }); -  $('.emoji-menu').remove(); -}; +  findMatchingEmojiElements(term) { +    const safeTerm = term.toLowerCase(); + +    const namesMatchingAlias = []; +    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(); +  } +}  | 
