Merge pull request #3791 from Klauswk/FixUserDropDown
Fix user drop down - HTML5 Issue #3764
This commit is contained in:
commit
5d75b79372
@ -81,6 +81,9 @@ class UserListItem extends Component {
|
||||
|
||||
this.state = {
|
||||
isActionsOpen: false,
|
||||
dropdownOffset: 0,
|
||||
dropdownDirection: 'top',
|
||||
dropdownVisible: false,
|
||||
};
|
||||
|
||||
this.handleScroll = this.handleScroll.bind(this);
|
||||
@ -134,21 +137,82 @@ class UserListItem extends Component {
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
this.checkDropdownDirection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the dropdown is visible, if so, check if should be draw on top or bottom direction.
|
||||
*/
|
||||
checkDropdownDirection() {
|
||||
if (this.isDropdownActivedByUser()) {
|
||||
const dropdown = findDOMNode(this.refs.dropdown);
|
||||
const dropdownTrigger = dropdown.children[0];
|
||||
const dropdownContent = dropdown.children[1];
|
||||
|
||||
const scrollContainer = dropdown.parentElement.parentElement;
|
||||
|
||||
let nextState = {
|
||||
dropdownVisible: true,
|
||||
};
|
||||
|
||||
const isDropdownVisible =
|
||||
this.checkIfDropdownIsVisible(dropdownContent.offsetTop, dropdownContent.offsetHeight);
|
||||
|
||||
if (!isDropdownVisible) {
|
||||
const offsetPageTop =
|
||||
(dropdownTrigger.offsetTop + dropdownTrigger.offsetHeight - scrollContainer.scrollTop);
|
||||
|
||||
nextState.dropdownOffset = window.innerHeight - offsetPageTop;
|
||||
nextState.dropdownDirection = 'bottom';
|
||||
}
|
||||
|
||||
this.setState(nextState);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the dropdown is visible and is opened by the user
|
||||
*
|
||||
* @return True if is visible and opened by the user.
|
||||
*/
|
||||
isDropdownActivedByUser() {
|
||||
const { isActionsOpen, dropdownVisible } = this.state;
|
||||
return isActionsOpen && !dropdownVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the content fit on the screen, false otherwise.
|
||||
*
|
||||
* @param {number} contentOffSetTop
|
||||
* @param {number} contentOffsetHeight
|
||||
* @return True if the content fit on the screen, false otherwise.
|
||||
*/
|
||||
checkIfDropdownIsVisible(contentOffSetTop, contentOffsetHeight) {
|
||||
return (contentOffSetTop + contentOffsetHeight) < window.innerHeight;
|
||||
}
|
||||
|
||||
|
||||
onActionsShow() {
|
||||
const dropdown = findDOMNode(this.refs.dropdown);
|
||||
const scrollContainer = dropdown.parentElement.parentElement;
|
||||
const dropdownTrigger = dropdown.children[0];
|
||||
|
||||
this.setState({
|
||||
contentTop: `${dropdown.offsetTop - dropdown.parentElement.parentElement.scrollTop}px`,
|
||||
isActionsOpen: true,
|
||||
active: true,
|
||||
dropdownVisible: false,
|
||||
dropdownOffset: dropdownTrigger.offsetTop - scrollContainer.scrollTop,
|
||||
dropdownDirection: 'top',
|
||||
});
|
||||
|
||||
findDOMNode(this).parentElement.addEventListener('scroll', this.handleScroll, false);
|
||||
scrollContainer.addEventListener('scroll', this.handleScroll, false);
|
||||
}
|
||||
|
||||
onActionsHide() {
|
||||
this.setState({
|
||||
active: false,
|
||||
isActionsOpen: false,
|
||||
dropdownVisible: false,
|
||||
});
|
||||
|
||||
findDOMNode(this).parentElement.removeEventListener('scroll', this.handleScroll, false);
|
||||
@ -161,7 +225,7 @@ class UserListItem extends Component {
|
||||
|
||||
let userItemContentsStyle = {};
|
||||
userItemContentsStyle[styles.userItemContentsCompact] = compact;
|
||||
userItemContentsStyle[styles.active] = this.state.active;
|
||||
userItemContentsStyle[styles.active] = this.state.isActionsOpen;
|
||||
|
||||
return (
|
||||
<li
|
||||
@ -181,7 +245,7 @@ class UserListItem extends Component {
|
||||
let actions = this.getAvailableActions();
|
||||
let contents = (
|
||||
<div tabIndex={0} className={styles.userItemContents}>
|
||||
<UserAvatar user={user}/>
|
||||
<UserAvatar user={user} />
|
||||
{this.renderUserName()}
|
||||
{this.renderUserIcons()}
|
||||
</div>
|
||||
@ -191,10 +255,12 @@ class UserListItem extends Component {
|
||||
return contents;
|
||||
}
|
||||
|
||||
const { dropdownOffset, dropdownDirection, dropdownVisible, } = this.state;
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
isOpen={this.state.isActionsOpen}
|
||||
ref="dropdown"
|
||||
isOpen={this.state.isActionsOpen}
|
||||
onShow={this.onActionsShow}
|
||||
onHide={this.onActionsHide}
|
||||
className={styles.dropdown}>
|
||||
@ -203,10 +269,11 @@ class UserListItem extends Component {
|
||||
</DropdownTrigger>
|
||||
<DropdownContent
|
||||
style={{
|
||||
top: this.state.contentTop,
|
||||
visibility: dropdownVisible ? 'visible' : 'hidden',
|
||||
[dropdownDirection]: `${dropdownOffset}px`,
|
||||
}}
|
||||
className={styles.dropdownContent}
|
||||
placement="right top">
|
||||
placement={`right ${dropdownDirection}`}>
|
||||
|
||||
<DropdownList>
|
||||
{
|
||||
@ -216,7 +283,7 @@ class UserListItem extends Component {
|
||||
key={_.uniqueId('action-header')}
|
||||
label={user.name}
|
||||
style={{ fontWeight: 600 }}
|
||||
defaultMessage={user.name}/>),
|
||||
defaultMessage={user.name} />),
|
||||
(<DropdownListSeparator key={_.uniqueId('action-separator')} />),
|
||||
].concat(actions)
|
||||
}
|
||||
@ -295,16 +362,16 @@ class UserListItem extends Component {
|
||||
{
|
||||
user.isSharingWebcam ?
|
||||
<span className={styles.userIconsContainer}>
|
||||
<Icon iconName='video'/>
|
||||
<Icon iconName='video' />
|
||||
</span>
|
||||
: null
|
||||
}
|
||||
{
|
||||
audioChatIcon ?
|
||||
<span className={cx(audioIconClassnames)}>
|
||||
<Icon iconName={audioChatIcon}/>
|
||||
</span>
|
||||
: null
|
||||
<span className={cx(audioIconClassnames)}>
|
||||
<Icon iconName={audioChatIcon} />
|
||||
</span>
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user