From 2568b3c0bee9200a0b3c0f53c39da7864d34f09c Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 29 May 2024 10:41:39 +0700 Subject: [PATCH 001/578] fix: #announce room should default to 'Admins Only' for posting --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index df2b0b9d703e..91e48065b5b4 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4743,7 +4743,7 @@ function buildOptimisticWorkspaceChats(policyID: string, policyName: string, exp false, policyName, undefined, - undefined, + CONST.REPORT.WRITE_CAPABILITIES.ADMINS, // #announce contains all policy members so notifying always should be opt-in only. CONST.REPORT.NOTIFICATION_PREFERENCE.DAILY, From e2a6f60a2904d1351d4068230943fc81bbcf4c14 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 16:08:01 -0700 Subject: [PATCH 002/578] Remove front-end workaround for authWrites issue --- src/libs/HttpUtils.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libs/HttpUtils.ts b/src/libs/HttpUtils.ts index a826c668be12..f8df7aa69846 100644 --- a/src/libs/HttpUtils.ts +++ b/src/libs/HttpUtils.ts @@ -37,9 +37,6 @@ const abortControllerMap = new Map(); abortControllerMap.set(ABORT_COMMANDS.All, new AbortController()); abortControllerMap.set(ABORT_COMMANDS.SearchForReports, new AbortController()); -// Some existing old commands (6+ years) exempted from the auth writes count check -const exemptedCommandsWithAuthWrites: string[] = ['SetWorkspaceAutoReportingFrequency']; - /** * The API commands that require the skew calculation */ @@ -133,7 +130,7 @@ function processHTTPRequest(url: string, method: RequestType = 'get', body: Form }); } - if (response.jsonCode === CONST.JSON_CODE.MANY_WRITES_ERROR && !exemptedCommandsWithAuthWrites.includes(response.data?.phpCommandName ?? '')) { + if (response.jsonCode === CONST.JSON_CODE.MANY_WRITES_ERROR) { if (response.data) { const {phpCommandName, authWriteCommands} = response.data; // eslint-disable-next-line max-len From 947babf42a8d6d9c2dad0dc95b63b78f4317c9f6 Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 30 Jul 2024 15:56:44 +0700 Subject: [PATCH 003/578] fix: tooltip is overlap on native --- src/components/LHNOptionsList/LHNOptionsList.tsx | 3 +++ .../OptionRowRendererComponent.tsx | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 src/components/LHNOptionsList/OptionRowRendererComponent.tsx diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 5f06fb78049a..b23997f0a61f 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -18,12 +18,14 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as DraftCommentUtils from '@libs/DraftCommentUtils'; +import getPlatform from '@libs/getPlatform'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import OptionRowLHNData from './OptionRowLHNData'; +import OptionRowRendererComponent from './OptionRowRendererComponent'; import type {LHNOptionsListProps, RenderItemProps} from './types'; const keyExtractor = (item: string) => `report_${item}`; @@ -244,6 +246,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio ref={flashListRef} indicatorStyle="white" keyboardShouldPersistTaps="always" + CellRendererComponent={getPlatform() !== CONST.PLATFORM.WEB ? OptionRowRendererComponent : undefined} contentContainerStyle={StyleSheet.flatten(contentContainerStyles)} data={data} testID="lhn-options-list" diff --git a/src/components/LHNOptionsList/OptionRowRendererComponent.tsx b/src/components/LHNOptionsList/OptionRowRendererComponent.tsx new file mode 100644 index 000000000000..2ca9b82d6ec0 --- /dev/null +++ b/src/components/LHNOptionsList/OptionRowRendererComponent.tsx @@ -0,0 +1,16 @@ +import {CellContainer} from '@shopify/flash-list'; +import type {CellContainerProps} from '@shopify/flash-list/dist/native/cell-container/CellContainer'; + +function OptionRowRendererComponent(props: CellContainerProps) { + return ( + + ); +} + +OptionRowRendererComponent.displayName = 'OptionRowRendererComponent'; + +export default OptionRowRendererComponent; From 2bd231707c457016750080f08e620ca340e1d86e Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 30 Jul 2024 16:42:28 +0700 Subject: [PATCH 004/578] hide tooltip on navigating --- .../BaseEducationalTooltip.tsx | 38 +++++++++---------- .../Tooltip/EducationalTooltip/index.tsx | 15 +++++++- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/components/Tooltip/EducationalTooltip/BaseEducationalTooltip.tsx b/src/components/Tooltip/EducationalTooltip/BaseEducationalTooltip.tsx index 5912649c6dcd..eb0522ce08a5 100644 --- a/src/components/Tooltip/EducationalTooltip/BaseEducationalTooltip.tsx +++ b/src/components/Tooltip/EducationalTooltip/BaseEducationalTooltip.tsx @@ -1,5 +1,4 @@ -import {useNavigation} from '@react-navigation/native'; -import React, {memo, useCallback, useEffect, useRef} from 'react'; +import React, {memo, useEffect, useRef} from 'react'; import type {LayoutChangeEvent} from 'react-native'; import GenericTooltip from '@components/Tooltip/GenericTooltip'; import type TooltipProps from '@components/Tooltip/types'; @@ -10,32 +9,29 @@ import getBounds from './getBounds'; * This tooltip would show immediately without user's interaction and hide after 5 seconds. */ function BaseEducationalTooltip({children, ...props}: TooltipProps) { - const navigation = useNavigation(); const hideTooltipRef = useRef<() => void>(); - const triggerHideTooltip = useCallback(() => { - if (!hideTooltipRef.current) { - return; - } + useEffect( + () => () => { + if (!hideTooltipRef.current) { + return; + } - hideTooltipRef.current(); - }, []); + hideTooltipRef.current(); + }, + [], + ); + // Automatically hide tooltip after 5 seconds useEffect(() => { - const unsubscribeBlur = navigation.addListener('blur', triggerHideTooltip); + if (!hideTooltipRef.current) { + return; + } + const intervalID = setInterval(hideTooltipRef.current, 5000); return () => { - unsubscribeBlur?.(); - triggerHideTooltip(); + clearInterval(intervalID); }; - }, [navigation, triggerHideTooltip]); - - // // Automatically hide tooltip after 5 seconds - // useEffect(() => { - // const intervalID = setInterval(triggerHideTooltip, 5000); - // return () => { - // clearInterval(intervalID); - // }; - // }, []); + }, []); return ( { + const unsubscribe = navigation.addListener('blur', () => { + setShouldHide(true); + }); + return unsubscribe; + }, [navigation]); + + if (!shouldRender || shouldHide) { return children; } From b57704a54cdf5f3c0065c3b511055d7f297391c3 Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 30 Jul 2024 16:51:14 +0700 Subject: [PATCH 005/578] remove redundant changes --- .../Tooltip/EducationalTooltip/BaseEducationalTooltip.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Tooltip/EducationalTooltip/BaseEducationalTooltip.tsx b/src/components/Tooltip/EducationalTooltip/BaseEducationalTooltip.tsx index eb0522ce08a5..cb158150fc88 100644 --- a/src/components/Tooltip/EducationalTooltip/BaseEducationalTooltip.tsx +++ b/src/components/Tooltip/EducationalTooltip/BaseEducationalTooltip.tsx @@ -27,6 +27,7 @@ function BaseEducationalTooltip({children, ...props}: TooltipProps) { if (!hideTooltipRef.current) { return; } + const intervalID = setInterval(hideTooltipRef.current, 5000); return () => { clearInterval(intervalID); From c43f1afa01672dcbf5555a42cbd861750a43bc99 Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 30 Jul 2024 17:13:10 +0700 Subject: [PATCH 006/578] add condition to show tooltip: has completed onboarding --- src/components/LHNOptionsList/OptionRowLHN.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/LHNOptionsList/OptionRowLHN.tsx b/src/components/LHNOptionsList/OptionRowLHN.tsx index f46343276400..387731b5e814 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.tsx +++ b/src/components/LHNOptionsList/OptionRowLHN.tsx @@ -33,6 +33,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {OptionRowLHNProps} from './types'; +import hasCompletedGuidedSetupFlowSelector from '@libs/hasCompletedGuidedSetupFlowSelector'; function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, optionItem, viewMode = 'default', style, onLayout = () => {}, hasDraftComment}: OptionRowLHNProps) { const theme = useTheme(); @@ -45,6 +46,9 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${optionItem?.reportID || -1}`); const [isFirstTimeNewExpensifyUser] = useOnyx(ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER); + const [hasCompletedGuidedSetupFlow] = useOnyx(ONYXKEYS.NVP_ONBOARDING, { + selector: hasCompletedGuidedSetupFlowSelector, + }); const {translate} = useLocalize(); const [isContextMenuActive, setIsContextMenuActive] = useState(false); @@ -167,7 +171,7 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti needsOffscreenAlphaCompositing > Date: Tue, 30 Jul 2024 17:44:04 +0700 Subject: [PATCH 007/578] fix lint --- src/components/LHNOptionsList/OptionRowLHN.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/LHNOptionsList/OptionRowLHN.tsx b/src/components/LHNOptionsList/OptionRowLHN.tsx index 387731b5e814..74e5089b3b9c 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.tsx +++ b/src/components/LHNOptionsList/OptionRowLHN.tsx @@ -22,6 +22,7 @@ import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import DateUtils from '@libs/DateUtils'; import DomUtils from '@libs/DomUtils'; +import hasCompletedGuidedSetupFlowSelector from '@libs/hasCompletedGuidedSetupFlowSelector'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import Parser from '@libs/Parser'; import Performance from '@libs/Performance'; @@ -33,7 +34,6 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {OptionRowLHNProps} from './types'; -import hasCompletedGuidedSetupFlowSelector from '@libs/hasCompletedGuidedSetupFlowSelector'; function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, optionItem, viewMode = 'default', style, onLayout = () => {}, hasDraftComment}: OptionRowLHNProps) { const theme = useTheme(); @@ -171,7 +171,7 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti needsOffscreenAlphaCompositing > Date: Thu, 8 Aug 2024 14:02:25 +0700 Subject: [PATCH 008/578] show tooltip when in lhn only --- src/components/LHNOptionsList/OptionRowLHN.tsx | 13 +++++++++---- src/styles/variables.ts | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/components/LHNOptionsList/OptionRowLHN.tsx b/src/components/LHNOptionsList/OptionRowLHN.tsx index 74e5089b3b9c..3b5261fc7492 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.tsx +++ b/src/components/LHNOptionsList/OptionRowLHN.tsx @@ -1,5 +1,5 @@ import {useFocusEffect} from '@react-navigation/native'; -import React, {useCallback, useRef, useState} from 'react'; +import React, {useCallback, useMemo, useRef, useState} from 'react'; import type {GestureResponderEvent, ViewStyle} from 'react-native'; import {StyleSheet, View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; @@ -23,6 +23,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import DateUtils from '@libs/DateUtils'; import DomUtils from '@libs/DomUtils'; import hasCompletedGuidedSetupFlowSelector from '@libs/hasCompletedGuidedSetupFlowSelector'; +import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import Parser from '@libs/Parser'; import Performance from '@libs/Performance'; @@ -30,8 +31,10 @@ import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManag import * as ReportUtils from '@libs/ReportUtils'; import * as SubscriptionUtils from '@libs/SubscriptionUtils'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {OptionRowLHNProps} from './types'; @@ -163,6 +166,7 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti const fullTitle = isGroupChat ? ReportUtils.getGroupChatName(undefined, false, report) : optionItem.text; const subscriptAvatarBorderColor = isFocused ? focusedBackgroundColor : theme.sidebar; + const isHomeActiveRoute = useMemo(() => Navigation.isActiveRoute(ROUTES.HOME), [Navigation.getActiveRoute()]); return ( {}, opti needsOffscreenAlphaCompositing > diff --git a/src/styles/variables.ts b/src/styles/variables.ts index ea838feee1a0..28620a5bac51 100644 --- a/src/styles/variables.ts +++ b/src/styles/variables.ts @@ -248,6 +248,7 @@ export default { composerTooltipShiftHorizontal: 10, composerTooltipShiftVertical: -10, + gbrTooltipShiftHorizontal: -20, h20: 20, h28: 28, From 3dba0d7334ac6db241c1a24f635b069d8949ca90 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 8 Aug 2024 15:19:46 +0700 Subject: [PATCH 009/578] remove hide tooltip on navigate --- .../Tooltip/EducationalTooltip/index.tsx | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/components/Tooltip/EducationalTooltip/index.tsx b/src/components/Tooltip/EducationalTooltip/index.tsx index 00552805a2e6..d43ff64d7e8e 100644 --- a/src/components/Tooltip/EducationalTooltip/index.tsx +++ b/src/components/Tooltip/EducationalTooltip/index.tsx @@ -1,20 +1,9 @@ -import {useNavigation} from '@react-navigation/native'; -import React, {useEffect, useState} from 'react'; +import React from 'react'; import type {TooltipExtendedProps} from '@components/Tooltip/types'; import BaseEducationalTooltip from './BaseEducationalTooltip'; function EducationalTooltip({shouldRender = true, children, ...props}: TooltipExtendedProps) { - const navigation = useNavigation(); - const [shouldHide, setShouldHide] = useState(false); - - useEffect(() => { - const unsubscribe = navigation.addListener('blur', () => { - setShouldHide(true); - }); - return unsubscribe; - }, [navigation]); - - if (!shouldRender || shouldHide) { + if (!shouldRender) { return children; } From 88e0299cbf5e472f40d9d1711a0e9ab8d9230bed Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 8 Aug 2024 15:29:51 +0700 Subject: [PATCH 010/578] create platform independant files --- src/components/LHNOptionsList/LHNOptionsList.tsx | 2 +- .../index.native.tsx} | 0 .../LHNOptionsList/OptionRowRendererComponent/index.tsx | 3 +++ 3 files changed, 4 insertions(+), 1 deletion(-) rename src/components/LHNOptionsList/{OptionRowRendererComponent.tsx => OptionRowRendererComponent/index.native.tsx} (100%) create mode 100644 src/components/LHNOptionsList/OptionRowRendererComponent/index.tsx diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 48d62349c60b..98a84fb07458 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -253,7 +253,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio ref={flashListRef} indicatorStyle="white" keyboardShouldPersistTaps="always" - CellRendererComponent={getPlatform() !== CONST.PLATFORM.WEB ? OptionRowRendererComponent : undefined} + CellRendererComponent={OptionRowRendererComponent} contentContainerStyle={StyleSheet.flatten(contentContainerStyles)} data={data} testID="lhn-options-list" diff --git a/src/components/LHNOptionsList/OptionRowRendererComponent.tsx b/src/components/LHNOptionsList/OptionRowRendererComponent/index.native.tsx similarity index 100% rename from src/components/LHNOptionsList/OptionRowRendererComponent.tsx rename to src/components/LHNOptionsList/OptionRowRendererComponent/index.native.tsx diff --git a/src/components/LHNOptionsList/OptionRowRendererComponent/index.tsx b/src/components/LHNOptionsList/OptionRowRendererComponent/index.tsx new file mode 100644 index 000000000000..09fa8c5d8232 --- /dev/null +++ b/src/components/LHNOptionsList/OptionRowRendererComponent/index.tsx @@ -0,0 +1,3 @@ +const OptionRowRendererComponent = undefined; + +export default OptionRowRendererComponent; \ No newline at end of file From 9768b009b0dc902788f0fc818d47e0e24a841505 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 8 Aug 2024 15:57:22 +0700 Subject: [PATCH 011/578] fix lint --- src/components/LHNOptionsList/LHNOptionsList.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 98a84fb07458..89f9a3573cba 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -17,7 +17,6 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as DraftCommentUtils from '@libs/DraftCommentUtils'; -import getPlatform from '@libs/getPlatform'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import variables from '@styles/variables'; From 5a175d9b04f89d53558b6045ba5936440b5ae6bf Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 11:25:28 +0200 Subject: [PATCH 012/578] fix undefined role route --- src/ROUTES.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 9650d323d676..340dd0efcda5 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -355,7 +355,10 @@ const ROUTES = { }, ROOM_INVITE: { route: 'r/:reportID/invite/:role?', - getRoute: (reportID: string, role?: string) => `r/${reportID}/invite/${role}` as const, + getRoute: (reportID: string, role?: string) => { + const route = role ? (`r/${reportID}/invite/${role}` as const) : (`r/${reportID}/invite` as const); + return route; + }, }, MONEY_REQUEST_HOLD_REASON: { route: ':type/edit/reason/:transactionID?', From 0d3cc6e311af6b3f7929cb1236d63b1169560dec Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 14:34:57 +0200 Subject: [PATCH 013/578] move search state to onyx wip --- src/ONYXKEYS.ts | 4 ++++ src/libs/actions/UserSearchPhrase.ts | 15 +++++++++++++++ src/pages/RoomInvitePage.tsx | 15 ++++++--------- src/pages/RoomMembersPage.tsx | 17 ++++++++++++----- 4 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 src/libs/actions/UserSearchPhrase.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 7102d6396381..06b2603deadb 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -400,6 +400,9 @@ const ONYXKEYS = { /** Stores the information about currently edited advanced approval workflow */ APPROVAL_WORKFLOW: 'approvalWorkflow', + /** Stores the user search value for persistance across the screens */ + USER_SEARCH_PHRASE: 'userSearchPhrase', + /** Collection Keys */ COLLECTION: { DOWNLOAD: 'download_', @@ -879,6 +882,7 @@ type OnyxValuesMapping = { [ONYXKEYS.NVP_WORKSPACE_TOOLTIP]: OnyxTypes.WorkspaceTooltip; [ONYXKEYS.NVP_PRIVATE_CANCELLATION_DETAILS]: OnyxTypes.CancellationDetails[]; [ONYXKEYS.APPROVAL_WORKFLOW]: OnyxTypes.ApprovalWorkflow; + [ONYXKEYS.USER_SEARCH_PHRASE]: string; }; type OnyxValues = OnyxValuesMapping & OnyxCollectionValuesMapping & OnyxFormValuesMapping & OnyxFormDraftValuesMapping; diff --git a/src/libs/actions/UserSearchPhrase.ts b/src/libs/actions/UserSearchPhrase.ts new file mode 100644 index 000000000000..d1104776dc46 --- /dev/null +++ b/src/libs/actions/UserSearchPhrase.ts @@ -0,0 +1,15 @@ +import Onyx from 'react-native-onyx'; +import ONYXKEYS from '@src/ONYXKEYS'; + +function clearUserSearchPhrase() { + Onyx.set(ONYXKEYS.USER_SEARCH_PHRASE, ''); +} + +/** + * Persists user search phrase from the serch input across the screens. + */ +function updateUserSearchPhrase(value: string) { + Onyx.merge(ONYXKEYS.USER_SEARCH_PHRASE, value); +} + +export {clearUserSearchPhrase as clearUserSearchValue, updateUserSearchPhrase}; diff --git a/src/pages/RoomInvitePage.tsx b/src/pages/RoomInvitePage.tsx index 17239e6d4fb5..3399985cb7eb 100644 --- a/src/pages/RoomInvitePage.tsx +++ b/src/pages/RoomInvitePage.tsx @@ -18,6 +18,7 @@ import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ReportActions from '@libs/actions/Report'; +import * as UserSearchPhraseActions from '@libs/actions/UserSearchPhrase'; import {READ_COMMANDS} from '@libs/API/types'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import HttpUtils from '@libs/HttpUtils'; @@ -38,7 +39,6 @@ import type {Policy} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {WithReportOrNotFoundProps} from './home/report/withReportOrNotFound'; import withReportOrNotFound from './home/report/withReportOrNotFound'; -import SearchInputManager from './workspace/SearchInputManager'; type RoomInvitePageProps = WithReportOrNotFoundProps & WithNavigationTransitionEndProps & StackScreenProps; @@ -53,15 +53,12 @@ function RoomInvitePage({ }: RoomInvitePageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); + const [userSearchPhrase] = useOnyx(ONYXKEYS.USER_SEARCH_PHRASE); + const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(userSearchPhrase ?? ''); const [selectedOptions, setSelectedOptions] = useState([]); const [isSearchingForReports] = useOnyx(ONYXKEYS.IS_SEARCHING_FOR_REPORTS, {initWithStoredValues: false}); - const {options, areOptionsInitialized} = useOptionsList(); - useEffect(() => { - setSearchTerm(SearchInputManager.searchInput); - // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - }, []); + const {options, areOptionsInitialized} = useOptionsList(); // Any existing participants and Expensify emails should not be eligible for invitation const excludedUsers = useMemo(() => { @@ -207,7 +204,7 @@ function RoomInvitePage({ if (reportID) { Report.inviteToRoom(reportID, invitedEmailsToAccountIDs); } - SearchInputManager.searchInput = ''; + UserSearchPhraseActions.clearUserSearchValue(); Navigation.navigate(backRoute); }, [selectedOptions, backRoute, reportID, validate]); @@ -239,6 +236,7 @@ function RoomInvitePage({ }, [debouncedSearchTerm, inviteOptions.userToInvite, inviteOptions.personalDetails, excludedUsers, translate, reportName]); useEffect(() => { + UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchTerm); ReportActions.searchInServer(debouncedSearchTerm); }, [debouncedSearchTerm]); @@ -265,7 +263,6 @@ function RoomInvitePage({ textInputLabel={translate('selectionList.nameEmailOrPhoneNumber')} textInputValue={searchTerm} onChangeText={(value) => { - SearchInputManager.searchInput = value; setSearchTerm(value); }} headerMessage={headerMessage} diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index 896b3d10162a..18e039d7581e 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -2,7 +2,7 @@ import {useIsFocused} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx, withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import Button from '@components/Button'; @@ -16,8 +16,10 @@ import type {ListItem} from '@components/SelectionList/types'; import UserListItem from '@components/SelectionList/UserListItem'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; +import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as UserSearchPhraseActions from '@libs/actions/UserSearchPhrase'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import localeCompare from '@libs/LocaleCompare'; import Log from '@libs/Log'; @@ -53,7 +55,8 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { const {formatPhoneNumber, translate} = useLocalize(); const [selectedMembers, setSelectedMembers] = useState([]); const [removeMembersConfirmModalVisible, setRemoveMembersConfirmModalVisible] = useState(false); - const [searchValue, setSearchValue] = useState(''); + const [userSearchPhrase] = useOnyx(ONYXKEYS.USER_SEARCH_PHRASE); + const [searchValue, debouncedSearchTerm, setSearchValue] = useDebouncedState(userSearchPhrase ?? ''); const [didLoadRoomMembers, setDidLoadRoomMembers] = useState(false); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const policy = useMemo(() => policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID ?? ''}`], [policies, report?.policyID]); @@ -61,13 +64,17 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { const isFocusedScreen = useIsFocused(); + // useEffect(() => { + // setSearchValue(userSearchPhrase); + // }, [isFocusedScreen]); + useEffect(() => { - setSearchValue(SearchInputManager.searchInput); - }, [isFocusedScreen]); + UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchTerm); + }, [debouncedSearchTerm]); useEffect( () => () => { - SearchInputManager.searchInput = ''; + UserSearchPhraseActions.clearUserSearchValue(); }, [], ); From 75654cf952b9b07ff6fa57998ed7ec0015f7dfff Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 15:03:25 +0200 Subject: [PATCH 014/578] apply onyx search persist to the members flow --- src/pages/RoomMembersPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index 18e039d7581e..1d2a7aa60666 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -64,9 +64,9 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { const isFocusedScreen = useIsFocused(); - // useEffect(() => { - // setSearchValue(userSearchPhrase); - // }, [isFocusedScreen]); + useEffect(() => { + setSearchValue(userSearchPhrase ?? ''); + }, [isFocusedScreen, setSearchValue, userSearchPhrase]); useEffect(() => { UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchTerm); From f06810d56b3e8750f155f1260aed0f1a35c40eed Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 15:15:52 +0200 Subject: [PATCH 015/578] cleanup --- src/pages/RoomMembersPage.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index 1d2a7aa60666..b72df5a36bd0 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -39,7 +39,6 @@ import type {Session} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {WithReportOrNotFoundProps} from './home/report/withReportOrNotFound'; import withReportOrNotFound from './home/report/withReportOrNotFound'; -import SearchInputManager from './workspace/SearchInputManager'; type RoomMembersPageOnyxProps = { session: OnyxEntry; @@ -56,7 +55,7 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { const [selectedMembers, setSelectedMembers] = useState([]); const [removeMembersConfirmModalVisible, setRemoveMembersConfirmModalVisible] = useState(false); const [userSearchPhrase] = useOnyx(ONYXKEYS.USER_SEARCH_PHRASE); - const [searchValue, debouncedSearchTerm, setSearchValue] = useDebouncedState(userSearchPhrase ?? ''); + const [searchValue, debouncedSearchTerm, setSearchValue] = useDebouncedState(''); const [didLoadRoomMembers, setDidLoadRoomMembers] = useState(false); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const policy = useMemo(() => policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID ?? ''}`], [policies, report?.policyID]); @@ -68,10 +67,6 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { setSearchValue(userSearchPhrase ?? ''); }, [isFocusedScreen, setSearchValue, userSearchPhrase]); - useEffect(() => { - UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchTerm); - }, [debouncedSearchTerm]); - useEffect( () => () => { UserSearchPhraseActions.clearUserSearchValue(); @@ -79,6 +74,10 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { [], ); + useEffect(() => { + UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchTerm); + }, [debouncedSearchTerm]); + /** * Get members for the current room */ @@ -302,7 +301,6 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { disableKeyboardShortcuts={removeMembersConfirmModalVisible} textInputValue={searchValue} onChangeText={(value) => { - SearchInputManager.searchInput = value; setSearchValue(value); }} headerMessage={headerMessage} From d6df1ba1b0f215ffb8ecf2972f96b885f7cafb28 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 15:36:30 +0200 Subject: [PATCH 016/578] remove persist from workspace invite page --- src/pages/workspace/WorkspaceInvitePage.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pages/workspace/WorkspaceInvitePage.tsx b/src/pages/workspace/WorkspaceInvitePage.tsx index c29819b3c6f9..ad48d15aa9df 100644 --- a/src/pages/workspace/WorkspaceInvitePage.tsx +++ b/src/pages/workspace/WorkspaceInvitePage.tsx @@ -38,7 +38,6 @@ import type {Beta, InvitedEmailsToAccountIDs} from '@src/types/onyx'; import type {Errors} from '@src/types/onyx/OnyxCommon'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import AccessOrNotFoundWrapper from './AccessOrNotFoundWrapper'; -import SearchInputManager from './SearchInputManager'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; @@ -77,7 +76,6 @@ function WorkspaceInvitePage({route, betas, invitedEmailsToAccountIDsDraft, poli }); useEffect(() => { - setSearchTerm(SearchInputManager.searchInput); return () => { Member.setWorkspaceInviteMembersDraft(route.params.policyID, {}); }; @@ -338,7 +336,6 @@ function WorkspaceInvitePage({route, betas, invitedEmailsToAccountIDsDraft, poli textInputLabel={translate('selectionList.nameEmailOrPhoneNumber')} textInputValue={searchTerm} onChangeText={(value) => { - SearchInputManager.searchInput = value; setSearchTerm(value); }} headerMessage={headerMessage} From 30ff249c389db433f9640283d679ad4cd588d656 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 15:38:29 +0200 Subject: [PATCH 017/578] cleanup --- src/libs/Navigation/AppNavigator/AuthScreens.tsx | 3 --- src/pages/workspace/SearchInputManager.ts | 5 ----- src/pages/workspace/WorkspaceInviteMessagePage.tsx | 2 -- 3 files changed, 10 deletions(-) delete mode 100644 src/pages/workspace/SearchInputManager.ts diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index 64816562a507..cac4337e2f7f 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -27,7 +27,6 @@ import * as SessionUtils from '@libs/SessionUtils'; import ConnectionCompletePage from '@pages/ConnectionCompletePage'; import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; import DesktopSignInRedirectPage from '@pages/signin/DesktopSignInRedirectPage'; -import SearchInputManager from '@pages/workspace/SearchInputManager'; import * as App from '@userActions/App'; import * as Download from '@userActions/Download'; import * as Modal from '@userActions/Modal'; @@ -174,8 +173,6 @@ const modalScreenListeners = { Modal.setModalVisibility(false); }, beforeRemove: () => { - // Clear search input (WorkspaceInvitePage) when modal is closed - SearchInputManager.searchInput = ''; Modal.setModalVisibility(false); Modal.willAlertModalBecomeVisible(false); }, diff --git a/src/pages/workspace/SearchInputManager.ts b/src/pages/workspace/SearchInputManager.ts deleted file mode 100644 index 599f7cca6cf9..000000000000 --- a/src/pages/workspace/SearchInputManager.ts +++ /dev/null @@ -1,5 +0,0 @@ -// eslint-disable-next-line prefer-const -let searchInput = ''; -export default { - searchInput, -}; diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.tsx b/src/pages/workspace/WorkspaceInviteMessagePage.tsx index df34875f5fa6..ff5b7326af84 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.tsx +++ b/src/pages/workspace/WorkspaceInviteMessagePage.tsx @@ -38,7 +38,6 @@ import INPUT_IDS from '@src/types/form/WorkspaceInviteMessageForm'; import type {InvitedEmailsToAccountIDs, PersonalDetailsList} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import AccessOrNotFoundWrapper from './AccessOrNotFoundWrapper'; -import SearchInputManager from './SearchInputManager'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; @@ -110,7 +109,6 @@ function WorkspaceInviteMessagePage({ // Please see https://github.com/Expensify/App/blob/main/README.md#Security for more details Member.addMembersToWorkspace(invitedEmailsToAccountIDsDraft ?? {}, `${welcomeNoteSubject}\n\n${welcomeNote}`, route.params.policyID); debouncedSaveDraft(null); - SearchInputManager.searchInput = ''; Navigation.dismissModal(); }; From a3118679ab75105e3319be4e71b623393c7f8a32 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 15:49:22 +0200 Subject: [PATCH 018/578] cleanup --- src/ONYXKEYS.ts | 4 ++-- .../{UserSearchPhrase.ts => RoomMembersUserSearchPhrase.ts} | 4 ++-- src/pages/RoomInvitePage.tsx | 4 ++-- src/pages/RoomMembersPage.tsx | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/libs/actions/{UserSearchPhrase.ts => RoomMembersUserSearchPhrase.ts} (72%) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 06b2603deadb..4c358e73a5a5 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -401,7 +401,7 @@ const ONYXKEYS = { APPROVAL_WORKFLOW: 'approvalWorkflow', /** Stores the user search value for persistance across the screens */ - USER_SEARCH_PHRASE: 'userSearchPhrase', + ROOM_MEMBERS_USER_SEARCH_PHRASE: 'roomMembersUserSearchPhrase', /** Collection Keys */ COLLECTION: { @@ -882,7 +882,7 @@ type OnyxValuesMapping = { [ONYXKEYS.NVP_WORKSPACE_TOOLTIP]: OnyxTypes.WorkspaceTooltip; [ONYXKEYS.NVP_PRIVATE_CANCELLATION_DETAILS]: OnyxTypes.CancellationDetails[]; [ONYXKEYS.APPROVAL_WORKFLOW]: OnyxTypes.ApprovalWorkflow; - [ONYXKEYS.USER_SEARCH_PHRASE]: string; + [ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE]: string; }; type OnyxValues = OnyxValuesMapping & OnyxCollectionValuesMapping & OnyxFormValuesMapping & OnyxFormDraftValuesMapping; diff --git a/src/libs/actions/UserSearchPhrase.ts b/src/libs/actions/RoomMembersUserSearchPhrase.ts similarity index 72% rename from src/libs/actions/UserSearchPhrase.ts rename to src/libs/actions/RoomMembersUserSearchPhrase.ts index d1104776dc46..4267e0a73f43 100644 --- a/src/libs/actions/UserSearchPhrase.ts +++ b/src/libs/actions/RoomMembersUserSearchPhrase.ts @@ -2,14 +2,14 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; function clearUserSearchPhrase() { - Onyx.set(ONYXKEYS.USER_SEARCH_PHRASE, ''); + Onyx.set(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE, ''); } /** * Persists user search phrase from the serch input across the screens. */ function updateUserSearchPhrase(value: string) { - Onyx.merge(ONYXKEYS.USER_SEARCH_PHRASE, value); + Onyx.merge(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE, value); } export {clearUserSearchPhrase as clearUserSearchValue, updateUserSearchPhrase}; diff --git a/src/pages/RoomInvitePage.tsx b/src/pages/RoomInvitePage.tsx index 3399985cb7eb..95fe77a6ec72 100644 --- a/src/pages/RoomInvitePage.tsx +++ b/src/pages/RoomInvitePage.tsx @@ -18,7 +18,7 @@ import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ReportActions from '@libs/actions/Report'; -import * as UserSearchPhraseActions from '@libs/actions/UserSearchPhrase'; +import * as UserSearchPhraseActions from '@libs/actions/RoomMembersUserSearchPhrase'; import {READ_COMMANDS} from '@libs/API/types'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import HttpUtils from '@libs/HttpUtils'; @@ -53,7 +53,7 @@ function RoomInvitePage({ }: RoomInvitePageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const [userSearchPhrase] = useOnyx(ONYXKEYS.USER_SEARCH_PHRASE); + const [userSearchPhrase] = useOnyx(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE); const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(userSearchPhrase ?? ''); const [selectedOptions, setSelectedOptions] = useState([]); const [isSearchingForReports] = useOnyx(ONYXKEYS.IS_SEARCHING_FOR_REPORTS, {initWithStoredValues: false}); diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index b72df5a36bd0..4b60b509bbed 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -19,7 +19,7 @@ import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalD import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as UserSearchPhraseActions from '@libs/actions/UserSearchPhrase'; +import * as UserSearchPhraseActions from '@libs/actions/RoomMembersUserSearchPhrase'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import localeCompare from '@libs/LocaleCompare'; import Log from '@libs/Log'; @@ -54,7 +54,7 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { const {formatPhoneNumber, translate} = useLocalize(); const [selectedMembers, setSelectedMembers] = useState([]); const [removeMembersConfirmModalVisible, setRemoveMembersConfirmModalVisible] = useState(false); - const [userSearchPhrase] = useOnyx(ONYXKEYS.USER_SEARCH_PHRASE); + const [userSearchPhrase] = useOnyx(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE); const [searchValue, debouncedSearchTerm, setSearchValue] = useDebouncedState(''); const [didLoadRoomMembers, setDidLoadRoomMembers] = useState(false); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; From ba8b96048ef5e1bf066c764be7052094776e348f Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 17:02:45 +0200 Subject: [PATCH 019/578] review fixes --- src/libs/actions/RoomMembersUserSearchPhrase.ts | 4 ++-- src/pages/RoomInvitePage.tsx | 2 +- src/pages/RoomMembersPage.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/RoomMembersUserSearchPhrase.ts b/src/libs/actions/RoomMembersUserSearchPhrase.ts index 4267e0a73f43..1395b1ecec7f 100644 --- a/src/libs/actions/RoomMembersUserSearchPhrase.ts +++ b/src/libs/actions/RoomMembersUserSearchPhrase.ts @@ -2,7 +2,7 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; function clearUserSearchPhrase() { - Onyx.set(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE, ''); + Onyx.merge(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE, ''); } /** @@ -12,4 +12,4 @@ function updateUserSearchPhrase(value: string) { Onyx.merge(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE, value); } -export {clearUserSearchPhrase as clearUserSearchValue, updateUserSearchPhrase}; +export {clearUserSearchPhrase, updateUserSearchPhrase}; diff --git a/src/pages/RoomInvitePage.tsx b/src/pages/RoomInvitePage.tsx index 95fe77a6ec72..d08c7b18b3be 100644 --- a/src/pages/RoomInvitePage.tsx +++ b/src/pages/RoomInvitePage.tsx @@ -204,7 +204,7 @@ function RoomInvitePage({ if (reportID) { Report.inviteToRoom(reportID, invitedEmailsToAccountIDs); } - UserSearchPhraseActions.clearUserSearchValue(); + UserSearchPhraseActions.clearUserSearchPhrase(); Navigation.navigate(backRoute); }, [selectedOptions, backRoute, reportID, validate]); diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index 4b60b509bbed..0bc8602aa45d 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -69,7 +69,7 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { useEffect( () => () => { - UserSearchPhraseActions.clearUserSearchValue(); + UserSearchPhraseActions.clearUserSearchPhrase(); }, [], ); From 5e68892c4643a58d9a3201452eb36e74991247e8 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 9 Aug 2024 17:01:41 +0700 Subject: [PATCH 020/578] fix: tooltip position --- src/components/LHNOptionsList/OptionRowLHN.tsx | 12 ++++++------ .../OptionRowRendererComponent/index.tsx | 2 +- .../EducationalTooltip/BaseEducationalTooltip.tsx | 4 ++-- src/components/Tooltip/types.ts | 6 ++++++ 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/components/LHNOptionsList/OptionRowLHN.tsx b/src/components/LHNOptionsList/OptionRowLHN.tsx index 3b5261fc7492..717bfc287e12 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.tsx +++ b/src/components/LHNOptionsList/OptionRowLHN.tsx @@ -43,7 +43,7 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti const styles = useThemeStyles(); const popoverAnchor = useRef(null); const StyleUtils = useStyleUtils(); - const isFocusedRef = useRef(true); + const [isScreenFocused, setIsScreenFocused] = useState(false); const {shouldUseNarrowLayout} = useResponsiveLayout(); // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing @@ -58,9 +58,9 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti useFocusEffect( useCallback(() => { - isFocusedRef.current = true; + setIsScreenFocused(true); return () => { - isFocusedRef.current = false; + setIsScreenFocused(false); }; }, []), ); @@ -133,7 +133,7 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti * @param [event] - A press event. */ const showPopover = (event: MouseEvent | GestureResponderEvent) => { - if (!isFocusedRef.current && shouldUseNarrowLayout) { + if (!isScreenFocused && shouldUseNarrowLayout) { return; } setIsContextMenuActive(true); @@ -166,7 +166,6 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti const fullTitle = isGroupChat ? ReportUtils.getGroupChatName(undefined, false, report) : optionItem.text; const subscriptAvatarBorderColor = isFocused ? focusedBackgroundColor : theme.sidebar; - const isHomeActiveRoute = useMemo(() => Navigation.isActiveRoute(ROUTES.HOME), [Navigation.getActiveRoute()]); return ( {}, opti needsOffscreenAlphaCompositing > void>(); useEffect( @@ -56,7 +56,7 @@ function BaseEducationalTooltip({children, shouldAutoDismiss = false, ...props}: height, width, x: px, - y: py, + y: isUseInInvertedList ? py - height : py, }); showTooltip(); }); diff --git a/src/components/Tooltip/types.ts b/src/components/Tooltip/types.ts index 4165b960f322..3005bea3dd20 100644 --- a/src/components/Tooltip/types.ts +++ b/src/components/Tooltip/types.ts @@ -75,11 +75,17 @@ type EducationalTooltipProps = ChildrenProps & SharedTooltipProps & { /** Whether to automatically dismiss the tooltip after 5 seconds */ shouldAutoDismiss?: boolean; + + /** Whether the Tooltip is used in inverted */ + isUseInInvertedList?: boolean; }; type TooltipExtendedProps = (EducationalTooltipProps | TooltipProps) & { /** Whether the actual Tooltip should be rendered. If false, it's just going to return the children */ shouldRender?: boolean; + + /** Whether the Tooltip is used in inverted */ + isUseInInvertedList?: boolean; }; export default TooltipProps; From fae7803b9d8f369af93e66ba77717248690d09dc Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 9 Aug 2024 17:15:40 +0700 Subject: [PATCH 021/578] lint fix --- src/components/LHNOptionsList/OptionRowLHN.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/LHNOptionsList/OptionRowLHN.tsx b/src/components/LHNOptionsList/OptionRowLHN.tsx index 717bfc287e12..d804e069e5fa 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.tsx +++ b/src/components/LHNOptionsList/OptionRowLHN.tsx @@ -1,5 +1,5 @@ import {useFocusEffect} from '@react-navigation/native'; -import React, {useCallback, useMemo, useRef, useState} from 'react'; +import React, {useCallback, useRef, useState} from 'react'; import type {GestureResponderEvent, ViewStyle} from 'react-native'; import {StyleSheet, View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; @@ -23,7 +23,6 @@ import useThemeStyles from '@hooks/useThemeStyles'; import DateUtils from '@libs/DateUtils'; import DomUtils from '@libs/DomUtils'; import hasCompletedGuidedSetupFlowSelector from '@libs/hasCompletedGuidedSetupFlowSelector'; -import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import Parser from '@libs/Parser'; import Performance from '@libs/Performance'; @@ -34,7 +33,6 @@ import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportA import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {OptionRowLHNProps} from './types'; @@ -174,7 +172,7 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti needsOffscreenAlphaCompositing > Date: Sun, 11 Aug 2024 18:05:19 +0100 Subject: [PATCH 022/578] Make the Room Members view of rooms and expense chats consistent with groups --- src/CONST.ts | 8 + src/ROUTES.ts | 4 + src/SCREENS.ts | 2 + .../ButtonWithDropdownMenu/types.ts | 3 + .../SelectionList/BaseSelectionList.tsx | 2 +- src/components/SelectionList/types.ts | 3 + src/languages/en.ts | 2 + src/languages/es.ts | 2 + .../ModalStackNavigators/index.tsx | 4 + .../Navigators/RightModalNavigator.tsx | 4 + src/libs/Navigation/linkingConfig/config.ts | 5 + src/libs/Navigation/types.ts | 9 + src/pages/RoomMembersDetailsPage.tsx | 137 ++++++++++++++ src/pages/RoomMembersPage.tsx | 177 ++++++++++++------ .../home/report/withReportOrNotFound.tsx | 5 +- 15 files changed, 311 insertions(+), 56 deletions(-) create mode 100644 src/pages/RoomMembersDetailsPage.tsx diff --git a/src/CONST.ts b/src/CONST.ts index eaae7b82ef74..52047b65a3d6 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -919,6 +919,9 @@ const CONST = { EXPORT_TO_INTEGRATION: 'exportToIntegration', MARK_AS_EXPORTED: 'markAsExported', }, + ROOM_MEMBERS_BULK_ACTION_TYPES: { + REMOVE: 'remove', + }, }, NEXT_STEP: { ICONS: { @@ -4026,6 +4029,11 @@ const CONST = { */ MAX_SELECTION_LIST_PAGE_LENGTH: 500, + /** + * We only include the members search bar when we hit 8 number of members + */ + SHOULD_SHOW_MEMBERS_SEARCH_INPUT_BREAKPOINT: 8, + /** * Bank account names */ diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 27f565929c56..39dc4b6a8510 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -354,6 +354,10 @@ const ROUTES = { route: 'r/:reportID/members', getRoute: (reportID: string) => `r/${reportID}/members` as const, }, + ROOM_MEMBERS_DETAILS: { + route: 'r/:reportID/members/:accountID', + getRoute: (reportID: string, accountID: string | number) => `r/${reportID}/members/${accountID}` as const, + }, ROOM_INVITE: { route: 'r/:reportID/invite/:role?', getRoute: (reportID: string, role?: string) => `r/${reportID}/invite/${role}` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index d125c9658bf2..14c2c822f6b4 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -152,6 +152,7 @@ const SCREENS = { SIGN_IN: 'SignIn', PRIVATE_NOTES: 'Private_Notes', ROOM_MEMBERS: 'RoomMembers', + ROOM_MEMBERS_DETAILS: 'RoomMembers_Details', ROOM_INVITE: 'RoomInvite', REFERRAL: 'Referral', PROCESS_MONEY_REQUEST_HOLD: 'ProcessMoneyRequestHold', @@ -490,6 +491,7 @@ const SCREENS = { }, ROOM_MEMBERS_ROOT: 'RoomMembers_Root', ROOM_INVITE_ROOT: 'RoomInvite_Root', + ROOM_MEMBERS_DETAILS_ROOT: 'RoomMembersDetails_Root', FLAG_COMMENT_ROOT: 'FlagComment_Root', REIMBURSEMENT_ACCOUNT: 'ReimbursementAccount', GET_ASSISTANCE: 'GetAssistance', diff --git a/src/components/ButtonWithDropdownMenu/types.ts b/src/components/ButtonWithDropdownMenu/types.ts index e4b81da94942..19d05499c48a 100644 --- a/src/components/ButtonWithDropdownMenu/types.ts +++ b/src/components/ButtonWithDropdownMenu/types.ts @@ -10,6 +10,8 @@ type PaymentType = DeepValueOf; +type RoomMemberBulkActionType = DeepValueOf; + type WorkspaceDistanceRatesBulkActionType = DeepValueOf; type WorkspaceTaxRatesBulkActionType = DeepValueOf; @@ -98,6 +100,7 @@ type ButtonWithDropdownMenuProps = { export type { PaymentType, WorkspaceMemberBulkActionType, + RoomMemberBulkActionType, WorkspaceDistanceRatesBulkActionType, DropdownOption, ButtonWithDropdownMenuProps, diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index e78d3d43d1ec..89d283d7d1de 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -97,6 +97,7 @@ function BaseSelectionList( shouldDelayFocus = true, shouldUpdateFocusedIndex = false, onLongPressRow, + shouldShowTextInput = !!textInputLabel || !!textInputIconLeft, }: BaseSelectionListProps, ref: ForwardedRef, ) { @@ -105,7 +106,6 @@ function BaseSelectionList( const listRef = useRef>>(null); const innerTextInputRef = useRef(null); const focusTimeoutRef = useRef(null); - const shouldShowTextInput = !!textInputLabel || !!textInputIconLeft; const shouldShowSelectAll = !!onSelectAll; const activeElementRole = useActiveElementRole(); const isFocused = useIsFocused(); diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 782307876e55..c1358f152a21 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -329,6 +329,9 @@ type BaseSelectionListProps = Partial & { /** Callback to fire when an error is dismissed */ onDismissError?: (item: TItem) => void; + /** Whether to show the text input */ + shouldShowTextInput?: boolean; + /** Label for the text input */ textInputLabel?: string; diff --git a/src/languages/en.ts b/src/languages/en.ts index bfe0eef70178..327628867ccc 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2999,6 +2999,7 @@ export default { removeMembersTitle: 'Remove members', removeMemberButtonTitle: 'Remove from workspace', removeMemberGroupButtonTitle: 'Remove from group', + removeMemberRoomButtonTitle: 'Remove from room', removeMemberPrompt: ({memberName}: {memberName: string}) => `Are you sure you want to remove ${memberName}?`, removeMemberTitle: 'Remove member', transferOwner: 'Transfer owner', @@ -3581,6 +3582,7 @@ export default { }, }, roomMembersPage: { + roomMembersListTitle: 'Directory of all room members.', memberNotFound: 'Member not found. To invite a new member to the room, please use the invite button above.', notAuthorized: `You don't have access to this page. If you're trying to join this room, just ask a room member to add you. Something else? Reach out to ${CONST.EMAIL.CONCIERGE}`, removeMembersPrompt: 'Are you sure you want to remove the selected members from the room?', diff --git a/src/languages/es.ts b/src/languages/es.ts index 76d55a096808..2f5f765d9364 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3051,6 +3051,7 @@ export default { removeMembersTitle: 'Eliminar miembros', removeMemberButtonTitle: 'Quitar del espacio de trabajo', removeMemberGroupButtonTitle: 'Quitar del grupo', + removeMemberRoomButtonTitle: 'Quitar de la sala', removeMemberPrompt: ({memberName}: {memberName: string}) => `¿Estás seguro de que deseas eliminar a ${memberName}?`, removeMemberTitle: 'Eliminar miembro', transferOwner: 'Transferir la propiedad', @@ -3635,6 +3636,7 @@ export default { }, }, roomMembersPage: { + roomMembersListTitle: 'Directorio de los miembros de la sala.', memberNotFound: 'Miembro no encontrado. Para invitar a un nuevo miembro a la sala de chat, por favor, utiliza el botón invitar que está más arriba.', notAuthorized: `No tienes acceso a esta página. Si estás intentando unirte a esta sala, pide a un miembro de la sala que te añada. ¿Necesitas algo más? Comunícate con ${CONST.EMAIL.CONCIERGE}`, removeMembersPrompt: '¿Estás seguro de que quieres eliminar a los miembros seleccionados de la sala de chat?', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index f903da87b4e9..e0595142fa0d 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -156,6 +156,9 @@ const RoomInviteModalStackNavigator = createModalStackNavigator require('../../../../pages/RoomInvitePage').default, }); +const RoomMembersDetailsModalStackNavigator = createModalStackNavigator({ + [SCREENS.ROOM_MEMBERS_DETAILS_ROOT]: () => require('../../../../pages/RoomMembersDetailsPage').default, +}); const NewChatModalStackNavigator = createModalStackNavigator({ [SCREENS.NEW_CHAT.ROOT]: () => require('../../../../pages/NewChatSelectorPage').default, [SCREENS.NEW_CHAT.NEW_CHAT_CONFIRM]: () => require('../../../../pages/NewChatConfirmPage').default, @@ -549,6 +552,7 @@ export { ReportSettingsModalStackNavigator, RoomInviteModalStackNavigator, RoomMembersModalStackNavigator, + RoomMembersDetailsModalStackNavigator, SettingsModalStackNavigator, SignInModalStackNavigator, CategoriesModalStackNavigator, diff --git a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx index 44355cbbe955..6835d38739fc 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx +++ b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx @@ -107,6 +107,10 @@ function RightModalNavigator({navigation, route}: RightModalNavigatorProps) { name={SCREENS.RIGHT_MODAL.ROOM_INVITE} component={ModalStackNavigators.RoomInviteModalStackNavigator} /> + ['config'] = { [SCREENS.ROOM_MEMBERS_ROOT]: ROUTES.ROOM_MEMBERS.route, }, }, + [SCREENS.RIGHT_MODAL.ROOM_MEMBERS_DETAILS]: { + screens: { + [SCREENS.ROOM_MEMBERS_DETAILS_ROOT]: ROUTES.ROOM_MEMBERS_DETAILS.route, + }, + }, [SCREENS.RIGHT_MODAL.MONEY_REQUEST]: { screens: { [SCREENS.MONEY_REQUEST.START]: ROUTES.MONEY_REQUEST_START.route, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index a43eab452463..6243132f574f 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -771,6 +771,13 @@ type RoomInviteNavigatorParamList = { }; }; +type RoomMembersDetailsNavigatorParamList = { + [SCREENS.ROOM_MEMBERS_DETAILS_ROOT]: { + reportID: string; + accountID: string; + }; +}; + type MoneyRequestNavigatorParamList = { [SCREENS.MONEY_REQUEST.STEP_SEND_FROM]: { iouType: IOUType; @@ -1073,6 +1080,7 @@ type RightModalNavigatorParamList = { [SCREENS.RIGHT_MODAL.REPORT_DESCRIPTION]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.PARTICIPANTS]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.ROOM_MEMBERS]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.ROOM_MEMBERS_DETAILS]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.ROOM_INVITE]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.MONEY_REQUEST]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.NEW_TASK]: NavigatorScreenParams; @@ -1357,6 +1365,7 @@ export type { RightModalNavigatorParamList, RoomInviteNavigatorParamList, RoomMembersNavigatorParamList, + RoomMembersDetailsNavigatorParamList, RootStackParamList, SearchNavigatorParamList, SettingsNavigatorParamList, diff --git a/src/pages/RoomMembersDetailsPage.tsx b/src/pages/RoomMembersDetailsPage.tsx new file mode 100644 index 000000000000..b2f8da10c7b7 --- /dev/null +++ b/src/pages/RoomMembersDetailsPage.tsx @@ -0,0 +1,137 @@ +import type {StackScreenProps} from '@react-navigation/stack'; +import React, {useCallback} from 'react'; +import {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; +import Avatar from '@components/Avatar'; +import Button from '@components/Button'; +import ConfirmModal from '@components/ConfirmModal'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import * as Expensicons from '@components/Icon/Expensicons'; +import MenuItem from '@components/MenuItem'; +import ScreenWrapper from '@components/ScreenWrapper'; +import Text from '@components/Text'; +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useLocalize from '@hooks/useLocalize'; +import useStyleUtils from '@hooks/useStyleUtils'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as Report from '@libs/actions/Report'; +import Navigation from '@navigation/Navigation'; +import type {RoomMembersDetailsNavigatorParamList} from '@navigation/types'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; +import type {PersonalDetails, PersonalDetailsList} from '@src/types/onyx'; +import NotFoundPage from './ErrorPage/NotFoundPage'; +import withReportOrNotFound from './home/report/withReportOrNotFound'; +import type {WithReportOrNotFoundProps} from './home/report/withReportOrNotFound'; + +type RoomMembersDetailsPageOnyxProps = { + /** Personal details of all users */ + personalDetails: OnyxEntry; +}; + +type RoomMembersDetailsPagePageProps = WithReportOrNotFoundProps & + StackScreenProps & + RoomMembersDetailsPageOnyxProps; + +function RoomMembersDetailsPage({personalDetails, report, route}: RoomMembersDetailsPagePageProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + const StyleUtils = useStyleUtils(); + const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + + const [isRemoveMemberConfirmModalVisible, setIsRemoveMemberConfirmModalVisible] = React.useState(false); + + const accountID = Number(route.params.accountID); + const backTo = ROUTES.ROOM_MEMBERS.getRoute(report?.reportID ?? '-1'); + + const member = report?.participants?.[accountID]; + const details = personalDetails?.[accountID] ?? ({} as PersonalDetails); + const fallbackIcon = details.fallbackIcon ?? ''; + const displayName = details.displayName ?? ''; + const isSelectedMemberCurrentUser = accountID === currentUserPersonalDetails?.accountID; + const removeUser = useCallback(() => { + setIsRemoveMemberConfirmModalVisible(false); + Report.removeFromGroupChat(report?.reportID, [accountID]); + Navigation.goBack(backTo); + }, [backTo, report, accountID]); + + const navigateToProfile = useCallback(() => { + Navigation.navigate(ROUTES.PROFILE.getRoute(accountID, Navigation.getActiveRoute())); + }, [accountID]); + + if (!member) { + return ; + } + + return ( + + Navigation.goBack(backTo)} + /> + + + + {!!(details.displayName ?? '') && ( + + {displayName} + + )} + <> +