From 961466870861dcb9461424c85d51e7e64c3d2b9f Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Thu, 9 Nov 2023 23:24:34 +0530 Subject: [PATCH 01/21] fix: close popover when dragging over --- src/components/PopoverProvider/index.tsx | 11 ++++++++ src/pages/home/ReportScreen.js | 22 ++++++++++++++-- .../ReportActionCompose/SuggestionEmoji.js | 6 ++--- .../report/ReportActionCompose/Suggestions.js | 26 ++++++++++++++++++- 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/components/PopoverProvider/index.tsx b/src/components/PopoverProvider/index.tsx index 06345ebdbc1c..a7ea893420c8 100644 --- a/src/components/PopoverProvider/index.tsx +++ b/src/components/PopoverProvider/index.tsx @@ -93,6 +93,17 @@ function PopoverContextProvider(props: PopoverContextProps) { }; }, [closePopover]); + React.useEffect(() => { + // hide popover on drag enter + const listener = () => { + closePopover(); + }; + document.addEventListener('dragenter', listener); + return () => { + document.removeEventListener('dragenter', listener); + }; + }, [closePopover]); + const onOpen = React.useCallback( (popoverParams: AnchorRef) => { if (activePopoverRef.current && activePopoverRef.current.ref !== popoverParams?.ref) { diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 7abf395644f8..65d1903ce3be 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -1,6 +1,6 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; +import React, {useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -10,6 +10,7 @@ import DragAndDropProvider from '@components/DragAndDrop/Provider'; import MoneyReportHeader from '@components/MoneyReportHeader'; import MoneyRequestHeader from '@components/MoneyRequestHeader'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import {PopoverContext} from '@components/PopoverProvider'; import ReportActionsSkeletonView from '@components/ReportActionsSkeletonView'; import ScreenWrapper from '@components/ScreenWrapper'; import TaskHeaderActionButton from '@components/TaskHeaderActionButton'; @@ -158,10 +159,15 @@ function ReportScreen({ const [isBannerVisible, setIsBannerVisible] = useState(true); const [listHeight, setListHeight] = useState(0); + const [isDraggingOver, setIsDraggingOver] = useState(false); + const prevIsDraggingOver = usePrevious(isDraggingOver); + const reportID = getReportID(route); const {addWorkspaceRoomOrChatPendingAction, addWorkspaceRoomOrChatErrors} = ReportUtils.getReportOfflinePendingActionAndErrors(report); const screenWrapperStyle = [styles.appContent, styles.flex1, {marginTop: viewportOffsetTop}]; + const {close: closePopover} = useContext(PopoverContext); + // There are no reportActions at all to display and we are still in the process of loading the next set of actions. const isLoadingInitialReportActions = _.isEmpty(reportActions) && reportMetadata.isLoadingInitialReportActions; @@ -273,6 +279,15 @@ function ReportScreen({ [route], ); + useEffect(() => { + if (prevIsDraggingOver === isDraggingOver) { + return; + } + if (isDraggingOver && closePopover) { + closePopover(); + } + }, [isDraggingOver, closePopover, prevIsDraggingOver]); + useEffect(() => { fetchReportIfNeeded(); ComposerActions.setShouldShowComposeInput(true); @@ -409,7 +424,10 @@ function ReportScreen({ shouldShowCloseButton /> )} - + ({...prevState, ...nextState})); diff --git a/src/pages/home/report/ReportActionCompose/Suggestions.js b/src/pages/home/report/ReportActionCompose/Suggestions.js index 05f35713c5f8..61e4ab5c9ac7 100644 --- a/src/pages/home/report/ReportActionCompose/Suggestions.js +++ b/src/pages/home/report/ReportActionCompose/Suggestions.js @@ -1,6 +1,8 @@ import PropTypes from 'prop-types'; -import React, {useCallback, useImperativeHandle, useRef} from 'react'; +import React, {useCallback, useContext, useEffect, useImperativeHandle, useRef} from 'react'; import {View} from 'react-native'; +import {DragAndDropContext} from '@components/DragAndDrop/Provider'; +import usePrevious from '@hooks/usePrevious'; import SuggestionEmoji from './SuggestionEmoji'; import SuggestionMention from './SuggestionMention'; import * as SuggestionProps from './suggestionProps'; @@ -45,6 +47,8 @@ function Suggestions({ }) { const suggestionEmojiRef = useRef(null); const suggestionMentionRef = useRef(null); + const {isDraggingOver} = useContext(DragAndDropContext); + const prevIsDraggingOver = usePrevious(isDraggingOver); const getSuggestions = useCallback(() => { if (suggestionEmojiRef.current && suggestionEmojiRef.current.getSuggestions) { @@ -111,6 +115,26 @@ function Suggestions({ [onSelectionChange, resetSuggestions, setShouldBlockSuggestionCalc, triggerHotkeyActions, updateShouldShowSuggestionMenuToFalse, getSuggestions], ); + useEffect(() => { + if (prevIsDraggingOver === isDraggingOver) { + return; + } + if (isDraggingOver) { + updateShouldShowSuggestionMenuToFalse(); + } + }, [isDraggingOver, prevIsDraggingOver, updateShouldShowSuggestionMenuToFalse]); + + useEffect(() => { + // hide popover on drag enter + const listener = () => { + updateShouldShowSuggestionMenuToFalse(); + }; + document.addEventListener('dragenter', listener); + return () => { + document.removeEventListener('dragenter', listener); + }; + }, [updateShouldShowSuggestionMenuToFalse]); + const baseProps = { value, setValue, From a1fb060292dd685d6567ecaf10858429e570952d Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 10 Nov 2023 00:22:52 +0530 Subject: [PATCH 02/21] early return when platform is not web or desktop --- src/pages/home/report/ReportActionCompose/Suggestions.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pages/home/report/ReportActionCompose/Suggestions.js b/src/pages/home/report/ReportActionCompose/Suggestions.js index 61e4ab5c9ac7..1d60956feeb8 100644 --- a/src/pages/home/report/ReportActionCompose/Suggestions.js +++ b/src/pages/home/report/ReportActionCompose/Suggestions.js @@ -6,6 +6,8 @@ import usePrevious from '@hooks/usePrevious'; import SuggestionEmoji from './SuggestionEmoji'; import SuggestionMention from './SuggestionMention'; import * as SuggestionProps from './suggestionProps'; +import getPlatform from '@libs/getPlatform'; +import CONST from '@src/CONST'; const propTypes = { /** A ref to this component */ @@ -125,6 +127,9 @@ function Suggestions({ }, [isDraggingOver, prevIsDraggingOver, updateShouldShowSuggestionMenuToFalse]); useEffect(() => { + if (![CONST.PLATFORM.WEB, CONST.PLATFORM.DESKTOP].includes(getPlatform())) { + return; + } // hide popover on drag enter const listener = () => { updateShouldShowSuggestionMenuToFalse(); From b9b011e19aefa4ddb1b94c3931c7c9586ba9d8e4 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 10 Nov 2023 00:25:37 +0530 Subject: [PATCH 03/21] fix lint --- src/pages/home/report/ReportActionCompose/Suggestions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose/Suggestions.js b/src/pages/home/report/ReportActionCompose/Suggestions.js index 1d60956feeb8..2e7a38d65c00 100644 --- a/src/pages/home/report/ReportActionCompose/Suggestions.js +++ b/src/pages/home/report/ReportActionCompose/Suggestions.js @@ -3,11 +3,11 @@ import React, {useCallback, useContext, useEffect, useImperativeHandle, useRef} import {View} from 'react-native'; import {DragAndDropContext} from '@components/DragAndDrop/Provider'; import usePrevious from '@hooks/usePrevious'; +import getPlatform from '@libs/getPlatform'; +import CONST from '@src/CONST'; import SuggestionEmoji from './SuggestionEmoji'; import SuggestionMention from './SuggestionMention'; import * as SuggestionProps from './suggestionProps'; -import getPlatform from '@libs/getPlatform'; -import CONST from '@src/CONST'; const propTypes = { /** A ref to this component */ From b2eb920a959f9d8eb3cb542387a80b0ddc231408 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 10 Nov 2023 00:27:59 +0530 Subject: [PATCH 04/21] only call close if popover is open --- src/pages/home/ReportScreen.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 65d1903ce3be..ad9b46970be0 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -166,7 +166,7 @@ function ReportScreen({ const {addWorkspaceRoomOrChatPendingAction, addWorkspaceRoomOrChatErrors} = ReportUtils.getReportOfflinePendingActionAndErrors(report); const screenWrapperStyle = [styles.appContent, styles.flex1, {marginTop: viewportOffsetTop}]; - const {close: closePopover} = useContext(PopoverContext); + const {close: closePopover, isOpen} = useContext(PopoverContext); // There are no reportActions at all to display and we are still in the process of loading the next set of actions. const isLoadingInitialReportActions = _.isEmpty(reportActions) && reportMetadata.isLoadingInitialReportActions; @@ -283,10 +283,10 @@ function ReportScreen({ if (prevIsDraggingOver === isDraggingOver) { return; } - if (isDraggingOver && closePopover) { + if (isDraggingOver && closePopover && isOpen) { closePopover(); } - }, [isDraggingOver, closePopover, prevIsDraggingOver]); + }, [isDraggingOver, closePopover, prevIsDraggingOver, isOpen]); useEffect(() => { fetchReportIfNeeded(); From 5be0aa1c340127a01780f371299d8e842ba6abcb Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 13 Nov 2023 00:54:47 +0530 Subject: [PATCH 05/21] final changes in RHP --- src/components/DragAndDrop/NoDropZone/index.js | 6 +++++- src/components/PopoverProvider/index.tsx | 1 - src/hooks/useDragAndDrop.ts | 11 ++++++++++- src/pages/settings/AboutPage/AboutPage.js | 1 + 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/components/DragAndDrop/NoDropZone/index.js b/src/components/DragAndDrop/NoDropZone/index.js index ac5b759dee63..098840d10896 100644 --- a/src/components/DragAndDrop/NoDropZone/index.js +++ b/src/components/DragAndDrop/NoDropZone/index.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; -import React, {useRef} from 'react'; +import React, {useContext, useRef} from 'react'; import {View} from 'react-native'; +import {PopoverContext} from '@components/PopoverProvider'; import useDragAndDrop from '@hooks/useDragAndDrop'; import styles from '@styles/styles'; @@ -11,10 +12,13 @@ const propTypes = { function NoDropZone({children}) { const noDropZone = useRef(null); + const {close: closePopover} = useContext(PopoverContext); useDragAndDrop({ dropZone: noDropZone, shouldAllowDrop: false, + onDragEnter: closePopover, }); + return ( (noDropZone.current = e)} diff --git a/src/components/PopoverProvider/index.tsx b/src/components/PopoverProvider/index.tsx index a7ea893420c8..6328fa037df0 100644 --- a/src/components/PopoverProvider/index.tsx +++ b/src/components/PopoverProvider/index.tsx @@ -94,7 +94,6 @@ function PopoverContextProvider(props: PopoverContextProps) { }, [closePopover]); React.useEffect(() => { - // hide popover on drag enter const listener = () => { closePopover(); }; diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 3f0142492d0d..6846e5198a5b 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -11,6 +11,7 @@ const DROP_EVENT = 'drop'; type DragAndDropParams = { dropZone: React.MutableRefObject; onDrop?: (event?: DragEvent) => void; + onDragEnter?: (event?: DragEvent) => void; shouldAllowDrop?: boolean; isDisabled?: boolean; shouldAcceptDrop?: (event?: DragEvent) => boolean; @@ -23,7 +24,14 @@ type DragAndDropOptions = { /** * @param dropZone – ref to the dropZone component */ -export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllowDrop = true, isDisabled = false, shouldAcceptDrop = () => true}: DragAndDropParams): DragAndDropOptions { +export default function useDragAndDrop({ + dropZone, + onDrop = () => {}, + onDragEnter = () => {}, + shouldAllowDrop = true, + isDisabled = false, + shouldAcceptDrop = () => true, +}: DragAndDropParams): DragAndDropOptions { const isFocused = useIsFocused(); const [isDraggingOver, setIsDraggingOver] = useState(false); @@ -75,6 +83,7 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow case DRAG_ENTER_EVENT: dragCounter.current++; setDropEffect(event); + onDragEnter(event); if (isDraggingOver) { return; } diff --git a/src/pages/settings/AboutPage/AboutPage.js b/src/pages/settings/AboutPage/AboutPage.js index b09117719a8c..0f660c226bff 100644 --- a/src/pages/settings/AboutPage/AboutPage.js +++ b/src/pages/settings/AboutPage/AboutPage.js @@ -64,6 +64,7 @@ function AboutPage(props) { action: () => { Link.openExternalLink(CONST.GITHUB_URL); }, + link: CONST.GITHUB_URL, }, { translationKey: 'initialSettingsPage.aboutPage.viewOpenJobs', From ca5e94a42a6e570a6b147103a3f93d14397d2704 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 13 Nov 2023 01:06:07 +0530 Subject: [PATCH 06/21] fix linter --- src/hooks/useDragAndDrop.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 6846e5198a5b..873153d1acc3 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -106,7 +106,7 @@ export default function useDragAndDrop({ break; } }, - [isFocused, isDisabled, shouldAcceptDrop, setDropEffect, isDraggingOver, onDrop], + [isFocused, isDisabled, shouldAcceptDrop, setDropEffect, isDraggingOver, onDrop, onDragEnter], ); useEffect(() => { From 09427f13f04421c3c933b78ab990205dabf784a8 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 13 Nov 2023 01:37:18 +0530 Subject: [PATCH 07/21] cleaning up --- src/pages/home/ReportScreen.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index ad9b46970be0..65d1903ce3be 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -166,7 +166,7 @@ function ReportScreen({ const {addWorkspaceRoomOrChatPendingAction, addWorkspaceRoomOrChatErrors} = ReportUtils.getReportOfflinePendingActionAndErrors(report); const screenWrapperStyle = [styles.appContent, styles.flex1, {marginTop: viewportOffsetTop}]; - const {close: closePopover, isOpen} = useContext(PopoverContext); + const {close: closePopover} = useContext(PopoverContext); // There are no reportActions at all to display and we are still in the process of loading the next set of actions. const isLoadingInitialReportActions = _.isEmpty(reportActions) && reportMetadata.isLoadingInitialReportActions; @@ -283,10 +283,10 @@ function ReportScreen({ if (prevIsDraggingOver === isDraggingOver) { return; } - if (isDraggingOver && closePopover && isOpen) { + if (isDraggingOver && closePopover) { closePopover(); } - }, [isDraggingOver, closePopover, prevIsDraggingOver, isOpen]); + }, [isDraggingOver, closePopover, prevIsDraggingOver]); useEffect(() => { fetchReportIfNeeded(); From 5d19455e30f54386fcc8c8c2ad7805fb36b49c76 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 13 Nov 2023 03:17:21 +0530 Subject: [PATCH 08/21] fixed crash on ios app --- src/components/DragAndDrop/Provider/index.native.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/DragAndDrop/Provider/index.native.js b/src/components/DragAndDrop/Provider/index.native.js index 4dac66912531..f4e7f4e42033 100644 --- a/src/components/DragAndDrop/Provider/index.native.js +++ b/src/components/DragAndDrop/Provider/index.native.js @@ -1,6 +1,7 @@ +import React from 'react'; import dragAndDropProviderPropTypes from './dragAndDropProviderPropTypes'; -const DragAndDropContext = {}; +const DragAndDropContext = React.createContext({}); function DragAndDropProvider({children}) { return children; From 9fbd0cf574bb8388a347db379d5db66780ff72d2 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 14 Nov 2023 02:35:24 +0530 Subject: [PATCH 09/21] added requested changes --- src/components/DragAndDrop/NoDropZone/index.js | 6 ++---- src/hooks/useDragAndDrop.ts | 14 +++++++++----- .../report/ReportActionCompose/Suggestions.js | 16 ---------------- src/pages/settings/AboutPage/AboutPage.js | 1 - 4 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/components/DragAndDrop/NoDropZone/index.js b/src/components/DragAndDrop/NoDropZone/index.js index 098840d10896..6e31c4e31285 100644 --- a/src/components/DragAndDrop/NoDropZone/index.js +++ b/src/components/DragAndDrop/NoDropZone/index.js @@ -1,7 +1,6 @@ import PropTypes from 'prop-types'; -import React, {useContext, useRef} from 'react'; +import React, {useRef} from 'react'; import {View} from 'react-native'; -import {PopoverContext} from '@components/PopoverProvider'; import useDragAndDrop from '@hooks/useDragAndDrop'; import styles from '@styles/styles'; @@ -12,11 +11,10 @@ const propTypes = { function NoDropZone({children}) { const noDropZone = useRef(null); - const {close: closePopover} = useContext(PopoverContext); useDragAndDrop({ dropZone: noDropZone, + shouldClosePopover: true, shouldAllowDrop: false, - onDragEnter: closePopover, }); return ( diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 873153d1acc3..dfe52a940fed 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -1,5 +1,6 @@ import {useIsFocused} from '@react-navigation/native'; -import React, {useCallback, useEffect, useRef, useState} from 'react'; +import React, {useCallback, useContext, useEffect, useRef, useState} from 'react'; +import {PopoverContext} from '@components/PopoverProvider'; const COPY_DROP_EFFECT = 'copy'; const NONE_DROP_EFFECT = 'none'; @@ -11,10 +12,10 @@ const DROP_EVENT = 'drop'; type DragAndDropParams = { dropZone: React.MutableRefObject; onDrop?: (event?: DragEvent) => void; - onDragEnter?: (event?: DragEvent) => void; shouldAllowDrop?: boolean; isDisabled?: boolean; shouldAcceptDrop?: (event?: DragEvent) => boolean; + shouldClosePopover?: boolean; }; type DragAndDropOptions = { @@ -27,13 +28,14 @@ type DragAndDropOptions = { export default function useDragAndDrop({ dropZone, onDrop = () => {}, - onDragEnter = () => {}, shouldAllowDrop = true, isDisabled = false, shouldAcceptDrop = () => true, + shouldClosePopover = false, }: DragAndDropParams): DragAndDropOptions { const isFocused = useIsFocused(); const [isDraggingOver, setIsDraggingOver] = useState(false); + const {close: closePopover} = useContext(PopoverContext); // This solution is borrowed from this SO: https://stackoverflow.com/questions/7110353/html5-dragleave-fired-when-hovering-a-child-element // This is necessary because dragging over children will cause dragleave to execute on the parent. @@ -83,7 +85,9 @@ export default function useDragAndDrop({ case DRAG_ENTER_EVENT: dragCounter.current++; setDropEffect(event); - onDragEnter(event); + if (shouldClosePopover) { + closePopover(); + } if (isDraggingOver) { return; } @@ -106,7 +110,7 @@ export default function useDragAndDrop({ break; } }, - [isFocused, isDisabled, shouldAcceptDrop, setDropEffect, isDraggingOver, onDrop, onDragEnter], + [isFocused, isDisabled, shouldAcceptDrop, setDropEffect, isDraggingOver, onDrop, shouldClosePopover, closePopover], ); useEffect(() => { diff --git a/src/pages/home/report/ReportActionCompose/Suggestions.js b/src/pages/home/report/ReportActionCompose/Suggestions.js index 2e7a38d65c00..32d0f80561bf 100644 --- a/src/pages/home/report/ReportActionCompose/Suggestions.js +++ b/src/pages/home/report/ReportActionCompose/Suggestions.js @@ -3,8 +3,6 @@ import React, {useCallback, useContext, useEffect, useImperativeHandle, useRef} import {View} from 'react-native'; import {DragAndDropContext} from '@components/DragAndDrop/Provider'; import usePrevious from '@hooks/usePrevious'; -import getPlatform from '@libs/getPlatform'; -import CONST from '@src/CONST'; import SuggestionEmoji from './SuggestionEmoji'; import SuggestionMention from './SuggestionMention'; import * as SuggestionProps from './suggestionProps'; @@ -126,20 +124,6 @@ function Suggestions({ } }, [isDraggingOver, prevIsDraggingOver, updateShouldShowSuggestionMenuToFalse]); - useEffect(() => { - if (![CONST.PLATFORM.WEB, CONST.PLATFORM.DESKTOP].includes(getPlatform())) { - return; - } - // hide popover on drag enter - const listener = () => { - updateShouldShowSuggestionMenuToFalse(); - }; - document.addEventListener('dragenter', listener); - return () => { - document.removeEventListener('dragenter', listener); - }; - }, [updateShouldShowSuggestionMenuToFalse]); - const baseProps = { value, setValue, diff --git a/src/pages/settings/AboutPage/AboutPage.js b/src/pages/settings/AboutPage/AboutPage.js index 0f660c226bff..b09117719a8c 100644 --- a/src/pages/settings/AboutPage/AboutPage.js +++ b/src/pages/settings/AboutPage/AboutPage.js @@ -64,7 +64,6 @@ function AboutPage(props) { action: () => { Link.openExternalLink(CONST.GITHUB_URL); }, - link: CONST.GITHUB_URL, }, { translationKey: 'initialSettingsPage.aboutPage.viewOpenJobs', From f9be717b0e600073ee45ecbd49e4801348869950 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Thu, 16 Nov 2023 03:45:38 +0530 Subject: [PATCH 10/21] clean up code --- .../DragAndDrop/NoDropZone/index.js | 1 - src/hooks/useDragAndDrop.ts | 2 +- src/pages/home/ReportScreen.js | 22 ++----------------- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/src/components/DragAndDrop/NoDropZone/index.js b/src/components/DragAndDrop/NoDropZone/index.js index 6e31c4e31285..bf0f453f5a5a 100644 --- a/src/components/DragAndDrop/NoDropZone/index.js +++ b/src/components/DragAndDrop/NoDropZone/index.js @@ -13,7 +13,6 @@ function NoDropZone({children}) { const noDropZone = useRef(null); useDragAndDrop({ dropZone: noDropZone, - shouldClosePopover: true, shouldAllowDrop: false, }); diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index dfe52a940fed..80a5c24a6999 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -31,7 +31,7 @@ export default function useDragAndDrop({ shouldAllowDrop = true, isDisabled = false, shouldAcceptDrop = () => true, - shouldClosePopover = false, + shouldClosePopover = true, }: DragAndDropParams): DragAndDropOptions { const isFocused = useIsFocused(); const [isDraggingOver, setIsDraggingOver] = useState(false); diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 65d1903ce3be..7abf395644f8 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -1,6 +1,6 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react'; +import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -10,7 +10,6 @@ import DragAndDropProvider from '@components/DragAndDrop/Provider'; import MoneyReportHeader from '@components/MoneyReportHeader'; import MoneyRequestHeader from '@components/MoneyRequestHeader'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; -import {PopoverContext} from '@components/PopoverProvider'; import ReportActionsSkeletonView from '@components/ReportActionsSkeletonView'; import ScreenWrapper from '@components/ScreenWrapper'; import TaskHeaderActionButton from '@components/TaskHeaderActionButton'; @@ -159,15 +158,10 @@ function ReportScreen({ const [isBannerVisible, setIsBannerVisible] = useState(true); const [listHeight, setListHeight] = useState(0); - const [isDraggingOver, setIsDraggingOver] = useState(false); - const prevIsDraggingOver = usePrevious(isDraggingOver); - const reportID = getReportID(route); const {addWorkspaceRoomOrChatPendingAction, addWorkspaceRoomOrChatErrors} = ReportUtils.getReportOfflinePendingActionAndErrors(report); const screenWrapperStyle = [styles.appContent, styles.flex1, {marginTop: viewportOffsetTop}]; - const {close: closePopover} = useContext(PopoverContext); - // There are no reportActions at all to display and we are still in the process of loading the next set of actions. const isLoadingInitialReportActions = _.isEmpty(reportActions) && reportMetadata.isLoadingInitialReportActions; @@ -279,15 +273,6 @@ function ReportScreen({ [route], ); - useEffect(() => { - if (prevIsDraggingOver === isDraggingOver) { - return; - } - if (isDraggingOver && closePopover) { - closePopover(); - } - }, [isDraggingOver, closePopover, prevIsDraggingOver]); - useEffect(() => { fetchReportIfNeeded(); ComposerActions.setShouldShowComposeInput(true); @@ -424,10 +409,7 @@ function ReportScreen({ shouldShowCloseButton /> )} - + Date: Mon, 20 Nov 2023 16:25:57 +0530 Subject: [PATCH 11/21] fix native drag and drop provider --- src/components/DragAndDrop/Provider/index.native.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/DragAndDrop/Provider/index.native.tsx b/src/components/DragAndDrop/Provider/index.native.tsx index ba32599c62b5..838b9439c313 100644 --- a/src/components/DragAndDrop/Provider/index.native.tsx +++ b/src/components/DragAndDrop/Provider/index.native.tsx @@ -1,6 +1,7 @@ +import React from 'react'; import type {DragAndDropContextParams, DragAndDropProviderProps} from './types'; -const DragAndDropContext: DragAndDropContextParams = {}; +const DragAndDropContext = React.createContext({}); function DragAndDropProvider({children}: DragAndDropProviderProps) { return children; From df59165625b20cccc0876c934a4f3e3c08a1ed40 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 20 Nov 2023 16:30:59 +0530 Subject: [PATCH 12/21] fix prettier diffs --- src/hooks/useDragAndDrop.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 3fe3274d10f9..091a205be93d 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -1,7 +1,7 @@ import {useIsFocused} from '@react-navigation/native'; import React, {useCallback, useContext, useEffect, useRef, useState} from 'react'; -import {PopoverContext} from '@components/PopoverProvider'; import {View} from 'react-native'; +import {PopoverContext} from '@components/PopoverProvider'; const COPY_DROP_EFFECT = 'copy'; const NONE_DROP_EFFECT = 'none'; From 18dc02766eecca022fb8094b8f3bb1c2f0095af5 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 20 Nov 2023 16:39:55 +0530 Subject: [PATCH 13/21] added requested changes --- src/hooks/useDragAndDrop.ts | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 091a205be93d..26fcb9720d46 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -1,7 +1,7 @@ -import {useIsFocused} from '@react-navigation/native'; -import React, {useCallback, useContext, useEffect, useRef, useState} from 'react'; -import {View} from 'react-native'; -import {PopoverContext} from '@components/PopoverProvider'; +import { useIsFocused } from '@react-navigation/native'; +import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'; +import { View } from 'react-native'; +import { PopoverContext } from '@components/PopoverProvider'; const COPY_DROP_EFFECT = 'copy'; const NONE_DROP_EFFECT = 'none'; @@ -28,15 +28,14 @@ type DragAndDropOptions = { */ export default function useDragAndDrop({ dropZone, - onDrop = () => {}, + onDrop = () => { }, shouldAllowDrop = true, isDisabled = false, shouldAcceptDrop = () => true, - shouldClosePopover = true, }: DragAndDropParams): DragAndDropOptions { const isFocused = useIsFocused(); const [isDraggingOver, setIsDraggingOver] = useState(false); - const {close: closePopover} = useContext(PopoverContext); + const { close: closePopover } = useContext(PopoverContext); // This solution is borrowed from this SO: https://stackoverflow.com/questions/7110353/html5-dragleave-fired-when-hovering-a-child-element // This is necessary because dragging over children will cause dragleave to execute on the parent. @@ -86,9 +85,7 @@ export default function useDragAndDrop({ case DRAG_ENTER_EVENT: dragCounter.current++; setDropEffect(event); - if (shouldClosePopover) { - closePopover(); - } + closePopover(); if (isDraggingOver) { return; } @@ -111,7 +108,7 @@ export default function useDragAndDrop({ break; } }, - [isFocused, isDisabled, shouldAcceptDrop, setDropEffect, isDraggingOver, onDrop, shouldClosePopover, closePopover], + [isFocused, isDisabled, shouldAcceptDrop, setDropEffect, isDraggingOver, onDrop, closePopover], ); useEffect(() => { @@ -140,5 +137,5 @@ export default function useDragAndDrop({ }; }, [dropZone, dropZoneDragHandler]); - return {isDraggingOver}; + return { isDraggingOver }; } From 133204c4a23933e390b9f679c96646d804bc77dc Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 20 Nov 2023 16:42:19 +0530 Subject: [PATCH 14/21] remove unrelated change --- src/hooks/useDragAndDrop.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 26fcb9720d46..8f36455b0a06 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -16,7 +16,6 @@ type DragAndDropParams = { shouldAllowDrop?: boolean; isDisabled?: boolean; shouldAcceptDrop?: (event?: DragEvent) => boolean; - shouldClosePopover?: boolean; }; type DragAndDropOptions = { From 157312a2bbc1dfd004ff5331f062d33ad41bdce0 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 20 Nov 2023 16:47:17 +0530 Subject: [PATCH 15/21] fix prettier diffs --- src/hooks/useDragAndDrop.ts | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 8f36455b0a06..a62c2cd33132 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -1,7 +1,7 @@ -import { useIsFocused } from '@react-navigation/native'; -import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'; -import { View } from 'react-native'; -import { PopoverContext } from '@components/PopoverProvider'; +import {useIsFocused} from '@react-navigation/native'; +import React, {useCallback, useContext, useEffect, useRef, useState} from 'react'; +import {View} from 'react-native'; +import {PopoverContext} from '@components/PopoverProvider'; const COPY_DROP_EFFECT = 'copy'; const NONE_DROP_EFFECT = 'none'; @@ -25,16 +25,10 @@ type DragAndDropOptions = { /** * @param dropZone – ref to the dropZone component */ -export default function useDragAndDrop({ - dropZone, - onDrop = () => { }, - shouldAllowDrop = true, - isDisabled = false, - shouldAcceptDrop = () => true, -}: DragAndDropParams): DragAndDropOptions { +export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllowDrop = true, isDisabled = false, shouldAcceptDrop = () => true}: DragAndDropParams): DragAndDropOptions { const isFocused = useIsFocused(); const [isDraggingOver, setIsDraggingOver] = useState(false); - const { close: closePopover } = useContext(PopoverContext); + const {close: closePopover} = useContext(PopoverContext); // This solution is borrowed from this SO: https://stackoverflow.com/questions/7110353/html5-dragleave-fired-when-hovering-a-child-element // This is necessary because dragging over children will cause dragleave to execute on the parent. @@ -136,5 +130,5 @@ export default function useDragAndDrop({ }; }, [dropZone, dropZoneDragHandler]); - return { isDraggingOver }; + return {isDraggingOver}; } From 8cc04fd4b01cb561f4cd4301d9c0dec72ecf8e9b Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 28 Nov 2023 17:43:27 +0530 Subject: [PATCH 16/21] fix typescript error --- src/hooks/useDragAndDrop.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index a62c2cd33132..0fab3952e97f 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -15,7 +15,7 @@ type DragAndDropParams = { onDrop?: (event: DragEvent) => void; shouldAllowDrop?: boolean; isDisabled?: boolean; - shouldAcceptDrop?: (event?: DragEvent) => boolean; + shouldAcceptDrop?: (event: DragEvent) => boolean; }; type DragAndDropOptions = { From 142212fe4254ee77d5257203e83c779938ff2db6 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Wed, 29 Nov 2023 23:15:04 +0530 Subject: [PATCH 17/21] added requested changes --- src/components/DragAndDrop/Provider/index.tsx | 1 + src/components/PopoverProvider/index.tsx | 10 ---------- src/hooks/useDragAndDrop.ts | 16 +++++++++++++--- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/components/DragAndDrop/Provider/index.tsx b/src/components/DragAndDrop/Provider/index.tsx index 761c512497ac..e97c70275172 100644 --- a/src/components/DragAndDrop/Provider/index.tsx +++ b/src/components/DragAndDrop/Provider/index.tsx @@ -26,6 +26,7 @@ function DragAndDropProvider({children, isDisabled = false, setIsDraggingOver = dropZone, onDrop: onDropHandler.current, shouldAcceptDrop, + shouldClosePopover: true, isDisabled, }); diff --git a/src/components/PopoverProvider/index.tsx b/src/components/PopoverProvider/index.tsx index 6328fa037df0..06345ebdbc1c 100644 --- a/src/components/PopoverProvider/index.tsx +++ b/src/components/PopoverProvider/index.tsx @@ -93,16 +93,6 @@ function PopoverContextProvider(props: PopoverContextProps) { }; }, [closePopover]); - React.useEffect(() => { - const listener = () => { - closePopover(); - }; - document.addEventListener('dragenter', listener); - return () => { - document.removeEventListener('dragenter', listener); - }; - }, [closePopover]); - const onOpen = React.useCallback( (popoverParams: AnchorRef) => { if (activePopoverRef.current && activePopoverRef.current.ref !== popoverParams?.ref) { diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 0fab3952e97f..c08719e48084 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -14,6 +14,7 @@ type DragAndDropParams = { dropZone: React.MutableRefObject; onDrop?: (event: DragEvent) => void; shouldAllowDrop?: boolean; + shouldClosePopover?: boolean; isDisabled?: boolean; shouldAcceptDrop?: (event: DragEvent) => boolean; }; @@ -25,7 +26,14 @@ type DragAndDropOptions = { /** * @param dropZone – ref to the dropZone component */ -export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllowDrop = true, isDisabled = false, shouldAcceptDrop = () => true}: DragAndDropParams): DragAndDropOptions { +export default function useDragAndDrop({ + dropZone, + onDrop = () => {}, + shouldAllowDrop = true, + isDisabled = false, + shouldClosePopover = false, + shouldAcceptDrop = () => true, +}: DragAndDropParams): DragAndDropOptions { const isFocused = useIsFocused(); const [isDraggingOver, setIsDraggingOver] = useState(false); const {close: closePopover} = useContext(PopoverContext); @@ -78,7 +86,9 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow case DRAG_ENTER_EVENT: dragCounter.current++; setDropEffect(event); - closePopover(); + if (shouldClosePopover) { + closePopover(); + } if (isDraggingOver) { return; } @@ -101,7 +111,7 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow break; } }, - [isFocused, isDisabled, shouldAcceptDrop, setDropEffect, isDraggingOver, onDrop, closePopover], + [isFocused, isDisabled, shouldAcceptDrop, setDropEffect, isDraggingOver, onDrop, closePopover, shouldClosePopover], ); useEffect(() => { From b31222308cb4dfdf2c322be9612b9ca4b3ec73de Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Wed, 29 Nov 2023 23:21:06 +0530 Subject: [PATCH 18/21] fix prettier diffs --- src/hooks/useDragAndDrop.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index c08719e48084..4c33ad1fee61 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -87,7 +87,7 @@ export default function useDragAndDrop({ dragCounter.current++; setDropEffect(event); if (shouldClosePopover) { - closePopover(); + closePopover(); } if (isDraggingOver) { return; From 47953904a261e18c2b3373c45dac0275f28d3ff2 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 1 Dec 2023 19:21:30 +0530 Subject: [PATCH 19/21] add requested changes --- src/components/DragAndDrop/Provider/index.tsx | 1 - src/hooks/useDragAndDrop.ts | 31 ++++++++----------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/components/DragAndDrop/Provider/index.tsx b/src/components/DragAndDrop/Provider/index.tsx index e97c70275172..761c512497ac 100644 --- a/src/components/DragAndDrop/Provider/index.tsx +++ b/src/components/DragAndDrop/Provider/index.tsx @@ -26,7 +26,6 @@ function DragAndDropProvider({children, isDisabled = false, setIsDraggingOver = dropZone, onDrop: onDropHandler.current, shouldAcceptDrop, - shouldClosePopover: true, isDisabled, }); diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 4c33ad1fee61..0e82cb22505f 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -14,7 +14,6 @@ type DragAndDropParams = { dropZone: React.MutableRefObject; onDrop?: (event: DragEvent) => void; shouldAllowDrop?: boolean; - shouldClosePopover?: boolean; isDisabled?: boolean; shouldAcceptDrop?: (event: DragEvent) => boolean; }; @@ -26,14 +25,7 @@ type DragAndDropOptions = { /** * @param dropZone – ref to the dropZone component */ -export default function useDragAndDrop({ - dropZone, - onDrop = () => {}, - shouldAllowDrop = true, - isDisabled = false, - shouldClosePopover = false, - shouldAcceptDrop = () => true, -}: DragAndDropParams): DragAndDropOptions { +export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllowDrop = true, isDisabled = false, shouldAcceptDrop = () => true}: DragAndDropParams): DragAndDropOptions { const isFocused = useIsFocused(); const [isDraggingOver, setIsDraggingOver] = useState(false); const {close: closePopover} = useContext(PopoverContext); @@ -53,9 +45,15 @@ export default function useDragAndDrop({ setIsDraggingOver(false); }, [isFocused, isDisabled]); - const setDropEffect = useCallback( + const handleDragEvent = useCallback( (event: DragEvent) => { - const effect = shouldAllowDrop && shouldAcceptDrop(event) ? COPY_DROP_EFFECT : NONE_DROP_EFFECT; + const shouldAcceptThisDrop = shouldAllowDrop && shouldAcceptDrop(event); + + if (shouldAcceptThisDrop && event.type === DRAG_ENTER_EVENT) { + closePopover(); + } + + const effect = shouldAcceptThisDrop ? COPY_DROP_EFFECT : NONE_DROP_EFFECT; if (event.dataTransfer) { // eslint-disable-next-line no-param-reassign @@ -64,7 +62,7 @@ export default function useDragAndDrop({ event.dataTransfer.effectAllowed = effect; } }, - [shouldAllowDrop, shouldAcceptDrop], + [shouldAllowDrop, shouldAcceptDrop, closePopover], ); /** @@ -81,14 +79,11 @@ export default function useDragAndDrop({ switch (event.type) { case DRAG_OVER_EVENT: - setDropEffect(event); + handleDragEvent(event); break; case DRAG_ENTER_EVENT: dragCounter.current++; - setDropEffect(event); - if (shouldClosePopover) { - closePopover(); - } + handleDragEvent(event); if (isDraggingOver) { return; } @@ -111,7 +106,7 @@ export default function useDragAndDrop({ break; } }, - [isFocused, isDisabled, shouldAcceptDrop, setDropEffect, isDraggingOver, onDrop, closePopover, shouldClosePopover], + [isFocused, isDisabled, shouldAcceptDrop, isDraggingOver, onDrop, handleDragEvent], ); useEffect(() => { From 20da9bb19f52f23d8a8801e2e8deb13d67a3a5ff Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 1 Dec 2023 19:40:24 +0530 Subject: [PATCH 20/21] added requested changes --- src/pages/home/report/ReportActionCompose/Suggestions.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose/Suggestions.js b/src/pages/home/report/ReportActionCompose/Suggestions.js index 32d0f80561bf..9d3da3864675 100644 --- a/src/pages/home/report/ReportActionCompose/Suggestions.js +++ b/src/pages/home/report/ReportActionCompose/Suggestions.js @@ -116,10 +116,11 @@ function Suggestions({ ); useEffect(() => { - if (prevIsDraggingOver === isDraggingOver) { + if (!isDraggingOver) { return; } - if (isDraggingOver) { + + if (!prevIsDraggingOver && isDraggingOver) { updateShouldShowSuggestionMenuToFalse(); } }, [isDraggingOver, prevIsDraggingOver, updateShouldShowSuggestionMenuToFalse]); From 88bb658eefe65e6266bcb4b48c9b7afa8e572991 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 1 Dec 2023 21:43:57 +0530 Subject: [PATCH 21/21] fix early return for usefffect in suggestions --- src/pages/home/report/ReportActionCompose/Suggestions.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose/Suggestions.js b/src/pages/home/report/ReportActionCompose/Suggestions.js index 9d3da3864675..5dc71fec6419 100644 --- a/src/pages/home/report/ReportActionCompose/Suggestions.js +++ b/src/pages/home/report/ReportActionCompose/Suggestions.js @@ -116,13 +116,10 @@ function Suggestions({ ); useEffect(() => { - if (!isDraggingOver) { + if (!(!prevIsDraggingOver && isDraggingOver)) { return; } - - if (!prevIsDraggingOver && isDraggingOver) { - updateShouldShowSuggestionMenuToFalse(); - } + updateShouldShowSuggestionMenuToFalse(); }, [isDraggingOver, prevIsDraggingOver, updateShouldShowSuggestionMenuToFalse]); const baseProps = {