Skip to content

Commit

Permalink
Merge pull request #2706 from parasharrajat/parasharrajat/ux
Browse files Browse the repository at this point in the history
Allow menus to be dynamically positioned.
  • Loading branch information
roryabraham authored May 10, 2021
2 parents 569a2ef + 5fd502d commit e5b508f
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 15 deletions.
21 changes: 14 additions & 7 deletions src/components/VideoChatButtonAndMenu.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {Component} from 'react';
import {View, Pressable} from 'react-native';
import {View, Pressable, Dimensions} from 'react-native';
import Icon from './Icon';
import {Phone} from './Icon/Expensicons';
import Popover from './Popover';
Expand All @@ -14,6 +14,11 @@ import withWindowDimensions, {windowDimensionsPropTypes} from './withWindowDimen
import withLocalize, {withLocalizePropTypes} from './withLocalize';
import compose from '../libs/compose';

const propTypes = {
...withLocalizePropTypes,
...windowDimensionsPropTypes,
};

class VideoChatButtonAndMenu extends Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -46,6 +51,14 @@ class VideoChatButtonAndMenu extends Component {
};
}

componentDidMount() {
Dimensions.addEventListener('change', this.measureVideoChatIconPosition);
}

componentWillUnmount() {
Dimensions.removeEventListener('change', this.measureVideoChatIconPosition);
}

/**
* Toggles the state variable isVideoChatMenuActive
*/
Expand Down Expand Up @@ -112,13 +125,7 @@ class VideoChatButtonAndMenu extends Component {
}
}

const propTypes = {
...withLocalizePropTypes,
...windowDimensionsPropTypes,
};

VideoChatButtonAndMenu.propTypes = propTypes;

VideoChatButtonAndMenu.displayName = 'VideoChatButtonAndMenu';
export default compose(
withWindowDimensions,
Expand Down
36 changes: 28 additions & 8 deletions src/pages/home/report/ReportActionCompose.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Pressable,
InteractionManager,
Text,
Dimensions,
} from 'react-native';
import {withNavigationFocus} from '@react-navigation/compat';
import _ from 'underscore';
Expand Down Expand Up @@ -33,7 +34,7 @@ import compose from '../../../libs/compose';
import CreateMenu from '../../../components/CreateMenu';
import Popover from '../../../components/Popover';
import EmojiPickerMenu from './EmojiPickerMenu';
import withWindowDimensions from '../../../components/withWindowDimensions';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions';
import withDrawerState from '../../../components/withDrawerState';
import getButtonState from '../../../libs/getButtonState';
import CONST from '../../../CONST';
Expand Down Expand Up @@ -82,6 +83,7 @@ const propTypes = {
isOffline: PropTypes.bool,
}),

...windowDimensionsPropTypes,
...withLocalizePropTypes,
};

Expand Down Expand Up @@ -110,7 +112,8 @@ class ReportActionCompose extends React.Component {
this.comment = props.comment;
this.shouldFocusInputOnScreenFocus = canFocusInputOnScreenFocus();
this.focusEmojiSearchInput = this.focusEmojiSearchInput.bind(this);

this.measureEmojiPopoverAnchorPosition = this.measureEmojiPopoverAnchorPosition.bind(this);
this.emojiPopoverAnchor = null;
this.emojiSearchInput = null;

this.state = {
Expand All @@ -128,6 +131,10 @@ class ReportActionCompose extends React.Component {
};
}

componentDidMount() {
Dimensions.addEventListener('change', this.measureEmojiPopoverAnchorPosition);
}

componentDidUpdate(prevProps) {
// We want to focus or refocus the input when a modal has been closed and the underlying screen is focused.
// We avoid doing this on native platforms since the software keyboard popping
Expand All @@ -139,6 +146,10 @@ class ReportActionCompose extends React.Component {
}
}

componentWillUnmount() {
Dimensions.removeEventListener('change', this.measureEmojiPopoverAnchorPosition);
}

/**
* Updates the Highlight state of the composer
*
Expand Down Expand Up @@ -227,17 +238,24 @@ class ReportActionCompose extends React.Component {
/**
* Show the ReportActionContextMenu modal popover.
*
* @param {Object} [event] - A press event.
*/
showEmojiPicker(event) {
showEmojiPicker() {
this.textInput.blur();
this.state.emojiPopoverAnchorPosition = {
horizontal: event.nativeEvent.pageX,
vertical: event.nativeEvent.pageY,
};
this.setState({isEmojiPickerVisible: true});
}

/**
* This gets called onLayout to find the cooridnates of the Anchor for the Emoji Picker.
*/
measureEmojiPopoverAnchorPosition() {
if (this.emojiPopoverAnchor) {
this.emojiPopoverAnchor.measureInWindow((x, y) => this.setState({
emojiPopoverAnchorPosition: {horizontal: x, vertical: y},
}));
}
}


/**
* Hide the ReportActionContextMenu modal popover.
*/
Expand Down Expand Up @@ -435,6 +453,8 @@ class ReportActionCompose extends React.Component {
styles.chatItemEmojiButton,
getButtonBackgroundColorStyle(getButtonState(hovered, pressed)),
])}
ref={el => this.emojiPopoverAnchor = el}
onLayout={this.measureEmojiPopoverAnchorPosition}
onPress={this.showEmojiPicker}
>
{({hovered, pressed}) => (
Expand Down

0 comments on commit e5b508f

Please sign in to comment.