From dded6349ee50d371ed5c920a4c3334700ad1d537 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 19 Dec 2023 21:55:13 +0530 Subject: [PATCH 01/65] test map when image is not loaded in request view --- .../ReportActionItem/MoneyRequestPreview.js | 10 +++++++++- src/components/ReportActionItem/MoneyRequestView.js | 13 ++++++++++++- src/libs/actions/IOU.js | 3 +++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestPreview.js b/src/components/ReportActionItem/MoneyRequestPreview.js index 12c6d0629370..1d798130dfd5 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview.js +++ b/src/components/ReportActionItem/MoneyRequestPreview.js @@ -38,6 +38,7 @@ import CONST from '@src/CONST'; import * as Localize from '@src/libs/Localize'; import ONYXKEYS from '@src/ONYXKEYS'; import ReportActionItemImages from './ReportActionItemImages'; +import ConfirmedRoute from '@components/ConfirmedRoute'; const propTypes = { /** The active IOUReport, used for Onyx subscription */ @@ -169,6 +170,8 @@ function MoneyRequestPreview(props) { const hasPendingWaypoints = lodashGet(props.transaction, 'pendingFields.waypoints', null); + const showMapAsImage = isDistanceRequest && hasPendingWaypoints; + const getSettledMessage = () => { if (isExpensifyCardTransaction) { return translate('common.done'); @@ -257,7 +260,12 @@ function MoneyRequestPreview(props) { !props.onPreviewPressed ? [styles.moneyRequestPreviewBox, ...props.containerStyles] : {}, ]} > - {hasReceipt && ( + {showMapAsImage && ( + + + + )} + {!showMapAsImage && hasReceipt && ( - {hasReceipt && ( + {showMapAsImage && ( + + + + + + )} + {!showMapAsImage && hasReceipt && ( Date: Tue, 9 Jan 2024 17:49:16 +0530 Subject: [PATCH 02/65] test changes --- src/components/ReportActionItem/MoneyRequestPreview.js | 2 +- src/components/ReportActionItem/MoneyRequestView.js | 2 +- src/libs/TransactionUtils.ts | 7 +++++-- src/libs/actions/IOU.js | 4 +++- src/types/onyx/Transaction.ts | 6 ++++-- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestPreview.js b/src/components/ReportActionItem/MoneyRequestPreview.js index 0663441c3834..9bba3aed205a 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview.js +++ b/src/components/ReportActionItem/MoneyRequestPreview.js @@ -38,8 +38,8 @@ import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import * as Localize from '@src/libs/Localize'; import ONYXKEYS from '@src/ONYXKEYS'; -import ReportActionItemImages from './ReportActionItemImages'; import ConfirmedRoute from '@components/ConfirmedRoute'; +import ReportActionItemImages from './ReportActionItemImages'; const propTypes = { /** The active IOUReport, used for Onyx subscription */ diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index eb658a7f8a1b..fc70b47d7101 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -42,8 +42,8 @@ import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import ReportActionItemImage from './ReportActionItemImage'; import ConfirmedRoute from '@components/ConfirmedRoute'; +import ReportActionItemImage from './ReportActionItemImage'; const violationNames = lodashValues(CONST.VIOLATIONS); diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index c34a6753c1d5..b8fad803d957 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -1,5 +1,6 @@ import lodashHas from 'lodash/has'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; @@ -7,8 +8,8 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {RecentWaypoint, Report, ReportAction, Transaction} from '@src/types/onyx'; import type {PolicyTaxRates} from '@src/types/onyx/PolicyTaxRates'; import type PolicyTaxRate from '@src/types/onyx/PolicyTaxRates'; -import type {Comment, Receipt, Waypoint, WaypointCollection} from '@src/types/onyx/Transaction'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; +import type {Comment, PendingFieldsCollection, Receipt, Waypoint, WaypointCollection} from '@src/types/onyx/Transaction'; +import {isNotEmptyObject} from '@src/types/utils/EmptyObject'; import {isCorporateCard, isExpensifyCard} from './CardUtils'; import DateUtils from './DateUtils'; import * as NumberUtils from './NumberUtils'; @@ -98,6 +99,7 @@ function buildOptimisticTransaction( category = '', tag = '', billable = false, + pendingFields: PendingFieldsCollection | null = null, ): Transaction { // transactionIDs are random, positive, 64-bit numeric strings. // Because JS can only handle 53-bit numbers, transactionIDs are strings in the front-end (just like reportActionID) @@ -112,6 +114,7 @@ function buildOptimisticTransaction( } return { + ...(isNotEmptyObject(pendingFields) ? {pendingFields} : {}), transactionID, amount, currency, diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 4e1a45101732..f4ff83e995c8 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -721,6 +721,8 @@ function getMoneyRequestInformation( receiptObject.state = receipt.state || CONST.IOU.RECEIPT_STATE.SCANREADY; filename = receipt.name; } + const existingTransaction = allTransactionDrafts[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${CONST.IOU.OPTIMISTIC_TRANSACTION_ID}`]; + const isDistanceRequest = existingTransaction && existingTransaction.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE let optimisticTransaction = TransactionUtils.buildOptimisticTransaction( ReportUtils.isExpenseReport(iouReport) ? -amount : amount, currency, @@ -736,6 +738,7 @@ function getMoneyRequestInformation( category, tag, billable, + isDistanceRequest ? {waypoints: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD} : null, ); const optimisticPolicyRecentlyUsedCategories = Policy.buildOptimisticPolicyRecentlyUsedCategories(iouReport.policyID, category); @@ -747,7 +750,6 @@ function getMoneyRequestInformation( // data. This is a big can of worms to change it to `Onyx.merge()` as explored in https://expensify.slack.com/archives/C05DWUDHVK7/p1692139468252109. // I want to clean this up at some point, but it's possible this will live in the code for a while so I've created https://github.com/Expensify/App/issues/25417 // to remind me to do this. - const existingTransaction = allTransactionDrafts[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${CONST.IOU.OPTIMISTIC_TRANSACTION_ID}`]; if (existingTransaction && existingTransaction.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE) { optimisticTransaction = OnyxUtils.fastMerge(existingTransaction, optimisticTransaction); // pendingFields: { diff --git a/src/types/onyx/Transaction.ts b/src/types/onyx/Transaction.ts index 8b7e26280305..a6b65f7cba38 100644 --- a/src/types/onyx/Transaction.ts +++ b/src/types/onyx/Transaction.ts @@ -49,6 +49,8 @@ type Route = { type Routes = Record; +type PendingFieldsCollection = Partial<{[K in keyof Transaction | keyof Comment]: ValueOf}>; + type Transaction = { amount: number; billable: boolean; @@ -76,7 +78,7 @@ type Transaction = { routes?: Routes; transactionID: string; tag: string; - pendingFields?: Partial<{[K in keyof Transaction | keyof Comment]: ValueOf}>; + pendingFields?: PendingFieldsCollection; /** Card Transactions */ @@ -97,4 +99,4 @@ type Transaction = { }; export default Transaction; -export type {WaypointCollection, Comment, Receipt, Waypoint}; +export type {WaypointCollection, Comment, Receipt, Waypoint, PendingFieldsCollection}; From 54a63d643b9ad602ace915090c3c18cae28af5b0 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 9 Jan 2024 18:07:40 +0530 Subject: [PATCH 03/65] fix lint --- src/components/ReportActionItem/MoneyRequestPreview.js | 2 +- src/components/ReportActionItem/MoneyRequestView.js | 2 +- src/libs/TransactionUtils.ts | 2 +- src/libs/actions/IOU.js | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestPreview.js b/src/components/ReportActionItem/MoneyRequestPreview.js index 9bba3aed205a..84ed317be294 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview.js +++ b/src/components/ReportActionItem/MoneyRequestPreview.js @@ -5,6 +5,7 @@ import React from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; +import ConfirmedRoute from '@components/ConfirmedRoute'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import MoneyRequestSkeletonView from '@components/MoneyRequestSkeletonView'; @@ -38,7 +39,6 @@ import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import * as Localize from '@src/libs/Localize'; import ONYXKEYS from '@src/ONYXKEYS'; -import ConfirmedRoute from '@components/ConfirmedRoute'; import ReportActionItemImages from './ReportActionItemImages'; const propTypes = { diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index fc70b47d7101..04b8d35e3448 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -5,6 +5,7 @@ import React, {useCallback} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import categoryPropTypes from '@components/categoryPropTypes'; +import ConfirmedRoute from '@components/ConfirmedRoute'; import * as Expensicons from '@components/Icon/Expensicons'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; @@ -42,7 +43,6 @@ import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import ConfirmedRoute from '@components/ConfirmedRoute'; import ReportActionItemImage from './ReportActionItemImage'; const violationNames = lodashValues(CONST.VIOLATIONS); diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index b8fad803d957..4155fe426f5a 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -1,6 +1,5 @@ import lodashHas from 'lodash/has'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; @@ -9,6 +8,7 @@ import type {RecentWaypoint, Report, ReportAction, Transaction} from '@src/types import type {PolicyTaxRates} from '@src/types/onyx/PolicyTaxRates'; import type PolicyTaxRate from '@src/types/onyx/PolicyTaxRates'; import type {Comment, PendingFieldsCollection, Receipt, Waypoint, WaypointCollection} from '@src/types/onyx/Transaction'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isNotEmptyObject} from '@src/types/utils/EmptyObject'; import {isCorporateCard, isExpensifyCard} from './CardUtils'; import DateUtils from './DateUtils'; diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index f4ff83e995c8..f004b44feca2 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -722,7 +722,7 @@ function getMoneyRequestInformation( filename = receipt.name; } const existingTransaction = allTransactionDrafts[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${CONST.IOU.OPTIMISTIC_TRANSACTION_ID}`]; - const isDistanceRequest = existingTransaction && existingTransaction.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE + const isDistanceRequest = existingTransaction && existingTransaction.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE; let optimisticTransaction = TransactionUtils.buildOptimisticTransaction( ReportUtils.isExpenseReport(iouReport) ? -amount : amount, currency, @@ -752,9 +752,9 @@ function getMoneyRequestInformation( // to remind me to do this. if (existingTransaction && existingTransaction.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE) { optimisticTransaction = OnyxUtils.fastMerge(existingTransaction, optimisticTransaction); -// pendingFields: { -// waypoints: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, -// } + // pendingFields: { + // waypoints: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + // } } // STEP 4: Build optimistic reportActions. We need: From 46141e379c495127f8287f3ca15a771c4eba63df Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 9 Jan 2024 18:09:37 +0530 Subject: [PATCH 04/65] fix lint --- src/libs/actions/IOU.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index f004b44feca2..d68b33e6b5ef 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -750,11 +750,8 @@ function getMoneyRequestInformation( // data. This is a big can of worms to change it to `Onyx.merge()` as explored in https://expensify.slack.com/archives/C05DWUDHVK7/p1692139468252109. // I want to clean this up at some point, but it's possible this will live in the code for a while so I've created https://github.com/Expensify/App/issues/25417 // to remind me to do this. - if (existingTransaction && existingTransaction.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE) { + if (isDistanceRequest) { optimisticTransaction = OnyxUtils.fastMerge(existingTransaction, optimisticTransaction); - // pendingFields: { - // waypoints: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - // } } // STEP 4: Build optimistic reportActions. We need: From be5367fc5e9078c60afeefa7477889ada34a6838 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 22 Jan 2024 20:13:45 +0530 Subject: [PATCH 05/65] ts fixes --- src/libs/TransactionUtils.ts | 6 +++--- tests/ui/UnreadIndicatorsTest.js | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 2e8207db860a..813bb128cb84 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -9,7 +9,7 @@ import type {PolicyTaxRates} from '@src/types/onyx/PolicyTaxRates'; import type PolicyTaxRate from '@src/types/onyx/PolicyTaxRates'; import type {Comment, PendingFieldsCollection, Receipt, Waypoint, WaypointCollection} from '@src/types/onyx/Transaction'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; -import {isNotEmptyObject} from '@src/types/utils/EmptyObject'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; import {isCorporateCard, isExpensifyCard} from './CardUtils'; import DateUtils from './DateUtils'; import * as NumberUtils from './NumberUtils'; @@ -100,7 +100,7 @@ function buildOptimisticTransaction( category = '', tag = '', billable = false, - pendingFields: PendingFieldsCollection | null = null, + pendingFields: PendingFieldsCollection | undefined = undefined, ): Transaction { // transactionIDs are random, positive, 64-bit numeric strings. // Because JS can only handle 53-bit numbers, transactionIDs are strings in the front-end (just like reportActionID) @@ -115,7 +115,7 @@ function buildOptimisticTransaction( } return { - ...(isNotEmptyObject(pendingFields) ? {pendingFields} : {}), + ...(!isEmptyObject(pendingFields) ? {pendingFields} : {}), transactionID, amount, currency, diff --git a/tests/ui/UnreadIndicatorsTest.js b/tests/ui/UnreadIndicatorsTest.js index e4d4d877f66b..88576f3dc89b 100644 --- a/tests/ui/UnreadIndicatorsTest.js +++ b/tests/ui/UnreadIndicatorsTest.js @@ -24,12 +24,16 @@ import appSetup from '../../src/setup'; import * as TestHelper from '../utils/TestHelper'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; import waitForBatchedUpdatesWithAct from '../utils/waitForBatchedUpdatesWithAct'; +import PendingMapView from '../../src/components/MapView/PendingMapView'; // We need a large timeout here as we are lazy loading React Navigation screens and this test is running against the entire mounted App jest.setTimeout(30000); jest.mock('../../src/libs/Notification/LocalNotification'); jest.mock('../../src/components/Icon/Expensicons'); +jest.mock('../../src/components/ConfirmedRoute.tsx', () => ( + +)); // Needed for: https://stackoverflow.com/questions/76903168/mocking-libraries-in-jest jest.mock('react-native/Libraries/LogBox/LogBox', () => ({ From e255ec88eb5f77c8e5b0a77a05ec4693afd66199 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 22 Jan 2024 20:25:05 +0530 Subject: [PATCH 06/65] test fix --- tests/ui/UnreadIndicatorsTest.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/ui/UnreadIndicatorsTest.js b/tests/ui/UnreadIndicatorsTest.js index 88576f3dc89b..01a3d735104b 100644 --- a/tests/ui/UnreadIndicatorsTest.js +++ b/tests/ui/UnreadIndicatorsTest.js @@ -24,16 +24,13 @@ import appSetup from '../../src/setup'; import * as TestHelper from '../utils/TestHelper'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; import waitForBatchedUpdatesWithAct from '../utils/waitForBatchedUpdatesWithAct'; -import PendingMapView from '../../src/components/MapView/PendingMapView'; // We need a large timeout here as we are lazy loading React Navigation screens and this test is running against the entire mounted App jest.setTimeout(30000); jest.mock('../../src/libs/Notification/LocalNotification'); jest.mock('../../src/components/Icon/Expensicons'); -jest.mock('../../src/components/ConfirmedRoute.tsx', () => ( - -)); +jest.mock('../../src/components/ConfirmedRoute.tsx'); // Needed for: https://stackoverflow.com/questions/76903168/mocking-libraries-in-jest jest.mock('react-native/Libraries/LogBox/LogBox', () => ({ From 17cb86a947002e25768b4cd2db2eac268cb4a569 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 22 Jan 2024 20:29:58 +0530 Subject: [PATCH 07/65] test fix attempt 2 --- tests/ui/UnreadIndicatorsTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/UnreadIndicatorsTest.js b/tests/ui/UnreadIndicatorsTest.js index 01a3d735104b..2241711497ff 100644 --- a/tests/ui/UnreadIndicatorsTest.js +++ b/tests/ui/UnreadIndicatorsTest.js @@ -30,7 +30,7 @@ jest.setTimeout(30000); jest.mock('../../src/libs/Notification/LocalNotification'); jest.mock('../../src/components/Icon/Expensicons'); -jest.mock('../../src/components/ConfirmedRoute.tsx'); +jest.mock('../../src/components/ConfirmedRoute.tsx', (props) => props.children); // Needed for: https://stackoverflow.com/questions/76903168/mocking-libraries-in-jest jest.mock('react-native/Libraries/LogBox/LogBox', () => ({ From c7165ddb967bf655bfb8843d50d051bbd5b72e53 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 22 Jan 2024 20:45:19 +0530 Subject: [PATCH 08/65] test fix attempt 3 --- tests/ui/UnreadIndicatorsTest.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/ui/UnreadIndicatorsTest.js b/tests/ui/UnreadIndicatorsTest.js index 2241711497ff..363c899d4328 100644 --- a/tests/ui/UnreadIndicatorsTest.js +++ b/tests/ui/UnreadIndicatorsTest.js @@ -30,7 +30,10 @@ jest.setTimeout(30000); jest.mock('../../src/libs/Notification/LocalNotification'); jest.mock('../../src/components/Icon/Expensicons'); -jest.mock('../../src/components/ConfirmedRoute.tsx', (props) => props.children); +jest.doMock('../../src/components/ConfirmedRoute.tsx', () => { + const Comp = (props) => props.children; + return Comp; +}); // Needed for: https://stackoverflow.com/questions/76903168/mocking-libraries-in-jest jest.mock('react-native/Libraries/LogBox/LogBox', () => ({ From b0068d381f1e212f131fe04a7ca3107a5bf2b274 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 22 Jan 2024 20:50:55 +0530 Subject: [PATCH 09/65] perf-test fix --- tests/perf-test/ReportActionsList.perf-test.js | 5 +++++ tests/perf-test/ReportScreen.perf-test.js | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/tests/perf-test/ReportActionsList.perf-test.js b/tests/perf-test/ReportActionsList.perf-test.js index 8e3312cfa4c7..515447a7a2ed 100644 --- a/tests/perf-test/ReportActionsList.perf-test.js +++ b/tests/perf-test/ReportActionsList.perf-test.js @@ -44,6 +44,11 @@ jest.mock('@react-navigation/native', () => { }; }); +jest.doMock('../../src/components/ConfirmedRoute.tsx', () => { + const Comp = (props) => props.children; + return Comp; +}); + beforeAll(() => Onyx.init({ keys: ONYXKEYS, diff --git a/tests/perf-test/ReportScreen.perf-test.js b/tests/perf-test/ReportScreen.perf-test.js index d58f71fa7ab4..97ea04ff55fb 100644 --- a/tests/perf-test/ReportScreen.perf-test.js +++ b/tests/perf-test/ReportScreen.perf-test.js @@ -29,6 +29,11 @@ jest.mock('react-native-reanimated', () => ({ useAnimatedRef: jest.fn, })); +jest.doMock('../../src/components/ConfirmedRoute.tsx', () => { + const Comp = (props) => props.children; + return Comp; +}); + jest.mock('../../src/components/withNavigationFocus', () => (Component) => { function WithNavigationFocus(props) { return ( From 365d37967684c85c0c059744637748346c4f82a6 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 22 Jan 2024 23:06:12 +0530 Subject: [PATCH 10/65] perf-test fix attempt 2 --- src/components/__mocks__/ConfirmedRoute.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/components/__mocks__/ConfirmedRoute.tsx diff --git a/src/components/__mocks__/ConfirmedRoute.tsx b/src/components/__mocks__/ConfirmedRoute.tsx new file mode 100644 index 000000000000..a759a2c1e193 --- /dev/null +++ b/src/components/__mocks__/ConfirmedRoute.tsx @@ -0,0 +1,8 @@ +import {View} from "react-native"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any +function ConfirmedRoute(props: any){ + return +} + +export default ConfirmedRoute; \ No newline at end of file From fb5a70ef1a038cffa40e8c001c020b489f04c5e3 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 22 Jan 2024 23:30:26 +0530 Subject: [PATCH 11/65] perf-test fix attempt 3 --- jest.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest.config.js b/jest.config.js index de7ed4b1f974..b5335f07482f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -8,7 +8,7 @@ module.exports = { `/?(*.)+(spec|test).${testFileExtension}`, ], transform: { - '^.+\\.jsx?$': 'babel-jest', + '^.+\\.[jt]sx?$': 'babel-jest', '^.+\\.svg?$': 'jest-transformer-svg', }, transformIgnorePatterns: ['/node_modules/(?!react-native)/'], From adb33f65224f4c82df7a375fdb0628e71a768010 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 23 Jan 2024 07:25:37 +0530 Subject: [PATCH 12/65] perf-test fix attempt 4 --- tests/perf-test/ReportActionsList.perf-test.js | 5 +---- tests/perf-test/ReportScreen.perf-test.js | 5 +---- tests/ui/UnreadIndicatorsTest.js | 5 +---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/tests/perf-test/ReportActionsList.perf-test.js b/tests/perf-test/ReportActionsList.perf-test.js index 515447a7a2ed..c81c4aa51df8 100644 --- a/tests/perf-test/ReportActionsList.perf-test.js +++ b/tests/perf-test/ReportActionsList.perf-test.js @@ -44,10 +44,7 @@ jest.mock('@react-navigation/native', () => { }; }); -jest.doMock('../../src/components/ConfirmedRoute.tsx', () => { - const Comp = (props) => props.children; - return Comp; -}); +jest.mock('../../src/components/ConfirmedRoute.tsx'); beforeAll(() => Onyx.init({ diff --git a/tests/perf-test/ReportScreen.perf-test.js b/tests/perf-test/ReportScreen.perf-test.js index 97ea04ff55fb..faa72fd3a367 100644 --- a/tests/perf-test/ReportScreen.perf-test.js +++ b/tests/perf-test/ReportScreen.perf-test.js @@ -29,10 +29,7 @@ jest.mock('react-native-reanimated', () => ({ useAnimatedRef: jest.fn, })); -jest.doMock('../../src/components/ConfirmedRoute.tsx', () => { - const Comp = (props) => props.children; - return Comp; -}); +jest.mock('../../src/components/ConfirmedRoute.tsx'); jest.mock('../../src/components/withNavigationFocus', () => (Component) => { function WithNavigationFocus(props) { diff --git a/tests/ui/UnreadIndicatorsTest.js b/tests/ui/UnreadIndicatorsTest.js index 363c899d4328..01a3d735104b 100644 --- a/tests/ui/UnreadIndicatorsTest.js +++ b/tests/ui/UnreadIndicatorsTest.js @@ -30,10 +30,7 @@ jest.setTimeout(30000); jest.mock('../../src/libs/Notification/LocalNotification'); jest.mock('../../src/components/Icon/Expensicons'); -jest.doMock('../../src/components/ConfirmedRoute.tsx', () => { - const Comp = (props) => props.children; - return Comp; -}); +jest.mock('../../src/components/ConfirmedRoute.tsx'); // Needed for: https://stackoverflow.com/questions/76903168/mocking-libraries-in-jest jest.mock('react-native/Libraries/LogBox/LogBox', () => ({ From 94c115adec14ae658d098d2d4e0a794e7da411fd Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 23 Jan 2024 08:16:55 +0530 Subject: [PATCH 13/65] fix lint --- src/components/__mocks__/ConfirmedRoute.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/__mocks__/ConfirmedRoute.tsx b/src/components/__mocks__/ConfirmedRoute.tsx index a759a2c1e193..3c78e764ebea 100644 --- a/src/components/__mocks__/ConfirmedRoute.tsx +++ b/src/components/__mocks__/ConfirmedRoute.tsx @@ -1,8 +1,8 @@ -import {View} from "react-native"; +import {View} from 'react-native'; // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any -function ConfirmedRoute(props: any){ - return +function ConfirmedRoute(props: any) { + return ; } -export default ConfirmedRoute; \ No newline at end of file +export default ConfirmedRoute; From 16bd5cdba5e545a808601004be02b71cb7c94104 Mon Sep 17 00:00:00 2001 From: MrRefactor Date: Mon, 29 Jan 2024 16:40:22 +0100 Subject: [PATCH 14/65] Fix always scrollable suggestion list --- .../BaseAutoCompleteSuggestions.tsx | 7 ++++++- src/styles/utils/index.ts | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx index 5da9c6981603..72ef6ef2f061 100644 --- a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx +++ b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx @@ -10,6 +10,8 @@ import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import * as Browser from '@libs/Browser'; +import getPlatform from '@libs/getPlatform'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import viewForwardedRef from '@src/types/utils/viewForwardedRef'; @@ -47,6 +49,9 @@ function BaseAutoCompleteSuggestions( const StyleUtils = useStyleUtils(); const rowHeight = useSharedValue(0); const scrollRef = useRef>(null); + const platform = getPlatform(); + const isMobileSafari = Browser.isMobileSafari(); + /** * Render a suggestion menu item component. */ @@ -67,7 +72,7 @@ function BaseAutoCompleteSuggestions( ); const innerHeight = CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT * suggestions.length; - const animatedStyles = useAnimatedStyle(() => StyleUtils.getAutoCompleteSuggestionContainerStyle(rowHeight.value)); + const animatedStyles = useAnimatedStyle(() => StyleUtils.getAutoCompleteSuggestionContainerStyle(rowHeight.value, platform, isMobileSafari)); const estimatedListSize = useMemo( () => ({ height: CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT * suggestions.length, diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 8b040dd8d72c..30b1245ebb5a 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -4,6 +4,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import type {EdgeInsets} from 'react-native-safe-area-context'; import type {ValueOf} from 'type-fest'; import * as Browser from '@libs/Browser'; +import type Platform from '@libs/getPlatform/types'; import * as UserUtils from '@libs/UserUtils'; // eslint-disable-next-line no-restricted-imports import {defaultTheme} from '@styles/theme'; @@ -792,17 +793,26 @@ function getBaseAutoCompleteSuggestionContainerStyle({left, bottom, width}: GetB /** * Gets the correct position for auto complete suggestion container */ -function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle { +function getAutoCompleteSuggestionContainerStyle(itemsHeight: number, platform: Platform, isMobileSafari: boolean): ViewStyle { 'worklet'; + // This if condition is reverting the workaround for broken scroll on all platforms but native android and iOS safari, where the issue with + // scrolling char behind suggestion list is occuring. Rewerting the fix resolves the issue with always scrollable list on other platforms. const borderWidth = 2; - const height = itemsHeight + 2 * CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_INNER_PADDING; + let height = itemsHeight + 2 * CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_INNER_PADDING; + let top = -(height + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_PADDING); + + if (platform === 'android' || isMobileSafari) { + top += borderWidth; + } else { + height += borderWidth; + } // The suggester is positioned absolutely within the component that includes the input and RecipientLocalTime view (for non-expanded mode only). To position it correctly, // we need to shift it by the suggester's height plus its padding and, if applicable, the height of the RecipientLocalTime view. return { overflow: 'hidden', - top: -(height + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_PADDING + borderWidth), + top, height, minHeight: CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, }; From dd639d421c6a7db84a69fe02858e3acb8a502cb4 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Tue, 30 Jan 2024 01:20:15 +0700 Subject: [PATCH 15/65] fix Inconsistent validation error message for required field in home address --- src/components/CountrySelector.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/components/CountrySelector.tsx b/src/components/CountrySelector.tsx index 589530cd7879..398809d79a2c 100644 --- a/src/components/CountrySelector.tsx +++ b/src/components/CountrySelector.tsx @@ -1,4 +1,5 @@ -import React, {forwardRef, useEffect} from 'react'; +import {useIsFocused} from '@react-navigation/native'; +import React, {forwardRef, useEffect, useRef} from 'react'; import type {ForwardedRef} from 'react'; import {View} from 'react-native'; import useLocalize from '@hooks/useLocalize'; @@ -24,13 +25,22 @@ type CountrySelectorProps = { inputID: string; }; -function CountrySelector({errorText = '', value: countryCode, onInputChange}: CountrySelectorProps, ref: ForwardedRef) { +function CountrySelector({errorText = '', value: countryCode, onInputChange, ...rest}: CountrySelectorProps, ref: ForwardedRef) { const styles = useThemeStyles(); const {translate} = useLocalize(); const title = countryCode ? translate(`allCountries.${countryCode}`) : ''; const countryTitleDescStyle = title.length === 0 ? styles.textNormal : null; + const didOpenContrySelector = useRef(false); + const isFocus = useIsFocused(); + useEffect(() => { + if (isFocus && didOpenContrySelector.current) { + didOpenContrySelector.current = false; + rest.onBlur && rest.onBlur(); + } + }, [isFocus, rest]); + useEffect(() => { // This will cause the form to revalidate and remove any error related to country name onInputChange(countryCode); @@ -47,6 +57,8 @@ function CountrySelector({errorText = '', value: countryCode, onInputChange}: Co description={translate('common.country')} onPress={() => { const activeRoute = Navigation.getActiveRouteWithoutParams(); + rest.onPress && rest.onPress(); + didOpenContrySelector.current = true; Navigation.navigate(ROUTES.SETTINGS_PERSONAL_DETAILS_ADDRESS_COUNTRY.getRoute(countryCode ?? '', activeRoute)); }} /> From fdfd0f5ef072247178da2fd76422234897d12bf1 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 31 Jan 2024 10:54:16 +0700 Subject: [PATCH 16/65] show loading indicator for uncached attachments --- src/components/Image/index.js | 5 ++++- src/components/ImageWithSizeCalculation.tsx | 13 +++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/components/Image/index.js b/src/components/Image/index.js index ef1a69e19c12..59fcde8273fd 100644 --- a/src/components/Image/index.js +++ b/src/components/Image/index.js @@ -3,12 +3,15 @@ import React, {useEffect, useMemo} from 'react'; import {Image as RNImage} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; +import useNetwork from '@hooks/useNetwork'; import ONYXKEYS from '@src/ONYXKEYS'; import {defaultProps, imagePropTypes} from './imagePropTypes'; import RESIZE_MODES from './resizeModes'; function Image(props) { const {source: propsSource, isAuthTokenRequired, onLoad, session} = props; + const {isOffline} = useNetwork(); + /** * Check if the image source is a URL - if so the `encryptedAuthToken` is appended * to the source. @@ -39,7 +42,7 @@ function Image(props) { RNImage.getSize(source.uri, (width, height) => { onLoad({nativeEvent: {width, height}}); }); - }, [onLoad, source]); + }, [onLoad, source, isOffline]); // Omit the props which the underlying RNImage won't use const forwardedProps = _.omit(props, ['source', 'onLoad', 'session', 'isAuthTokenRequired']); diff --git a/src/components/ImageWithSizeCalculation.tsx b/src/components/ImageWithSizeCalculation.tsx index d0559327274a..344904796f31 100644 --- a/src/components/ImageWithSizeCalculation.tsx +++ b/src/components/ImageWithSizeCalculation.tsx @@ -2,6 +2,7 @@ import delay from 'lodash/delay'; import React, {useEffect, useRef, useState} from 'react'; import type {ImageSourcePropType, StyleProp, ViewStyle} from 'react-native'; import {View} from 'react-native'; +import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import Log from '@libs/Log'; import FullscreenLoadingIndicator from './FullscreenLoadingIndicator'; @@ -42,13 +43,21 @@ function ImageWithSizeCalculation({url, style, onMeasure, isAuthTokenRequired}: const isLoadedRef = useRef(null); const [isImageCached, setIsImageCached] = useState(true); const [isLoading, setIsLoading] = useState(false); + const {isOffline} = useNetwork(); const onError = () => { Log.hmmm('Unable to fetch image to calculate size', {url}); + if (isOffline) { + return; + } + setIsLoading(false); + setIsImageCached(true); }; const imageLoadedSuccessfully = (event: OnLoadNativeEvent) => { isLoadedRef.current = true; + setIsLoading(false); + setIsImageCached(true); onMeasure({ width: event.nativeEvent.width, height: event.nativeEvent.height, @@ -82,10 +91,6 @@ function ImageWithSizeCalculation({url, style, onMeasure, isAuthTokenRequired}: } setIsLoading(true); }} - onLoadEnd={() => { - setIsLoading(false); - setIsImageCached(true); - }} onError={onError} onLoad={imageLoadedSuccessfully} /> From bf40b7ca25490abf3d900372f15f1ff805ce9152 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 31 Jan 2024 11:15:35 +0700 Subject: [PATCH 17/65] fix: menu popup can not be closed again --- .../report/ContextMenu/PopoverReportActionContextMenu.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx index 272548214ece..0311a9b3183c 100644 --- a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx @@ -65,10 +65,9 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef([]); const contentRef = useRef(null); - const anchorRef = useRef(null); const dimensionsEventListener = useRef(null); const contextMenuAnchorRef = useRef(null); - const contextMenuTargetNode = useRef(null); + const contextMenuTargetNode = useRef(null); const onPopoverShow = useRef(() => {}); const onPopoverHide = useRef(() => {}); @@ -166,7 +165,7 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef { const {pageX = 0, pageY = 0} = extractPointerEvent(event); contextMenuAnchorRef.current = contextMenuAnchor; - contextMenuTargetNode.current = event.target as HTMLElement; + contextMenuTargetNode.current = event.target as HTMLDivElement; setInstanceID(Math.random().toString(36).substr(2, 5)); @@ -307,7 +306,7 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef Date: Thu, 1 Feb 2024 16:06:07 +0530 Subject: [PATCH 18/65] adjustment according to recommendation --- .../ReportActionItem/MoneyRequestView.js | 36 +++++++------------ 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index 4160bee1d3cc..c318f306272f 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -237,7 +237,7 @@ function MoneyRequestView({report, parentReport, parentReportActions, policyCate - {showMapAsImage && ( + {(showMapAsImage || hasReceipt) && ( - - - - )} - {!showMapAsImage && hasReceipt && ( - { - Transaction.clearError(transaction.transactionID); - }} - > - - + {showMapAsImage ? ( + + ) : ( + + )} )} From 424c7c6848e8adc37cc5c6a2728cc6cd555e5990 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 1 Feb 2024 17:39:09 +0700 Subject: [PATCH 19/65] fix: right click to open popover --- .../ContextMenu/BaseReportActionContextMenu.tsx | 1 + .../ContextMenu/PopoverReportActionContextMenu.tsx | 12 ++++++++---- .../report/ContextMenu/ReportActionContextMenu.ts | 3 +++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx index 213d94f51f81..52b62c2d15b3 100755 --- a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -208,6 +208,7 @@ function BaseReportActionContextMenu({ undefined, undefined, filteredContextMenuActions, + true, ); }; diff --git a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx index 0311a9b3183c..bf1dcfd98c0a 100644 --- a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx @@ -65,9 +65,10 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef([]); const contentRef = useRef(null); + const anchorRef = useRef(null); const dimensionsEventListener = useRef(null); const contextMenuAnchorRef = useRef(null); - const contextMenuTargetNode = useRef(null); + const contextMenuTargetNode = useRef(null); const onPopoverShow = useRef(() => {}); const onPopoverHide = useRef(() => {}); @@ -162,11 +163,14 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef { const {pageX = 0, pageY = 0} = extractPointerEvent(event); contextMenuAnchorRef.current = contextMenuAnchor; - contextMenuTargetNode.current = event.target as HTMLDivElement; - + contextMenuTargetNode.current = event.target as HTMLElement; + if (isThreeDotButton) { + anchorRef.current = event.target as HTMLDivElement; + } setInstanceID(Math.random().toString(36).substr(2, 5)); onPopoverShow.current = onShow; @@ -306,7 +310,7 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef void; type ReportActionContextMenu = { @@ -113,6 +114,7 @@ function showContextMenu( isPinnedChat = false, isUnreadChat = false, disabledActions: ContextMenuAction[] = [], + isThreeDotButton = false, ) { if (!contextMenuRef.current) { return; @@ -140,6 +142,7 @@ function showContextMenu( isPinnedChat, isUnreadChat, disabledActions, + isThreeDotButton, ); } From b8b9f4e3b47e9591c7c863a6a9a18cfba47a32b4 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Sat, 3 Feb 2024 19:54:18 +0530 Subject: [PATCH 20/65] merge main --- src/libs/TransactionUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index da87f0a0b1ac..a4bd47fade52 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -6,7 +6,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {RecentWaypoint, Report, ReportAction, Transaction, TransactionViolation} from '@src/types/onyx'; import type {PolicyTaxRate, PolicyTaxRates} from '@src/types/onyx/PolicyTaxRates'; -import type {Comment, PendingFieldsCollection, Receipt, Waypoint, WaypointCollection} from '@src/types/onyx/Transaction'; +import type {Comment, TransactionPendingFieldsKey, Receipt, Waypoint, WaypointCollection} from '@src/types/onyx/Transaction'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import {isCorporateCard, isExpensifyCard} from './CardUtils'; @@ -99,7 +99,7 @@ function buildOptimisticTransaction( category = '', tag = '', billable = false, - pendingFields: PendingFieldsCollection | undefined = undefined, + pendingFields: Partial<{[K in TransactionPendingFieldsKey]: ValueOf}> | undefined = undefined, ): Transaction { // transactionIDs are random, positive, 64-bit numeric strings. // Because JS can only handle 53-bit numbers, transactionIDs are strings in the front-end (just like reportActionID) From fdd2b8840dba9c213886aed9fa95d8ea13af0b37 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Sat, 3 Feb 2024 19:55:20 +0530 Subject: [PATCH 21/65] fix lint --- src/components/ReportActionItem/MoneyRequestPreview.tsx | 2 +- src/components/ReportActionItem/MoneyRequestView.tsx | 2 +- src/libs/TransactionUtils.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestPreview.tsx b/src/components/ReportActionItem/MoneyRequestPreview.tsx index 6d7f8c66b8c4..cade1affc0c4 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview.tsx @@ -5,8 +5,8 @@ import React from 'react'; import {View} from 'react-native'; import type {GestureResponderEvent, StyleProp, ViewStyle} from 'react-native'; import {withOnyx} from 'react-native-onyx'; -import ConfirmedRoute from '@components/ConfirmedRoute'; import type {OnyxEntry} from 'react-native-onyx'; +import ConfirmedRoute from '@components/ConfirmedRoute'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import MoneyRequestSkeletonView from '@components/MoneyRequestSkeletonView'; diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 94ef244ff2d7..d493913f84c6 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -1,8 +1,8 @@ import React, {useCallback} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; -import ConfirmedRoute from '@components/ConfirmedRoute'; import type {OnyxEntry} from 'react-native-onyx'; +import ConfirmedRoute from '@components/ConfirmedRoute'; import * as Expensicons from '@components/Icon/Expensicons'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index a4bd47fade52..d3ffa993f821 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -6,7 +6,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {RecentWaypoint, Report, ReportAction, Transaction, TransactionViolation} from '@src/types/onyx'; import type {PolicyTaxRate, PolicyTaxRates} from '@src/types/onyx/PolicyTaxRates'; -import type {Comment, TransactionPendingFieldsKey, Receipt, Waypoint, WaypointCollection} from '@src/types/onyx/Transaction'; +import type {Comment, Receipt, TransactionPendingFieldsKey, Waypoint, WaypointCollection} from '@src/types/onyx/Transaction'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import {isCorporateCard, isExpensifyCard} from './CardUtils'; From 99a68d62a85b5408e5b937e79a310c5495e7fbcc Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 5 Feb 2024 23:00:19 +0700 Subject: [PATCH 22/65] fix: Room visibility can not be changed after a room is created --- src/ROUTES.ts | 4 + src/SCREENS.ts | 1 + src/languages/en.ts | 1 + src/languages/es.ts | 1 + .../AppNavigator/ModalStackNavigators.tsx | 1 + src/libs/Navigation/linkingConfig/config.ts | 3 + src/libs/Navigation/types.ts | 3 + src/libs/ReportUtils.ts | 8 ++ .../settings/Report/ReportSettingsPage.js | 17 +++- src/pages/settings/Report/VisibilityPage.tsx | 93 +++++++++++++++++++ 10 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 src/pages/settings/Report/VisibilityPage.tsx diff --git a/src/ROUTES.ts b/src/ROUTES.ts index a84dc9c8f9ae..f95743e3e0c6 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -218,6 +218,10 @@ const ROUTES = { route: 'r/:reportID/welcomeMessage', getRoute: (reportID: string) => `r/${reportID}/welcomeMessage` as const, }, + REPORT_SETTINGS_VISIBILITY: { + route: 'r/:reportID/settings/visibility', + getRoute: (reportID: string) => `r/${reportID}/settings/visibility` as const, + }, SPLIT_BILL_DETAILS: { route: 'r/:reportID/split/:reportActionID', getRoute: (reportID: string, reportActionID: string) => `r/${reportID}/split/${reportActionID}` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 96b284dbea2f..3f2ad7655e4f 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -171,6 +171,7 @@ const SCREENS = { ROOM_NAME: 'Report_Settings_Room_Name', NOTIFICATION_PREFERENCES: 'Report_Settings_Notification_Preferences', WRITE_CAPABILITY: 'Report_Settings_Write_Capability', + VISIBILITY: 'Report_Settings_Visibility', }, NEW_TASK: { diff --git a/src/languages/en.ts b/src/languages/en.ts index 145d8414c1e3..c08c3bbffd32 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1909,6 +1909,7 @@ export default { genericUpdateReportFieldFailureMessage: 'Unexpected error while updating the field, please try again later', genericUpdateReporNameEditFailureMessage: 'Unexpected error while renaming the report, please try again later', noActivityYet: 'No activity yet', + visibilityPublicPrompt: 'Anyone can find this room', }, chronos: { oooEventSummaryFullDay: ({summary, dayCount, date}: OOOEventSummaryFullDayParams) => `${summary} for ${dayCount} ${dayCount === 1 ? 'day' : 'days'} until ${date}`, diff --git a/src/languages/es.ts b/src/languages/es.ts index 517b3ba1e2f9..81daa6dc962e 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1935,6 +1935,7 @@ export default { genericUpdateReportFieldFailureMessage: 'Error inesperado al actualizar el campo. Por favor, inténtalo más tarde', genericUpdateReporNameEditFailureMessage: 'Error inesperado al cambiar el nombre del informe. Vuelva a intentarlo más tarde.', noActivityYet: 'Sin actividad todavía', + visibilityPublicPrompt: 'Anyone can find this room', }, chronos: { oooEventSummaryFullDay: ({summary, dayCount, date}: OOOEventSummaryFullDayParams) => `${summary} por ${dayCount} ${dayCount === 1 ? 'día' : 'días'} hasta el ${date}`, diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx index 4606f867c3fc..e0062729b949 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx @@ -135,6 +135,7 @@ const ReportSettingsModalStackNavigator = createModalStackNavigator require('../../../pages/settings/Report/RoomNamePage').default as React.ComponentType, [SCREENS.REPORT_SETTINGS.NOTIFICATION_PREFERENCES]: () => require('../../../pages/settings/Report/NotificationPreferencePage').default as React.ComponentType, [SCREENS.REPORT_SETTINGS.WRITE_CAPABILITY]: () => require('../../../pages/settings/Report/WriteCapabilityPage').default as React.ComponentType, + [SCREENS.REPORT_SETTINGS.VISIBILITY]: () => require('../../../pages/settings/Report/VisibilityPage').default as React.ComponentType, }); const TaskModalStackNavigator = createModalStackNavigator({ diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index f1c9c316fe93..b87540c37cbd 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -278,6 +278,9 @@ const config: LinkingOptions['config'] = { [SCREENS.REPORT_SETTINGS.WRITE_CAPABILITY]: { path: ROUTES.REPORT_SETTINGS_WRITE_CAPABILITY.route, }, + [SCREENS.REPORT_SETTINGS.VISIBILITY]: { + path: ROUTES.REPORT_SETTINGS_VISIBILITY.route, + }, }, }, [SCREENS.RIGHT_MODAL.REPORT_WELCOME_MESSAGE]: { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 3c4cf17853f1..fc3e3348de34 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -174,6 +174,9 @@ type ReportSettingsNavigatorParamList = { [SCREENS.REPORT_SETTINGS.ROOM_NAME]: undefined; [SCREENS.REPORT_SETTINGS.NOTIFICATION_PREFERENCES]: undefined; [SCREENS.REPORT_SETTINGS.WRITE_CAPABILITY]: undefined; + [SCREENS.REPORT_SETTINGS.VISIBILITY]: { + reportID: string; + }; }; type ReportWelcomeMessageNavigatorParamList = { diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 568ce49ff961..8478ccb0dcff 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4303,6 +4303,13 @@ function canEditWriteCapability(report: OnyxEntry, policy: OnyxEntry, policy: OnyxEntry): boolean { + return PolicyUtils.isPolicyAdmin(policy) && !isArchivedRoom(report); +} + /** * Returns the onyx data needed for the task assignee chat */ @@ -4949,6 +4956,7 @@ export { isReportFieldDisabled, getAvailableReportFields, getAllAncestorReportActionIDs, + canEditRoomVisibility, }; export type { diff --git a/src/pages/settings/Report/ReportSettingsPage.js b/src/pages/settings/Report/ReportSettingsPage.js index c7cfd9c7850d..7b05dcc34f6d 100644 --- a/src/pages/settings/Report/ReportSettingsPage.js +++ b/src/pages/settings/Report/ReportSettingsPage.js @@ -76,6 +76,7 @@ function ReportSettingsPage(props) { const writeCapabilityText = translate(`writeCapabilityPage.writeCapability.${writeCapability}`); const shouldAllowWriteCapabilityEditing = useMemo(() => ReportUtils.canEditWriteCapability(report, linkedWorkspace), [report, linkedWorkspace]); + const shouldAllowChangeVisibility = useMemo(() => ReportUtils.canEditRoomVisibility(report, linkedWorkspace), [report, linkedWorkspace]); const shouldShowNotificationPref = !isMoneyRequestReport && report.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; const roomNameLabel = translate(isMoneyRequestReport ? 'workspace.editor.nameInputLabel' : 'newRoomPage.roomName'); @@ -174,8 +175,17 @@ function ReportSettingsPage(props) { /> )} - {Boolean(report.visibility) && ( - + + {Boolean(report.visibility) && + (shouldAllowChangeVisibility ? ( + Navigation.navigate(ROUTES.REPORT_SETTINGS_VISIBILITY.getRoute(report.reportID))} + /> + ) : ( + {translate(`newRoomPage.${report.visibility}Description`)} - )} - + ))} {!shouldDisableWelcomeMessage && ( ; +}; + +type VisibilityProps = VisibilityOnyxProps & StackScreenProps; + +function VisibilityPage({report}: VisibilityProps) { + const [showConfirmModal, setShowConfirmModal] = useState(false); + + const shouldDisableVisibility = ReportUtils.isArchivedRoom(report); + const {translate} = useLocalize(); + + const visibilityOptions = useMemo( + () => + Object.values(CONST.REPORT.VISIBILITY) + .filter((visibilityOption) => visibilityOption !== CONST.REPORT.VISIBILITY.PUBLIC_ANNOUNCE) + .map((visibilityOption) => ({ + text: translate(`newRoomPage.visibilityOptions.${visibilityOption}`), + value: visibilityOption, + alternateText: translate(`newRoomPage.${visibilityOption}Description`), + keyForList: visibilityOption, + isSelected: visibilityOption === report?.visibility, + })), + [], + ); + + const changeVisibility = useCallback(() => {}, []); + + const hideModal = useCallback(() => { + setShowConfirmModal(false); + }, []); + + return ( + + + ReportUtils.goBackToDetailsPage(report)} + /> + { + if (option.value === CONST.REPORT.VISIBILITY.PUBLIC) { + setShowConfirmModal(true); + } + }} + initiallyFocusedOptionKey={visibilityOptions.find((visibility) => visibility.isSelected)?.keyForList} + /> + { + changeVisibility(); + hideModal(); + }} + onCancel={hideModal} + title={translate('common.areYouSure')} + prompt={translate('report.visibilityPublicPrompt')} + confirmText={translate('common.yes')} + cancelText={translate('common.no')} + danger + /> + + + ); +} + +VisibilityPage.displayName = 'VisibilityPage'; + +export default withOnyx({ + report: { + key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID ?? ''}`, + }, +})(VisibilityPage); From c9d14bed01a38b9b2f33ecb25475d0092f2d720a Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 7 Feb 2024 00:58:48 +0700 Subject: [PATCH 23/65] fix: Copy to clipboard on the system message for paid expense copies negative amount --- src/libs/actions/IOU.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index a7a82e642e62..2422247a2bbb 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3081,9 +3081,10 @@ function getSendMoneyParams( } function getPayMoneyRequestParams(chatReport: OnyxTypes.Report, iouReport: OnyxTypes.Report, recipient: Participant, paymentMethodType: PaymentMethodType): PayMoneyRequestData { + const total = iouReport.total ?? 0; const optimisticIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( CONST.IOU.REPORT_ACTION_TYPE.PAY, - -(iouReport.total ?? 0), + ReportUtils.isExpenseReport(iouReport) ? -total : total, iouReport.currency ?? '', '', [recipient], From 58fd97912ccaf56605b066251ef4c5a48f82c6f4 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Wed, 7 Feb 2024 20:07:12 +0530 Subject: [PATCH 24/65] ts fix --- src/libs/actions/IOU.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index d096287107dd..362d66fae687 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -794,7 +794,7 @@ function getMoneyRequestInformation( category, tag, billable, - isDistanceRequest ? {waypoints: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD} : null, + isDistanceRequest ? {waypoints: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD} : undefined, ); const optimisticPolicyRecentlyUsedCategories = Policy.buildOptimisticPolicyRecentlyUsedCategories(iouReport.policyID, category); From a555fd3dffab634bc565536ca066c97da30a87d9 Mon Sep 17 00:00:00 2001 From: Pedro Guerreiro Date: Wed, 7 Feb 2024 18:30:46 +0000 Subject: [PATCH 25/65] fix: wrong route format causing console errors --- src/ROUTES.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 016e4267803b..b40f75cf8e8e 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -85,28 +85,28 @@ const ROUTES = { SETTINGS_APP_DOWNLOAD_LINKS: 'settings/about/app-download-links', SETTINGS_WALLET: 'settings/wallet', SETTINGS_WALLET_DOMAINCARD: { - route: '/settings/wallet/card/:domain', - getRoute: (domain: string) => `/settings/wallet/card/${domain}` as const, + route: 'settings/wallet/card/:domain', + getRoute: (domain: string) => `settings/wallet/card/${domain}` as const, }, SETTINGS_REPORT_FRAUD: { - route: '/settings/wallet/card/:domain/report-virtual-fraud', - getRoute: (domain: string) => `/settings/wallet/card/${domain}/report-virtual-fraud` as const, + route: 'settings/wallet/card/:domain/report-virtual-fraud', + getRoute: (domain: string) => `settings/wallet/card/${domain}/report-virtual-fraud` as const, }, SETTINGS_WALLET_CARD_GET_PHYSICAL_NAME: { - route: '/settings/wallet/card/:domain/get-physical/name', - getRoute: (domain: string) => `/settings/wallet/card/${domain}/get-physical/name` as const, + route: 'settings/wallet/card/:domain/get-physical/name', + getRoute: (domain: string) => `settings/wallet/card/${domain}/get-physical/name` as const, }, SETTINGS_WALLET_CARD_GET_PHYSICAL_PHONE: { - route: '/settings/wallet/card/:domain/get-physical/phone', - getRoute: (domain: string) => `/settings/wallet/card/${domain}/get-physical/phone` as const, + route: 'settings/wallet/card/:domain/get-physical/phone', + getRoute: (domain: string) => `settings/wallet/card/${domain}/get-physical/phone` as const, }, SETTINGS_WALLET_CARD_GET_PHYSICAL_ADDRESS: { - route: '/settings/wallet/card/:domain/get-physical/address', - getRoute: (domain: string) => `/settings/wallet/card/${domain}/get-physical/address` as const, + route: 'settings/wallet/card/:domain/get-physical/address', + getRoute: (domain: string) => `settings/wallet/card/${domain}/get-physical/address` as const, }, SETTINGS_WALLET_CARD_GET_PHYSICAL_CONFIRM: { - route: '/settings/wallet/card/:domain/get-physical/confirm', - getRoute: (domain: string) => `/settings/wallet/card/${domain}/get-physical/confirm` as const, + route: 'settings/wallet/card/:domain/get-physical/confirm', + getRoute: (domain: string) => `settings/wallet/card/${domain}/get-physical/confirm` as const, }, SETTINGS_ADD_DEBIT_CARD: 'settings/wallet/add-debit-card', SETTINGS_ADD_BANK_ACCOUNT: 'settings/wallet/add-bank-account', @@ -118,8 +118,8 @@ const ROUTES = { SETTINGS_WALLET_TRANSFER_BALANCE: 'settings/wallet/transfer-balance', SETTINGS_WALLET_CHOOSE_TRANSFER_ACCOUNT: 'settings/wallet/choose-transfer-account', SETTINGS_WALLET_REPORT_CARD_LOST_OR_DAMAGED: { - route: '/settings/wallet/card/:domain/report-card-lost-or-damaged', - getRoute: (domain: string) => `/settings/wallet/card/${domain}/report-card-lost-or-damaged` as const, + route: 'settings/wallet/card/:domain/report-card-lost-or-damaged', + getRoute: (domain: string) => `settings/wallet/card/${domain}/report-card-lost-or-damaged` as const, }, SETTINGS_WALLET_CARD_ACTIVATE: { route: 'settings/wallet/card/:domain/activate', From 9332a29db3e0474562415663b88289860e2a3c62 Mon Sep 17 00:00:00 2001 From: Pedro Guerreiro Date: Wed, 7 Feb 2024 18:32:01 +0000 Subject: [PATCH 26/65] fix: invalid phone number bypassing get physical card flow --- src/libs/GetPhysicalCardUtils.ts | 13 +++++++------ .../settings/Wallet/Card/BaseGetPhysicalCard.js | 3 +-- .../settings/Wallet/Card/GetPhysicalCardPhone.js | 5 ++--- src/pages/settings/Wallet/ExpensifyCardPage.js | 6 +----- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/libs/GetPhysicalCardUtils.ts b/src/libs/GetPhysicalCardUtils.ts index 139297a26513..7d2f3752fdc3 100644 --- a/src/libs/GetPhysicalCardUtils.ts +++ b/src/libs/GetPhysicalCardUtils.ts @@ -1,5 +1,6 @@ import ROUTES from '@src/ROUTES'; import type {Login} from '@src/types/onyx'; +import * as LoginUtils from './LoginUtils'; import Navigation from './Navigation/Navigation'; import * as PersonalDetailsUtils from './PersonalDetailsUtils'; import * as UserUtils from './UserUtils'; @@ -32,7 +33,7 @@ type LoginList = Record; * @param loginList * @returns */ -function getCurrentRoute(domain: string, privatePersonalDetails: PrivatePersonalDetails, loginList: LoginList) { +function getCurrentRoute(domain: string, privatePersonalDetails: PrivatePersonalDetails) { const { address: {street, city, state, country, zip}, legalFirstName, @@ -43,7 +44,7 @@ function getCurrentRoute(domain: string, privatePersonalDetails: PrivatePersonal if (!legalFirstName && !legalLastName) { return ROUTES.SETTINGS_WALLET_CARD_GET_PHYSICAL_NAME.getRoute(domain); } - if (!phoneNumber && !UserUtils.getSecondaryPhoneLogin(loginList)) { + if (!phoneNumber || !LoginUtils.validateNumber(phoneNumber)) { return ROUTES.SETTINGS_WALLET_CARD_GET_PHYSICAL_PHONE.getRoute(domain); } if (!(street && city && state && country && zip)) { @@ -60,8 +61,8 @@ function getCurrentRoute(domain: string, privatePersonalDetails: PrivatePersonal * @param loginList * @returns */ -function goToNextPhysicalCardRoute(domain: string, privatePersonalDetails: PrivatePersonalDetails, loginList: LoginList) { - Navigation.navigate(getCurrentRoute(domain, privatePersonalDetails, loginList)); +function goToNextPhysicalCardRoute(domain: string, privatePersonalDetails: PrivatePersonalDetails) { + Navigation.navigate(getCurrentRoute(domain, privatePersonalDetails)); } /** @@ -72,8 +73,8 @@ function goToNextPhysicalCardRoute(domain: string, privatePersonalDetails: Priva * @param loginList * @returns */ -function setCurrentRoute(currentRoute: string, domain: string, privatePersonalDetails: PrivatePersonalDetails, loginList: LoginList) { - const expectedRoute = getCurrentRoute(domain, privatePersonalDetails, loginList); +function setCurrentRoute(currentRoute: string, domain: string, privatePersonalDetails: PrivatePersonalDetails) { + const expectedRoute = getCurrentRoute(domain, privatePersonalDetails); // If the user is on the current route or the current route is confirmation, then he's allowed to stay on the current step if ([currentRoute, ROUTES.SETTINGS_WALLET_CARD_GET_PHYSICAL_CONFIRM.getRoute(domain)].includes(expectedRoute)) { diff --git a/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.js b/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.js index ade598608f50..c50c6d15509a 100644 --- a/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.js +++ b/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.js @@ -176,8 +176,7 @@ function BaseGetPhysicalCard({ } // Redirect user to previous steps of the flow if he hasn't finished them yet - const updatedPrivatePersonalDetails = GetPhysicalCardUtils.getUpdatedPrivatePersonalDetails(draftValues); - GetPhysicalCardUtils.setCurrentRoute(currentRoute, domain, updatedPrivatePersonalDetails, loginList); + GetPhysicalCardUtils.setCurrentRoute(currentRoute, domain, GetPhysicalCardUtils.getUpdatedPrivatePersonalDetails(draftValues)); isRouteSet.current = true; }, [cardList, currentRoute, domain, draftValues, loginList, privatePersonalDetails]); diff --git a/src/pages/settings/Wallet/Card/GetPhysicalCardPhone.js b/src/pages/settings/Wallet/Card/GetPhysicalCardPhone.js index 27897c08d125..55702b9d8062 100644 --- a/src/pages/settings/Wallet/Card/GetPhysicalCardPhone.js +++ b/src/pages/settings/Wallet/Card/GetPhysicalCardPhone.js @@ -1,4 +1,3 @@ -import Str from 'expensify-common/lib/str'; import PropTypes from 'prop-types'; import React from 'react'; import {withOnyx} from 'react-native-onyx'; @@ -7,7 +6,7 @@ import InputWrapper from '@components/Form/InputWrapper'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; import FormUtils from '@libs/FormUtils'; -import {parsePhoneNumber} from '@libs/PhoneNumber'; +import * as LoginUtils from '@libs/LoginUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -47,7 +46,7 @@ function GetPhysicalCardPhone({ const onValidate = (values) => { const errors = {}; - if (!(parsePhoneNumber(values.phoneNumber).possible && Str.isValidPhone(values.phoneNumber))) { + if (!LoginUtils.validateNumber(values.phoneNumber)) { errors.phoneNumber = 'common.error.phoneNumber'; } else if (_.isEmpty(values.phoneNumber)) { errors.phoneNumber = 'common.error.fieldRequired'; diff --git a/src/pages/settings/Wallet/ExpensifyCardPage.js b/src/pages/settings/Wallet/ExpensifyCardPage.js index cacf35db22a6..e62b821b7a72 100644 --- a/src/pages/settings/Wallet/ExpensifyCardPage.js +++ b/src/pages/settings/Wallet/ExpensifyCardPage.js @@ -116,8 +116,6 @@ const defaultProps = { function ExpensifyCardPage({ cardList, draftValues, - loginList, - privatePersonalDetails, route: { params: {domain}, }, @@ -159,9 +157,7 @@ function ExpensifyCardPage({ }; const goToGetPhysicalCardFlow = () => { - const updatedDraftValues = GetPhysicalCardUtils.getUpdatedDraftValues(draftValues, privatePersonalDetails, loginList); - - GetPhysicalCardUtils.goToNextPhysicalCardRoute(domain, GetPhysicalCardUtils.getUpdatedPrivatePersonalDetails(updatedDraftValues), loginList); + GetPhysicalCardUtils.goToNextPhysicalCardRoute(domain, GetPhysicalCardUtils.getUpdatedPrivatePersonalDetails(draftValues)); }; const hasDetectedDomainFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN); From 3021f3648cc68ae9cc64109bce69e4f0a4d30239 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Fri, 9 Feb 2024 20:02:02 +0530 Subject: [PATCH 27/65] Fix ts bug --- src/components/ReportActionItem/MoneyRequestView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 3e72aa77a21c..f929d1b0e6c8 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -107,7 +107,7 @@ function MoneyRequestView({ } = ReportUtils.getTransactionDetails(transaction) ?? {}; const isEmptyMerchant = transactionMerchant === '' || transactionMerchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT; const isDistanceRequest = TransactionUtils.isDistanceRequest(transaction); - let formattedTransactionAmount = transactionAmount ? CurrencyUtils.convertToDisplayString(transactionAmount, transactionCurrency) : ''; + const formattedTransactionAmount = transactionAmount ? CurrencyUtils.convertToDisplayString(transactionAmount, transactionCurrency) : ''; const hasPendingWaypoints = transaction?.pendingFields?.waypoints; const showMapAsImage = isDistanceRequest && hasPendingWaypoints; const formattedOriginalAmount = transactionOriginalAmount && transactionOriginalCurrency && CurrencyUtils.convertToDisplayString(transactionOriginalAmount, transactionOriginalCurrency); From 133666416ae1323f7897ec213ee380a31434cb08 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Fri, 9 Feb 2024 20:05:56 +0530 Subject: [PATCH 28/65] Fix minor bug after merge --- src/components/ReportActionItem/MoneyRequestPreview.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ReportActionItem/MoneyRequestPreview.tsx b/src/components/ReportActionItem/MoneyRequestPreview.tsx index 8c54e53a55b3..5126c3315fc5 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview.tsx @@ -181,6 +181,7 @@ function MoneyRequestPreview({ const receiptImages = hasReceipt ? [ReceiptUtils.getThumbnailAndImageURIs(transaction)] : []; + const hasPendingWaypoints = transaction?.pendingFields?.waypoints; const showMapAsImage = isDistanceRequest && hasPendingWaypoints; const getSettledMessage = (): string => { From 439336be9c66e437c05100e9db8360313af12742 Mon Sep 17 00:00:00 2001 From: MrRefactor Date: Tue, 13 Feb 2024 12:09:27 +0100 Subject: [PATCH 29/65] Split autoCompleteSuggestionContainerStyle to platform files --- .../BaseAutoCompleteSuggestions.tsx | 6 +--- .../autoCompleteSuggestion/index.android.ts | 20 +++++++++++++ .../utils/autoCompleteSuggestion/index.ts | 20 +++++++++++++ .../autoCompleteSuggestion/index.website.ts | 30 +++++++++++++++++++ src/styles/utils/index.ts | 29 +----------------- 5 files changed, 72 insertions(+), 33 deletions(-) create mode 100644 src/styles/utils/autoCompleteSuggestion/index.android.ts create mode 100644 src/styles/utils/autoCompleteSuggestion/index.ts create mode 100644 src/styles/utils/autoCompleteSuggestion/index.website.ts diff --git a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx index 72ef6ef2f061..fcc14c922a82 100644 --- a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx +++ b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx @@ -10,8 +10,6 @@ import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import * as Browser from '@libs/Browser'; -import getPlatform from '@libs/getPlatform'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import viewForwardedRef from '@src/types/utils/viewForwardedRef'; @@ -49,8 +47,6 @@ function BaseAutoCompleteSuggestions( const StyleUtils = useStyleUtils(); const rowHeight = useSharedValue(0); const scrollRef = useRef>(null); - const platform = getPlatform(); - const isMobileSafari = Browser.isMobileSafari(); /** * Render a suggestion menu item component. @@ -72,7 +68,7 @@ function BaseAutoCompleteSuggestions( ); const innerHeight = CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT * suggestions.length; - const animatedStyles = useAnimatedStyle(() => StyleUtils.getAutoCompleteSuggestionContainerStyle(rowHeight.value, platform, isMobileSafari)); + const animatedStyles = useAnimatedStyle(() => StyleUtils.getAutoCompleteSuggestionContainerStyle(rowHeight.value)); const estimatedListSize = useMemo( () => ({ height: CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT * suggestions.length, diff --git a/src/styles/utils/autoCompleteSuggestion/index.android.ts b/src/styles/utils/autoCompleteSuggestion/index.android.ts new file mode 100644 index 000000000000..09536b29f485 --- /dev/null +++ b/src/styles/utils/autoCompleteSuggestion/index.android.ts @@ -0,0 +1,20 @@ +import type {ViewStyle} from 'react-native'; +import CONST from '@src/CONST'; + +function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle { + 'worklet'; + + const borderWidth = 2; + const height = itemsHeight + 2 * CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_INNER_PADDING; + + // The suggester is positioned absolutely within the component that includes the input and RecipientLocalTime view (for non-expanded mode only). To position it correctly, + // we need to shift it by the suggester's height plus its padding and, if applicable, the height of the RecipientLocalTime view. + return { + overflow: 'hidden', + top: -(height + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_PADDING) + borderWidth, + height, + minHeight: CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, + }; +} + +export default getAutoCompleteSuggestionContainerStyle \ No newline at end of file diff --git a/src/styles/utils/autoCompleteSuggestion/index.ts b/src/styles/utils/autoCompleteSuggestion/index.ts new file mode 100644 index 000000000000..b8c92d2b2517 --- /dev/null +++ b/src/styles/utils/autoCompleteSuggestion/index.ts @@ -0,0 +1,20 @@ +import type {ViewStyle} from 'react-native'; +import CONST from '@src/CONST'; + +function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle { + 'worklet'; + + const borderWidth = 2; + const height = itemsHeight + 2 * CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_INNER_PADDING + borderWidth; + + // The suggester is positioned absolutely within the component that includes the input and RecipientLocalTime view (for non-expanded mode only). To position it correctly, + // we need to shift it by the suggester's height plus its padding and, if applicable, the height of the RecipientLocalTime view. + return { + overflow: 'hidden', + top: -(height + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_PADDING), + height, + minHeight: CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, + }; +} + +export default getAutoCompleteSuggestionContainerStyle \ No newline at end of file diff --git a/src/styles/utils/autoCompleteSuggestion/index.website.ts b/src/styles/utils/autoCompleteSuggestion/index.website.ts new file mode 100644 index 000000000000..cf48c040dad2 --- /dev/null +++ b/src/styles/utils/autoCompleteSuggestion/index.website.ts @@ -0,0 +1,30 @@ +import type {ViewStyle} from 'react-native'; +import CONST from '@src/CONST'; +import * as Browser from '@libs/Browser'; + +const isMobileSafari = Browser.isMobileSafari(); + +function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle { + 'worklet'; + + const borderWidth = 2; + let height = itemsHeight + 2 * CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_INNER_PADDING; + let top = -(height + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_PADDING); + + if ( isMobileSafari) { + top += borderWidth; + } else { + height += borderWidth; + } + + // The suggester is positioned absolutely within the component that includes the input and RecipientLocalTime view (for non-expanded mode only). To position it correctly, + // we need to shift it by the suggester's height plus its padding and, if applicable, the height of the RecipientLocalTime view. + return { + overflow: 'hidden', + top, + height, + minHeight: CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, + }; +} + +export default getAutoCompleteSuggestionContainerStyle \ No newline at end of file diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 30b1245ebb5a..8f3849d0afcd 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -4,7 +4,6 @@ import type {OnyxEntry} from 'react-native-onyx'; import type {EdgeInsets} from 'react-native-safe-area-context'; import type {ValueOf} from 'type-fest'; import * as Browser from '@libs/Browser'; -import type Platform from '@libs/getPlatform/types'; import * as UserUtils from '@libs/UserUtils'; // eslint-disable-next-line no-restricted-imports import {defaultTheme} from '@styles/theme'; @@ -15,6 +14,7 @@ import CONST from '@src/CONST'; import type {Transaction} from '@src/types/onyx'; import {defaultStyles} from '..'; import type {ThemeStyles} from '..'; +import getAutoCompleteSuggestionContainerStyle from './autoCompleteSuggestion'; import getCardStyles from './cardStyles'; import containerComposeStyles from './containerComposeStyles'; import FontUtils from './FontUtils'; @@ -790,33 +790,6 @@ function getBaseAutoCompleteSuggestionContainerStyle({left, bottom, width}: GetB }; } -/** - * Gets the correct position for auto complete suggestion container - */ -function getAutoCompleteSuggestionContainerStyle(itemsHeight: number, platform: Platform, isMobileSafari: boolean): ViewStyle { - 'worklet'; - - // This if condition is reverting the workaround for broken scroll on all platforms but native android and iOS safari, where the issue with - // scrolling char behind suggestion list is occuring. Rewerting the fix resolves the issue with always scrollable list on other platforms. - const borderWidth = 2; - let height = itemsHeight + 2 * CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_INNER_PADDING; - let top = -(height + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_PADDING); - - if (platform === 'android' || isMobileSafari) { - top += borderWidth; - } else { - height += borderWidth; - } - - // The suggester is positioned absolutely within the component that includes the input and RecipientLocalTime view (for non-expanded mode only). To position it correctly, - // we need to shift it by the suggester's height plus its padding and, if applicable, the height of the RecipientLocalTime view. - return { - overflow: 'hidden', - top, - height, - minHeight: CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, - }; -} function getEmojiReactionBubbleTextStyle(isContextMenu = false): TextStyle { if (isContextMenu) { From b90c64cf3f018b13b7ec282ae76c18fdc0caef4a Mon Sep 17 00:00:00 2001 From: MrRefactor Date: Tue, 13 Feb 2024 12:29:47 +0100 Subject: [PATCH 30/65] Prettier fixes --- src/styles/utils/autoCompleteSuggestion/index.android.ts | 2 +- src/styles/utils/autoCompleteSuggestion/index.ts | 2 +- src/styles/utils/autoCompleteSuggestion/index.website.ts | 6 +++--- src/styles/utils/index.ts | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/styles/utils/autoCompleteSuggestion/index.android.ts b/src/styles/utils/autoCompleteSuggestion/index.android.ts index 09536b29f485..20ce5e4819f2 100644 --- a/src/styles/utils/autoCompleteSuggestion/index.android.ts +++ b/src/styles/utils/autoCompleteSuggestion/index.android.ts @@ -17,4 +17,4 @@ function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle }; } -export default getAutoCompleteSuggestionContainerStyle \ No newline at end of file +export default getAutoCompleteSuggestionContainerStyle; diff --git a/src/styles/utils/autoCompleteSuggestion/index.ts b/src/styles/utils/autoCompleteSuggestion/index.ts index b8c92d2b2517..edfdbf55e185 100644 --- a/src/styles/utils/autoCompleteSuggestion/index.ts +++ b/src/styles/utils/autoCompleteSuggestion/index.ts @@ -17,4 +17,4 @@ function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle }; } -export default getAutoCompleteSuggestionContainerStyle \ No newline at end of file +export default getAutoCompleteSuggestionContainerStyle; diff --git a/src/styles/utils/autoCompleteSuggestion/index.website.ts b/src/styles/utils/autoCompleteSuggestion/index.website.ts index cf48c040dad2..ddfcbb600e3d 100644 --- a/src/styles/utils/autoCompleteSuggestion/index.website.ts +++ b/src/styles/utils/autoCompleteSuggestion/index.website.ts @@ -1,6 +1,6 @@ import type {ViewStyle} from 'react-native'; -import CONST from '@src/CONST'; import * as Browser from '@libs/Browser'; +import CONST from '@src/CONST'; const isMobileSafari = Browser.isMobileSafari(); @@ -11,7 +11,7 @@ function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle let height = itemsHeight + 2 * CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_INNER_PADDING; let top = -(height + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_PADDING); - if ( isMobileSafari) { + if (isMobileSafari) { top += borderWidth; } else { height += borderWidth; @@ -27,4 +27,4 @@ function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle }; } -export default getAutoCompleteSuggestionContainerStyle \ No newline at end of file +export default getAutoCompleteSuggestionContainerStyle; diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 8f3849d0afcd..91e1a0c2235f 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -790,7 +790,6 @@ function getBaseAutoCompleteSuggestionContainerStyle({left, bottom, width}: GetB }; } - function getEmojiReactionBubbleTextStyle(isContextMenu = false): TextStyle { if (isContextMenu) { return { From 033be5001e10da21a67980659651609fb42d6cef Mon Sep 17 00:00:00 2001 From: Pedro Guerreiro Date: Tue, 13 Feb 2024 21:44:16 +0000 Subject: [PATCH 31/65] fix: draft values not being properly set when entering get physical card flow from expensify card page --- .../settings/Wallet/ExpensifyCardPage.js | 41 ++++++++----------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/pages/settings/Wallet/ExpensifyCardPage.js b/src/pages/settings/Wallet/ExpensifyCardPage.js index 93b3efd8aa2e..38d8b5f13adb 100644 --- a/src/pages/settings/Wallet/ExpensifyCardPage.js +++ b/src/pages/settings/Wallet/ExpensifyCardPage.js @@ -14,6 +14,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as FormActions from '@libs/actions/FormActions'; import * as CardUtils from '@libs/CardUtils'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import FormUtils from '@libs/FormUtils'; @@ -88,35 +89,16 @@ const propTypes = { const defaultProps = { cardList: null, - draftValues: { - addressLine1: '', - addressLine2: '', - city: '', - state: '', - country: '', - zipPostCode: '', - phoneNumber: '', - legalFirstName: '', - legalLastName: '', - }, - loginList: {}, - privatePersonalDetails: { - legalFirstName: '', - legalLastName: '', - phoneNumber: null, - address: { - street: '', - city: '', - state: '', - zip: '', - country: '', - }, - }, + draftValues: null, + loginList: null, + privatePersonalDetails: null, }; function ExpensifyCardPage({ cardList, draftValues, + privatePersonalDetails, + loginList, route: { params: {domain}, }, @@ -158,7 +140,16 @@ function ExpensifyCardPage({ }; const goToGetPhysicalCardFlow = () => { - GetPhysicalCardUtils.goToNextPhysicalCardRoute(domain, GetPhysicalCardUtils.getUpdatedPrivatePersonalDetails(draftValues)); + let updatedDraftValues = draftValues; + + if (!draftValues) { + updatedDraftValues = GetPhysicalCardUtils.getUpdatedDraftValues(null, privatePersonalDetails, loginList); + // Form draft data needs to be initialized with the private personal details + // If no draft data exists + FormActions.setDraftValues(ONYXKEYS.FORMS.GET_PHYSICAL_CARD_FORM, updatedDraftValues); + } + + GetPhysicalCardUtils.goToNextPhysicalCardRoute(domain, GetPhysicalCardUtils.getUpdatedPrivatePersonalDetails(updatedDraftValues)); }; const hasDetectedDomainFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN); From 46d580473ed81a33c621976b717b8c6c4e680576 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 14 Feb 2024 10:08:25 +0700 Subject: [PATCH 32/65] update test --- tests/actions/IOUTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/actions/IOUTest.js b/tests/actions/IOUTest.js index cb31afbf8f8f..11fb22db01b6 100644 --- a/tests/actions/IOUTest.js +++ b/tests/actions/IOUTest.js @@ -1742,7 +1742,7 @@ describe('actions/IOU', () => { }), ]), originalMessage: expect.objectContaining({ - amount: -amount, + amount: amount, paymentType: CONST.IOU.PAYMENT_TYPE.VBBA, type: 'pay', }), From 7581a42ea86e83fdd7526e0ea304f977f7c56ae1 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 14 Feb 2024 10:18:35 +0700 Subject: [PATCH 33/65] lint fix --- tests/actions/IOUTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/actions/IOUTest.js b/tests/actions/IOUTest.js index 11fb22db01b6..c43837fbfd34 100644 --- a/tests/actions/IOUTest.js +++ b/tests/actions/IOUTest.js @@ -1742,7 +1742,7 @@ describe('actions/IOU', () => { }), ]), originalMessage: expect.objectContaining({ - amount: amount, + amount, paymentType: CONST.IOU.PAYMENT_TYPE.VBBA, type: 'pay', }), From f799ae6ec0392be7456e95ddb4f99ceb77a8d874 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 14 Feb 2024 16:05:21 +0700 Subject: [PATCH 34/65] integrate API --- .../parameters/UpdateRoomVisibilityParams.ts | 8 +++++ src/libs/API/types.ts | 1 + src/libs/actions/Report.ts | 36 ++++++++++++++++++- src/pages/settings/Report/VisibilityPage.tsx | 24 +++++++++---- src/types/onyx/Report.ts | 6 ++-- 5 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 src/libs/API/parameters/UpdateRoomVisibilityParams.ts diff --git a/src/libs/API/parameters/UpdateRoomVisibilityParams.ts b/src/libs/API/parameters/UpdateRoomVisibilityParams.ts new file mode 100644 index 000000000000..a69559f0ce47 --- /dev/null +++ b/src/libs/API/parameters/UpdateRoomVisibilityParams.ts @@ -0,0 +1,8 @@ +import type {RoomVisibility} from '@src/types/onyx/Report'; + +type UpdateRoomVisibilityParams = { + reportID: string; + visibility: RoomVisibility; +}; + +export default UpdateRoomVisibilityParams; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index f5d99d8cf40e..99075710a07a 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -85,6 +85,7 @@ const WRITE_COMMANDS = { DELETE_COMMENT: 'DeleteComment', UPDATE_COMMENT: 'UpdateComment', UPDATE_REPORT_NOTIFICATION_PREFERENCE: 'UpdateReportNotificationPreference', + UPDATE_ROOM_VISIBILITY: 'UpdateRoomVisibility', UPDATE_ROOM_DESCRIPTION: 'UpdateRoomDescription', UPDATE_REPORT_WRITE_CAPABILITY: 'UpdateReportWriteCapability', ADD_WORKSPACE_ROOM: 'AddWorkspaceRoom', diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index b02d27daf03f..84869076772d 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -40,6 +40,7 @@ import type { UpdateReportWriteCapabilityParams, UpdateRoomDescriptionParams, } from '@libs/API/parameters'; +import type UpdateRoomVisibilityParams from '@libs/API/parameters/UpdateRoomVisibilityParams'; import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as CollectionUtils from '@libs/CollectionUtils'; import DateUtils from '@libs/DateUtils'; @@ -68,7 +69,7 @@ import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import type {PersonalDetails, PersonalDetailsList, PolicyReportField, RecentlyUsedReportFields, ReportActionReactions, ReportMetadata, ReportUserIsTyping} from '@src/types/onyx'; import type {Decision, OriginalMessageIOU} from '@src/types/onyx/OriginalMessage'; -import type {NotificationPreference, WriteCapability} from '@src/types/onyx/Report'; +import type {NotificationPreference, RoomVisibility, WriteCapability} from '@src/types/onyx/Report'; import type Report from '@src/types/onyx/Report'; import type {Message, ReportActionBase, ReportActions} from '@src/types/onyx/ReportAction'; import type ReportAction from '@src/types/onyx/ReportAction'; @@ -1440,6 +1441,38 @@ function updateNotificationPreference( } } +function updateRoomVisibility(reportID: string, previousValue: RoomVisibility | undefined, newValue: RoomVisibility, navigate: boolean, report: OnyxEntry | EmptyObject = {}) { + if (previousValue === newValue) { + if (navigate && !isEmptyObject(report) && report.reportID) { + ReportUtils.goBackToDetailsPage(report); + } + return; + } + + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + value: {visibility: newValue}, + }, + ]; + + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + value: {visibility: previousValue}, + }, + ]; + + const parameters: UpdateRoomVisibilityParams = {reportID, visibility: newValue}; + + API.write(WRITE_COMMANDS.UPDATE_ROOM_VISIBILITY, parameters, {optimisticData, failureData}); + if (navigate && !isEmptyObject(report)) { + ReportUtils.goBackToDetailsPage(report); + } +} + /** * This will subscribe to an existing thread, or create a new one and then subsribe to it if necessary * @@ -2918,4 +2951,5 @@ export { updateReportField, updateReportName, resolveActionableMentionWhisper, + updateRoomVisibility, }; diff --git a/src/pages/settings/Report/VisibilityPage.tsx b/src/pages/settings/Report/VisibilityPage.tsx index 01f7420565f9..daa662f65c2e 100644 --- a/src/pages/settings/Report/VisibilityPage.tsx +++ b/src/pages/settings/Report/VisibilityPage.tsx @@ -1,4 +1,4 @@ -import {StackScreenProps} from '@react-navigation/stack'; +import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useMemo, useState} from 'react'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; @@ -8,12 +8,14 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import useLocalize from '@hooks/useLocalize'; -import {ReportSettingsNavigatorParamList} from '@libs/Navigation/types'; +import type {ReportSettingsNavigatorParamList} from '@libs/Navigation/types'; import * as ReportUtils from '@libs/ReportUtils'; +import * as ReportActions from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import SCREENS from '@src/SCREENS'; +import type SCREENS from '@src/SCREENS'; import type {Report} from '@src/types/onyx'; +import type {RoomVisibility} from '@src/types/onyx/Report'; type VisibilityOnyxProps = { report: OnyxEntry; @@ -38,10 +40,18 @@ function VisibilityPage({report}: VisibilityProps) { keyForList: visibilityOption, isSelected: visibilityOption === report?.visibility, })), - [], + [translate, report?.visibility], ); - const changeVisibility = useCallback(() => {}, []); + const changeVisibility = useCallback( + (newVisibility: RoomVisibility) => { + if (!report) { + return; + } + ReportActions.updateRoomVisibility(report.reportID, report.visibility, newVisibility, true, report); + }, + [report], + ); const hideModal = useCallback(() => { setShowConfirmModal(false); @@ -62,14 +72,16 @@ function VisibilityPage({report}: VisibilityProps) { onSelectRow={(option) => { if (option.value === CONST.REPORT.VISIBILITY.PUBLIC) { setShowConfirmModal(true); + return; } + changeVisibility(option.value); }} initiallyFocusedOptionKey={visibilityOptions.find((visibility) => visibility.isSelected)?.keyForList} /> { - changeVisibility(); + changeVisibility(CONST.REPORT.VISIBILITY.PUBLIC); hideModal(); }} onCancel={hideModal} diff --git a/src/types/onyx/Report.ts b/src/types/onyx/Report.ts index fbd61a9c5365..f5c4606fd335 100644 --- a/src/types/onyx/Report.ts +++ b/src/types/onyx/Report.ts @@ -8,6 +8,8 @@ type NotificationPreference = ValueOf; +type RoomVisibility = ValueOf; + type Note = { note: string; errors?: OnyxCommon.Errors; @@ -110,7 +112,7 @@ type Report = { openOnAdminRoom?: boolean; /** The report visibility */ - visibility?: ValueOf; + visibility?: RoomVisibility; /** Report cached total */ cachedTotal?: string; @@ -178,4 +180,4 @@ type Report = { export default Report; -export type {NotificationPreference, WriteCapability, Note}; +export type {NotificationPreference, RoomVisibility, WriteCapability, Note}; From 45fc86403ee2da4988316024447de27cc41e3e50 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 14 Feb 2024 16:48:54 +0700 Subject: [PATCH 35/65] type fix --- src/libs/API/parameters/index.ts | 1 + src/libs/API/types.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 482c5e0336c4..50fea8b720eb 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -85,6 +85,7 @@ export type {default as DeleteCommentParams} from './DeleteCommentParams'; export type {default as UpdateCommentParams} from './UpdateCommentParams'; export type {default as UpdateReportNotificationPreferenceParams} from './UpdateReportNotificationPreferenceParams'; export type {default as UpdateRoomDescriptionParams} from './UpdateRoomDescriptionParams'; +export type {default as UpdateRoomVisibilityParams} from './UpdateRoomVisibilityParams'; export type {default as UpdateReportWriteCapabilityParams} from './UpdateReportWriteCapabilityParams'; export type {default as AddWorkspaceRoomParams} from './AddWorkspaceRoomParams'; export type {default as UpdatePolicyRoomNameParams} from './UpdatePolicyRoomNameParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 99075710a07a..81df3d87d39d 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -223,6 +223,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.DELETE_COMMENT]: Parameters.DeleteCommentParams; [WRITE_COMMANDS.UPDATE_COMMENT]: Parameters.UpdateCommentParams; [WRITE_COMMANDS.UPDATE_REPORT_NOTIFICATION_PREFERENCE]: Parameters.UpdateReportNotificationPreferenceParams; + [WRITE_COMMANDS.UPDATE_ROOM_VISIBILITY]: Parameters.UpdateRoomVisibilityParams; [WRITE_COMMANDS.UPDATE_ROOM_DESCRIPTION]: Parameters.UpdateRoomDescriptionParams; [WRITE_COMMANDS.UPDATE_REPORT_WRITE_CAPABILITY]: Parameters.UpdateReportWriteCapabilityParams; [WRITE_COMMANDS.ADD_WORKSPACE_ROOM]: Parameters.AddWorkspaceRoomParams; From 0eba5a2f7a2a29b4131cecbb4b5679fbe67c2892 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 14 Feb 2024 22:40:00 +0700 Subject: [PATCH 36/65] rename --- .../report/ContextMenu/PopoverReportActionContextMenu.tsx | 8 +++++--- .../home/report/ContextMenu/ReportActionContextMenu.ts | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx index 0e6b18a71fdc..0b4154a15e80 100644 --- a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx @@ -65,7 +65,7 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef([]); const contentRef = useRef(null); - const anchorRef = useRef(null); + const anchorRef = useRef(null); const dimensionsEventListener = useRef(null); const contextMenuAnchorRef = useRef(null); const contextMenuTargetNode = useRef(null); @@ -163,13 +163,15 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef { const {pageX = 0, pageY = 0} = extractPointerEvent(event); contextMenuAnchorRef.current = contextMenuAnchor; contextMenuTargetNode.current = event.target as HTMLElement; - if (isThreeDotButton) { + if (shouldCloseOnTarget) { anchorRef.current = event.target as HTMLDivElement; + } else { + anchorRef.current = null; } setInstanceID(Math.random().toString(36).substr(2, 5)); diff --git a/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts b/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts index 74be6d7652a5..6664a38d2e19 100644 --- a/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts +++ b/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts @@ -34,7 +34,7 @@ type ShowContextMenu = ( isPinnedChat?: boolean, isUnreadChat?: boolean, disabledOptions?: ContextMenuAction[], - isThreeDotButton?: boolean, + shouldCloseOnTarget?: boolean, ) => void; type ReportActionContextMenu = { @@ -114,7 +114,7 @@ function showContextMenu( isPinnedChat = false, isUnreadChat = false, disabledActions: ContextMenuAction[] = [], - isThreeDotButton = false, + shouldCloseOnTarget = false, ) { if (!contextMenuRef.current) { return; @@ -142,7 +142,7 @@ function showContextMenu( isPinnedChat, isUnreadChat, disabledActions, - isThreeDotButton, + shouldCloseOnTarget, ); } From 07d77a47903583f9858d121f65bd8572b1aa3456 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 15 Feb 2024 00:13:53 +0700 Subject: [PATCH 37/65] fix uncache image --- src/components/ImageWithSizeCalculation.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/ImageWithSizeCalculation.tsx b/src/components/ImageWithSizeCalculation.tsx index 344904796f31..eb30d857aaa4 100644 --- a/src/components/ImageWithSizeCalculation.tsx +++ b/src/components/ImageWithSizeCalculation.tsx @@ -47,11 +47,14 @@ function ImageWithSizeCalculation({url, style, onMeasure, isAuthTokenRequired}: const onError = () => { Log.hmmm('Unable to fetch image to calculate size', {url}); + if (isLoadedRef.current) { + isLoadedRef.current = false; + setIsImageCached(false); + } if (isOffline) { return; } setIsLoading(false); - setIsImageCached(true); }; const imageLoadedSuccessfully = (event: OnLoadNativeEvent) => { From 1b46c8044d0432a4ea34d9dc0e4ef5f14bd8b775 Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 19 Feb 2024 14:23:05 +0700 Subject: [PATCH 38/65] remove visibilityPublicPrompt --- src/languages/en.ts | 1 - src/languages/es.ts | 1 - src/pages/settings/Report/VisibilityPage.tsx | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 0df520afeb6a..82aedf16aac5 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2076,7 +2076,6 @@ export default { genericUpdateReportFieldFailureMessage: 'Unexpected error while updating the field, please try again later', genericUpdateReporNameEditFailureMessage: 'Unexpected error while renaming the report, please try again later', noActivityYet: 'No activity yet', - visibilityPublicPrompt: 'Anyone can find this room', }, chronos: { oooEventSummaryFullDay: ({summary, dayCount, date}: OOOEventSummaryFullDayParams) => `${summary} for ${dayCount} ${dayCount === 1 ? 'day' : 'days'} until ${date}`, diff --git a/src/languages/es.ts b/src/languages/es.ts index e58e73ae3c09..466ff1298200 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2104,7 +2104,6 @@ export default { genericUpdateReportFieldFailureMessage: 'Error inesperado al actualizar el campo. Por favor, inténtalo más tarde', genericUpdateReporNameEditFailureMessage: 'Error inesperado al cambiar el nombre del informe. Vuelva a intentarlo más tarde.', noActivityYet: 'Sin actividad todavía', - visibilityPublicPrompt: 'Anyone can find this room', }, chronos: { oooEventSummaryFullDay: ({summary, dayCount, date}: OOOEventSummaryFullDayParams) => `${summary} por ${dayCount} ${dayCount === 1 ? 'día' : 'días'} hasta el ${date}`, diff --git a/src/pages/settings/Report/VisibilityPage.tsx b/src/pages/settings/Report/VisibilityPage.tsx index daa662f65c2e..797e8406f992 100644 --- a/src/pages/settings/Report/VisibilityPage.tsx +++ b/src/pages/settings/Report/VisibilityPage.tsx @@ -86,7 +86,7 @@ function VisibilityPage({report}: VisibilityProps) { }} onCancel={hideModal} title={translate('common.areYouSure')} - prompt={translate('report.visibilityPublicPrompt')} + prompt={translate('newRoomPage.publicDescription')} confirmText={translate('common.yes')} cancelText={translate('common.no')} danger From e992ac478fe8901fe2f6af5bb6298ecc4752c67a Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Mon, 19 Feb 2024 17:07:30 +0100 Subject: [PATCH 39/65] update Share code and Status buttons --- src/pages/settings/InitialSettingsPage.js | 46 ++++++++++++++++++++--- src/styles/index.ts | 15 ++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 941cdb2f0643..d3868d18cb4e 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -11,11 +11,14 @@ import cardPropTypes from '@components/cardPropTypes'; import ConfirmModal from '@components/ConfirmModal'; import CurrentUserPersonalDetailsSkeletonView from '@components/CurrentUserPersonalDetailsSkeletonView'; import HeaderPageLayout from '@components/HeaderPageLayout'; +import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import MenuItem from '@components/MenuItem'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import {withNetwork} from '@components/OnyxProvider'; +import {PressableWithFeedback} from '@components/Pressable'; import Text from '@components/Text'; +import Tooltip from '@components/Tooltip'; import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsDefaultProps, withCurrentUserPersonalDetailsPropTypes} from '@components/withCurrentUserPersonalDetails'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useLocalize from '@hooks/useLocalize'; @@ -31,6 +34,7 @@ import Navigation from '@libs/Navigation/Navigation'; import * as UserUtils from '@libs/UserUtils'; import walletTermsPropTypes from '@pages/EnablePayments/walletTermsPropTypes'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; +import variables from '@styles/variables'; import * as Link from '@userActions/Link'; import * as PaymentMethods from '@userActions/PaymentMethods'; import * as PersonalDetails from '@userActions/PersonalDetails'; @@ -100,6 +104,7 @@ function InitialSettingsPage(props) { const popoverAnchor = useRef(null); const {translate} = useLocalize(); const activeRoute = useNavigationState(getTopmostSettingsCentralPaneName); + const emojiCode = lodashGet(props, 'currentUserPersonalDetails.status.emojiCode', ''); const [shouldShowSignoutConfirmModal, setShouldShowSignoutConfirmModal] = useState(false); @@ -151,11 +156,6 @@ function InitialSettingsPage(props) { ? 'error' : null, }, - { - translationKey: 'common.shareCode', - icon: Expensicons.QrCode, - routeName: ROUTES.SETTINGS_SHARE_CODE, - }, { translationKey: 'common.preferences', icon: Expensicons.Gear, @@ -332,6 +332,42 @@ function InitialSettingsPage(props) { ) : ( <> + + + Navigation.navigate(ROUTES.SETTINGS_SHARE_CODE)} + > + + + + + + + Navigation.navigate(ROUTES.SETTINGS_STATUS)} + > + + {emojiCode ? ( + {emojiCode} + ) : ( + + )} + + + + bottom: -8, }, + primaryMediumIcon: { + alignItems: 'center', + backgroundColor: theme.buttonDefaultBG, + borderRadius: 20, + color: theme.textReversed, + height: 40, + width: 40, + justifyContent: 'center', + }, + + primaryMediumText: { + fontSize: variables.iconSizeNormal, + lineHeight: variables.iconSizeNormal, + }, + workspaceOwnerAvatarWrapper: { margin: 6, }, From 5a6a80beb24c175c708cbeab94827cf78674f2d7 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Tue, 20 Feb 2024 01:15:33 +0700 Subject: [PATCH 40/65] fix lint --- src/components/CountrySelector.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/CountrySelector.tsx b/src/components/CountrySelector.tsx index 44e360846ffc..4d10ba7a8b2d 100644 --- a/src/components/CountrySelector.tsx +++ b/src/components/CountrySelector.tsx @@ -24,9 +24,11 @@ type CountrySelectorProps = { /** inputID used by the Form component */ // eslint-disable-next-line react/no-unused-prop-types inputID: string; + onBlur: () => void; + onPress: () => void; }; -function CountrySelector({errorText = '', value: countryCode, onInputChange, ...rest}: CountrySelectorProps, ref: ForwardedRef) { +function CountrySelector({errorText = '', value: countryCode, onInputChange, onBlur = () => {}, onPress = () => {}, ...rest}: CountrySelectorProps, ref: ForwardedRef) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -36,10 +38,11 @@ function CountrySelector({errorText = '', value: countryCode, onInputChange, ... const didOpenContrySelector = useRef(false); const isFocus = useIsFocused(); useEffect(() => { - if (isFocus && didOpenContrySelector.current) { - didOpenContrySelector.current = false; - rest.onBlur && rest.onBlur(); + if (!isFocus || !didOpenContrySelector.current) { + return; } + didOpenContrySelector.current = false; + onBlur(); }, [isFocus, rest]); useEffect(() => { @@ -58,7 +61,7 @@ function CountrySelector({errorText = '', value: countryCode, onInputChange, ... description={translate('common.country')} onPress={() => { const activeRoute = Navigation.getActiveRouteWithoutParams(); - rest.onPress && rest.onPress(); + onPress(); didOpenContrySelector.current = true; Navigation.navigate(ROUTES.SETTINGS_ADDRESS_COUNTRY.getRoute(countryCode ?? '', activeRoute)); }} From 55dbf991965a0902ff23a842b51c2d8fcd279129 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Tue, 20 Feb 2024 01:26:50 +0700 Subject: [PATCH 41/65] fix missing dep onBlur --- src/components/CountrySelector.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/CountrySelector.tsx b/src/components/CountrySelector.tsx index 4d10ba7a8b2d..9125a0f7164a 100644 --- a/src/components/CountrySelector.tsx +++ b/src/components/CountrySelector.tsx @@ -43,7 +43,7 @@ function CountrySelector({errorText = '', value: countryCode, onInputChange, onB } didOpenContrySelector.current = false; onBlur(); - }, [isFocus, rest]); + }, [isFocus, onBlur]); useEffect(() => { // This will cause the form to revalidate and remove any error related to country name From ffe8a5231ef9b7b49382ef63766fe232d0f461f2 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Tue, 20 Feb 2024 01:32:29 +0700 Subject: [PATCH 42/65] fix remove rest --- src/components/CountrySelector.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/CountrySelector.tsx b/src/components/CountrySelector.tsx index 9125a0f7164a..9bb5dbdd41d2 100644 --- a/src/components/CountrySelector.tsx +++ b/src/components/CountrySelector.tsx @@ -28,7 +28,7 @@ type CountrySelectorProps = { onPress: () => void; }; -function CountrySelector({errorText = '', value: countryCode, onInputChange, onBlur = () => {}, onPress = () => {}, ...rest}: CountrySelectorProps, ref: ForwardedRef) { +function CountrySelector({errorText = '', value: countryCode, onInputChange, onBlur = () => {}, onPress = () => {}}: CountrySelectorProps, ref: ForwardedRef) { const styles = useThemeStyles(); const {translate} = useLocalize(); From 304ff3e9318bd2af7604496adc2806407c269642 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Tue, 20 Feb 2024 02:51:55 +0700 Subject: [PATCH 43/65] fix dm show up twice --- src/libs/OptionsListUtils.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index d6f718da2b2c..e0aa9bd4f547 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -7,6 +7,7 @@ import lodashSet from 'lodash/set'; import lodashSortBy from 'lodash/sortBy'; import Onyx from 'react-native-onyx'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import _ from 'underscore'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -1491,6 +1492,10 @@ function getOptions( return; } + if (_.isEmpty(accountIDs)) { + return; + } + // Save the report in the map if this is a single participant so we can associate the reportID with the // personal detail option later. Individuals should not be associated with single participant // policyExpenseChats or chatRooms since those are not people. From ca1dcf3f625c0f8266aea5e05f486a0a30d00699 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Tue, 20 Feb 2024 03:07:22 +0700 Subject: [PATCH 44/65] fix use lodash instead --- src/libs/OptionsListUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index e0aa9bd4f547..6a4496c83d1b 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1,5 +1,6 @@ /* eslint-disable no-continue */ import Str from 'expensify-common/lib/str'; +import _ from 'lodash'; // eslint-disable-next-line you-dont-need-lodash-underscore/get import lodashGet from 'lodash/get'; import lodashOrderBy from 'lodash/orderBy'; @@ -7,7 +8,6 @@ import lodashSet from 'lodash/set'; import lodashSortBy from 'lodash/sortBy'; import Onyx from 'react-native-onyx'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import _ from 'underscore'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; From e3c364912ec21c6ca0f22e070d381cd019adb6e7 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Tue, 20 Feb 2024 17:46:26 +0700 Subject: [PATCH 45/65] fix remove default function onBlur and onPress --- src/components/CountrySelector.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/CountrySelector.tsx b/src/components/CountrySelector.tsx index 9bb5dbdd41d2..8ff6ff4125b7 100644 --- a/src/components/CountrySelector.tsx +++ b/src/components/CountrySelector.tsx @@ -24,11 +24,11 @@ type CountrySelectorProps = { /** inputID used by the Form component */ // eslint-disable-next-line react/no-unused-prop-types inputID: string; - onBlur: () => void; - onPress: () => void; + onBlur?: () => void; + onPress?: () => void; }; -function CountrySelector({errorText = '', value: countryCode, onInputChange, onBlur = () => {}, onPress = () => {}}: CountrySelectorProps, ref: ForwardedRef) { +function CountrySelector({errorText = '', value: countryCode, onInputChange, onBlur, onPress}: CountrySelectorProps, ref: ForwardedRef) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -36,14 +36,14 @@ function CountrySelector({errorText = '', value: countryCode, onInputChange, onB const countryTitleDescStyle = title.length === 0 ? styles.textNormal : null; const didOpenContrySelector = useRef(false); - const isFocus = useIsFocused(); + const isFocused = useIsFocused(); useEffect(() => { - if (!isFocus || !didOpenContrySelector.current) { + if (!isFocused || !didOpenContrySelector.current) { return; } didOpenContrySelector.current = false; - onBlur(); - }, [isFocus, onBlur]); + onBlur?.(); + }, [isFocused, onBlur]); useEffect(() => { // This will cause the form to revalidate and remove any error related to country name @@ -61,7 +61,7 @@ function CountrySelector({errorText = '', value: countryCode, onInputChange, onB description={translate('common.country')} onPress={() => { const activeRoute = Navigation.getActiveRouteWithoutParams(); - onPress(); + onPress?.(); didOpenContrySelector.current = true; Navigation.navigate(ROUTES.SETTINGS_ADDRESS_COUNTRY.getRoute(countryCode ?? '', activeRoute)); }} From 6d3b7bc4216a2ae1c560e945b8d1299564b8c278 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:38:02 +0100 Subject: [PATCH 46/65] move sharecode to RHP --- src/components/QRShare/index.tsx | 9 +- .../AppNavigator/ModalStackNavigators.tsx | 2 +- .../FULL_SCREEN_TO_RHP_MAPPING.ts | 1 + src/libs/Navigation/linkingConfig/config.ts | 7 +- src/libs/Navigation/types.ts | 2 +- src/pages/ShareCodePage.tsx | 96 ++++++++----------- src/styles/index.ts | 1 - 7 files changed, 47 insertions(+), 71 deletions(-) diff --git a/src/components/QRShare/index.tsx b/src/components/QRShare/index.tsx index 45a4a4fd4964..c7e9e7637a6c 100644 --- a/src/components/QRShare/index.tsx +++ b/src/components/QRShare/index.tsx @@ -9,15 +9,12 @@ import QRCode from '@components/QRCode'; import Text from '@components/Text'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import useWindowDimensions from '@hooks/useWindowDimensions'; import variables from '@styles/variables'; -import CONST from '@src/CONST'; import type {QRShareHandle, QRShareProps} from './types'; function QRShare({url, title, subtitle, logo, logoRatio, logoMarginRatio}: QRShareProps, ref: ForwardedRef) { const styles = useThemeStyles(); const theme = useTheme(); - const {isSmallScreenWidth} = useWindowDimensions(); const [qrCodeSize, setQrCodeSize] = useState(1); const svgRef = useRef(); @@ -32,11 +29,7 @@ function QRShare({url, title, subtitle, logo, logoRatio, logoMarginRatio}: QRSha const onLayout = (event: LayoutChangeEvent) => { const containerWidth = event.nativeEvent.layout.width - variables.qrShareHorizontalPadding * 2 || 0; - if (isSmallScreenWidth) { - setQrCodeSize(Math.max(1, containerWidth)); - return; - } - setQrCodeSize(Math.max(1, Math.min(containerWidth, CONST.CENTRAL_PANE_ANIMATION_HEIGHT))); + setQrCodeSize(Math.max(1, containerWidth)); }; return ( diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx index 24e23ebcf760..f5a44a0c9e4f 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx @@ -191,7 +191,6 @@ const AccountSettingsModalStackNavigator = createModalStackNavigator( [SCREENS.SETTINGS.PREFERENCES.ROOT]: () => require('../../../pages/settings/Preferences/PreferencesPage').default as React.ComponentType, [SCREENS.SETTINGS.SECURITY]: () => require('../../../pages/settings/Security/SecuritySettingsPage').default as React.ComponentType, [SCREENS.SETTINGS.PROFILE.ROOT]: () => require('../../../pages/settings/Profile/ProfilePage').default as React.ComponentType, - [SCREENS.SETTINGS.SHARE_CODE]: () => require('../../../pages/ShareCodePage').default as React.ComponentType, [SCREENS.SETTINGS.WALLET.ROOT]: () => require('../../../pages/settings/Wallet/WalletPage').default as React.ComponentType, [SCREENS.SETTINGS.ABOUT]: () => require('../../../pages/settings/AboutPage/AboutPage').default as React.ComponentType, }, @@ -203,6 +202,7 @@ const WorkspaceSwitcherModalStackNavigator = createModalStackNavigator({ + [SCREENS.SETTINGS.SHARE_CODE]: () => require('../../../pages/ShareCodePage').default as React.ComponentType, [SCREENS.SETTINGS.PROFILE.PRONOUNS]: () => require('../../../pages/settings/Profile/PronounsPage').default as React.ComponentType, [SCREENS.SETTINGS.PROFILE.DISPLAY_NAME]: () => require('../../../pages/settings/Profile/DisplayNamePage').default as React.ComponentType, [SCREENS.SETTINGS.PROFILE.TIMEZONE]: () => require('../../../pages/settings/Profile/TimezoneInitialPage').default as React.ComponentType, diff --git a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts index 427ca2251e88..65d1112803e5 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -18,6 +18,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.SETTINGS.PROFILE.DATE_OF_BIRTH, SCREENS.SETTINGS.PROFILE.ADDRESS, SCREENS.SETTINGS.PROFILE.ADDRESS_COUNTRY, + SCREENS.SETTINGS.SHARE_CODE, ], [SCREENS.SETTINGS.PREFERENCES.ROOT]: [SCREENS.SETTINGS.PREFERENCES.PRIORITY_MODE, SCREENS.SETTINGS.PREFERENCES.LANGUAGE, SCREENS.SETTINGS.PREFERENCES.THEME], [SCREENS.SETTINGS.WALLET.ROOT]: [ diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index c8808b15b686..19514613ee3f 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -264,6 +264,9 @@ const config: LinkingOptions['config'] = { path: ROUTES.KEYBOARD_SHORTCUTS, }, [SCREENS.WORKSPACE.NAME]: ROUTES.WORKSPACE_PROFILE_NAME.route, + [SCREENS.SETTINGS.SHARE_CODE]: { + path: ROUTES.SETTINGS_SHARE_CODE, + }, }, }, [SCREENS.RIGHT_MODAL.PRIVATE_NOTES]: { @@ -498,10 +501,6 @@ const config: LinkingOptions['config'] = { }, [SCREENS.SETTINGS_CENTRAL_PANE]: { screens: { - [SCREENS.SETTINGS.SHARE_CODE]: { - path: ROUTES.SETTINGS_SHARE_CODE, - exact: true, - }, [SCREENS.SETTINGS.PROFILE.ROOT]: { path: ROUTES.SETTINGS_PROFILE, exact: true, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 78f8746ed918..61bd11634a55 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -417,6 +417,7 @@ type RightModalNavigatorParamList = { [SCREENS.RIGHT_MODAL.NEW_CHAT]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.DETAILS]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.PROFILE]: NavigatorScreenParams; + [SCREENS.SETTINGS.SHARE_CODE]: undefined; [SCREENS.RIGHT_MODAL.REPORT_DETAILS]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.REPORT_SETTINGS]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.REPORT_DESCRIPTION]: NavigatorScreenParams; @@ -441,7 +442,6 @@ type RightModalNavigatorParamList = { }; type SettingsCentralPaneNavigatorParamList = { - [SCREENS.SETTINGS.SHARE_CODE]: undefined; [SCREENS.SETTINGS.PROFILE.ROOT]: undefined; [SCREENS.SETTINGS.PREFERENCES.ROOT]: undefined; [SCREENS.SETTINGS.SECURITY]: undefined; diff --git a/src/pages/ShareCodePage.tsx b/src/pages/ShareCodePage.tsx index f17b81041236..1e23bc3e556d 100644 --- a/src/pages/ShareCodePage.tsx +++ b/src/pages/ShareCodePage.tsx @@ -6,12 +6,10 @@ import expensifyLogo from '@assets/images/expensify-logo-round-transparent.png'; import ContextMenuItem from '@components/ContextMenuItem'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; -import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; import QRShareWithDownload from '@components/QRShare/QRShareWithDownload'; import type QRShareWithDownloadHandle from '@components/QRShare/QRShareWithDownload/types'; import ScreenWrapper from '@components/ScreenWrapper'; -import Section from '@components/Section'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useEnvironment from '@hooks/useEnvironment'; import useLocalize from '@hooks/useLocalize'; @@ -78,65 +76,51 @@ function ShareCodePage({report}: ShareCodePageProps) { Navigation.goBack(isReport ? ROUTES.REPORT_WITH_ID_DETAILS.getRoute(report.reportID) : undefined)} - shouldShowBackButton={isReport || isSmallScreenWidth} - icon={Illustrations.QRCode} + shouldShowBackButton /> - -
- - - + + + - - Clipboard.setString(url)} - shouldLimitWidth={false} - wrapperStyle={themeStyles.sectionMenuItemTopDescription} - /> + + Clipboard.setString(url)} + shouldLimitWidth={false} + wrapperStyle={themeStyles.sectionMenuItemTopDescription} + /> - {isNative && ( - qrCodeRef.current?.download?.()} - wrapperStyle={themeStyles.sectionMenuItemTopDescription} - /> - )} + {isNative && ( + qrCodeRef.current?.download?.()} + wrapperStyle={themeStyles.sectionMenuItemTopDescription} + /> + )} - - Navigation.navigate(ROUTES.REFERRAL_DETAILS_MODAL.getRoute(CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SHARE_CODE, Navigation.getActiveRouteWithoutParams())) - } - wrapperStyle={themeStyles.sectionMenuItemTopDescription} - shouldShowRightIcon - /> - -
+ Navigation.navigate(ROUTES.REFERRAL_DETAILS_MODAL.getRoute(CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SHARE_CODE, Navigation.getActiveRouteWithoutParams()))} + wrapperStyle={themeStyles.sectionMenuItemTopDescription} + shouldShowRightIcon + />
diff --git a/src/styles/index.ts b/src/styles/index.ts index ac136b5e2831..4a4270dc957c 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -3074,7 +3074,6 @@ const styles = (theme: ThemeColors) => primaryMediumText: { fontSize: variables.iconSizeNormal, - lineHeight: variables.iconSizeNormal, }, workspaceOwnerAvatarWrapper: { From 1317b891a5aac9538d1f0473f8f08b5cf22ce363 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:48:07 +0100 Subject: [PATCH 47/65] fix buttons paddings --- src/pages/ShareCodePage.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pages/ShareCodePage.tsx b/src/pages/ShareCodePage.tsx index 1e23bc3e556d..59d7f9e8a446 100644 --- a/src/pages/ShareCodePage.tsx +++ b/src/pages/ShareCodePage.tsx @@ -79,7 +79,7 @@ function ShareCodePage({report}: ShareCodePageProps) { shouldShowBackButton /> - + Clipboard.setString(url)} shouldLimitWidth={false} - wrapperStyle={themeStyles.sectionMenuItemTopDescription} /> {isNative && ( @@ -110,7 +109,6 @@ function ShareCodePage({report}: ShareCodePageProps) { icon={Expensicons.Download} // eslint-disable-next-line @typescript-eslint/no-misused-promises onPress={() => qrCodeRef.current?.download?.()} - wrapperStyle={themeStyles.sectionMenuItemTopDescription} /> )} @@ -118,7 +116,6 @@ function ShareCodePage({report}: ShareCodePageProps) { title={translate(`referralProgram.${CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SHARE_CODE}.buttonText1`)} icon={Expensicons.Cash} onPress={() => Navigation.navigate(ROUTES.REFERRAL_DETAILS_MODAL.getRoute(CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SHARE_CODE, Navigation.getActiveRouteWithoutParams()))} - wrapperStyle={themeStyles.sectionMenuItemTopDescription} shouldShowRightIcon /> From d16662135acc8f90a9568e479191f90d61a8a209 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:58:21 +0100 Subject: [PATCH 48/65] cleanup --- src/pages/ShareCodePage.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pages/ShareCodePage.tsx b/src/pages/ShareCodePage.tsx index 59d7f9e8a446..83b966a0d81d 100644 --- a/src/pages/ShareCodePage.tsx +++ b/src/pages/ShareCodePage.tsx @@ -37,7 +37,6 @@ function ShareCodePage({report}: ShareCodePageProps) { const {translate} = useLocalize(); const {environmentURL} = useEnvironment(); const qrCodeRef = useRef(null); - const {isSmallScreenWidth} = useWindowDimensions(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const isReport = !!report?.reportID; @@ -69,10 +68,7 @@ function ShareCodePage({report}: ShareCodePageProps) { const isNative = platform === CONST.PLATFORM.IOS || platform === CONST.PLATFORM.ANDROID; return ( - + Navigation.goBack(isReport ? ROUTES.REPORT_WITH_ID_DETAILS.getRoute(report.reportID) : undefined)} From 5fb3e35a01173ae42a5d646f54770bcb9aa9ccb8 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:02:12 +0100 Subject: [PATCH 49/65] lint --- src/pages/ShareCodePage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/ShareCodePage.tsx b/src/pages/ShareCodePage.tsx index 83b966a0d81d..f2bba4b17a9a 100644 --- a/src/pages/ShareCodePage.tsx +++ b/src/pages/ShareCodePage.tsx @@ -14,7 +14,6 @@ import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails' import useEnvironment from '@hooks/useEnvironment'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import useWindowDimensions from '@hooks/useWindowDimensions'; import Clipboard from '@libs/Clipboard'; import getPlatform from '@libs/getPlatform'; import Navigation from '@libs/Navigation/Navigation'; From 5ad20f3cb3a5c60b0ae45fb90975dc052448956a Mon Sep 17 00:00:00 2001 From: Amarparab2024 <156438377+Amarparab2024@users.noreply.github.com> Date: Tue, 20 Feb 2024 23:07:45 +0530 Subject: [PATCH 50/65] fix shouldEnableMaxHeight --- src/pages/SearchPage/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/SearchPage/index.js b/src/pages/SearchPage/index.js index 7c472296dfe1..a3fdf4c45819 100644 --- a/src/pages/SearchPage/index.js +++ b/src/pages/SearchPage/index.js @@ -143,6 +143,7 @@ function SearchPage({betas, reports, isSearchingForReports}) { includeSafeAreaPaddingBottom={false} testID={SearchPage.displayName} onEntryTransitionEnd={handleScreenTransitionEnd} + shouldEnableMaxHeight > {({didScreenTransitionEnd, safeAreaPaddingBottomStyle}) => ( <> From f217bb5a438dc0f28a1ba39365846c06d28e46fc Mon Sep 17 00:00:00 2001 From: caitlinwhite1 Date: Tue, 20 Feb 2024 14:27:58 -0600 Subject: [PATCH 51/65] Update redirects.csv Old referral program link --- docs/redirects.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/redirects.csv b/docs/redirects.csv index 76b7bac3fc99..8e160e3bcdf2 100644 --- a/docs/redirects.csv +++ b/docs/redirects.csv @@ -54,3 +54,4 @@ https://help.expensify.com/articles/expensify-classic/getting-started/Employees, https://help.expensify.com/articles/expensify-classic/getting-started/Using-The-App,https://help.expensify.com/articles/expensify-classic/getting-started/Join-your-company's-workspace https://help.expensify.com/articles/expensify-classic/getting-started/support/Expensify-Support,https://use.expensify.com/support https://help.expensify.com/articles/expensify-classic/getting-started/Plan-Types,https://use.expensify.com/ +https://help.expensify.com/articles/new-expensify/payments/Referral-Program,https://help.expensify.com/articles/expensify-classic/get-paid-back/Referral-Program From 806e07f34780a2a6808bf7ece06a61be4dd1ca47 Mon Sep 17 00:00:00 2001 From: jeremy-croff Date: Sat, 10 Feb 2024 19:13:28 -0600 Subject: [PATCH 52/65] fix(35835): composer timing render updates --- .../setShouldShowComposeInputKeyboardAware/index.ios.ts | 2 +- src/pages/home/report/ReportActionItemMessageEdit.tsx | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libs/setShouldShowComposeInputKeyboardAware/index.ios.ts b/src/libs/setShouldShowComposeInputKeyboardAware/index.ios.ts index cd50938c70b9..ebf99e8527d7 100644 --- a/src/libs/setShouldShowComposeInputKeyboardAware/index.ios.ts +++ b/src/libs/setShouldShowComposeInputKeyboardAware/index.ios.ts @@ -2,4 +2,4 @@ import setShouldShowComposeInputKeyboardAwareBuilder from './setShouldShowCompos // On iOS, there is a visible delay in displaying input after the keyboard has been closed with the `keyboardDidHide` event // Because of that - on iOS we can use `keyboardWillHide` that is not available on android -export default setShouldShowComposeInputKeyboardAwareBuilder('keyboardWillHide'); +export default setShouldShowComposeInputKeyboardAwareBuilder('keyboardDidHide'); diff --git a/src/pages/home/report/ReportActionItemMessageEdit.tsx b/src/pages/home/report/ReportActionItemMessageEdit.tsx index e97aa0338f90..824ea6af0097 100644 --- a/src/pages/home/report/ReportActionItemMessageEdit.tsx +++ b/src/pages/home/report/ReportActionItemMessageEdit.tsx @@ -23,6 +23,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as Browser from '@libs/Browser'; import * as ComposerUtils from '@libs/ComposerUtils'; +import * as ComposerActions from '@userActions/Composer'; import * as EmojiUtils from '@libs/EmojiUtils'; import focusComposerWithDelay from '@libs/focusComposerWithDelay'; import onyxSubscribe from '@libs/onyxSubscribe'; @@ -210,6 +211,9 @@ function ReportActionItemMessageEdit( // eslint-disable-next-line react-hooks/exhaustive-deps -- this cleanup needs to be called only on unmount }, [action.reportActionID]); + // show the composer quickly after done editing + useEffect(() => ()=> ComposerActions.setShouldShowComposeInput(true), []) + /** * Save the draft of the comment. This debounced so that we're not ceaselessly saving your edit. Saving the draft * allows one to navigate somewhere else and come back to the comment and still have it in edit mode. @@ -288,7 +292,7 @@ function ReportActionItemMessageEdit( ReportActionComposeFocusManager.clear(); ReportActionComposeFocusManager.focus(); } - + // Scroll to the last comment after editing to make sure the whole comment is clearly visible in the report. if (index === 0) { const keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => { From 28f9afd8202936e8535b85a415a574c76e58998b Mon Sep 17 00:00:00 2001 From: jeremy-croff Date: Tue, 20 Feb 2024 22:04:53 -0600 Subject: [PATCH 53/65] fix(35835): rebase with signed commits. Updated comments. --- .../setShouldShowComposeInputKeyboardAware/index.ios.ts | 2 -- .../setShouldShowComposeInputKeyboardAwareBuilder.ts | 2 -- src/pages/home/report/ReportActionItemMessageEdit.tsx | 8 ++++---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/libs/setShouldShowComposeInputKeyboardAware/index.ios.ts b/src/libs/setShouldShowComposeInputKeyboardAware/index.ios.ts index ebf99e8527d7..68c750b05a5f 100644 --- a/src/libs/setShouldShowComposeInputKeyboardAware/index.ios.ts +++ b/src/libs/setShouldShowComposeInputKeyboardAware/index.ios.ts @@ -1,5 +1,3 @@ import setShouldShowComposeInputKeyboardAwareBuilder from './setShouldShowComposeInputKeyboardAwareBuilder'; -// On iOS, there is a visible delay in displaying input after the keyboard has been closed with the `keyboardDidHide` event -// Because of that - on iOS we can use `keyboardWillHide` that is not available on android export default setShouldShowComposeInputKeyboardAwareBuilder('keyboardDidHide'); diff --git a/src/libs/setShouldShowComposeInputKeyboardAware/setShouldShowComposeInputKeyboardAwareBuilder.ts b/src/libs/setShouldShowComposeInputKeyboardAware/setShouldShowComposeInputKeyboardAwareBuilder.ts index 8d5ef578b66c..72df7a730e02 100644 --- a/src/libs/setShouldShowComposeInputKeyboardAware/setShouldShowComposeInputKeyboardAwareBuilder.ts +++ b/src/libs/setShouldShowComposeInputKeyboardAware/setShouldShowComposeInputKeyboardAwareBuilder.ts @@ -5,8 +5,6 @@ import * as Composer from '@userActions/Composer'; import type SetShouldShowComposeInputKeyboardAware from './types'; let keyboardEventListener: EmitterSubscription | null = null; -// On iOS, there is a visible delay in displaying input after the keyboard has been closed with the `keyboardDidHide` event -// Because of that - on iOS we can use `keyboardWillHide` that is not available on android const setShouldShowComposeInputKeyboardAwareBuilder: (keyboardEvent: KeyboardEventName) => SetShouldShowComposeInputKeyboardAware = (keyboardEvent: KeyboardEventName) => (shouldShow: boolean) => { diff --git a/src/pages/home/report/ReportActionItemMessageEdit.tsx b/src/pages/home/report/ReportActionItemMessageEdit.tsx index 824ea6af0097..25629fc4e538 100644 --- a/src/pages/home/report/ReportActionItemMessageEdit.tsx +++ b/src/pages/home/report/ReportActionItemMessageEdit.tsx @@ -23,7 +23,6 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as Browser from '@libs/Browser'; import * as ComposerUtils from '@libs/ComposerUtils'; -import * as ComposerActions from '@userActions/Composer'; import * as EmojiUtils from '@libs/EmojiUtils'; import focusComposerWithDelay from '@libs/focusComposerWithDelay'; import onyxSubscribe from '@libs/onyxSubscribe'; @@ -31,6 +30,7 @@ import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManag import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import setShouldShowComposeInputKeyboardAware from '@libs/setShouldShowComposeInputKeyboardAware'; +import * as ComposerActions from '@userActions/Composer'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import * as InputFocus from '@userActions/InputFocus'; import * as Report from '@userActions/Report'; @@ -211,8 +211,8 @@ function ReportActionItemMessageEdit( // eslint-disable-next-line react-hooks/exhaustive-deps -- this cleanup needs to be called only on unmount }, [action.reportActionID]); - // show the composer quickly after done editing - useEffect(() => ()=> ComposerActions.setShouldShowComposeInput(true), []) + // show the composer after editing is complete for devices that hide the composer during editing. + useEffect(() => () => ComposerActions.setShouldShowComposeInput(true), []); /** * Save the draft of the comment. This debounced so that we're not ceaselessly saving your edit. Saving the draft @@ -292,7 +292,7 @@ function ReportActionItemMessageEdit( ReportActionComposeFocusManager.clear(); ReportActionComposeFocusManager.focus(); } - + // Scroll to the last comment after editing to make sure the whole comment is clearly visible in the report. if (index === 0) { const keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => { From 20a749a5e903bb8628502e08f2cbe5cfcf6b6a4f Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 21 Feb 2024 11:13:56 +0700 Subject: [PATCH 54/65] add notfound page --- src/pages/settings/Report/VisibilityPage.tsx | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/pages/settings/Report/VisibilityPage.tsx b/src/pages/settings/Report/VisibilityPage.tsx index 797e8406f992..a03068832637 100644 --- a/src/pages/settings/Report/VisibilityPage.tsx +++ b/src/pages/settings/Report/VisibilityPage.tsx @@ -1,7 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useMemo, useState} from 'react'; -import {withOnyx} from 'react-native-onyx'; -import type {OnyxEntry} from 'react-native-onyx'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import ConfirmModal from '@components/ConfirmModal'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; @@ -10,18 +8,14 @@ import SelectionList from '@components/SelectionList'; import useLocalize from '@hooks/useLocalize'; import type {ReportSettingsNavigatorParamList} from '@libs/Navigation/types'; import * as ReportUtils from '@libs/ReportUtils'; +import type {WithReportOrNotFoundProps} from '@pages/home/report/withReportOrNotFound'; +import withReportOrNotFound from '@pages/home/report/withReportOrNotFound'; import * as ReportActions from '@userActions/Report'; import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; import type SCREENS from '@src/SCREENS'; -import type {Report} from '@src/types/onyx'; import type {RoomVisibility} from '@src/types/onyx/Report'; -type VisibilityOnyxProps = { - report: OnyxEntry; -}; - -type VisibilityProps = VisibilityOnyxProps & StackScreenProps; +type VisibilityProps = WithReportOrNotFoundProps & StackScreenProps; function VisibilityPage({report}: VisibilityProps) { const [showConfirmModal, setShowConfirmModal] = useState(false); @@ -68,6 +62,7 @@ function VisibilityPage({report}: VisibilityProps) { onBackButtonPress={() => ReportUtils.goBackToDetailsPage(report)} /> { if (option.value === CONST.REPORT.VISIBILITY.PUBLIC) { @@ -98,8 +93,4 @@ function VisibilityPage({report}: VisibilityProps) { VisibilityPage.displayName = 'VisibilityPage'; -export default withOnyx({ - report: { - key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID ?? ''}`, - }, -})(VisibilityPage); +export default withReportOrNotFound()(VisibilityPage); From de91e5427e7fe3823e10f0f60230b255abb79915 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Wed, 21 Feb 2024 21:02:42 +0700 Subject: [PATCH 55/65] fix remove lodash --- src/libs/OptionsListUtils.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 6a4496c83d1b..c1d8f49c85c7 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1,6 +1,5 @@ /* eslint-disable no-continue */ import Str from 'expensify-common/lib/str'; -import _ from 'lodash'; // eslint-disable-next-line you-dont-need-lodash-underscore/get import lodashGet from 'lodash/get'; import lodashOrderBy from 'lodash/orderBy'; @@ -1492,7 +1491,7 @@ function getOptions( return; } - if (_.isEmpty(accountIDs)) { + if (!accountIDs || accountIDs.length === 0) { return; } From 972084ded272602bca2c4da8350e4a522702957d Mon Sep 17 00:00:00 2001 From: MrRefactor Date: Wed, 21 Feb 2024 15:25:55 +0100 Subject: [PATCH 56/65] Implement shouldPreventScrollOnAutoCompleteSuggestion function --- .../autoCompleteSuggestion/index.android.ts | 21 ++------------ .../utils/autoCompleteSuggestion/index.ts | 21 ++------------ .../autoCompleteSuggestion/index.website.ts | 28 ++----------------- .../utils/autoCompleteSuggestion/types.ts | 3 ++ src/styles/utils/index.ts | 23 ++++++++++++++- 5 files changed, 34 insertions(+), 62 deletions(-) create mode 100644 src/styles/utils/autoCompleteSuggestion/types.ts diff --git a/src/styles/utils/autoCompleteSuggestion/index.android.ts b/src/styles/utils/autoCompleteSuggestion/index.android.ts index 20ce5e4819f2..88b7a7c84297 100644 --- a/src/styles/utils/autoCompleteSuggestion/index.android.ts +++ b/src/styles/utils/autoCompleteSuggestion/index.android.ts @@ -1,20 +1,5 @@ -import type {ViewStyle} from 'react-native'; -import CONST from '@src/CONST'; +import type ShouldPreventScrollOnAutoCompleteSuggestion from './types'; -function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle { - 'worklet'; +const shouldPreventScrollOnAutoCompleteSuggestion: ShouldPreventScrollOnAutoCompleteSuggestion = () => false; - const borderWidth = 2; - const height = itemsHeight + 2 * CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_INNER_PADDING; - - // The suggester is positioned absolutely within the component that includes the input and RecipientLocalTime view (for non-expanded mode only). To position it correctly, - // we need to shift it by the suggester's height plus its padding and, if applicable, the height of the RecipientLocalTime view. - return { - overflow: 'hidden', - top: -(height + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_PADDING) + borderWidth, - height, - minHeight: CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, - }; -} - -export default getAutoCompleteSuggestionContainerStyle; +export default shouldPreventScrollOnAutoCompleteSuggestion; diff --git a/src/styles/utils/autoCompleteSuggestion/index.ts b/src/styles/utils/autoCompleteSuggestion/index.ts index edfdbf55e185..e756e7178c57 100644 --- a/src/styles/utils/autoCompleteSuggestion/index.ts +++ b/src/styles/utils/autoCompleteSuggestion/index.ts @@ -1,20 +1,5 @@ -import type {ViewStyle} from 'react-native'; -import CONST from '@src/CONST'; +import type ShouldPreventScrollOnAutoCompleteSuggestion from './types'; -function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle { - 'worklet'; +const shouldPreventScrollOnAutoCompleteSuggestion: ShouldPreventScrollOnAutoCompleteSuggestion = () => true; - const borderWidth = 2; - const height = itemsHeight + 2 * CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_INNER_PADDING + borderWidth; - - // The suggester is positioned absolutely within the component that includes the input and RecipientLocalTime view (for non-expanded mode only). To position it correctly, - // we need to shift it by the suggester's height plus its padding and, if applicable, the height of the RecipientLocalTime view. - return { - overflow: 'hidden', - top: -(height + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_PADDING), - height, - minHeight: CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, - }; -} - -export default getAutoCompleteSuggestionContainerStyle; +export default shouldPreventScrollOnAutoCompleteSuggestion; diff --git a/src/styles/utils/autoCompleteSuggestion/index.website.ts b/src/styles/utils/autoCompleteSuggestion/index.website.ts index ddfcbb600e3d..badec5dfc774 100644 --- a/src/styles/utils/autoCompleteSuggestion/index.website.ts +++ b/src/styles/utils/autoCompleteSuggestion/index.website.ts @@ -1,30 +1,8 @@ -import type {ViewStyle} from 'react-native'; import * as Browser from '@libs/Browser'; -import CONST from '@src/CONST'; +import type ShouldPreventScrollOnAutoCompleteSuggestion from './types'; const isMobileSafari = Browser.isMobileSafari(); -function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle { - 'worklet'; +const shouldPreventScrollOnAutoCompleteSuggestion: ShouldPreventScrollOnAutoCompleteSuggestion = () => !isMobileSafari; - const borderWidth = 2; - let height = itemsHeight + 2 * CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_INNER_PADDING; - let top = -(height + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_PADDING); - - if (isMobileSafari) { - top += borderWidth; - } else { - height += borderWidth; - } - - // The suggester is positioned absolutely within the component that includes the input and RecipientLocalTime view (for non-expanded mode only). To position it correctly, - // we need to shift it by the suggester's height plus its padding and, if applicable, the height of the RecipientLocalTime view. - return { - overflow: 'hidden', - top, - height, - minHeight: CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, - }; -} - -export default getAutoCompleteSuggestionContainerStyle; +export default shouldPreventScrollOnAutoCompleteSuggestion; diff --git a/src/styles/utils/autoCompleteSuggestion/types.ts b/src/styles/utils/autoCompleteSuggestion/types.ts new file mode 100644 index 000000000000..563d305eb236 --- /dev/null +++ b/src/styles/utils/autoCompleteSuggestion/types.ts @@ -0,0 +1,3 @@ +type ShouldPreventScrollOnAutoCompleteSuggestion = () => boolean; + +export default ShouldPreventScrollOnAutoCompleteSuggestion; diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 91e1a0c2235f..f713095d639f 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -14,7 +14,7 @@ import CONST from '@src/CONST'; import type {Transaction} from '@src/types/onyx'; import {defaultStyles} from '..'; import type {ThemeStyles} from '..'; -import getAutoCompleteSuggestionContainerStyle from './autoCompleteSuggestion'; +import shouldPreventScrollOnAutoCompleteSuggestion from './autoCompleteSuggestion'; import getCardStyles from './cardStyles'; import containerComposeStyles from './containerComposeStyles'; import FontUtils from './FontUtils'; @@ -790,6 +790,27 @@ function getBaseAutoCompleteSuggestionContainerStyle({left, bottom, width}: GetB }; } +const shouldPreventScroll = shouldPreventScrollOnAutoCompleteSuggestion(); + +/** + * Gets the correct position for auto complete suggestion container + */ +function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle { + 'worklet'; + + const borderWidth = 2; + const height = itemsHeight + 2 * CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_INNER_PADDING + (shouldPreventScroll ? borderWidth : 0); + + // The suggester is positioned absolutely within the component that includes the input and RecipientLocalTime view (for non-expanded mode only). To position it correctly, + // we need to shift it by the suggester's height plus its padding and, if applicable, the height of the RecipientLocalTime view. + return { + overflow: 'hidden', + top: -(height + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTER_PADDING + (shouldPreventScroll ? 0 : borderWidth)), + height, + minHeight: CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, + }; +} + function getEmojiReactionBubbleTextStyle(isContextMenu = false): TextStyle { if (isContextMenu) { return { From 700f383ebb39a03d1f1e6a88890820690c31382b Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Wed, 21 Feb 2024 21:30:12 +0700 Subject: [PATCH 57/65] fix add comment and remove onPress --- src/components/CountrySelector.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/CountrySelector.tsx b/src/components/CountrySelector.tsx index 8ff6ff4125b7..5b5e99ac0621 100644 --- a/src/components/CountrySelector.tsx +++ b/src/components/CountrySelector.tsx @@ -24,11 +24,12 @@ type CountrySelectorProps = { /** inputID used by the Form component */ // eslint-disable-next-line react/no-unused-prop-types inputID: string; + + /** Callback to call when the picker modal is dismissed */ onBlur?: () => void; - onPress?: () => void; }; -function CountrySelector({errorText = '', value: countryCode, onInputChange, onBlur, onPress}: CountrySelectorProps, ref: ForwardedRef) { +function CountrySelector({errorText = '', value: countryCode, onInputChange, onBlur}: CountrySelectorProps, ref: ForwardedRef) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -61,7 +62,6 @@ function CountrySelector({errorText = '', value: countryCode, onInputChange, onB description={translate('common.country')} onPress={() => { const activeRoute = Navigation.getActiveRouteWithoutParams(); - onPress?.(); didOpenContrySelector.current = true; Navigation.navigate(ROUTES.SETTINGS_ADDRESS_COUNTRY.getRoute(countryCode ?? '', activeRoute)); }} From 51ebef3d8d00738ef441b90627af0373e35921bc Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 21 Feb 2024 08:53:15 -0700 Subject: [PATCH 58/65] use RadioListItem --- .../settings/Profile/CustomStatus/StatusClearAfterPage.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.js b/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.js index 61208447495d..8354734701cd 100644 --- a/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.js +++ b/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.js @@ -8,7 +8,7 @@ import FormProvider from '@components/Form/FormProvider'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScreenWrapper from '@components/ScreenWrapper'; -import BaseListItem from '@components/SelectionList/BaseListItem'; +import RadioListItem from '@components/SelectionList/RadioListItem'; import Text from '@components/Text'; import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsDefaultProps} from '@components/withCurrentUserPersonalDetails'; import withLocalize from '@components/withLocalize'; @@ -157,9 +157,9 @@ function StatusClearAfterPage({currentUserPersonalDetails, customStatus}) { const timePeriodOptions = useCallback( () => _.map(statusType, (item, index) => ( - updateMode(item)} showTooltip={false} isFocused={item.isSelected} From e546ae6a8b73e17ebc3db9a9140e033bb6a15e46 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Wed, 21 Feb 2024 17:29:48 +0100 Subject: [PATCH 59/65] Handle goBack from the ShareCodePage on the small screen width --- .../FULL_SCREEN_TO_RHP_MAPPING.ts | 1 - .../linkingConfig/getAdaptedStateFromPath.ts | 20 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts index 65d1112803e5..427ca2251e88 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -18,7 +18,6 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.SETTINGS.PROFILE.DATE_OF_BIRTH, SCREENS.SETTINGS.PROFILE.ADDRESS, SCREENS.SETTINGS.PROFILE.ADDRESS_COUNTRY, - SCREENS.SETTINGS.SHARE_CODE, ], [SCREENS.SETTINGS.PREFERENCES.ROOT]: [SCREENS.SETTINGS.PREFERENCES.PRIORITY_MODE, SCREENS.SETTINGS.PREFERENCES.LANGUAGE, SCREENS.SETTINGS.PREFERENCES.THEME], [SCREENS.SETTINGS.WALLET.ROOT]: [ diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts index 8e246d82ff72..a91e2cf17d5b 100644 --- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts @@ -6,6 +6,7 @@ import getTopmostNestedRHPRoute from '@libs/Navigation/getTopmostNestedRHPRoute' import type {BottomTabName, CentralPaneName, FullScreenName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types'; import {extractPolicyIDFromPath, getPathWithoutPolicyID} from '@libs/PolicyUtils'; import NAVIGATORS from '@src/NAVIGATORS'; +import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; import CENTRAL_PANE_TO_RHP_MAPPING from './CENTRAL_PANE_TO_RHP_MAPPING'; import config from './config'; @@ -70,14 +71,16 @@ function createCentralPaneNavigator(route: NavigationPartialRoute): NavigationPartialRoute { +function createFullScreenNavigator(route?: NavigationPartialRoute): NavigationPartialRoute { const routes = []; routes.push({name: SCREENS.SETTINGS.ROOT}); - routes.push({ - name: SCREENS.SETTINGS_CENTRAL_PANE, - state: getRoutesWithIndex([route]), - }); + if (route) { + routes.push({ + name: SCREENS.SETTINGS_CENTRAL_PANE, + state: getRoutesWithIndex([route]), + }); + } return { name: NAVIGATORS.FULL_SCREEN_NAVIGATOR, @@ -122,13 +125,18 @@ function getMatchingRootRouteForRHPRoute( return createCentralPaneNavigator({name: centralPaneName as CentralPaneName, params: route.params}); } } - + // Check for FullScreenNavigator for (const [fullScreenName, RHPNames] of Object.entries(FULL_SCREEN_TO_RHP_MAPPING)) { if (RHPNames && RHPNames.includes(route.name)) { return createFullScreenNavigator({name: fullScreenName as FullScreenName, params: route.params}); } } + + // This screen is opened from the LHN of the FullStackNavigator, so in this case we shouldn't push any CentralPane screen + if (route.name === SCREENS.SETTINGS.SHARE_CODE) { + return createFullScreenNavigator(); + } } function getAdaptedState(state: PartialState>, policyID?: string): GetAdaptedStateReturnType { From cf538a8753027a174c0720402db3b49ec755aba9 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Wed, 21 Feb 2024 17:37:12 +0100 Subject: [PATCH 60/65] Fix lint --- src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts index a91e2cf17d5b..e7c5466852cf 100644 --- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts @@ -6,7 +6,6 @@ import getTopmostNestedRHPRoute from '@libs/Navigation/getTopmostNestedRHPRoute' import type {BottomTabName, CentralPaneName, FullScreenName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types'; import {extractPolicyIDFromPath, getPathWithoutPolicyID} from '@libs/PolicyUtils'; import NAVIGATORS from '@src/NAVIGATORS'; -import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; import CENTRAL_PANE_TO_RHP_MAPPING from './CENTRAL_PANE_TO_RHP_MAPPING'; import config from './config'; @@ -125,7 +124,7 @@ function getMatchingRootRouteForRHPRoute( return createCentralPaneNavigator({name: centralPaneName as CentralPaneName, params: route.params}); } } - + // Check for FullScreenNavigator for (const [fullScreenName, RHPNames] of Object.entries(FULL_SCREEN_TO_RHP_MAPPING)) { if (RHPNames && RHPNames.includes(route.name)) { From 79d50e476c5ec6b550c94220c23adccfe190a904 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 21 Feb 2024 09:38:28 -0700 Subject: [PATCH 61/65] rm keyForList --- .../settings/Profile/CustomStatus/StatusClearAfterPage.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.js b/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.js index 8354734701cd..290d6431492d 100644 --- a/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.js +++ b/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.js @@ -156,10 +156,9 @@ function StatusClearAfterPage({currentUserPersonalDetails, customStatus}) { const timePeriodOptions = useCallback( () => - _.map(statusType, (item, index) => ( + _.map(statusType, (item) => ( updateMode(item)} showTooltip={false} isFocused={item.isSelected} From 9610f7c2a97ca43114fc7503df8061f2c0cab8c0 Mon Sep 17 00:00:00 2001 From: MrRefactor Date: Wed, 21 Feb 2024 18:57:51 +0100 Subject: [PATCH 62/65] Prettier fix --- .../AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx index fcc14c922a82..5da9c6981603 100644 --- a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx +++ b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx @@ -47,7 +47,6 @@ function BaseAutoCompleteSuggestions( const StyleUtils = useStyleUtils(); const rowHeight = useSharedValue(0); const scrollRef = useRef>(null); - /** * Render a suggestion menu item component. */ From c30f48337ebbd24e78cdc2633756057bb3824cfc Mon Sep 17 00:00:00 2001 From: Someshwar Tripathi Date: Wed, 21 Feb 2024 23:33:08 +0530 Subject: [PATCH 63/65] Fix amount selection logic --- src/pages/iou/steps/MoneyRequestAmountForm.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/steps/MoneyRequestAmountForm.tsx b/src/pages/iou/steps/MoneyRequestAmountForm.tsx index 5bec1052c790..cb1f73ae2207 100644 --- a/src/pages/iou/steps/MoneyRequestAmountForm.tsx +++ b/src/pages/iou/steps/MoneyRequestAmountForm.tsx @@ -104,7 +104,7 @@ function MoneyRequestAmountForm( */ const onMouseDown = (event: React.MouseEvent, ids: string[]) => { const relatedTargetId = (event.nativeEvent?.target as HTMLElement)?.id; - if (ids.includes(relatedTargetId)) { + if (!ids.includes(relatedTargetId)) { return; } @@ -127,7 +127,7 @@ function MoneyRequestAmountForm( }, []); useEffect(() => { - if (!currency || typeof amount === 'number') { + if (!currency || typeof amount !== 'number') { return; } initializeAmount(amount); From 9f8cb4cde3df3e491fdd664bc2f43f3b4d8c69b0 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Wed, 21 Feb 2024 20:43:55 +0000 Subject: [PATCH 64/65] Update version to 1.4.43-8 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index ddda3199f51a..59dd7793edfe 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001044307 - versionName "1.4.43-7" + versionCode 1001044308 + versionName "1.4.43-8" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index f082f213a415..57a4bdc97817 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.43.7 + 1.4.43.8 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 98e9859ff5dc..fac756f0ae2a 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.43.7 + 1.4.43.8 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 196d25080609..abf5db7bba30 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 1.4.43 CFBundleVersion - 1.4.43.7 + 1.4.43.8 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 4ddd24c2ad47..c278186648a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.43-7", + "version": "1.4.43-8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.43-7", + "version": "1.4.43-8", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 92698102e064..922301d79dc8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.43-7", + "version": "1.4.43-8", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 6b82cfdb44aa34d9d49ee2ade479725e424e9f50 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Wed, 21 Feb 2024 21:48:53 +0000 Subject: [PATCH 65/65] Update version to 1.4.43-9 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 59dd7793edfe..fc376ad08862 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001044308 - versionName "1.4.43-8" + versionCode 1001044309 + versionName "1.4.43-9" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 57a4bdc97817..93faff6ab427 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.43.8 + 1.4.43.9 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index fac756f0ae2a..85d5f45e4184 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.43.8 + 1.4.43.9 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index abf5db7bba30..6b0cc0c08d14 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 1.4.43 CFBundleVersion - 1.4.43.8 + 1.4.43.9 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index c278186648a9..c114de61408f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.43-8", + "version": "1.4.43-9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.43-8", + "version": "1.4.43-9", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 922301d79dc8..66d60bcd87cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.43-8", + "version": "1.4.43-9", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",