From 1f93872573f4ee3005cd445c738116a85edd8b31 Mon Sep 17 00:00:00 2001 From: Cong Pham Date: Tue, 13 Feb 2024 00:50:42 +0700 Subject: [PATCH] 35756 close emoji when navigation back --- src/components/EmojiPicker/EmojiPicker.js | 2 ++ src/components/Modal/index.tsx | 22 +++++++++++++++++-- src/components/Modal/types.ts | 3 +++ src/components/Popover/index.tsx | 1 + src/components/Popover/types.ts | 3 +++ src/components/PopoverWithMeasuredContent.tsx | 5 +++++ 6 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPicker.js b/src/components/EmojiPicker/EmojiPicker.js index e138ca4d4194..6bceaf570ccc 100644 --- a/src/components/EmojiPicker/EmojiPicker.js +++ b/src/components/EmojiPicker/EmojiPicker.js @@ -7,6 +7,7 @@ import withViewportOffsetTop from '@components/withViewportOffsetTop'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import * as Browser from '@libs/Browser'; import calculateAnchorPosition from '@libs/calculateAnchorPosition'; import CONST from '@src/CONST'; import EmojiPickerMenu from './EmojiPickerMenu'; @@ -169,6 +170,7 @@ const EmojiPicker = forwardRef((props, ref) => { // emojis. The best alternative is to set it to 1ms so it just "pops" in and out return ( {}, type, onModalShow = () => {}, children, ...rest}: BaseModalProps) { +function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = () => {}, children, shouldHandleNavigationBack, ...rest}: BaseModalProps) { const theme = useTheme(); const StyleUtils = useStyleUtils(); const [previousStatusBarColor, setPreviousStatusBarColor] = useState(); @@ -22,8 +22,15 @@ function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = ( const hideModal = () => { setStatusBarColor(previousStatusBarColor); onModalHide(); + if (window.history.state.shouldGoBack) { + window.history.back(); + } }; + const handlePopStateRef = useRef(() => { + rest.onClose(); + }); + const showModal = () => { const statusBarColor = StatusBar.getBackgroundColor() ?? theme.appBG; @@ -35,9 +42,20 @@ function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = ( setStatusBarColor(isFullScreenModal ? theme.appBG : StyleUtils.getThemeBackgroundColor(statusBarColor)); } + if (shouldHandleNavigationBack) { + window.history.pushState({shouldGoBack: true}, '', null); + window.addEventListener('popstate', handlePopStateRef.current); + } onModalShow?.(); }; + useEffect( + () => () => { + window.removeEventListener('popstate', handlePopStateRef.current); + }, + [], + ); + return ( & { * */ hideModalContentWhileAnimating?: boolean; + /** Whether handle navigation back when modal show. */ + shouldHandleNavigationBack?: boolean; + /** Should we use a custom backdrop for the modal? (This prevents focus issues on desktop) */ shouldUseCustomBackdrop?: boolean; }; diff --git a/src/components/Popover/index.tsx b/src/components/Popover/index.tsx index e1cd18ba4767..19fc86c9f936 100644 --- a/src/components/Popover/index.tsx +++ b/src/components/Popover/index.tsx @@ -92,6 +92,7 @@ function Popover(props: PopoverProps) { // eslint-disable-next-line react/jsx-props-no-spreading {...props} onClose={onCloseWithPopoverContext} + shouldHandleNavigationBack={props.shouldHandleNavigationBack} type={isSmallScreenWidth ? CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED : CONST.MODAL.MODAL_TYPE.POPOVER} popoverAnchorPosition={isSmallScreenWidth ? undefined : anchorPosition} fullscreen={isSmallScreenWidth ? true : fullscreen} diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index 314c1ba141c3..4e2f38293f6e 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -37,6 +37,9 @@ type PopoverProps = BaseModalProps & /** Whether we want to show the popover on the right side of the screen */ fromSidebarMediumScreen?: boolean; + + /** Whether handle navigation back when modal show. */ + shouldHandleNavigationBack?: boolean; }; type PopoverWithWindowDimensionsProps = PopoverProps & WindowDimensionsProps; diff --git a/src/components/PopoverWithMeasuredContent.tsx b/src/components/PopoverWithMeasuredContent.tsx index 792002441ac6..deda6dbd217a 100644 --- a/src/components/PopoverWithMeasuredContent.tsx +++ b/src/components/PopoverWithMeasuredContent.tsx @@ -14,6 +14,9 @@ import type {WindowDimensionsProps} from './withWindowDimensions/types'; type PopoverWithMeasuredContentProps = Omit & { /** The horizontal and vertical anchors points for the popover */ anchorPosition: AnchorPosition; + + /** Whether handle navigation back when modal show. */ + shouldHandleNavigationBack?: boolean; }; /** @@ -42,6 +45,7 @@ function PopoverWithMeasuredContent({ statusBarTranslucent = true, avoidKeyboard = false, hideModalContentWhileAnimating = false, + shouldHandleNavigationBack = false, ...props }: PopoverWithMeasuredContentProps) { const styles = useThemeStyles(); @@ -117,6 +121,7 @@ function PopoverWithMeasuredContent({ }; return isContentMeasured ? (