diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index 2b82650a0729..32c224990df1 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -1,5 +1,5 @@ /* eslint-disable rulesdir/onyx-props-must-have-default */ -import React from 'react'; +import React, {useEffect, useRef, useCallback} from 'react'; import {View, InteractionManager} from 'react-native'; import _ from 'underscore'; import PropTypes from 'prop-types'; @@ -7,16 +7,13 @@ import styles from '../../../styles/styles'; import * as StyleUtils from '../../../styles/StyleUtils'; import ONYXKEYS from '../../../ONYXKEYS'; import safeAreaInsetPropTypes from '../../safeAreaInsetPropTypes'; -import compose from '../../../libs/compose'; import Navigation from '../../../libs/Navigation/Navigation'; import ROUTES from '../../../ROUTES'; import Icon from '../../../components/Icon'; import * as Expensicons from '../../../components/Icon/Expensicons'; import Tooltip from '../../../components/Tooltip'; import CONST from '../../../CONST'; -import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; import * as App from '../../../libs/actions/App'; -import withWindowDimensions from '../../../components/withWindowDimensions'; import LHNOptionsList from '../../../components/LHNOptionsList/LHNOptionsList'; import SidebarUtils from '../../../libs/SidebarUtils'; import Header from '../../../components/Header'; @@ -30,6 +27,8 @@ import KeyboardShortcut from '../../../libs/KeyboardShortcut'; import onyxSubscribe from '../../../libs/onyxSubscribe'; import * as ReportActionContextMenu from '../report/ContextMenu/ReportActionContextMenu'; import SignInOrAvatarWithOptionalStatus from './SignInOrAvatarWithOptionalStatus'; +import useLocalize from '../../../hooks/useLocalize'; +import useWindowDimensions from '../../../hooks/useWindowDimensions'; const basePropTypes = { /** Toggles the navigation menu open and closed */ @@ -37,9 +36,6 @@ const basePropTypes = { /** Safe area insets required for mobile devices margins */ insets: safeAreaInsetPropTypes.isRequired, - - /** Whether we are viewing below the responsive breakpoint */ - isSmallScreenWidth: PropTypes.bool.isRequired, }; const propTypes = { @@ -49,54 +45,49 @@ const propTypes = { isLoading: PropTypes.bool.isRequired, + // eslint-disable-next-line react/require-default-props priorityMode: PropTypes.oneOf(_.values(CONST.PRIORITY_MODE)), isActiveReport: PropTypes.func.isRequired, - - ...withLocalizePropTypes, -}; - -const defaultProps = { - priorityMode: CONST.PRIORITY_MODE.DEFAULT, }; -class SidebarLinks extends React.PureComponent { - constructor(props) { - super(props); +function SidebarLinks({onLinkClick, insets, optionListItems, isLoading, priorityMode = CONST.PRIORITY_MODE.DEFAULT, isActiveReport, isCreateMenuOpen}) { + const modal = useRef({}); + const {translate, updateLocale} = useLocalize(); + const {isSmallScreenWidth} = useWindowDimensions(); - this.showSearchPage = this.showSearchPage.bind(this); - this.showReportPage = this.showReportPage.bind(this); - - if (this.props.isSmallScreenWidth) { - App.confirmReadyToOpenApp(); + useEffect(() => { + if (!isSmallScreenWidth) { + return; } - } + App.confirmReadyToOpenApp(); + }, [isSmallScreenWidth]); - componentDidMount() { + useEffect(() => { App.setSidebarLoaded(); SidebarUtils.setIsSidebarLoadedReady(); - this.isSidebarLoaded = true; - // Eagerly set the locale on date-fns, it helps navigating to the report screen faster InteractionManager.runAfterInteractions(() => { requestAnimationFrame(() => { - this.props.updateLocale(); + updateLocale(); }); }); - let modal = {}; - this.unsubscribeOnyxModal = onyxSubscribe({ + const unsubscribeOnyxModal = onyxSubscribe({ key: ONYXKEYS.MODAL, callback: (modalArg) => { - modal = modalArg; + if (_.isNull(modalArg)) { + return; + } + modal.current = modalArg; }, }); const shortcutConfig = CONST.KEYBOARD_SHORTCUTS.ESCAPE; - this.unsubscribeEscapeKey = KeyboardShortcut.subscribe( + const unsubscribeEscapeKey = KeyboardShortcut.subscribe( shortcutConfig.shortcutKey, () => { - if (modal.willAlertModalBecomeVisible) { + if (modal.current.willAlertModalBecomeVisible) { return; } @@ -109,26 +100,27 @@ class SidebarLinks extends React.PureComponent { ); ReportActionContextMenu.hideContextMenu(false); - } - componentWillUnmount() { - SidebarUtils.resetIsSidebarLoadedReadyPromise(); - if (this.unsubscribeEscapeKey) { - this.unsubscribeEscapeKey(); - } - if (this.unsubscribeOnyxModal) { - this.unsubscribeOnyxModal(); - } - } - - showSearchPage() { - if (this.props.isCreateMenuOpen) { + return () => { + SidebarUtils.resetIsSidebarLoadedReadyPromise(); + if (unsubscribeEscapeKey) { + unsubscribeEscapeKey(); + } + if (unsubscribeOnyxModal) { + unsubscribeOnyxModal(); + } + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const showSearchPage = useCallback(() => { + if (isCreateMenuOpen) { // Prevent opening Search page when click Search icon quickly after clicking FAB icon return; } Navigation.navigate(ROUTES.SEARCH); - } + }, [isCreateMenuOpen]); /** * Show Report page with selected report id @@ -136,72 +128,69 @@ class SidebarLinks extends React.PureComponent { * @param {Object} option * @param {String} option.reportID */ - showReportPage(option) { - // Prevent opening Report page when clicking LHN row quickly after clicking FAB icon - // or when clicking the active LHN row on large screens - // or when continuously clicking different LHNs, only apply to small screen - // since getTopmostReportId always returns on other devices - const reportActionID = Navigation.getTopmostReportActionId(); - if ( - this.props.isCreateMenuOpen || - (option.reportID === Navigation.getTopmostReportId() && !reportActionID) || - (this.props.isSmallScreenWidth && this.props.isActiveReport(option.reportID) && !reportActionID) - ) { - return; - } - Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(option.reportID)); - this.props.onLinkClick(); - } - - render() { - const viewMode = this.props.priorityMode === CONST.PRIORITY_MODE.GSD ? CONST.OPTION_MODE.COMPACT : CONST.OPTION_MODE.DEFAULT; - - return ( - - -
- } - accessibilityRole={CONST.ACCESSIBILITY_ROLE.TEXT} - shouldShowEnvironmentBadge - /> - - - - - - - - - { + // Prevent opening Report page when clicking LHN row quickly after clicking FAB icon + // or when clicking the active LHN row on large screens + // or when continuously clicking different LHNs, only apply to small screen + // since getTopmostReportId always returns on other devices + const reportActionID = Navigation.getTopmostReportActionId(); + if (isCreateMenuOpen || (option.reportID === Navigation.getTopmostReportId() && !reportActionID) || (isSmallScreenWidth && isActiveReport(option.reportID) && !reportActionID)) { + return; + } + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(option.reportID)); + onLinkClick(); + }, + [isCreateMenuOpen, isSmallScreenWidth, isActiveReport, onLinkClick], + ); + + const viewMode = priorityMode === CONST.PRIORITY_MODE.GSD ? CONST.OPTION_MODE.COMPACT : CONST.OPTION_MODE.DEFAULT; + + return ( + + +
+ } + accessibilityRole={CONST.ACCESSIBILITY_ROLE.TEXT} + shouldShowEnvironmentBadge /> - {this.props.isLoading && } + + + + + + - ); - } + + + {isLoading && } + + ); } SidebarLinks.propTypes = propTypes; -SidebarLinks.defaultProps = defaultProps; -export default compose(withLocalize, withWindowDimensions)(SidebarLinks); +SidebarLinks.displayName = 'SidebarLinks'; +export default SidebarLinks; export {basePropTypes}; diff --git a/src/pages/home/sidebar/SidebarLinksData.js b/src/pages/home/sidebar/SidebarLinksData.js index 243ba24cdd00..f0a43e7647b8 100644 --- a/src/pages/home/sidebar/SidebarLinksData.js +++ b/src/pages/home/sidebar/SidebarLinksData.js @@ -63,7 +63,7 @@ const defaultProps = { policies: [], }; -function SidebarLinksData({isFocused, allReportActions, betas, chatReports, currentReportID, insets, isLoadingReportData, isSmallScreenWidth, onLinkClick, policies, priorityMode}) { +function SidebarLinksData({isFocused, allReportActions, betas, chatReports, currentReportID, insets, isLoadingReportData, onLinkClick, policies, priorityMode}) { const {translate} = useLocalize(); const reportIDsRef = useRef(null); @@ -107,7 +107,6 @@ function SidebarLinksData({isFocused, allReportActions, betas, chatReports, curr // Forwarded props: onLinkClick={onLinkClick} insets={insets} - isSmallScreenWidth={isSmallScreenWidth} priorityMode={priorityMode} // Data props: isActiveReport={isActiveReport} diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js index bc4d28fdf09f..065fbb4d6f43 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js @@ -6,15 +6,9 @@ import ScreenWrapper from '../../../../components/ScreenWrapper'; import Timing from '../../../../libs/actions/Timing'; import CONST from '../../../../CONST'; import Performance from '../../../../libs/Performance'; -import withWindowDimensions, {windowDimensionsPropTypes} from '../../../../components/withWindowDimensions'; import sidebarPropTypes from './sidebarPropTypes'; import * as Browser from '../../../../libs/Browser'; -const propTypes = { - ...sidebarPropTypes, - ...windowDimensionsPropTypes, -}; - /** * Function called when a pinned chat is selected. */ @@ -42,7 +36,6 @@ function BaseSidebarScreen(props) { @@ -53,7 +46,7 @@ function BaseSidebarScreen(props) { ); } -BaseSidebarScreen.propTypes = propTypes; +BaseSidebarScreen.propTypes = sidebarPropTypes; BaseSidebarScreen.displayName = 'BaseSidebarScreen'; -export default withWindowDimensions(BaseSidebarScreen); +export default BaseSidebarScreen; diff --git a/src/pages/home/sidebar/SidebarScreen/index.js b/src/pages/home/sidebar/SidebarScreen/index.js index 5006136a633e..86d85be6cb04 100755 --- a/src/pages/home/sidebar/SidebarScreen/index.js +++ b/src/pages/home/sidebar/SidebarScreen/index.js @@ -3,10 +3,11 @@ import sidebarPropTypes from './sidebarPropTypes'; import BaseSidebarScreen from './BaseSidebarScreen'; import FloatingActionButtonAndPopover from './FloatingActionButtonAndPopover'; import FreezeWrapper from '../../../../libs/Navigation/FreezeWrapper'; -import withWindowDimensions from '../../../../components/withWindowDimensions'; +import useWindowDimensions from '../../../../hooks/useWindowDimensions'; function SidebarScreen(props) { const popoverModal = useRef(null); + const {isSmallScreenWidth} = useWindowDimensions(); /** * Method to hide popover when dragover. @@ -33,7 +34,7 @@ function SidebarScreen(props) { }; return ( - + +