summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/awards_handler.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/awards_handler.js')
-rw-r--r--app/assets/javascripts/awards_handler.js380
1 files changed, 380 insertions, 0 deletions
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
new file mode 100644
index 00000000000..ea683b31f75
--- /dev/null
+++ b/app/assets/javascripts/awards_handler.js
@@ -0,0 +1,380 @@
+(function() {
+ this.AwardsHandler = (function() {
+ function AwardsHandler() {
+ this.aliases = gl.emojiAliases();
+ $(document).off('click', '.js-add-award').on('click', '.js-add-award', (function(_this) {
+ return function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ return _this.showEmojiMenu($(e.currentTarget));
+ };
+ })(this));
+ $('html').on('click', function(e) {
+ var $target;
+ $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');
+ return $('.emoji-menu').removeClass('is-visible');
+ }
+ }
+ });
+ $(document).off('click', '.js-emoji-btn').on('click', '.js-emoji-btn', (function(_this) {
+ return function(e) {
+ var $target, emoji;
+ e.preventDefault();
+ $target = $(e.currentTarget);
+ emoji = $target.find('.icon').data('emoji');
+ $target.closest('.js-awards-block').addClass('current');
+ return _this.addAward(_this.getVotesBlock(), _this.getAwardUrl(), emoji);
+ };
+ })(this));
+ }
+
+ AwardsHandler.prototype.showEmojiMenu = function($addBtn) {
+ var $holder, $menu, url;
+ $menu = $('.emoji-menu');
+ if ($addBtn.hasClass('js-note-emoji')) {
+ $addBtn.closest('.note').find('.js-awards-block').addClass('current');
+ } else {
+ $addBtn.closest('.js-awards-block').addClass('current');
+ }
+ if ($menu.length) {
+ $holder = $addBtn.closest('.js-award-holder');
+ if ($menu.is('.is-visible')) {
+ $addBtn.removeClass('is-active');
+ $menu.removeClass('is-visible');
+ return $('#emoji_search').blur();
+ } else {
+ $addBtn.addClass('is-active');
+ this.positionMenu($menu, $addBtn);
+ $menu.addClass('is-visible');
+ return $('#emoji_search').focus();
+ }
+ } else {
+ $addBtn.addClass('is-loading is-active');
+ url = this.getAwardMenuUrl();
+ return this.createEmojiMenu(url, (function(_this) {
+ return function() {
+ $addBtn.removeClass('is-loading');
+ $menu = $('.emoji-menu');
+ _this.positionMenu($menu, $addBtn);
+ if (!_this.frequentEmojiBlockRendered) {
+ _this.renderFrequentlyUsedBlock();
+ }
+ return setTimeout(function() {
+ $menu.addClass('is-visible');
+ $('#emoji_search').focus();
+ return _this.setupSearch();
+ }, 200);
+ };
+ })(this));
+ }
+ };
+
+ AwardsHandler.prototype.createEmojiMenu = function(awardMenuUrl, callback) {
+ return $.get(awardMenuUrl, function(response) {
+ $('body').append(response);
+ return callback();
+ });
+ };
+
+ AwardsHandler.prototype.positionMenu = function($menu, $addBtn) {
+ var css, position;
+ position = $addBtn.data('position');
+ css = {
+ top: ($addBtn.offset().top + $addBtn.outerHeight()) + "px"
+ };
+ if ((position != null) && 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(votesBlock, awardUrl, emoji, checkMutuality, callback) {
+ if (checkMutuality == null) {
+ checkMutuality = true;
+ }
+ emoji = this.normilizeEmojiName(emoji);
+ this.postEmoji(awardUrl, emoji, (function(_this) {
+ return function() {
+ _this.addAwardToEmojiBar(votesBlock, emoji, checkMutuality);
+ return typeof callback === "function" ? callback() : void 0;
+ };
+ })(this));
+ return $('.emoji-menu').removeClass('is-visible');
+ };
+
+ AwardsHandler.prototype.addAwardToEmojiBar = function(votesBlock, emoji, checkForMutuality) {
+ var $emojiButton, counter;
+ if (checkForMutuality == null) {
+ checkForMutuality = true;
+ }
+ if (checkForMutuality) {
+ this.checkMutuality(votesBlock, emoji);
+ }
+ this.addEmojiToFrequentlyUsedList(emoji);
+ emoji = this.normilizeEmojiName(emoji);
+ $emojiButton = this.findEmojiIcon(votesBlock, emoji).parent();
+ if ($emojiButton.length > 0) {
+ if (this.isActive($emojiButton)) {
+ return this.decrementCounter($emojiButton, emoji);
+ } else {
+ counter = $emojiButton.find('.js-counter');
+ counter.text(parseInt(counter.text()) + 1);
+ $emojiButton.addClass('active');
+ this.addMeToUserList(votesBlock, emoji);
+ return this.animateEmoji($emojiButton);
+ }
+ } else {
+ votesBlock.removeClass('hidden');
+ return this.createEmoji(votesBlock, emoji);
+ }
+ };
+
+ AwardsHandler.prototype.getVotesBlock = function() {
+ var currentBlock;
+ currentBlock = $('.js-awards-block.current');
+ if (currentBlock.length) {
+ return currentBlock;
+ } else {
+ return $('.js-awards-block').eq(0);
+ }
+ };
+
+ AwardsHandler.prototype.getAwardUrl = function() {
+ return this.getVotesBlock().data('award-url');
+ };
+
+ AwardsHandler.prototype.checkMutuality = function(votesBlock, emoji) {
+ var $emojiButton, awardUrl, isAlreadyVoted, mutualVote;
+ awardUrl = this.getAwardUrl();
+ if (emoji === 'thumbsup' || emoji === 'thumbsdown') {
+ mutualVote = emoji === 'thumbsup' ? 'thumbsdown' : 'thumbsup';
+ $emojiButton = votesBlock.find("[data-emoji=" + mutualVote + "]").parent();
+ isAlreadyVoted = $emojiButton.hasClass('active');
+ if (isAlreadyVoted) {
+ this.showEmojiLoader($emojiButton);
+ return this.addAward(votesBlock, awardUrl, mutualVote, false, function() {
+ return $emojiButton.removeClass('is-loading');
+ });
+ }
+ }
+ };
+
+ AwardsHandler.prototype.showEmojiLoader = function($emojiButton) {
+ var $loader;
+ $loader = $emojiButton.find('.fa-spinner');
+ if (!$loader.length) {
+ $emojiButton.append('<i class="fa fa-spinner fa-spin award-control-icon award-control-icon-loading"></i>');
+ }
+ return $emojiButton.addClass('is-loading');
+ };
+
+ AwardsHandler.prototype.isActive = function($emojiButton) {
+ return $emojiButton.hasClass('active');
+ };
+
+ AwardsHandler.prototype.decrementCounter = function($emojiButton, emoji) {
+ var counter, counterNumber;
+ counter = $('.js-counter', $emojiButton);
+ counterNumber = parseInt(counter.text(), 10);
+ if (counterNumber > 1) {
+ counter.text(counterNumber - 1);
+ this.removeMeFromUserList($emojiButton, emoji);
+ } else if (emoji === 'thumbsup' || emoji === 'thumbsdown') {
+ $emojiButton.tooltip('destroy');
+ counter.text('0');
+ this.removeMeFromUserList($emojiButton, emoji);
+ if ($emojiButton.parents('.note').length) {
+ this.removeEmoji($emojiButton);
+ }
+ } else {
+ this.removeEmoji($emojiButton);
+ }
+ return $emojiButton.removeClass('active');
+ };
+
+ AwardsHandler.prototype.removeEmoji = function($emojiButton) {
+ var $votesBlock;
+ $emojiButton.tooltip('destroy');
+ $emojiButton.remove();
+ $votesBlock = this.getVotesBlock();
+ if ($votesBlock.find('.js-emoji-btn').length === 0) {
+ return $votesBlock.addClass('hidden');
+ }
+ };
+
+ AwardsHandler.prototype.getAwardTooltip = function($awardBlock) {
+ return $awardBlock.attr('data-original-title') || $awardBlock.attr('data-title') || '';
+ };
+
+ AwardsHandler.prototype.removeMeFromUserList = function($emojiButton, emoji) {
+ var authors, awardBlock, newAuthors, originalTitle;
+ awardBlock = $emojiButton;
+ originalTitle = this.getAwardTooltip(awardBlock);
+ authors = originalTitle.split(', ');
+ authors.splice(authors.indexOf('me'), 1);
+ newAuthors = authors.join(', ');
+ awardBlock.closest('.js-emoji-btn').removeData('original-title').attr('data-original-title', newAuthors);
+ return this.resetTooltip(awardBlock);
+ };
+
+ AwardsHandler.prototype.addMeToUserList = function(votesBlock, emoji) {
+ var awardBlock, origTitle, users;
+ awardBlock = this.findEmojiIcon(votesBlock, emoji).parent();
+ origTitle = this.getAwardTooltip(awardBlock);
+ users = [];
+ if (origTitle) {
+ users = origTitle.trim().split(', ');
+ }
+ users.push('me');
+ awardBlock.attr('title', users.join(', '));
+ return this.resetTooltip(awardBlock);
+ };
+
+ AwardsHandler.prototype.resetTooltip = function(award) {
+ var cb;
+ award.tooltip('destroy');
+ cb = function() {
+ return award.tooltip();
+ };
+ return setTimeout(cb, 200);
+ };
+
+ AwardsHandler.prototype.createEmoji_ = function(votesBlock, emoji) {
+ var $emojiButton, buttonHtml, emojiCssClass;
+ emojiCssClass = this.resolveNameToCssClass(emoji);
+ buttonHtml = "<button class='btn award-control js-emoji-btn has-tooltip active' title='me' data-placement='bottom'> <div class='icon emoji-icon " + emojiCssClass + "' data-emoji='" + emoji + "'></div> <span class='award-control-text js-counter'>1</span> </button>";
+ $emojiButton = $(buttonHtml);
+ $emojiButton.insertBefore(votesBlock.find('.js-award-holder')).find('.emoji-icon').data('emoji', emoji);
+ this.animateEmoji($emojiButton);
+ $('.award-control').tooltip();
+ return votesBlock.removeClass('current');
+ };
+
+ AwardsHandler.prototype.animateEmoji = function($emoji) {
+ var className;
+ className = 'pulse animated';
+ $emoji.addClass(className);
+ return setTimeout((function() {
+ return $emoji.removeClass(className);
+ }), 321);
+ };
+
+ AwardsHandler.prototype.createEmoji = function(votesBlock, emoji) {
+ if ($('.emoji-menu').length) {
+ return this.createEmoji_(votesBlock, emoji);
+ }
+ return this.createEmojiMenu(this.getAwardMenuUrl(), (function(_this) {
+ return function() {
+ return _this.createEmoji_(votesBlock, emoji);
+ };
+ })(this));
+ };
+
+ AwardsHandler.prototype.getAwardMenuUrl = function() {
+ return gon.award_menu_url;
+ };
+
+ AwardsHandler.prototype.resolveNameToCssClass = function(emoji) {
+ var emojiIcon, unicodeName;
+ emojiIcon = $(".emoji-menu-content [data-emoji='" + emoji + "']");
+ if (emojiIcon.length > 0) {
+ unicodeName = emojiIcon.data('unicode-name');
+ } else {
+ unicodeName = $(".emoji-menu-content [data-aliases*=':" + emoji + ":']").data('unicode-name');
+ }
+ return "emoji-" + unicodeName;
+ };
+
+ AwardsHandler.prototype.postEmoji = function(awardUrl, emoji, callback) {
+ return $.post(awardUrl, {
+ name: emoji
+ }, function(data) {
+ if (data.ok) {
+ return callback();
+ }
+ });
+ };
+
+ AwardsHandler.prototype.findEmojiIcon = function(votesBlock, emoji) {
+ return votesBlock.find(".js-emoji-btn [data-emoji='" + emoji + "']");
+ };
+
+ AwardsHandler.prototype.scrollToAwards = function() {
+ var options;
+ options = {
+ scrollTop: $('.awards').offset().top - 110
+ };
+ return $('body, html').animate(options, 200);
+ };
+
+ AwardsHandler.prototype.normilizeEmojiName = function(emoji) {
+ return this.aliases[emoji] || emoji;
+ };
+
+ AwardsHandler.prototype.addEmojiToFrequentlyUsedList = function(emoji) {
+ var frequentlyUsedEmojis;
+ frequentlyUsedEmojis = this.getFrequentlyUsedEmojis();
+ frequentlyUsedEmojis.push(emoji);
+ return $.cookie('frequently_used_emojis', frequentlyUsedEmojis.join(','), {
+ expires: 365
+ });
+ };
+
+ AwardsHandler.prototype.getFrequentlyUsedEmojis = function() {
+ var frequentlyUsedEmojis;
+ frequentlyUsedEmojis = ($.cookie('frequently_used_emojis') || '').split(',');
+ return _.compact(_.uniq(frequentlyUsedEmojis));
+ };
+
+ AwardsHandler.prototype.renderFrequentlyUsedBlock = function() {
+ var emoji, frequentlyUsedEmojis, i, len, ul;
+ if ($.cookie('frequently_used_emojis')) {
+ frequentlyUsedEmojis = this.getFrequentlyUsedEmojis();
+ ul = $("<ul class='clearfix emoji-menu-list frequent-emojis'>");
+ for (i = 0, len = frequentlyUsedEmojis.length; i < len; i++) {
+ emoji = frequentlyUsedEmojis[i];
+ $(".emoji-menu-content [data-emoji='" + emoji + "']").closest('li').clone().appendTo(ul);
+ }
+ $('.emoji-menu-content').prepend(ul).prepend($('<h5>').text('Frequently used'));
+ }
+ return this.frequentEmojiBlockRendered = true;
+ };
+
+ AwardsHandler.prototype.setupSearch = function() {
+ return $('input.emoji-search').on('keyup', (function(_this) {
+ return function(ev) {
+ var found_emojis, h5, term, ul;
+ term = $(ev.target).val();
+ $('ul.emoji-menu-search, h5.emoji-search').remove();
+ if (term) {
+ h5 = $('<h5>').text('Search results');
+ found_emojis = _this.searchEmojis(term).show();
+ ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(found_emojis);
+ $('.emoji-menu-content ul, .emoji-menu-content h5').hide();
+ return $('.emoji-menu-content').append(h5).append(ul);
+ } else {
+ return $('.emoji-menu-content').children().show();
+ }
+ };
+ })(this));
+ };
+
+ AwardsHandler.prototype.searchEmojis = function(term) {
+ return $(".emoji-menu-list:not(.frequent-emojis) [data-emoji*='" + term + "']").closest('li').clone();
+ };
+
+ return AwardsHandler;
+
+ })();
+
+}).call(this);