From 451c730fa806b4f2745e0adb4b181b550ffcba5f Mon Sep 17 00:00:00 2001
From: Huzaifa Rasheed <huzaifarasheed900@gmail.com>
Date: Wed, 2 Aug 2023 10:59:05 +0500
Subject: [PATCH 1/5] Fix edit menu popup hiding pay option

---
 src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
index 346738574da3..35d5729a2375 100644
--- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
+++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
@@ -87,7 +87,7 @@ function BasePaymentsPage(props) {
                 anchorPositionVertical: position.y,
             });
         },
-        [windowWidth],
+        [windowWidth, shouldShowLoadingSpinner],
     );
 
     const setMenuPosition = useCallback(() => {

From 8788e834563d60a89c89bf50a4325c7cbcaf69b6 Mon Sep 17 00:00:00 2001
From: Huzaifa Rasheed <68777211+huzaifa-99@users.noreply.github.com>
Date: Wed, 2 Aug 2023 21:33:36 +0500
Subject: [PATCH 2/5] Use effect instead of callback for recalculating popover
 position

---
 src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
index 35d5729a2375..e7098f348f7e 100644
--- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
+++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
@@ -87,7 +87,7 @@ function BasePaymentsPage(props) {
                 anchorPositionVertical: position.y,
             });
         },
