Commit 783a5ae9 authored by Phil Hughes's avatar Phil Hughes Committed by Fatih Acet

Adds the emoji menu to the body and then re-positions it depending on which button clicked

This spots bugs where the menu could be in a div that has overflow hidden on ie. diff comments
parent bf96c305
...@@ -13,6 +13,7 @@ class @AwardsHandler ...@@ -13,6 +13,7 @@ class @AwardsHandler
$("html").on 'click', (event) -> $("html").on 'click', (event) ->
if !$(event.target).closest(".emoji-menu").length if !$(event.target).closest(".emoji-menu").length
if $(".emoji-menu").is(":visible") if $(".emoji-menu").is(":visible")
$('.js-add-award.is-active').removeClass 'is-active'
$(".emoji-menu").removeClass "is-visible" $(".emoji-menu").removeClass "is-visible"
$(document) $(document)
...@@ -22,10 +23,13 @@ class @AwardsHandler ...@@ -22,10 +23,13 @@ class @AwardsHandler
handleClick: (e) => handleClick: (e) =>
e.preventDefault() e.preventDefault()
$emojiBtn = $(e.currentTarget) $emojiBtn = $(e.currentTarget)
$votesBlock = $($emojiBtn.closest('.js-award-holder').data('target')) $addAwardBtn = $('.js-add-award.is-active')
$votesBlock = $($addAwardBtn.closest('.js-award-holder').data('target'))
if $votesBlock.length is 0 if $addAwardBtn.length is 0
$votesBlock = $emojiBtn.closest('.js-awards-block') $votesBlock = $emojiBtn.closest('.js-awards-block')
else if $votesBlock.length is 0
$votesBlock = $addAwardBtn.closest('.js-awards-block')
$votesBlock.addClass 'js-awards-block-current' $votesBlock.addClass 'js-awards-block-current'
awardUrl = $votesBlock.data 'award-url' awardUrl = $votesBlock.data 'award-url'
...@@ -35,32 +39,56 @@ class @AwardsHandler ...@@ -35,32 +39,56 @@ class @AwardsHandler
@addAward awardUrl, emoji @addAward awardUrl, emoji
showEmojiMenu: ($addBtn) -> showEmojiMenu: ($addBtn) ->
if $(".emoji-menu").length $menu = $('.emoji-menu')
$holder = $addBtn.closest('.js-award-holder')
if $holder.find('.emoji-menu').length is 0 if $menu.length
$(".emoji-menu").detach().appendTo $holder $holder = $addBtn.closest('.js-award-holder')
if $(".emoji-menu").is ".is-visible" if $menu.is ".is-visible"
$(".emoji-menu").removeClass "is-visible" $addBtn.removeClass "is-active"
$menu.removeClass "is-visible"
$("#emoji_search").blur() $("#emoji_search").blur()
else else
$(".emoji-menu").addClass "is-visible" $addBtn.addClass "is-active"
@positionMenu($menu, $addBtn)
$menu.addClass "is-visible"
$("#emoji_search").focus() $("#emoji_search").focus()
else else
$addBtn.addClass "is-loading" $addBtn.addClass "is-loading is-active"
$.get $addBtn.data('award-menu-url'), (response) => $.get $addBtn.data('award-menu-url'), (response) =>
$addBtn.removeClass "is-loading" $addBtn.removeClass "is-loading"
$addBtn.closest('.js-award-holder').append response $('body').append response
$menu = $(".emoji-menu")
@positionMenu($menu, $addBtn)
@renderFrequentlyUsedBlock() @renderFrequentlyUsedBlock()
setTimeout => setTimeout =>
$(".emoji-menu").addClass "is-visible" $menu.addClass "is-visible"
$("#emoji_search").focus() $("#emoji_search").focus()
@setupSearch() @setupSearch()
, 200 , 200
positionMenu: ($menu, $addBtn) ->
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
css =
top: "#{$addBtn.offset().top + $addBtn.outerHeight()}px"
if position? and position is '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"
$menu.css(css)
addAward: (awardUrl, emoji) -> addAward: (awardUrl, emoji) ->
emoji = @normilizeEmojiName(emoji) emoji = @normilizeEmojiName(emoji)
@postEmoji awardUrl, emoji, => @postEmoji awardUrl, emoji, =>
......
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
.emoji-menu { .emoji-menu {
position: absolute; position: absolute;
top: 100%;
left: 0;
margin-top: 3px; margin-top: 3px;
z-index: 1000; z-index: 1000;
min-width: 160px; min-width: 160px;
...@@ -21,7 +19,12 @@ ...@@ -21,7 +19,12 @@
opacity: 0; opacity: 0;
transform: scale(.2); transform: scale(.2);
transform-origin: 0 -45px; transform-origin: 0 -45px;
transition: all .3s cubic-bezier(.87,-.41,.19,1.44); transition: .3s cubic-bezier(.87,-.41,.19,1.44);
transition-property: transform, opacity;
&.is-aligned-right {
transform-origin: 100% -45px;
}
&.is-visible { &.is-visible {
pointer-events: all; pointer-events: all;
......
...@@ -280,14 +280,6 @@ ul.notes { ...@@ -280,14 +280,6 @@ ul.notes {
} }
} }
.note-action-award-holder {
.emoji-menu {
left: auto;
right: -15px;
transform-origin: 100% -45px;
}
}
.note-award-control { .note-award-control {
display: block; display: block;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
.note-actions .note-actions
- if current_user - if current_user
.award-menu-holder.note-action-award-holder.js-award-holder.js-award-action-btn{ data: { target: "##{dom_id(note)} .js-awards-block" } } .award-menu-holder.note-action-award-holder.js-award-holder.js-award-action-btn{ data: { target: "##{dom_id(note)} .js-awards-block" } }
= link_to '#', title: 'Award emoji', class: 'note-award-control js-add-award', data: { award_menu_url: emojis_path } do = link_to '#', title: 'Award emoji', class: 'note-award-control js-add-award', data: { award_menu_url: emojis_path, position: "right" } do
= icon('smile-o', {class: "award-control-icon award-control-icon-normal"}) = icon('smile-o', {class: "award-control-icon award-control-icon-normal"})
= icon('spinner spin', {class: "award-control-icon award-control-icon-loading"}) = icon('spinner spin', {class: "award-control-icon award-control-icon-loading"})
- if note_editable?(note) - if note_editable?(note)
......
...@@ -46,8 +46,9 @@ feature 'Issue awards', js: true, feature: true do ...@@ -46,8 +46,9 @@ feature 'Issue awards', js: true, feature: true do
page.within('.note') do page.within('.note') do
find('.js-add-award').click find('.js-add-award').click
expect(page).to have_selector('.emoji-menu', count: 1)
end end
expect(page).to have_selector('.emoji-menu', count: 1)
end end
it 'should add award to note' do it 'should add award to note' do
...@@ -117,16 +118,14 @@ feature 'Issue awards', js: true, feature: true do ...@@ -117,16 +118,14 @@ feature 'Issue awards', js: true, feature: true do
def show_note_award_menu def show_note_award_menu
page.within('.note') do page.within('.note') do
find('.js-add-award').click find('.js-add-award').click
expect(page).to have_selector('.emoji-menu')
end end
expect(page).to have_selector('.emoji-menu')
end end
def award_on_note(index = 1) def award_on_note(index = 1)
page.within('.note') do page.within('.emoji-menu') do
page.within('.emoji-menu') do buttons = all('.js-emoji-btn')
buttons = all('.js-emoji-btn') buttons[index].click
buttons[index].click
end
end end
end end
......
...@@ -46,8 +46,9 @@ feature 'Merge request awards', js: true, feature: true do ...@@ -46,8 +46,9 @@ feature 'Merge request awards', js: true, feature: true do
page.within('.note') do page.within('.note') do
find('.js-add-award').click find('.js-add-award').click
expect(page).to have_selector('.emoji-menu', count: 1)
end end
expect(page).to have_selector('.emoji-menu', count: 1)
end end
it 'should add award to note' do it 'should add award to note' do
...@@ -117,16 +118,14 @@ feature 'Merge request awards', js: true, feature: true do ...@@ -117,16 +118,14 @@ feature 'Merge request awards', js: true, feature: true do
def show_note_award_menu def show_note_award_menu
page.within('.note') do page.within('.note') do
find('.js-add-award').click find('.js-add-award').click
expect(page).to have_selector('.emoji-menu')
end end
expect(page).to have_selector('.emoji-menu')
end end
def award_on_note(index = 1) def award_on_note(index = 1)
page.within('.note') do page.within('.emoji-menu') do
page.within('.emoji-menu') do buttons = all('.js-emoji-btn')
buttons = all('.js-emoji-btn') buttons[index].click
buttons[index].click
end
end end
end end
......
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