Skip to content

Commit

Permalink
Merge pull request #1878 from Expensify/luke-add-video-chat-links
Browse files Browse the repository at this point in the history
Add Video Call Chat Links
  • Loading branch information
marcaaron authored Apr 1, 2021
2 parents 0867cbf + f2f82b9 commit c6e2eff
Show file tree
Hide file tree
Showing 11 changed files with 147 additions and 4 deletions.
8 changes: 8 additions & 0 deletions assets/images/google-meet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions assets/images/phone.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/images/zoom-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const CONST = {
PRESSED: 'pressed',
},
CLOUDFRONT_URL,
NEW_ZOOM_MEETING_URL: 'https://zoom.us/start/videomeeting',
NEW_GOOGLE_MEET_MEETING_URL: 'https://meet.google.com/new',
PDF_VIEWER_URL: '/pdf/web/viewer.html',
EXPENSIFY_ICON_URL: `${CLOUDFRONT_URL}/images/favicon-2019.png`,
UPWORK_URL: 'https://www.upwork.com/ab/jobs/search/?q=Expensify%20React%20Native&user_location_match=2',
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/Expensicons.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import MagnifyingGlass from '../../../assets/images/magnifyingglass.svg';
import Mail from '../../../assets/images/mail.svg';
import Paperclip from '../../../assets/images/paperclip.svg';
import Pencil from '../../../assets/images/pencil.svg';
import Phone from '../../../assets/images/phone.svg';
import Pin from '../../../assets/images/pin.svg';
import PinCircle from '../../../assets/images/pin-circle.svg';
import Plus from '../../../assets/images/plus.svg';
Expand Down Expand Up @@ -35,6 +36,7 @@ export {
Mail,
Paperclip,
Pencil,
Phone,
Pin,
PinCircle,
Plus,
Expand Down
4 changes: 1 addition & 3 deletions src/components/Icon/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import _ from 'underscore';
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import themeColors from '../../styles/themes/default';
import variables from '../../styles/variables';
import * as Expensicons from './Expensicons';

const propTypes = {
// The asset to render.
src: PropTypes.oneOf(_.values(Expensicons)).isRequired,
src: PropTypes.func.isRequired,

// The width of the icon.
width: PropTypes.number,
Expand Down
7 changes: 7 additions & 0 deletions src/components/MenuItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import Icon from './Icon';
import {ArrowRight} from './Icon/Expensicons';

const propTypes = {
// Any additional styles to apply
// eslint-disable-next-line react/forbid-prop-types
wrapperStyle: PropTypes.object,

// Function to fire when component is pressed
onPress: PropTypes.func.isRequired,

Expand All @@ -25,19 +29,22 @@ const propTypes = {

const defaultProps = {
shouldShowRightArrow: false,
wrapperStyle: {},
};

const MenuItem = ({
onPress,
icon,
title,
shouldShowRightArrow,
wrapperStyle,
}) => (
<Pressable
onPress={onPress}
style={({hovered}) => ([
styles.createMenuItem,
hovered && {backgroundColor: themeColors.buttonHoveredBG},
wrapperStyle,
])}
>
<View style={styles.flexRow}>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Modal/BaseModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class BaseModal extends PureComponent {
deviceHeight={this.props.windowHeight}
deviceWidth={this.props.windowWidth}
animationIn={this.props.animationIn || animationIn}
animationOut={animationOut}
animationOut={this.props.animationOut || animationOut}
useNativeDriver={this.props.useNativeDriver}
statusBarTranslucent
>
Expand Down
1 change: 1 addition & 0 deletions src/components/Popover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const Popover = props => (
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
animationIn={props.isSmallScreenWidth ? undefined : props.animationIn}
animationOut={props.isSmallScreenWidth ? undefined : props.animationOut}
/>
);

Expand Down
114 changes: 114 additions & 0 deletions src/components/VideoChatButtonAndMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import React, {Component} from 'react';
import {View, Pressable} from 'react-native';
import Icon from './Icon';
import {Phone} from './Icon/Expensicons';
import Popover from './Popover';
import MenuItem from './MenuItem';
import openURLInNewTab from '../libs/openURLInNewTab';
import ZoomIcon from '../../assets/images/zoom-icon.svg';
import GoogleMeetIcon from '../../assets/images/google-meet.svg';
import CONST from '../CONST';
import styles from '../styles/styles';
import themeColors from '../styles/themes/default';
import withWindowDimensions from './withWindowDimensions';

class VideoChatButtonAndMenu extends Component {
constructor(props) {
super(props);

this.toggleVideoChatMenu = this.toggleVideoChatMenu.bind(this);
this.measureVideoChatIconPosition = this.measureVideoChatIconPosition.bind(this);
this.videoChatIconWrapper = null;
this.menuItemData = [
{
icon: ZoomIcon,
text: 'Zoom',
onPress: () => openURLInNewTab(CONST.NEW_ZOOM_MEETING_URL),
},
{
icon: GoogleMeetIcon,
text: 'Google Meet',
onPress: () => openURLInNewTab(CONST.NEW_GOOGLE_MEET_MEETING_URL),
},
].map(item => ({
...item,
onPress: () => {
item.onPress();
this.toggleVideoChatMenu();
},
}));

this.state = {
isVideoChatMenuActive: false,
videoChatIconPosition: {x: 0, y: 0},
};
}

/**
* Toggles the state variable isVideoChatMenuActive
*/
toggleVideoChatMenu() {
this.setState(prevState => ({
isVideoChatMenuActive: !prevState.isVideoChatMenuActive,
}));
}

/**
* This gets called onLayout to find the cooridnates of the wrapper for the video chat button.
*/
measureVideoChatIconPosition() {
if (this.videoChatIconWrapper) {
this.videoChatIconWrapper.measureInWindow((x, y) => this.setState({
videoChatIconPosition: {x, y},
}));
}
}

render() {
return (
<>
<View
ref={el => this.videoChatIconWrapper = el}
onLayout={this.measureVideoChatIconPosition}
>
<Pressable
onPress={() => {
this.toggleVideoChatMenu();
}}
style={[styles.touchableButtonImage, styles.mr0]}
>
<Icon
src={Phone}
fill={this.state.isVideoChatMenuActive
? themeColors.heading
: themeColors.icon}
/>
</Pressable>
</View>
<Popover
onClose={this.toggleVideoChatMenu}
isVisible={this.state.isVideoChatMenuActive}
anchorPosition={{
left: this.state.videoChatIconPosition.x - 150,
top: this.state.videoChatIconPosition.y + 40,
}}
animationIn="fadeInDown"
animationOut="fadeOutUp"
>
{this.menuItemData.map(({icon, text, onPress}) => (
<MenuItem
wrapperStyle={styles.mr3}
key={text}
icon={icon}
title={text}
onPress={onPress}
/>
))}
</Popover>
</>
);
}
}

VideoChatButtonAndMenu.displayName = 'VideoChatButtonAndMenu';
export default withWindowDimensions(VideoChatButtonAndMenu);
2 changes: 2 additions & 0 deletions src/pages/home/HeaderView.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {getReportParticipantsTitle} from '../../libs/reportUtils';
import OptionRowTitle from './sidebar/OptionRowTitle';
import {getPersonalDetailsForLogins} from '../../libs/OptionsListUtils';
import {participantPropTypes} from './sidebar/optionPropTypes';
import VideoChatButtonAndMenu from '../../components/VideoChatButtonAndMenu';
import IOUBadge from '../../components/IOUBadge';

const propTypes = {
Expand Down Expand Up @@ -100,6 +101,7 @@ const HeaderView = (props) => {
{props.report.hasOutstandingIOU && (
<IOUBadge iouReportID={props.report.iouReportID} />
)}
<VideoChatButtonAndMenu />
<Pressable
onPress={() => togglePinnedState(props.report)}
style={[styles.touchableButtonImage, styles.mr0]}
Expand Down

0 comments on commit c6e2eff

Please sign in to comment.