From f25302c6322ca1140516c9184d0da3de3d89e49a Mon Sep 17 00:00:00 2001 From: Someshwar Tripathi Date: Sat, 1 Jul 2023 23:34:56 +0530 Subject: [PATCH 1/4] Migrate to function component --- .../BaseVideoChatButtonAndMenu.js | 212 +++++++++--------- 1 file changed, 100 insertions(+), 112 deletions(-) diff --git a/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js b/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js index f705b132593d..19a48b45733f 100755 --- a/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js +++ b/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import React, {Component} from 'react'; +import React, {useState, useRef, useEffect, useCallback} from 'react'; import {View, Dimensions, Linking} from 'react-native'; import PropTypes from 'prop-types'; import Icon from '../Icon'; @@ -28,131 +28,119 @@ const propTypes = { ...windowDimensionsPropTypes, }; -class BaseVideoChatButtonAndMenu extends Component { - constructor(props) { - super(props); +function BaseVideoChatButtonAndMenu (props) { + const [isVideoChatMenuActive, setMenuVisibility] = useState(false); + const [videoChatIconPosition, setVideoChatIconPosition] = useState({x: 0, y: 0}); + const videoChatIconWrapperRef = useRef(null); + const dimensionsEventListenerRef = useRef(null); + const videoChatButtonRef = useRef(null); - this.dimensionsEventListener = null; - - this.measureVideoChatIconPosition = this.measureVideoChatIconPosition.bind(this); - this.videoChatIconWrapper = null; - this.menuItemData = [ - { - icon: ZoomIcon, - text: props.translate('videoChatButtonAndMenu.zoom'), - onPress: () => { - this.setMenuVisibility(false); - Linking.openURL(CONST.NEW_ZOOM_MEETING_URL); - }, + const menuItemData = [ + { + icon: ZoomIcon, + text: props.translate('videoChatButtonAndMenu.zoom'), + onPress: () => { + setMenuVisibility(false); + Linking.openURL(CONST.NEW_ZOOM_MEETING_URL); }, - { - icon: GoogleMeetIcon, - text: props.translate('videoChatButtonAndMenu.googleMeet'), - onPress: () => { - this.setMenuVisibility(false); - Linking.openURL(this.props.googleMeetURL); - }, + }, + { + icon: GoogleMeetIcon, + text: props.translate('videoChatButtonAndMenu.googleMeet'), + onPress: () => { + setMenuVisibility(false); + Linking.openURL(props.googleMeetURL); }, - ]; - - this.state = { - isVideoChatMenuActive: false, - videoChatIconPosition: {x: 0, y: 0}, - }; - } - - componentDidMount() { - this.dimensionsEventListener = Dimensions.addEventListener('change', this.measureVideoChatIconPosition); - } - - componentWillUnmount() { - if (!this.dimensionsEventListener) { - return; - } - this.dimensionsEventListener.remove(); - } + }, + ]; /** - * Set the state variable isVideoChatMenuActive - * @param {Boolean} isVideoChatMenuActive + * This gets called onLayout to find the coordinates of the wrapper for the video chat button. */ - setMenuVisibility(isVideoChatMenuActive) { - this.setState({isVideoChatMenuActive}); - } - - /** - * This gets called onLayout to find the cooridnates of the wrapper for the video chat button. - */ - measureVideoChatIconPosition() { - if (!this.videoChatIconWrapper) { + const measureVideoChatIconPosition = useCallback(() => { + if (!videoChatIconWrapperRef.current) { return; } - this.videoChatIconWrapper.measureInWindow((x, y) => - this.setState({ - videoChatIconPosition: {x, y}, - }), - ); - } + videoChatIconWrapperRef.current.measureInWindow((x, y) => { + setVideoChatIconPosition({x, y}); + }); + },[]); + + const closePopover = useCallback(() => { + setMenuVisibility(false); + }, []) + + useEffect(() => { + dimensionsEventListenerRef.current = Dimensions.addEventListener('change', measureVideoChatIconPosition); + + return () => { + if (!dimensionsEventListenerRef.current) { + return; + } - render() { - return ( - <> - (this.videoChatIconWrapper = el)} - onLayout={this.measureVideoChatIconPosition} - > - - (this.videoChatButton = el)} - onPress={Session.checkIfActionIsAllowed(() => { - // Drop focus to avoid blue focus ring. - this.videoChatButton.blur(); + dimensionsEventListenerRef.current.remove(); + }; + }, [measureVideoChatIconPosition]); + + return ( + <> + + + { + // Drop focus to avoid blue focus ring. + videoChatButtonRef.current.blur(); - // If this is the Concierge chat, we'll open the modal for requesting a setup call instead - if (this.props.isConcierge && this.props.guideCalendarLink) { - Linking.openURL(this.props.guideCalendarLink); - return; - } - this.setMenuVisibility(true); - })} - style={styles.touchableButtonImage} - accessibilityLabel={this.props.translate('videoChatButtonAndMenu.tooltip')} - accessibilityRole="button" - > - - - + // If this is the Concierge chat, we'll open the modal for requesting a setup call instead + if (props.isConcierge && props.guideCalendarLink) { + Linking.openURL(props.guideCalendarLink); + return; + } + setMenuVisibility(true); + })} + style={styles.touchableButtonImage} + accessibilityLabel={props.translate('videoChatButtonAndMenu.tooltip')} + accessibilityRole="button" + > + + + + + + + + {_.map(menuItemData, ({icon, text, onPress}) => ( + + ))} - this.setMenuVisibility(false)} - isVisible={this.state.isVideoChatMenuActive} - anchorPosition={{ - left: this.state.videoChatIconPosition.x - 150, - top: this.state.videoChatIconPosition.y + 40, - }} - > - - {_.map(this.menuItemData, ({icon, text, onPress}) => ( - - ))} - - - - ); - } -} + + + ); +}; BaseVideoChatButtonAndMenu.propTypes = propTypes; BaseVideoChatButtonAndMenu.defaultProps = defaultProps; +BaseVideoChatButtonAndMenu.displayName = 'BaseVideoChatButtonAndMenu'; export default compose(withWindowDimensions, withLocalize)(BaseVideoChatButtonAndMenu); From 3879ca091a7e0e02839ca663f55a4d14b4c9f756 Mon Sep 17 00:00:00 2001 From: Someshwar Tripathi Date: Fri, 7 Jul 2023 15:49:22 +0530 Subject: [PATCH 2/4] Change setter function name This change is for the isVideoChatMenuActive state hook. The name change is from setMenuVisibility to setIsVideoChatMenuActive. This adheres to useState hook naming conventions where the setter function is the state variable prefixed by set. --- .../BaseVideoChatButtonAndMenu.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js b/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js index 681e84693712..5c600d6316b6 100755 --- a/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js +++ b/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js @@ -29,7 +29,7 @@ const propTypes = { }; function BaseVideoChatButtonAndMenu(props) { - const [isVideoChatMenuActive, setMenuVisibility] = useState(false); + const [isVideoChatMenuActive, setIsVideoChatMenuActive] = useState(false); const [videoChatIconPosition, setVideoChatIconPosition] = useState({x: 0, y: 0}); const videoChatIconWrapperRef = useRef(null); const dimensionsEventListenerRef = useRef(null); @@ -40,7 +40,7 @@ function BaseVideoChatButtonAndMenu(props) { icon: ZoomIcon, text: props.translate('videoChatButtonAndMenu.zoom'), onPress: () => { - setMenuVisibility(false); + setIsVideoChatMenuActive(false); Linking.openURL(CONST.NEW_ZOOM_MEETING_URL); }, }, @@ -48,7 +48,7 @@ function BaseVideoChatButtonAndMenu(props) { icon: GoogleMeetIcon, text: props.translate('videoChatButtonAndMenu.googleMeet'), onPress: () => { - setMenuVisibility(false); + setIsVideoChatMenuActive(false); Linking.openURL(props.googleMeetURL); }, }, @@ -68,7 +68,7 @@ function BaseVideoChatButtonAndMenu(props) { }, []); const closePopover = useCallback(() => { - setMenuVisibility(false); + setIsVideoChatMenuActive(false); }, []); useEffect(() => { @@ -101,7 +101,7 @@ function BaseVideoChatButtonAndMenu(props) { Linking.openURL(props.guideCalendarLink); return; } - setMenuVisibility(true); + setIsVideoChatMenuActive(true); })} style={styles.touchableButtonImage} accessibilityLabel={props.translate('videoChatButtonAndMenu.tooltip')} From 456762bf7e5508512cef9eac2525e24a8de3ee80 Mon Sep 17 00:00:00 2001 From: Someshwar Tripathi Date: Fri, 7 Jul 2023 15:52:23 +0530 Subject: [PATCH 3/4] Replace closePopover() with inline anonymous function --- .../VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js b/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js index 5c600d6316b6..86cb27855ae4 100755 --- a/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js +++ b/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js @@ -67,10 +67,6 @@ function BaseVideoChatButtonAndMenu(props) { }); }, []); - const closePopover = useCallback(() => { - setIsVideoChatMenuActive(false); - }, []); - useEffect(() => { dimensionsEventListenerRef.current = Dimensions.addEventListener('change', measureVideoChatIconPosition); @@ -116,7 +112,7 @@ function BaseVideoChatButtonAndMenu(props) { setIsVideoChatMenuActive(false)} isVisible={isVideoChatMenuActive} anchorPosition={{ left: videoChatIconPosition.x - 150, From 4b80fb53d00aa8316e63f3623abe8b6bacd5f11b Mon Sep 17 00:00:00 2001 From: Someshwar Tripathi Date: Fri, 7 Jul 2023 15:59:11 +0530 Subject: [PATCH 4/4] Replace DimensionsEventListenerRef with local variable --- .../VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js b/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js index 86cb27855ae4..4c0e2b551382 100755 --- a/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js +++ b/src/components/VideoChatButtonAndMenu/BaseVideoChatButtonAndMenu.js @@ -32,7 +32,6 @@ function BaseVideoChatButtonAndMenu(props) { const [isVideoChatMenuActive, setIsVideoChatMenuActive] = useState(false); const [videoChatIconPosition, setVideoChatIconPosition] = useState({x: 0, y: 0}); const videoChatIconWrapperRef = useRef(null); - const dimensionsEventListenerRef = useRef(null); const videoChatButtonRef = useRef(null); const menuItemData = [ @@ -68,14 +67,14 @@ function BaseVideoChatButtonAndMenu(props) { }, []); useEffect(() => { - dimensionsEventListenerRef.current = Dimensions.addEventListener('change', measureVideoChatIconPosition); + const dimensionsEventListener = Dimensions.addEventListener('change', measureVideoChatIconPosition); return () => { - if (!dimensionsEventListenerRef.current) { + if (!dimensionsEventListener) { return; } - dimensionsEventListenerRef.current.remove(); + dimensionsEventListener.remove(); }; }, [measureVideoChatIconPosition]);