-        [windowWidth, shouldShowLoadingSpinner],
+        [windowWidth],
     );
 
     const setMenuPosition = useCallback(() => {
@@ -348,7 +348,7 @@ function BasePaymentsPage(props) {
             return;
         }
         setMenuPosition();
-    }, [props.shouldListenForResize, setMenuPosition]);
+    }, [props.shouldListenForResize, setMenuPosition, shouldShowLoadingSpinner]);
 
     useEffect(() => {
         if (!shouldShowDefaultDeleteMenu && !showPassword.shouldShowPasswordPrompt) {

From 2ccf6bbd3bd9972c0778d6c21d55fabe91d3fa0c Mon Sep 17 00:00:00 2001
From: Huzaifa Rasheed <huzaifarasheed900@gmail.com>
Date: Sat, 5 Aug 2023 18:28:09 +0500
Subject: [PATCH 3/5] Set correct popover anchor on payment method press

---
 .../Payments/PaymentsPage/BasePaymentsPage.js | 44 ++++++++-----------
 1 file changed, 18 insertions(+), 26 deletions(-)

diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
index a703e4fd9b3d..ef79296706b0 100644
--- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
+++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
@@ -54,13 +54,13 @@ function BasePaymentsPage(props) {
     });
     const addPaymentMethodAnchorRef = useRef(null);
     const deletePaymentMethodAnchorRef = useRef(null);
+    const paymentMethodButtonRef = useRef(null);
     const [anchorPosition, setAnchorPosition] = useState({
         anchorPositionHorizontal: 0,
         anchorPositionVertical: 0,
         anchorPositionTop: 0,
         anchorPositionRight: 0,
     });
-    const [addPaymentMethodButton, setAddPaymentMethodButton] = useState(null);
     const [showConfirmDeleteContent, setShowConfirmDeleteContent] = useState(false);
 
     const updateShouldShowLoadingSpinner = useCallback(() => {
@@ -78,27 +78,20 @@ function BasePaymentsPage(props) {
      *
      * @param {Object} position
      */
-    const setPositionAddPaymentMenu = useCallback(
-        (position) => {
-            setAnchorPosition({
-                anchorPositionTop: position.top + position.height + variables.addPaymentPopoverTopSpacing,
-
-                // We want the position to be 13px to the right of the left border
-                anchorPositionRight: windowWidth - position.right + variables.addPaymentPopoverRightSpacing,
-                anchorPositionHorizontal: position.x,
-                anchorPositionVertical: position.y,
-            });
-        },
-        [windowWidth],
-    );
-
     const setMenuPosition = useCallback(() => {
-        if (!addPaymentMethodButton) {
-            return;
-        }
-        const buttonPosition = getClickedTargetLocation(addPaymentMethodButton);
-        setPositionAddPaymentMenu(buttonPosition);
-    }, [addPaymentMethodButton, setPositionAddPaymentMenu]);
+        if (!paymentMethodButtonRef.current) return;
+
+        const position = getClickedTargetLocation(paymentMethodButtonRef.current);
+
+        setAnchorPosition({
+            anchorPositionTop: position.top + position.height + variables.addPaymentPopoverTopSpacing,
+
+            // We want the position to be 13px to the right of the left border
+            anchorPositionRight: windowWidth - position.right + variables.addPaymentPopoverRightSpacing,
+            anchorPositionHorizontal: position.x,
+            anchorPositionVertical: position.y,
+        });
+    }, [windowWidth]);
 
     const getSelectedPaymentMethodID = useCallback(() => {
         if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.PAYPAL) {
@@ -139,8 +132,7 @@ function BasePaymentsPage(props) {
      * @param {String|Number} methodID
      */
     const paymentMethodPressed = (nativeEvent, accountType, account, isDefault, methodID) => {
-        const position = getClickedTargetLocation(nativeEvent.currentTarget);
-        setAddPaymentMethodButton(nativeEvent.currentTarget);
+        paymentMethodButtonRef.current = nativeEvent.currentTarget;
 
         // The delete/default menu
         if (accountType) {
@@ -175,11 +167,11 @@ function BasePaymentsPage(props) {
                 methodID,
             });
             setShouldShowDefaultDeleteMenu(true);
-            setPositionAddPaymentMenu(position);
+            setMenuPosition();
             return;
         }
         setShouldShowAddPaymentMenu(true);
-        setPositionAddPaymentMenu(position);
+        setMenuPosition();
     };
 
     /**
@@ -350,7 +342,7 @@ function BasePaymentsPage(props) {
             return;
         }
         setMenuPosition();
-    }, [props.shouldListenForResize, setMenuPosition, shouldShowLoadingSpinner]);
+    }, [props.shouldListenForResize, setMenuPosition]);
 
     useEffect(() => {
         if (!shouldShowDefaultDeleteMenu && !showPassword.shouldShowPasswordPrompt) {

From be726be1a084113b12997e327c0f47948a33958d Mon Sep 17 00:00:00 2001
From: Huzaifa Rasheed <huzaifarasheed900@gmail.com>
Date: Sat, 5 Aug 2023 18:29:44 +0500
Subject: [PATCH 4/5] Update popover position when payment list header changes

---
 .../Payments/PaymentsPage/BasePaymentsPage.js | 91 ++++++++++---------
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
index ef79296706b0..b7f42236ee10 100644
--- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
+++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
@@ -269,52 +269,55 @@ function BasePaymentsPage(props) {
         setShouldShowDefaultDeleteMenu(false);
     };
 
-    const listHeaderComponent = () => (
-        <>
-            {Permissions.canUseWallet(props.betas) && (
-                <>
-                    <View style={[styles.mv5]}>
-                        {shouldShowLoadingSpinner ? (
-                            <ActivityIndicator
-                                color={themeColors.spinner}
-                                size="large"
-                            />
-                        ) : (
-                            <OfflineWithFeedback
-                                pendingAction={CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}
-                                errors={props.walletTerms.errors}
-                                onClose={PaymentMethods.clearWalletTermsError}
-                                errorRowStyles={[styles.ml10, styles.mr2]}
-                            >
-                                <CurrentWalletBalance />
-                            </OfflineWithFeedback>
+    const listHeaderComponent = useCallback(
+        () => (
+            <>
+                {Permissions.canUseWallet(props.betas) && (
+                    <View onLayout={setMenuPosition}>
+                        <View style={[styles.mv5]}>
+                            {shouldShowLoadingSpinner ? (
+                                <ActivityIndicator
+                                    color={themeColors.spinner}
+                                    size="large"
+                                />
+                            ) : (
+                                <OfflineWithFeedback
+                                    pendingAction={CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}
+                                    errors={props.walletTerms.errors}
+                                    onClose={PaymentMethods.clearWalletTermsError}
+                                    errorRowStyles={[styles.ml10, styles.mr2]}
+                                >
+                                    <CurrentWalletBalance />
+                                </OfflineWithFeedback>
+                            )}
+                        </View>
+                        {props.userWallet.currentBalance > 0 && (
+                            <View style={styles.mb3}>
+                                <KYCWall
+                                    onSuccessfulKYC={navigateToTransferBalancePage}
+                                    enablePaymentsRoute={ROUTES.SETTINGS_ENABLE_PAYMENTS}
+                                    addBankAccountRoute={ROUTES.SETTINGS_ADD_BANK_ACCOUNT}
+                                    addDebitCardRoute={ROUTES.SETTINGS_ADD_DEBIT_CARD}
+                                    popoverPlacement="bottom"
+                                >
+                                    {(triggerKYCFlow) => (
+                                        <MenuItem
+                                            title={translate('common.transferBalance')}
+                                            icon={Expensicons.Transfer}
+                                            onPress={triggerKYCFlow}
+                                            shouldShowRightIcon
+                                            disabled={props.network.isOffline}
+                                        />
+                                    )}
+                                </KYCWall>
+                            </View>
                         )}
                     </View>
-                    {props.userWallet.currentBalance > 0 && (
-                        <View style={styles.mb3}>
-                            <KYCWall
-                                onSuccessfulKYC={navigateToTransferBalancePage}
-                                enablePaymentsRoute={ROUTES.SETTINGS_ENABLE_PAYMENTS}
-                                addBankAccountRoute={ROUTES.SETTINGS_ADD_BANK_ACCOUNT}
-                                addDebitCardRoute={ROUTES.SETTINGS_ADD_DEBIT_CARD}
-                                popoverPlacement="bottom"
-                            >
-                                {(triggerKYCFlow) => (
-                                    <MenuItem
-                                        title={translate('common.transferBalance')}
-                                        icon={Expensicons.Transfer}
-                                        onPress={triggerKYCFlow}
-                                        shouldShowRightIcon
-                                        disabled={props.network.isOffline}
-                                    />
-                                )}
-                            </KYCWall>
-                        </View>
-                    )}
-                </>
-            )}
-            <Text style={[styles.ph5, styles.textLabelSupporting, styles.mb1]}>{translate('paymentsPage.paymentMethodsTitle')}</Text>
-        </>
+                )}
+                <Text style={[styles.ph5, styles.textLabelSupporting, styles.mb1]}>{translate('paymentsPage.paymentMethodsTitle')}</Text>
+            </>
+        ),
+        [props.betas, props.network.isOffline, props.userWallet.currentBalance, props.walletTerms.errors, shouldShowLoadingSpinner, translate, setMenuPosition],
     );
 
     useEffect(() => {

From 81ca4553b475079be09527ba331aa3c9abc56ad2 Mon Sep 17 00:00:00 2001
From: Huzaifa Rasheed <huzaifarasheed900@gmail.com>
Date: Tue, 8 Aug 2023 19:34:11 +0500
Subject: [PATCH 5/5] Update payment list anchor on flat list content change

---
 src/pages/settings/Payments/PaymentMethodList.js           | 5 +++++
 .../settings/Payments/PaymentsPage/BasePaymentsPage.js     | 7 ++++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/pages/settings/Payments/PaymentMethodList.js b/src/pages/settings/Payments/PaymentMethodList.js
index 0d0040752f25..d2e628ac7438 100644
--- a/src/pages/settings/Payments/PaymentMethodList.js
+++ b/src/pages/settings/Payments/PaymentMethodList.js
@@ -70,6 +70,9 @@ const propTypes = {
     /** Content for the FlatList header component */
     listHeaderComponent: PropTypes.func,
 
+    /** Callback for whenever FlatList component size changes */
+    onListContentSizeChange: PropTypes.func,
+
     /** React ref being forwarded to the PaymentMethodList Button */
     buttonRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
 
@@ -93,6 +96,7 @@ const defaultProps = {
     selectedMethodID: '',
     listHeaderComponent: null,
     buttonRef: () => {},
+    onListContentSizeChange: () => {},
 };
 
 /**
@@ -246,6 +250,7 @@ function PaymentMethodList(props) {
                 keyExtractor={(item) => item.key}
                 ListEmptyComponent={renderListEmptyComponent(translate)}
                 ListHeaderComponent={props.listHeaderComponent}
+                onContentSizeChange={props.onListContentSizeChange}
             />
             {props.shouldShowAddPaymentMethodButton && (
                 <FormAlertWrapper>
diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
index 0fa615fffff2..359809dda0f1 100644
--- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
+++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
@@ -269,7 +269,7 @@ function BasePaymentsPage(props) {
         () => (
             <>
                 {Permissions.canUseWallet(props.betas) && (
-                    <View onLayout={setMenuPosition}>
+                    <>
                         <View style={[styles.mv5]}>
                             {shouldShowLoadingSpinner ? (
                                 <ActivityIndicator
@@ -308,12 +308,12 @@ function BasePaymentsPage(props) {
                                 </KYCWall>
                             </View>
                         )}
-                    </View>
+                    </>
                 )}
                 <Text style={[styles.ph5, styles.textLabelSupporting, styles.mb1]}>{translate('paymentsPage.paymentMethodsTitle')}</Text>
             </>
         ),
-        [props.betas, props.network.isOffline, props.userWallet.currentBalance, props.walletTerms.errors, shouldShowLoadingSpinner, translate, setMenuPosition],
+        [props.betas, props.network.isOffline, props.userWallet.currentBalance, props.walletTerms.errors, shouldShowLoadingSpinner, translate],
     );
 
     useEffect(() => {
@@ -398,6 +398,7 @@ function BasePaymentsPage(props) {
                         activePaymentMethodID={shouldShowDefaultDeleteMenu ? getSelectedPaymentMethodID() : ''}
                         listHeaderComponent={listHeaderComponent}
                         buttonRef={addPaymentMethodAnchorRef}
+                        onListContentSizeChange={shouldShowAddPaymentMenu || shouldShowDefaultDeleteMenu ? setMenuPosition : () => {}}
                     />
                 </OfflineWithFeedback>
             </View>
