From 61cecae3fdd56763852301f364b71af59be449da Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Wed, 30 Jul 2025 16:21:00 +0530 Subject: [PATCH 1/4] Refactored localeCompare in ContactUtils --- src/libs/ContactUtils.ts | 8 ++++---- .../iou/request/MoneyRequestParticipantsSelector.tsx | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libs/ContactUtils.ts b/src/libs/ContactUtils.ts index 3fba1a4f8f7d..6b0dff618bc2 100644 --- a/src/libs/ContactUtils.ts +++ b/src/libs/ContactUtils.ts @@ -1,12 +1,12 @@ +import type {LocaleContextProps} from '@components/LocaleContextProvider'; import CONST from '@src/CONST'; import type {PersonalDetails} from '@src/types/onyx'; import type {DeviceContact, StringHolder} from './ContactImport/types'; -import localeCompare from './LocaleCompare'; import {getUserToInviteContactOption} from './OptionsListUtils'; import type {SearchOption} from './OptionsListUtils'; import RandomAvatarUtils from './RandomAvatarUtils'; -function sortEmailObjects(emails?: StringHolder[]): string[] { +function sortEmailObjects(emails: StringHolder[], localeCompare: LocaleContextProps['localeCompare']): string[] { if (!emails?.length) { return []; } @@ -28,10 +28,10 @@ function sortEmailObjects(emails?: StringHolder[]): string[] { }); } -const getContacts = (deviceContacts: DeviceContact[] | []): Array> => { +const getContacts = (deviceContacts: DeviceContact[] | [], localeCompare: LocaleContextProps['localeCompare']): Array> => { return deviceContacts .map((contact) => { - const email = sortEmailObjects(contact?.emailAddresses ?? [])?.at(0) ?? ''; + const email = sortEmailObjects(contact?.emailAddresses ?? [], localeCompare)?.at(0) ?? ''; // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const avatarSource = (contact?.imageData || RandomAvatarUtils.getAvatarForContact(`${contact?.firstName}${email}${contact?.lastName}`)) ?? ''; const phoneNumber = contact.phoneNumbers?.[0]?.value ?? ''; diff --git a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx index daaed0fa91c4..948e9cd082cb 100644 --- a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx +++ b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx @@ -102,7 +102,7 @@ function MoneyRequestParticipantsSelector( }: MoneyRequestParticipantsSelectorProps, ref: Ref, ) { - const {translate} = useLocalize(); + const {translate, localeCompare} = useLocalize(); const styles = useThemeStyles(); const [betas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: true}); const [contactPermissionState, setContactPermissionState] = useState(RESULTS.UNAVAILABLE); @@ -139,10 +139,10 @@ function MoneyRequestParticipantsSelector( const importAndSaveContacts = useCallback(() => { contactImport().then(({contactList, permissionStatus}: ContactImportResult) => { setContactPermissionState(permissionStatus); - const usersFromContact = getContacts(contactList); + const usersFromContact = getContacts(contactList, localeCompare); setContacts(usersFromContact); }); - }, []); + }, [localeCompare]); useEffect(() => { searchInServer(debouncedSearchTerm.trim()); From 376e04403dd181f217a5687a6657e80cb18fb979 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Fri, 1 Aug 2025 00:38:06 +0530 Subject: [PATCH 2/4] Fix logic --- src/hooks/useContactImport.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hooks/useContactImport.ts b/src/hooks/useContactImport.ts index 0b071fbc0cee..3590429b3e24 100644 --- a/src/hooks/useContactImport.ts +++ b/src/hooks/useContactImport.ts @@ -7,6 +7,7 @@ import useContactPermissions from '@libs/ContactPermission/useContactPermissions import getContacts from '@libs/ContactUtils'; import type {SearchOption} from '@libs/OptionsListUtils'; import type {PersonalDetails} from '@src/types/onyx'; +import useLocalize from './useLocalize'; /** * Return type of the useContactImport hook. @@ -26,14 +27,15 @@ type UseContactImportResult = { function useContactImport(): UseContactImportResult { const [contactPermissionState, setContactPermissionState] = useState(RESULTS.UNAVAILABLE); const [contacts, setContacts] = useState>>([]); + const {localeCompare} = useLocalize(); const importAndSaveContacts = useCallback(() => { contactImport().then(({contactList, permissionStatus}: ContactImportResult) => { setContactPermissionState(permissionStatus); - const usersFromContact = getContacts(contactList); + const usersFromContact = getContacts(contactList, localeCompare); setContacts(usersFromContact); }); - }, []); + }, [localeCompare]); useContactPermissions({ importAndSaveContacts, From f759de26d03e8f3c04c650806608a8218a7dba2d Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Fri, 1 Aug 2025 00:41:45 +0530 Subject: [PATCH 3/4] Fix lint --- src/pages/iou/request/MoneyRequestParticipantsSelector.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx index b985a18c1a8d..02f29e5416c3 100644 --- a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx +++ b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx @@ -97,7 +97,7 @@ function MoneyRequestParticipantsSelector( }: MoneyRequestParticipantsSelectorProps, ref: Ref, ) { - const {translate, localeCompare} = useLocalize(); + const {translate} = useLocalize(); const styles = useThemeStyles(); const [betas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: true}); const {contactPermissionState, contacts, setContactPermissionState, importAndSaveContacts} = useContactImport(); @@ -462,7 +462,7 @@ function MoneyRequestParticipantsSelector( const initiateContactImportAndSetState = useCallback(() => { setContactPermissionState(RESULTS.GRANTED); InteractionManager.runAfterInteractions(importAndSaveContacts); - }, [importAndSaveContacts]); + }, [importAndSaveContacts, setContactPermissionState]); const footerContent = useMemo(() => { if (isDismissed && !shouldShowSplitBillErrorMessage && !participants.length) { From 40edd4f1323fe09e307a3f4d92664eb771c3ef16 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 7 Aug 2025 22:46:49 +0530 Subject: [PATCH 4/4] Added some tests --- src/libs/ContactUtils.ts | 1 + tests/unit/ContactUtilsTest.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/unit/ContactUtilsTest.ts diff --git a/src/libs/ContactUtils.ts b/src/libs/ContactUtils.ts index 6b0dff618bc2..34576062b426 100644 --- a/src/libs/ContactUtils.ts +++ b/src/libs/ContactUtils.ts @@ -53,3 +53,4 @@ const getContacts = (deviceContacts: DeviceContact[] | [], localeCompare: Locale }; export default getContacts; +export {sortEmailObjects}; diff --git a/tests/unit/ContactUtilsTest.ts b/tests/unit/ContactUtilsTest.ts new file mode 100644 index 000000000000..e3feee4155b8 --- /dev/null +++ b/tests/unit/ContactUtilsTest.ts @@ -0,0 +1,12 @@ +import {sortEmailObjects} from '@src/libs/ContactUtils'; +import {localeCompare} from '../utils/TestHelper'; + +describe('ContactUtils', () => { + describe('sortEmailObjects', () => { + it('Should sort email objects with Expensify emails first', () => { + const emails = [{value: 'user2@gmail.com'}, {value: 'user2@expensify.com'}, {value: 'user1@gmail.com'}, {value: 'user1@expensify.com'}]; + const sortedEmails = sortEmailObjects(emails, localeCompare); + expect(sortedEmails).toEqual(['user1@expensify.com', 'user2@expensify.com', 'user1@gmail.com', 'user2@gmail.com']); + }); + }); +});