Merge pull request #8101 from RocketChat/dynamic-popover
[FIX] Dynamic popover # Conflicts: # packages/rocketchat-ui-master/public/icons.svgpull/8689/head
parent
eab15e96c8
commit
8643d35542
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
@ -1,71 +0,0 @@ |
||||
/* globals popover */ |
||||
|
||||
this.popover = { |
||||
close() { |
||||
document.querySelectorAll('[data-popover="anchor"]:checked').forEach((checkbox) => { |
||||
checkbox.checked = false; |
||||
}); |
||||
} |
||||
}; |
||||
|
||||
function preventDefault(e) { |
||||
e = e || window.event; |
||||
if (e.preventDefault) { |
||||
e.preventDefault(); |
||||
} |
||||
e.returnValue = false; |
||||
} |
||||
|
||||
function enableWindowScroll() { |
||||
if (window.removeEventListener) { |
||||
window.removeEventListener('DOMMouseScroll', preventDefault, false); |
||||
} |
||||
window.onmousewheel = document.onmousewheel = null; |
||||
window.onwheel = null; |
||||
} |
||||
|
||||
function disableWindowScroll() { |
||||
if (window.addEventListener) { |
||||
window.addEventListener('DOMMouseScroll', preventDefault, false); |
||||
} |
||||
window.onwheel = preventDefault; |
||||
} |
||||
|
||||
$(document).on('click', function(e) { |
||||
const element = $(e.target); |
||||
if ($(element).parents('.message').length) { |
||||
if ($(element).data('popover') === 'label' || $(element).data('popover') === 'anchor') { |
||||
disableWindowScroll(); |
||||
|
||||
$(element).parents('.message').addClass('active'); |
||||
|
||||
const popover = $(element).siblings('.rc-popover'); |
||||
const popoverContent = popover.children('.rc-popover__content'); |
||||
setTimeout(function() { |
||||
const popoverWidth = popoverContent.outerWidth(); |
||||
const popoverHeight = popoverContent.outerHeight(); |
||||
const popoverHeightHalf = popoverContent.outerHeight() / 2; |
||||
const pointer = $(e.target).offset().top - $('.messages-container header').outerHeight(); |
||||
const roomHeight = $('.messages-box').outerHeight(); |
||||
|
||||
let top; |
||||
if (pointer + popoverHeightHalf > roomHeight) { |
||||
top = popoverHeight - (roomHeight - pointer); |
||||
} else if (popoverHeightHalf < pointer) { |
||||
top = popoverHeightHalf; |
||||
} else { |
||||
top = pointer - 10; |
||||
} |
||||
|
||||
popover.css({ |
||||
top: -top, |
||||
right: popoverWidth + 30 |
||||
}); |
||||
}, 100); |
||||
} else if ($(element).hasClass('rc-popover__wrapper') || $(element).hasClass('rc-popover__item-text') || $(element).hasClass('rc-popover__icon-element')) { |
||||
enableWindowScroll(); |
||||
$(element).parents('.message').removeClass('active'); |
||||
popover.close(); |
||||
} |
||||
} |
||||
}); |
@ -0,0 +1,28 @@ |
||||
<template name="popover"> |
||||
<div class="rc-popover rc-popover--{{popoverClass}}" data-popover="popover" style="display:block;"> |
||||
<div class="rc-popover__content"> |
||||
{{#each column in columns}} |
||||
<div class="rc-popover__column"> |
||||
{{#each group in column.groups}} |
||||
{{#if group.title}} |
||||
<h3 class="rc-popover__title">{{group.title}}</h3> |
||||
{{/if}} |
||||
<ul class="rc-popover__list"> |
||||
{{#each item in group.items}} |
||||
<li class="rc-popover__item rc-popover__item--{{item.class}}" data-type={{item.type}} data-id={{item.id}} > |
||||
{{#if item.icon}} |
||||
<span class="rc-popover__icon"> |
||||
{{> icon block="rc-popover__icon-element" icon=item.icon }} |
||||
</span> |
||||
{{/if}} |
||||
<span class="rc-popover__item-text">{{item.name}}</span> |
||||
</li> |
||||
{{/each}} |
||||
</ul> |
||||
<span class="rc-popover__divider"></span> |
||||
{{/each}} |
||||
</div> |
||||
{{/each}} |
||||
</div> |
||||
</div> |
||||
</template> |
@ -0,0 +1,133 @@ |
||||
/* globals popover */ |
||||
|
||||
this.popover = { |
||||
renderedPopover: null, |
||||
open(config) { |
||||
this.renderedPopover = Blaze.renderWithData(Template.popover, config, document.body); |
||||
}, |
||||
close() { |
||||
Blaze.remove(this.renderedPopover); |
||||
|
||||
const activeElement = this.renderedPopover.dataVar.curValue.activeElement; |
||||
if (activeElement) { |
||||
$(activeElement).removeClass('active'); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
Template.popover.onRendered(function() { |
||||
$('.rc-popover').click(function(e) { |
||||
if (e.currentTarget === e.target) { |
||||
popover.close(); |
||||
} |
||||
}); |
||||
|
||||
const activeElement = this.data.activeElement; |
||||
const popoverContent = this.firstNode.children[0]; |
||||
const position = this.data.position; |
||||
const customCSSProperties = this.data.customCSSProperties; |
||||
|
||||
if (position) { |
||||
popoverContent.style.top = `${ position.top }px`; |
||||
popoverContent.style.left = `${ position.left }px`; |
||||
} else { |
||||
const popoverWidth = popoverContent.offsetWidth; |
||||
const popoverHeight = popoverContent.offsetHeight; |
||||
const popoverHeightHalf = popoverHeight / 2; |
||||
const windowWidth = window.innerWidth; |
||||
const windowHeight = window.innerHeight; |
||||
const mousePosition = this.data.mousePosition; |
||||
|
||||
let top; |
||||
if (mousePosition.y <= popoverHeight) { |
||||
top = 10; |
||||
} else if (mousePosition.y + popoverHeightHalf > windowHeight) { |
||||
top = windowHeight - popoverHeight - 10; |
||||
} else { |
||||
top = mousePosition.y - popoverHeightHalf; |
||||
} |
||||
|
||||
let right; |
||||
if (mousePosition.x + popoverWidth >= windowWidth) { |
||||
right = mousePosition.x - popoverWidth; |
||||
} else if (mousePosition.x <= popoverWidth) { |
||||
right = 10; |
||||
} else if (mousePosition.x <= windowWidth / 2) { |
||||
right = mousePosition.x; |
||||
} else { |
||||
right = mousePosition.x - popoverWidth; |
||||
} |
||||
|
||||
popoverContent.style.top = `${ top }px`; |
||||
popoverContent.style.left = `${ right }px`; |
||||
} |
||||
|
||||
if (customCSSProperties) { |
||||
Object.keys(customCSSProperties).forEach(function(property) { |
||||
popoverContent.style[property] = customCSSProperties[property]; |
||||
}); |
||||
} |
||||
|
||||
if (activeElement) { |
||||
$(activeElement).addClass('active'); |
||||
} |
||||
|
||||
popoverContent.style.opacity = 1; |
||||
}); |
||||
|
||||
Template.popover.events({ |
||||
'click [data-type="messagebox-action"]'(event, t) { |
||||
const action = RocketChat.messageBox.actions.getById(event.currentTarget.dataset.id); |
||||
if ((action[0] != null ? action[0].action : undefined) != null) { |
||||
action[0].action({rid: t.data.data.rid, messageBox: document.querySelector('.rc-message-box'), element: event.currentTarget, event}); |
||||
popover.close(); |
||||
} |
||||
}, |
||||
'click [data-type="message-action"]'(e, t) { |
||||
const button = RocketChat.MessageAction.getButtonById(e.currentTarget.dataset.id); |
||||
if ((button != null ? button.action : undefined) != null) { |
||||
button.action.call(t.data.data, e, t.data.instance); |
||||
popover.close(); |
||||
} |
||||
}, |
||||
'click [data-type="set-state"]'(e) { |
||||
AccountBox.setStatus(e.currentTarget.dataset.id); |
||||
RocketChat.callbacks.run('userStatusManuallySet', e.currentTarget.dataset.status); |
||||
popover.close(); |
||||
}, |
||||
'click [data-type="open"]'(e) { |
||||
const open = e.currentTarget.dataset.id; |
||||
|
||||
switch (open) { |
||||
case 'account': |
||||
SideNav.setFlex('accountFlex'); |
||||
SideNav.openFlex(); |
||||
FlowRouter.go('account'); |
||||
break; |
||||
case 'logout': |
||||
const user = Meteor.user(); |
||||
Meteor.logout(() => { |
||||
RocketChat.callbacks.run('afterLogoutCleanUp', user); |
||||
Meteor.call('logoutCleanUp', user); |
||||
FlowRouter.go('home'); |
||||
}); |
||||
break; |
||||
case 'administration': |
||||
SideNav.setFlex('adminFlex'); |
||||
SideNav.openFlex(); |
||||
FlowRouter.go('admin-info'); |
||||
break; |
||||
} |
||||
|
||||
if (this.href) { |
||||
FlowRouter.go(this.href); |
||||
} |
||||
|
||||
if (this.sideNav != null) { |
||||
SideNav.setFlex(this.sideNav); |
||||
SideNav.openFlex(); |
||||
} |
||||
|
||||
popover.close(); |
||||
} |
||||
}); |
Loading…
Reference in new issue