From 90834be4db9ffdcf72d07bf94a91676d4bcfa83e Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 13:33:21 +0700 Subject: [PATCH 01/19] fix allow to search selfDM in new chat page --- src/libs/OptionsListUtils.ts | 8 ++++++-- src/pages/NewChatPage.tsx | 14 +++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 2aad4179c337..049e538cb18a 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1505,7 +1505,8 @@ function createOptionList(personalDetails: OnyxEntry, repor } function createOptionFromReport(report: Report, personalDetails: OnyxEntry) { - const accountIDs = report.participantAccountIDs ?? []; + const isSelfDM = ReportUtils.isSelfDM(report); + const accountIDs = isSelfDM ? [currentUserAccountID ?? 0] : report.participantAccountIDs ?? []; return { item: report, @@ -1741,7 +1742,10 @@ function getOptions( } // Exclude the current user from the personal details list - const optionsToExclude: Option[] = [{login: currentUserLogin}, {login: CONST.EMAIL.NOTIFICATIONS}]; + const optionsToExclude: Option[] = [{login: CONST.EMAIL.NOTIFICATIONS}]; + if (!includeSelfDM) { + optionsToExclude.push({login: currentUserLogin}); + } // If we're including selected options from the search results, we only want to exclude them if the search input is empty // This is because on certain pages, we show the selected options at the top when the search input is empty diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index 470afc28d76e..b3ac000daea7 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -25,7 +25,7 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import type {OptionData} from '@libs/ReportUtils'; +import {getReport, type OptionData} from '@libs/ReportUtils'; import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; @@ -68,6 +68,10 @@ function useOptions({isGroupChat}: NewChatPageProps) { {}, [], true, + undefined, + undefined, + undefined, + true, ); const maxParticipantsReached = selectedOptions.length === CONST.REPORT.MAXIMUM_PARTICIPANTS; @@ -182,6 +186,11 @@ function NewChatPage({isGroupChat}: NewChatPageProps) { */ const createChat = useCallback( (option?: OptionsListUtils.Option) => { + const report = getReport(option?.reportID); + if (option?.isSelfDM && report) { + Navigation.dismissModalWithReport(report); + return; + } let login = ''; if (option?.login) { @@ -200,6 +209,9 @@ function NewChatPage({isGroupChat}: NewChatPageProps) { const itemRightSideComponent = useCallback( (item: ListItem & OptionsListUtils.Option) => { + if (item.isSelfDM) { + return null; + } /** * Removes a selected option from list if already selected. If not already selected add this option to the list. * @param option From 4fa9decddd651f15dd24cc19aef277acaf837288 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 13:51:13 +0700 Subject: [PATCH 02/19] fix lint --- src/pages/NewChatPage.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index b3ac000daea7..f0b983033c94 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -25,7 +25,8 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import {getReport, type OptionData} from '@libs/ReportUtils'; +import type {OptionData} from '@libs/ReportUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; @@ -186,9 +187,9 @@ function NewChatPage({isGroupChat}: NewChatPageProps) { */ const createChat = useCallback( (option?: OptionsListUtils.Option) => { - const report = getReport(option?.reportID); + const report = ReportUtils.getReport(option?.reportID); if (option?.isSelfDM && report) { - Navigation.dismissModalWithReport(report); + Navigation.dismissModal(report.reportID); return; } let login = ''; From 84605aad893eab7948de04f89f980eca8e372583 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 14:30:01 +0700 Subject: [PATCH 03/19] fix use option.reportID in createChat --- src/pages/NewChatPage.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index f0b983033c94..3e5a99c1b222 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -187,9 +187,8 @@ function NewChatPage({isGroupChat}: NewChatPageProps) { */ const createChat = useCallback( (option?: OptionsListUtils.Option) => { - const report = ReportUtils.getReport(option?.reportID); - if (option?.isSelfDM && report) { - Navigation.dismissModal(report.reportID); + if (option?.isSelfDM) { + Navigation.dismissModal(option.reportID); return; } let login = ''; From d40e0cf3c16eb0737d18b26b682d99cd192dd6c2 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 14:36:26 +0700 Subject: [PATCH 04/19] fix lint --- src/pages/NewChatPage.tsx | 1 - tests/unit/OptionsListUtilsTest.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index 3e5a99c1b222..3f0c9a23da3f 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -26,7 +26,6 @@ import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import type {OptionData} from '@libs/ReportUtils'; -import * as ReportUtils from '@libs/ReportUtils'; import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; diff --git a/tests/unit/OptionsListUtilsTest.ts b/tests/unit/OptionsListUtilsTest.ts index 75ed7fa9d5b1..4c332d0e2e07 100644 --- a/tests/unit/OptionsListUtilsTest.ts +++ b/tests/unit/OptionsListUtilsTest.ts @@ -368,7 +368,7 @@ describe('OptionsListUtils', () => { // When we filter in the Search view without providing a searchValue let results = OptionsListUtils.getSearchOptions(OPTIONS, '', [CONST.BETAS.ALL]); // Then the 2 personalDetails that don't have reports should be returned - expect(results.personalDetails.length).toBe(2); + expect(results.personalDetails.length).toBe(3); // Then all of the reports should be shown including the archived rooms. expect(results.recentReports.length).toBe(Object.values(OPTIONS.reports).length); @@ -2618,7 +2618,7 @@ describe('OptionsListUtils', () => { const options = OptionsListUtils.getSearchOptions(OPTIONS, '', [CONST.BETAS.ALL]); const filteredOptions = OptionsListUtils.filterOptions(options, searchText); - expect(filteredOptions.recentReports.length).toBe(5); + expect(filteredOptions.recentReports.length).toBe(6); expect(filteredOptions.recentReports[0].text).toBe('Invisible Woman'); expect(filteredOptions.recentReports[1].text).toBe('Spider-Man'); expect(filteredOptions.recentReports[2].text).toBe('Black Widow'); From ac68346d8a8bd3b0e91d5547af3dd295b1d090d0 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 14:50:03 +0700 Subject: [PATCH 05/19] fix revert fix jest --- tests/unit/OptionsListUtilsTest.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/OptionsListUtilsTest.ts b/tests/unit/OptionsListUtilsTest.ts index 4c332d0e2e07..75ed7fa9d5b1 100644 --- a/tests/unit/OptionsListUtilsTest.ts +++ b/tests/unit/OptionsListUtilsTest.ts @@ -368,7 +368,7 @@ describe('OptionsListUtils', () => { // When we filter in the Search view without providing a searchValue let results = OptionsListUtils.getSearchOptions(OPTIONS, '', [CONST.BETAS.ALL]); // Then the 2 personalDetails that don't have reports should be returned - expect(results.personalDetails.length).toBe(3); + expect(results.personalDetails.length).toBe(2); // Then all of the reports should be shown including the archived rooms. expect(results.recentReports.length).toBe(Object.values(OPTIONS.reports).length); @@ -2618,7 +2618,7 @@ describe('OptionsListUtils', () => { const options = OptionsListUtils.getSearchOptions(OPTIONS, '', [CONST.BETAS.ALL]); const filteredOptions = OptionsListUtils.filterOptions(options, searchText); - expect(filteredOptions.recentReports.length).toBe(6); + expect(filteredOptions.recentReports.length).toBe(5); expect(filteredOptions.recentReports[0].text).toBe('Invisible Woman'); expect(filteredOptions.recentReports[1].text).toBe('Spider-Man'); expect(filteredOptions.recentReports[2].text).toBe('Black Widow'); From 666e9dab5eb4d064dec1d018b76e9f27e5a0fbb4 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 24 Apr 2024 02:48:13 +0700 Subject: [PATCH 06/19] fix jest test --- src/libs/OptionsListUtils.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 049e538cb18a..4f647e760519 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1743,9 +1743,6 @@ function getOptions( // Exclude the current user from the personal details list const optionsToExclude: Option[] = [{login: CONST.EMAIL.NOTIFICATIONS}]; - if (!includeSelfDM) { - optionsToExclude.push({login: currentUserLogin}); - } // If we're including selected options from the search results, we only want to exclude them if the search input is empty // This is because on certain pages, we show the selected options at the top when the search input is empty @@ -1824,6 +1821,7 @@ function getOptions( } if (includePersonalDetails) { + optionsToExclude.push({login: currentUserLogin}); // Next loop over all personal details removing any that are selectedUsers or recentChats allPersonalDetailsOptions.forEach((personalDetailOption) => { if (optionsToExclude.some((optionToExclude) => optionToExclude.login === personalDetailOption.login)) { From f60a61093e447477b14b65a5ef96caa3df36bbb6 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 24 Apr 2024 03:00:39 +0700 Subject: [PATCH 07/19] fix move logic push currentUserLogin to top --- 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 4f647e760519..de1f1ca797f4 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1820,8 +1820,8 @@ function getOptions( } } + optionsToExclude.push({login: currentUserLogin}); if (includePersonalDetails) { - optionsToExclude.push({login: currentUserLogin}); // Next loop over all personal details removing any that are selectedUsers or recentChats allPersonalDetailsOptions.forEach((personalDetailOption) => { if (optionsToExclude.some((optionToExclude) => optionToExclude.login === personalDetailOption.login)) { From 6698121471588e6138e368126802df2d5182ab03 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 24 Apr 2024 10:00:06 +0700 Subject: [PATCH 08/19] fix create new var personalDetailsOptionsToExclude --- src/libs/OptionsListUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index de1f1ca797f4..508aead725a4 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1820,11 +1820,11 @@ function getOptions( } } - optionsToExclude.push({login: currentUserLogin}); if (includePersonalDetails) { + const personalDetailsOptionsToExclude = [...optionsToExclude, {login: currentUserLogin}]; // Next loop over all personal details removing any that are selectedUsers or recentChats allPersonalDetailsOptions.forEach((personalDetailOption) => { - if (optionsToExclude.some((optionToExclude) => optionToExclude.login === personalDetailOption.login)) { + if (personalDetailsOptionsToExclude.some((optionToExclude) => optionToExclude.login === personalDetailOption.login)) { return; } const {searchText, participantsList, isChatRoom} = personalDetailOption; From 003defb7825d83f3b6d8406351b549c0880342a1 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 24 Apr 2024 10:00:48 +0700 Subject: [PATCH 09/19] fix remove comment --- src/libs/OptionsListUtils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 508aead725a4..b9e62be19769 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1741,7 +1741,6 @@ function getOptions( allPersonalDetailsOptions = lodashOrderBy(allPersonalDetailsOptions, [(personalDetail) => personalDetail.text?.toLowerCase()], 'asc'); } - // Exclude the current user from the personal details list const optionsToExclude: Option[] = [{login: CONST.EMAIL.NOTIFICATIONS}]; // If we're including selected options from the search results, we only want to exclude them if the search input is empty From a00ef2c85a74671c1361873d9c3da6be3d0ba5fc Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Thu, 18 Apr 2024 12:18:13 +0200 Subject: [PATCH 10/19] Add first version of SearchFilters component --- assets/images/all.svg | 1 + src/components/Icon/Expensicons.ts | 2 + src/pages/Search/SearchFilters.tsx | 93 ++++++++++++++++++++++++ src/pages/Search/SearchPageBottomTab.tsx | 51 +------------ 4 files changed, 99 insertions(+), 48 deletions(-) create mode 100644 assets/images/all.svg create mode 100644 src/pages/Search/SearchFilters.tsx diff --git a/assets/images/all.svg b/assets/images/all.svg new file mode 100644 index 000000000000..d1a833d280ce --- /dev/null +++ b/assets/images/all.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts index 877e4972a3ec..8d57e672141a 100644 --- a/src/components/Icon/Expensicons.ts +++ b/src/components/Icon/Expensicons.ts @@ -1,4 +1,5 @@ import AddReaction from '@assets/images/add-reaction.svg'; +import All from "@assets/images/all.svg"; import Android from '@assets/images/android.svg'; import Apple from '@assets/images/apple.svg'; import ArrowRightLong from '@assets/images/arrow-right-long.svg'; @@ -165,6 +166,7 @@ export { ActiveRoomAvatar, AddReaction, AdminRoomAvatar, + All, Android, AnnounceRoomAvatar, Apple, diff --git a/src/pages/Search/SearchFilters.tsx b/src/pages/Search/SearchFilters.tsx new file mode 100644 index 000000000000..175c630e672b --- /dev/null +++ b/src/pages/Search/SearchFilters.tsx @@ -0,0 +1,93 @@ +import React from 'react'; +import {View} from 'react-native'; +import MenuItem from '@components/MenuItem'; +import TabSelectorItem from '@components/TabSelector/TabSelectorItem'; +import useActiveRoute from '@hooks/useActiveRoute'; +import useSingleExecution from '@hooks/useSingleExecution'; +import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; +import useWindowDimensions from '@hooks/useWindowDimensions'; +import Navigation from '@libs/Navigation/Navigation'; +import * as Expensicons from '@src/components/Icon/Expensicons'; +import CONST from '@src/CONST'; +import type {Route} from '@src/ROUTES'; +import ROUTES from '@src/ROUTES'; +import type IconAsset from '@src/types/utils/IconAsset'; + +type SearchMenuItem = { + title: string; + icon: IconAsset; + route: Route; +}; + +const searchMenuItems: SearchMenuItem[] = [ + { + title: 'All', + icon: Expensicons.All, + route: ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.ALL), + }, + // More tabs prepared for final version but in v1 we support only "All" + // { + // title: 'Sent', + // icon: Expensicons.Send, + // route: ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.SENT), + // }, + // { + // title: 'Drafts', + // icon: Expensicons.Pencil, + // route: ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.DRAFTS), + // }, +]; + +function SearchFilters() { + const theme = useTheme(); + const styles = useThemeStyles(); + const {singleExecution} = useSingleExecution(); + const activeRoute = useActiveRoute(); + const {isSmallScreenWidth} = useWindowDimensions(); + + const currentQuery = activeRoute?.params && 'query' in activeRoute.params ? activeRoute?.params?.query : ''; + const flexDirection = isSmallScreenWidth && styles.flexRow; + + return ( + + {searchMenuItems.map((item) => { + const isActive = item.title.toLowerCase() === currentQuery; + const onPress = singleExecution(() => Navigation.navigate(item.route)); + + if (isSmallScreenWidth) { + return ( + + ); + } + + return ( + + ); + })} + + ); +} + +SearchFilters.displayName = 'SearchFilters'; + +export default SearchFilters; diff --git a/src/pages/Search/SearchPageBottomTab.tsx b/src/pages/Search/SearchPageBottomTab.tsx index f90f066d72a7..197b703404c3 100644 --- a/src/pages/Search/SearchPageBottomTab.tsx +++ b/src/pages/Search/SearchPageBottomTab.tsx @@ -1,14 +1,6 @@ import React from 'react'; -import {View} from 'react-native'; -import MenuItem from '@components/MenuItem'; import ScreenWrapper from '@components/ScreenWrapper'; -import useActiveRoute from '@hooks/useActiveRoute'; -import useSingleExecution from '@hooks/useSingleExecution'; -import useThemeStyles from '@hooks/useThemeStyles'; -import Navigation from '@libs/Navigation/Navigation'; -import * as Expensicons from '@src/components/Icon/Expensicons'; -import CONST from '@src/CONST'; -import ROUTES from '@src/ROUTES'; +import SearchFilters from './SearchFilters'; import type IconAsset from '@src/types/utils/IconAsset'; // import EmptySearchView from './EmptySearchView'; @@ -20,48 +12,11 @@ type SearchMenuItem = { }; function SearchPageBottomTab() { - const styles = useThemeStyles(); - const {singleExecution} = useSingleExecution(); - const activeRoute = useActiveRoute(); - const currentQuery = activeRoute?.params && 'query' in activeRoute.params ? activeRoute?.params?.query : ''; - - const searchMenuItems: SearchMenuItem[] = [ - { - title: 'All', - icon: Expensicons.ExpensifyLogoNew, - action: singleExecution(() => Navigation.navigate(ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.ALL))), - }, - { - title: 'Sent', - icon: Expensicons.ExpensifyLogoNew, - action: singleExecution(() => Navigation.navigate(ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.SENT))), - }, - { - title: 'Drafts', - icon: Expensicons.ExpensifyLogoNew, - action: singleExecution(() => Navigation.navigate(ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.DRAFTS))), - }, - ]; - return ( - - {searchMenuItems.map((item) => ( - - ))} - {/* */} + + {/* Search results list goes here */} ); } From 95da343e22bd6722dac3a83792671289108f6781 Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Mon, 22 Apr 2024 11:58:16 +0200 Subject: [PATCH 11/19] Improve SearchFilters and add breadcrumbs --- .../createCustomBottomTabNavigator/TopBar.tsx | 14 +++++++------ src/pages/Search/SearchFilters.tsx | 20 +++++++++++-------- src/pages/Search/SearchPageBottomTab.tsx | 17 ++++++++-------- .../SidebarScreen/BaseSidebarScreen.tsx | 8 +++++++- src/styles/index.ts | 5 +++++ 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx index a06c9d08c529..573f2349d953 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx @@ -25,9 +25,9 @@ type TopBarOnyxProps = { }; // eslint-disable-next-line react/no-unused-prop-types -type TopBarProps = {activeWorkspaceID?: string} & TopBarOnyxProps; +type TopBarProps = {breadcrumbLabel: string; activeWorkspaceID?: string; shouldDisplaySearch?: boolean} & TopBarOnyxProps; -function TopBar({policy, session}: TopBarProps) { +function TopBar({policy, session, breadcrumbLabel, shouldDisplaySearch = true}: TopBarProps) { const styles = useThemeStyles(); const theme = useTheme(); const {translate} = useLocalize(); @@ -39,6 +39,9 @@ function TopBar({policy, session}: TopBarProps) { type: CONST.BREADCRUMB_TYPE.ROOT, }; + const displaySignIn = isAnonymousUser; + const displaySearch = !isAnonymousUser && shouldDisplaySearch; + return ( - {isAnonymousUser ? ( - - ) : ( + {displaySignIn && } + {displaySearch && ( + style={[styles.searchFiltersTabItem]} + > + + ); } diff --git a/src/pages/Search/SearchPageBottomTab.tsx b/src/pages/Search/SearchPageBottomTab.tsx index 197b703404c3..fc95e59309c9 100644 --- a/src/pages/Search/SearchPageBottomTab.tsx +++ b/src/pages/Search/SearchPageBottomTab.tsx @@ -1,21 +1,22 @@ import React from 'react'; import ScreenWrapper from '@components/ScreenWrapper'; +import useLocalize from '@hooks/useLocalize'; +import TopBar from '@navigation/AppNavigator/createCustomBottomTabNavigator/TopBar'; import SearchFilters from './SearchFilters'; -import type IconAsset from '@src/types/utils/IconAsset'; // import EmptySearchView from './EmptySearchView'; -type SearchMenuItem = { - title: string; - icon: IconAsset; - action: () => void; -}; - function SearchPageBottomTab() { + const {translate} = useLocalize(); + return ( - {/* */} + + {/* */} {/* Search results list goes here */} ); diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.tsx b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.tsx index fe61af021d7f..db30773f5155 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.tsx +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.tsx @@ -1,6 +1,7 @@ import React, {useEffect} from 'react'; import {View} from 'react-native'; import ScreenWrapper from '@components/ScreenWrapper'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Browser from '@libs/Browser'; import TopBar from '@libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar'; @@ -21,6 +22,8 @@ const startTimer = () => { function BaseSidebarScreen() { const styles = useThemeStyles(); const activeWorkspaceID = getPolicyIDFromNavigationState(); + const {translate} = useLocalize(); + useEffect(() => { Performance.markStart(CONST.TIMING.SIDEBAR_LOADED); Timing.start(CONST.TIMING.SIDEBAR_LOADED, true); @@ -36,7 +39,10 @@ function BaseSidebarScreen() { > {({insets}) => ( <> - + textLineThrough: { textDecorationLine: 'line-through', }, + + searchFiltersTabItem: { + flexBasis: '33%', + minWidth: 200, + }, } satisfies Styles); type ThemeStyles = ReturnType; From 66c8f860afebeee9e55a32507837c5513c31d3c1 Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Mon, 22 Apr 2024 12:23:47 +0200 Subject: [PATCH 12/19] Add v2 styling of SearchFilters --- src/components/Icon/Expensicons.ts | 2 +- src/pages/Search/SearchFilters.tsx | 43 ++++++------- src/pages/Search/SearchFiltersNarrow.tsx | 78 ++++++++++++++++++++++++ src/styles/index.ts | 7 ++- 4 files changed, 100 insertions(+), 30 deletions(-) create mode 100644 src/pages/Search/SearchFiltersNarrow.tsx diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts index 8d57e672141a..2f0d8a05a572 100644 --- a/src/components/Icon/Expensicons.ts +++ b/src/components/Icon/Expensicons.ts @@ -1,5 +1,5 @@ import AddReaction from '@assets/images/add-reaction.svg'; -import All from "@assets/images/all.svg"; +import All from '@assets/images/all.svg'; import Android from '@assets/images/android.svg'; import Apple from '@assets/images/apple.svg'; import ArrowRightLong from '@assets/images/arrow-right-long.svg'; diff --git a/src/pages/Search/SearchFilters.tsx b/src/pages/Search/SearchFilters.tsx index 732fb47bb83a..d701057e44d3 100644 --- a/src/pages/Search/SearchFilters.tsx +++ b/src/pages/Search/SearchFilters.tsx @@ -1,10 +1,8 @@ import React from 'react'; import {View} from 'react-native'; import MenuItem from '@components/MenuItem'; -import TabSelectorItem from '@components/TabSelector/TabSelectorItem'; import useActiveRoute from '@hooks/useActiveRoute'; import useSingleExecution from '@hooks/useSingleExecution'; -import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import Navigation from '@libs/Navigation/Navigation'; @@ -13,14 +11,15 @@ import CONST from '@src/CONST'; import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import type IconAsset from '@src/types/utils/IconAsset'; +import SearchFiltersNarrow from './SearchFiltersNarrow'; -type SearchMenuItem = { +type SearchMenuFilterItem = { title: string; icon: IconAsset; route: Route; }; -const searchMenuItems: SearchMenuItem[] = [ +const filterItems: SearchMenuFilterItem[] = [ { title: 'All', icon: Expensicons.All, @@ -40,39 +39,30 @@ const searchMenuItems: SearchMenuItem[] = [ ]; function SearchFilters() { - const theme = useTheme(); const styles = useThemeStyles(); const {singleExecution} = useSingleExecution(); const activeRoute = useActiveRoute(); const {isSmallScreenWidth} = useWindowDimensions(); const currentQuery = activeRoute?.params && 'query' in activeRoute.params ? activeRoute?.params?.query : ''; - const flexDirection = isSmallScreenWidth && styles.flexRow; + + if (isSmallScreenWidth) { + const activeItemLabel = String(currentQuery); + + return ( + + ); + } return ( - - {searchMenuItems.map((item) => { + + {filterItems.map((item) => { const isActive = item.title.toLowerCase() === currentQuery; const onPress = singleExecution(() => Navigation.navigate(item.route)); - if (isSmallScreenWidth) { - return ( - - - - ); - } - return ( (null); + + const openMenu = () => setIsPopoverVisible(true); + const closeMenu = () => setIsPopoverVisible(false); + + const activeItem = filterItems.find((item) => item.title.toLowerCase() === activeItemLabel); + const popoverMenuItems = filterItems.map((item) => ({ + text: item.title, + onSelected: singleExecution(() => Navigation.navigate(item.route)), + })); + + return ( + <> + + {({hovered}) => ( + + + + {activeItem?.title} + + + + )} + + + + ); +} + +SearchFiltersNarrow.displayName = 'SearchFiltersNarrow'; + +export default SearchFiltersNarrow; diff --git a/src/styles/index.ts b/src/styles/index.ts index 6d28f3c8bdc2..2e070b2e1d6d 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4875,9 +4875,10 @@ const styles = (theme: ThemeColors) => textDecorationLine: 'line-through', }, - searchFiltersTabItem: { - flexBasis: '33%', - minWidth: 200, + searchFiltersButtonText: { + marginLeft: 4, + marginRight: 4, + fontWeight: 'bold', }, } satisfies Styles); From df8d7e32f6c749cdf8a973cc1350c8fdcec7b623 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Apr 2024 19:25:08 +0530 Subject: [PATCH 13/19] Revert "Merge pull request #40807 from Expensify/dsilva_changingPropertyBeingUsedByFullstory" This reverts commit 51372ab1171059ff514ffed1dc1511452aee6a57, reversing changes made to e58ec4940cbed9352266760bebee0a03257c4717. --- src/ONYXKEYS.ts | 4 -- src/libs/actions/Session/index.ts | 2 +- src/libs/fullstory/index.native.ts | 33 +++++++++------- src/libs/fullstory/index.ts | 61 ++++++++++++++---------------- src/libs/fullstory/types.ts | 7 +++- src/types/onyx/UserMetadata.ts | 8 ---- src/types/onyx/index.ts | 2 - 7 files changed, 55 insertions(+), 62 deletions(-) delete mode 100644 src/types/onyx/UserMetadata.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index c17c911d18b3..45c2d152542d 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -188,9 +188,6 @@ const ONYXKEYS = { /** User's Expensify Wallet */ USER_WALLET: 'userWallet', - /** User's metadata that will be used to segmentation */ - USER_METADATA: 'userMetadata', - /** Object containing Onfido SDK Token + applicantID */ WALLET_ONFIDO: 'walletOnfido', @@ -600,7 +597,6 @@ type OnyxValuesMapping = { [ONYXKEYS.USER_LOCATION]: OnyxTypes.UserLocation; [ONYXKEYS.LOGIN_LIST]: OnyxTypes.LoginList; [ONYXKEYS.SESSION]: OnyxTypes.Session; - [ONYXKEYS.USER_METADATA]: OnyxTypes.UserMetadata; [ONYXKEYS.STASHED_SESSION]: OnyxTypes.Session; [ONYXKEYS.BETAS]: OnyxTypes.Beta[]; [ONYXKEYS.NVP_PRIORITY_MODE]: ValueOf; diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index aa83d14a1675..cef66487a438 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -66,7 +66,7 @@ Onyx.connect({ }); Onyx.connect({ - key: ONYXKEYS.USER_METADATA, + key: ONYXKEYS.SESSION, callback: Fullstory.consentAndIdentify, }); diff --git a/src/libs/fullstory/index.native.ts b/src/libs/fullstory/index.native.ts index 67d7c7f2fe90..548598bf60bc 100644 --- a/src/libs/fullstory/index.native.ts +++ b/src/libs/fullstory/index.native.ts @@ -1,6 +1,7 @@ import FullStory, {FSPage} from '@fullstory/react-native'; import type {OnyxEntry} from 'react-native-onyx'; -import type {UserMetadata} from '@src/types/onyx'; +import type Session from '@src/types/onyx/Session'; +import type {UserSession} from './types'; /** * Fullstory React-Native lib adapter @@ -18,31 +19,37 @@ const FS = { consent: (c: boolean) => FullStory.consent(c), /** - * Initializes the FullStory metadata with the provided metadata information. + * Initializes the FullStory session with the provided session information. */ - consentAndIdentify: (value: OnyxEntry) => { + consentAndIdentify: (value: OnyxEntry) => { try { - // We only use FullStory in production environment + const session: UserSession = { + email: value?.email, + accountID: value?.accountID, + }; + // set consent FullStory.consent(true); - FS.fsIdentify(value); + FS.fsIdentify(session); } catch (e) { // error handler } }, /** - * Sets the FullStory user identity based on the provided metadata information. - * If the metadata is null or the email is 'undefined', the user identity is anonymized. - * If the metadata contains an accountID, the user identity is defined with it. + * Sets the FullStory user identity based on the provided session information. + * If the session is null or the email is 'undefined', the user identity is anonymized. + * If the session contains an email, the user identity is defined with the email and account ID. */ - fsIdentify: (metadata: UserMetadata | null) => { - if (!metadata?.accountID) { - // anonymize FullStory user identity metadata + fsIdentify: (session: UserSession) => { + if (!session || session.email === 'undefined') { + // anonymize FullStory user identity session FullStory.anonymize(); } else { // define FullStory user identity - FullStory.identify(String(metadata.accountID), { - properties: metadata, + FullStory.identify(String(session.accountID), { + properties: { + accountID: session.accountID, + }, }); } }, diff --git a/src/libs/fullstory/index.ts b/src/libs/fullstory/index.ts index 5b60f20f9ddf..0cb849983c80 100644 --- a/src/libs/fullstory/index.ts +++ b/src/libs/fullstory/index.ts @@ -1,9 +1,7 @@ import {FullStory, init, isInitialized} from '@fullstory/browser'; import type {OnyxEntry} from 'react-native-onyx'; -import CONST from '@src/CONST'; -import * as Environment from '@src/libs/Environment/Environment'; -import type {UserMetadata} from '@src/types/onyx'; -import type NavigationProperties from './types'; +import type Session from '@src/types/onyx/Session'; +import type {NavigationProperties, UserSession} from './types'; // Placeholder Browser API does not support Manual Page definition class FSPage { @@ -29,17 +27,12 @@ const FS = { */ onReady: () => new Promise((resolve) => { - Environment.getEnvironment().then((envName: string) => { - if (CONST.ENVIRONMENT.PRODUCTION !== envName) { - return; - } - // Initialised via HEAD snippet - if (!isInitialized()) { - init({orgId: ''}, resolve); - } else { - FullStory('observe', {type: 'start', callback: resolve}); - } - }); + // Initialised via HEAD snippet + if (isInitialized()) { + init({orgId: ''}, resolve); + } else { + FullStory('observe', {type: 'start', callback: resolve}); + } }), /** @@ -53,18 +46,18 @@ const FS = { consent: (c: boolean) => FullStory('setIdentity', {consent: c}), /** - * Initializes the FullStory metadata with the provided metadata information. + * Initializes the FullStory session with the provided session information. */ - consentAndIdentify: (value: OnyxEntry) => { + consentAndIdentify: (value: OnyxEntry) => { try { - Environment.getEnvironment().then((envName: string) => { - if (CONST.ENVIRONMENT.PRODUCTION !== envName) { - return; - } - FS.onReady().then(() => { - FS.consent(true); - FS.fsIdentify(value); - }); + FS.onReady().then(() => { + const session: UserSession = { + email: value?.email, + accountID: value?.accountID, + }; + // set consent + FS.consent(true); + FS.fsIdentify(session); }); } catch (e) { // error handler @@ -72,19 +65,21 @@ const FS = { }, /** - * Sets the FullStory user identity based on the provided metadata information. - * If the metadata does not contain an email, the user identity is anonymized. - * If the metadata contains an accountID, the user identity is defined with it. + * Sets the FullStory user identity based on the provided session information. + * If the session does not contain an email, the user identity is anonymized. + * If the session contains an email, the user identity is defined with the email and account ID. */ - fsIdentify: (metadata: UserMetadata | null) => { - if (!metadata?.accountID) { - // anonymize FullStory user identity metadata + fsIdentify: (session: UserSession) => { + if (typeof session.email === 'undefined') { + // anonymize FullStory user identity session FS.anonymize(); } else { // define FullStory user identity FullStory('setIdentity', { - uid: String(metadata.accountID), - properties: metadata, + uid: String(session.accountID), + properties: { + accountID: session.accountID, + }, }); } }, diff --git a/src/libs/fullstory/types.ts b/src/libs/fullstory/types.ts index 24878fd0fbd3..386e35536d97 100644 --- a/src/libs/fullstory/types.ts +++ b/src/libs/fullstory/types.ts @@ -1,5 +1,10 @@ +type UserSession = { + email: string | undefined; + accountID: number | undefined; +}; + type NavigationProperties = { path: string; }; -export default NavigationProperties; +export type {UserSession, NavigationProperties}; diff --git a/src/types/onyx/UserMetadata.ts b/src/types/onyx/UserMetadata.ts deleted file mode 100644 index fc6490264087..000000000000 --- a/src/types/onyx/UserMetadata.ts +++ /dev/null @@ -1,8 +0,0 @@ -type UserMetadata = { - planType?: string; - role?: string; - freeTrial?: boolean; - accountID?: number; -}; - -export default UserMetadata; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 84a8d5c85c40..ea0870a7b8c6 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -72,7 +72,6 @@ import type {TransactionViolation, ViolationName} from './TransactionViolation'; import type TransactionViolations from './TransactionViolation'; import type User from './User'; import type UserLocation from './UserLocation'; -import type UserMetadata from './UserMetadata'; import type UserWallet from './UserWallet'; import type WalletAdditionalDetails from './WalletAdditionalDetails'; import type {WalletAdditionalQuestionDetails} from './WalletAdditionalDetails'; @@ -156,7 +155,6 @@ export type { TransactionViolations, User, UserLocation, - UserMetadata, UserWallet, ViolationName, WalletAdditionalDetails, From 41898c3d5b8eead48ede966ec251b9067a82e170 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Apr 2024 19:25:50 +0530 Subject: [PATCH 14/19] Revert "Merge pull request #40817 from Expensify/dsilva_changingGTMToThirdPartyScripts" This reverts commit 7ea2b6c4d794208bfcd23f825e4967ce9487e9e1, reversing changes made to 03588419f4ddd32b22b70a5e17ac845586a66a48. --- .github/workflows/typecheck.yml | 2 +- config/webpack/webpack.common.ts | 2 +- web/gtm.js | 11 +++ web/index.html | 6 +- web/thirdPartyScripts.js | 155 ------------------------------- 5 files changed, 16 insertions(+), 160 deletions(-) create mode 100644 web/gtm.js delete mode 100644 web/thirdPartyScripts.js diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index 88d4d24a5723..f20939f9df0a 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -30,7 +30,7 @@ jobs: # - git diff is used to see the files that were added on this branch # - gh pr view is used to list files touched by this PR. Git diff may give false positives if the branch isn't up-to-date with main # - wc counts the words in the result of the intersection - count_new_js=$(comm -1 -2 <(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/*.js' '__mocks__/*.js' '.storybook/*.js' 'assets/*.js' 'config/*.js' 'desktop/*.js' 'jest/*.js' 'scripts/*.js' 'tests/*.js' 'workflow_tests/*.js' '.github/libs/*.js' '.github/scripts/*.js') <(gh pr view ${{ github.event.pull_request.number }} --json files | jq -r '.files | map(.path) | .[]') | wc -l) + count_new_js=$(comm -1 -2 <(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/*.js' '__mocks__/*.js' '.storybook/*.js' 'assets/*.js' 'config/*.js' 'desktop/*.js' 'jest/*.js' 'scripts/*.js' 'tests/*.js' 'web/*.js' 'workflow_tests/*.js' '.github/libs/*.js' '.github/scripts/*.js') <(gh pr view ${{ github.event.pull_request.number }} --json files | jq -r '.files | map(.path) | .[]') | wc -l) if [ "$count_new_js" -gt "0" ]; then echo "ERROR: Found new JavaScript files in the project; use TypeScript instead." exit 1 diff --git a/config/webpack/webpack.common.ts b/config/webpack/webpack.common.ts index 9d397b9557a3..7cafafca9973 100644 --- a/config/webpack/webpack.common.ts +++ b/config/webpack/webpack.common.ts @@ -98,7 +98,7 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment): {from: 'web/apple-touch-icon.png'}, {from: 'assets/images/expensify-app-icon.svg'}, {from: 'web/manifest.json'}, - {from: 'web/thirdPartyScripts.js'}, + {from: 'web/gtm.js'}, {from: 'assets/css', to: 'css'}, {from: 'assets/fonts/web', to: 'fonts'}, {from: 'assets/sounds', to: 'sounds'}, diff --git a/web/gtm.js b/web/gtm.js new file mode 100644 index 000000000000..ee96d01b9a67 --- /dev/null +++ b/web/gtm.js @@ -0,0 +1,11 @@ +/* eslint-disable no-param-reassign, prefer-template */ +(function (w, d, s, l, i) { + w[l] = w[l] || []; + w[l].push({'gtm.start': new Date().getTime(), event: 'gtm.js'}); + const f = d.getElementsByTagName(s)[0]; + const j = d.createElement(s); + const dl = l !== 'dataLayer' ? '&l=' + l : ''; + j.async = true; + j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; + f.parentNode.insertBefore(j, f); +})(window, document, 'script', 'dataLayer', 'GTM-N4M3FLJZ'); diff --git a/web/index.html b/web/index.html index be6396190d25..115803573bbd 100644 --- a/web/index.html +++ b/web/index.html @@ -122,9 +122,9 @@ <% if (htmlWebpackPlugin.options.isProduction) { %> - - - + + + <% } %> <% } %> diff --git a/web/thirdPartyScripts.js b/web/thirdPartyScripts.js deleted file mode 100644 index 15e77dbd490e..000000000000 --- a/web/thirdPartyScripts.js +++ /dev/null @@ -1,155 +0,0 @@ -/* eslint-disable */ -// Google Tag Manager -(function (w, d, s, l, i) { - w[l] = w[l] || []; - w[l].push({'gtm.start': new Date().getTime(), event: 'gtm.js'}); - const f = d.getElementsByTagName(s)[0]; - const j = d.createElement(s); - const dl = l !== 'dataLayer' ? '&l=' + l : ''; - j.async = true; - j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; - f.parentNode.insertBefore(j, f); -})(window, document, 'script', 'dataLayer', 'GTM-N4M3FLJZ'); - -// FullStory -window['_fs_host'] = 'fullstory.com'; -window['_fs_script'] = 'edge.fullstory.com/s/fs.js'; -window['_fs_org'] = 'o-1WN56P-na1'; -window['_fs_namespace'] = 'FS'; -!(function (m, n, e, t, l, o, g, y) { - var s, - f, - a = (function (h) { - return !(h in m) || (m.console && m.console.log && m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].'), !1); - })(e); - function p(b) { - var h, - d = []; - function j() { - h && - (d.forEach(function (b) { - var d; - try { - d = b[h[0]] && b[h[0]](h[1]); - } catch (h) { - return void (b[3] && b[3](h)); - } - d && d.then ? d.then(b[2], b[3]) : b[2] && b[2](d); - }), - (d.length = 0)); - } - function r(b) { - return function (d) { - h || ((h = [b, d]), j()); - }; - } - return ( - b(r(0), r(1)), - { - then: function (b, h) { - return p(function (r, i) { - d.push([b, h, r, i]), j(); - }); - }, - } - ); - } - a && - ((g = m[e] = - (function () { - var b = function (b, d, j, r) { - function i(i, c) { - h(b, d, j, i, c, r); - } - r = r || 2; - var c, - u = /Async$/; - return u.test(b) ? ((b = b.replace(u, '')), 'function' == typeof Promise ? new Promise(i) : p(i)) : h(b, d, j, c, c, r); - }; - function h(h, d, j, r, i, c) { - return b._api ? b._api(h, d, j, r, i, c) : (b.q && b.q.push([h, d, j, r, i, c]), null); - } - return (b.q = []), b; - })()), - (y = function (b) { - function h(h) { - 'function' == typeof h[4] && h[4](new Error(b)); - } - var d = g.q; - if (d) { - for (var j = 0; j < d.length; j++) h(d[j]); - (d.length = 0), (d.push = h); - } - }), - (function () { - ((o = n.createElement(t)).async = !0), - (o.crossOrigin = 'anonymous'), - (o.src = 'https://' + l), - (o.onerror = function () { - y('Error loading ' + l); - }); - var b = n.getElementsByTagName(t)[0]; - b && b.parentNode ? b.parentNode.insertBefore(o, b) : n.head.appendChild(o); - })(), - (function () { - function b() {} - function h(b, h, d) { - g(b, h, d, 1); - } - function d(b, d, j) { - h('setProperties', {type: b, properties: d}, j); - } - function j(b, h) { - d('user', b, h); - } - function r(b, h, d) { - j( - { - uid: b, - }, - d, - ), - h && j(h, d); - } - (g.identify = r), - (g.setUserVars = j), - (g.identifyAccount = b), - (g.clearUserCookie = b), - (g.setVars = d), - (g.event = function (b, d, j) { - h( - 'trackEvent', - { - name: b, - properties: d, - }, - j, - ); - }), - (g.anonymize = function () { - r(!1); - }), - (g.shutdown = function () { - h('shutdown'); - }), - (g.restart = function () { - h('restart'); - }), - (g.log = function (b, d) { - h('log', {level: b, msg: d}); - }), - (g.consent = function (b) { - h('setIdentity', {consent: !arguments.length || b}); - }); - })(), - (s = 'fetch'), - (f = 'XMLHttpRequest'), - (g._w = {}), - (g._w[f] = m[f]), - (g._w[s] = m[s]), - m[s] && - (m[s] = function () { - return g._w[s].apply(this, arguments); - }), - (g._v = '2.0.0')); -})(window, document, window._fs_namespace, 'script', window._fs_script); From bcc705ed5f5c4bfcbd2503d3a54383e6291d4ca3 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Apr 2024 19:26:46 +0530 Subject: [PATCH 15/19] Revert "Merge pull request #40294 from LCOleksii/fullstory-integration" This reverts commit 1928c3ae8a36c12ff2b79104fe14a43446cfd809, reversing changes made to 9b839f4f18d724dba1ed17ed5967f7e033781428. --- android/app/build.gradle | 10 +-- android/build.gradle | 6 +- babel.config.js | 17 ----- ios/NewExpensify.xcodeproj/project.pbxproj | 4 - ios/Podfile.lock | 28 ------- jest/setup.ts | 2 - jest/setupMockFullstoryLib.ts | 24 ------ package-lock.json | 48 ------------ package.json | 2 - src/libs/Navigation/NavigationRoot.tsx | 3 - src/libs/actions/Session/index.ts | 6 -- src/libs/fullstory/index.native.ts | 59 -------------- src/libs/fullstory/index.ts | 89 ---------------------- src/libs/fullstory/types.ts | 10 --- 14 files changed, 2 insertions(+), 306 deletions(-) delete mode 100644 jest/setupMockFullstoryLib.ts delete mode 100644 src/libs/fullstory/index.native.ts delete mode 100644 src/libs/fullstory/index.ts delete mode 100644 src/libs/fullstory/types.ts diff --git a/android/app/build.gradle b/android/app/build.gradle index bb508ea9f4de..93b538b3d943 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -2,20 +2,12 @@ apply plugin: "com.android.application" apply plugin: "org.jetbrains.kotlin.android" apply plugin: "com.facebook.react" apply plugin: "com.google.firebase.firebase-perf" -apply plugin: "fullstory" apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle" /** * This is the configuration block to customize your React Native Android app. * By default you don't need to apply any configuration, just uncomment the lines you need. */ - -/* Fullstory settings */ -fullstory { - org 'o-1WN56P-na1' - enabledVariants 'all' -} - react { /* Folders */ // The root of your project, i.e. where "package.json" lives. Default is '..' @@ -170,7 +162,7 @@ android { signingConfig null // buildTypes take precedence over productFlavors when it comes to the signing configuration, // thus we need to manually set the signing config, so that the e2e uses the debug config again. - // In other words, the signingConfig setting above will be ignored when we build the flavor in release mode. + // In other words, the signingConfig setting above will be ignored when we build the flavor in release mode. productFlavors.all { flavor -> // All release builds should be signed with the release config ... flavor.signingConfig signingConfigs.release diff --git a/android/build.gradle b/android/build.gradle index 7ecd482b38f0..10600480d8bb 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -20,7 +20,6 @@ buildscript { repositories { google() mavenCentral() - maven {url "https://maven.fullstory.com"} } dependencies { classpath("com.android.tools.build:gradle") @@ -28,9 +27,6 @@ buildscript { classpath("com.google.gms:google-services:4.3.4") classpath("com.google.firebase:firebase-crashlytics-gradle:2.7.1") classpath("com.google.firebase:perf-plugin:1.4.1") - // Fullstory integration - classpath ("com.fullstory:gradle-plugin-local:1.45.1") - // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") @@ -74,7 +70,7 @@ allprojects { // 'mapbox' is the fixed username for Mapbox's Maven repository. username = 'mapbox' - // The value for password is read from the 'MAPBOX_DOWNLOADS_TOKEN' gradle property. + // The value for password is read from the 'MAPBOX_DOWNLOADS_TOKEN' gradle property. // Run "npm run setup-mapbox-sdk" to set this property in «USER_HOME»/.gradle/gradle.properties // Example gradle.properties entry: diff --git a/babel.config.js b/babel.config.js index 0660cdb452fb..9f8b7a711d78 100644 --- a/babel.config.js +++ b/babel.config.js @@ -14,23 +14,6 @@ const defaultPlugins = [ // source code transformation as we do not use class property assignment. 'transform-class-properties', - /* Fullstory */ - [ - '@fullstory/react-native', - { - version: '1.4.0', - org: 'o-1WN56P-na1', - enabledVariants: 'all', - }, - ], - [ - '@fullstory/babel-plugin-annotate-react', - { - native: true, - setFSTagName: true, - }, - ], - // Keep it last 'react-native-reanimated/plugin', ]; diff --git a/ios/NewExpensify.xcodeproj/project.pbxproj b/ios/NewExpensify.xcodeproj/project.pbxproj index e7ce320f65d6..7f50db5da85a 100644 --- a/ios/NewExpensify.xcodeproj/project.pbxproj +++ b/ios/NewExpensify.xcodeproj/project.pbxproj @@ -681,7 +681,6 @@ "${PODS_ROOT}/Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests-frameworks.sh", "${BUILT_PRODUCTS_DIR}/MapboxMaps/MapboxMaps.framework", "${BUILT_PRODUCTS_DIR}/Turf/Turf.framework", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/FullStory/FullStory.framework/FullStory", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCommon/MapboxCommon.framework/MapboxCommon", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCoreMaps/MapboxCoreMaps.framework/MapboxCoreMaps", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxMobileEvents/MapboxMobileEvents.framework/MapboxMobileEvents", @@ -693,7 +692,6 @@ outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxMaps.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Turf.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FullStory.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCommon.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCoreMaps.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxMobileEvents.framework", @@ -737,7 +735,6 @@ "${PODS_ROOT}/Target Support Files/Pods-NewExpensify/Pods-NewExpensify-frameworks.sh", "${BUILT_PRODUCTS_DIR}/MapboxMaps/MapboxMaps.framework", "${BUILT_PRODUCTS_DIR}/Turf/Turf.framework", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/FullStory/FullStory.framework/FullStory", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCommon/MapboxCommon.framework/MapboxCommon", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCoreMaps/MapboxCoreMaps.framework/MapboxCoreMaps", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxMobileEvents/MapboxMobileEvents.framework/MapboxMobileEvents", @@ -749,7 +746,6 @@ outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxMaps.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Turf.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FullStory.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCommon.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCoreMaps.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxMobileEvents.framework", diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6ef495a65bd3..ed387a8d522f 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -138,27 +138,6 @@ PODS: - GoogleUtilities/Environment (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - fmt (6.2.1) - - FullStory (1.43.1) - - fullstory_react-native (1.4.2): - - FullStory (~> 1.14) - - glog - - hermes-engine - - RCT-Folly (= 2022.05.16.00) - - RCTRequired - - RCTTypeSafety - - React-Codegen - - React-Core - - React-debug - - React-Fabric - - React-graphics - - React-ImageManager - - React-NativeModulesApple - - React-RCTFabric - - React-rendererdebug - - React-utils - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - - Yoga - glog (0.3.5) - GoogleAppMeasurement (8.8.0): - GoogleAppMeasurement/AdIdSupport (= 8.8.0) @@ -2197,7 +2176,6 @@ SPEC REPOS: - FirebasePerformance - FirebaseRemoteConfig - fmt - - FullStory - GoogleAppMeasurement - GoogleDataTransport - GoogleSignIn @@ -2246,10 +2224,6 @@ EXTERNAL SOURCES: :path: "../node_modules/expo-modules-core" FBLazyVector: :path: "../node_modules/react-native/Libraries/FBLazyVector" - fullstory_react-native: - :path: "../node_modules/@fullstory/react-native" - FBReactNativeSpec: - :path: "../node_modules/react-native/React/FBReactNativeSpec" glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" hermes-engine: @@ -2465,8 +2439,6 @@ SPEC CHECKSUMS: FirebasePerformance: 0c01a7a496657d7cea86d40c0b1725259d164c6c FirebaseRemoteConfig: 2d6e2cfdb49af79535c8af8a80a4a5009038ec2b fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 - FullStory: e035758fef275fb59c6471f61b179652aeca452b - fullstory_react-native: a56e2bb52753b69f01aab3ae876087db08488034 glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2 GoogleAppMeasurement: 5ba1164e3c844ba84272555e916d0a6d3d977e91 GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a diff --git a/jest/setup.ts b/jest/setup.ts index 174e59a7e493..488e3e36a1d3 100644 --- a/jest/setup.ts +++ b/jest/setup.ts @@ -2,11 +2,9 @@ import '@shopify/flash-list/jestSetup'; import 'react-native-gesture-handler/jestSetup'; import mockStorage from 'react-native-onyx/dist/storage/__mocks__'; import 'setimmediate'; -import mockFSLibrary from './setupMockFullstoryLib'; import setupMockImages from './setupMockImages'; setupMockImages(); -mockFSLibrary(); // This mock is required as per setup instructions for react-navigation testing // https://reactnavigation.org/docs/testing/#mocking-native-modules diff --git a/jest/setupMockFullstoryLib.ts b/jest/setupMockFullstoryLib.ts deleted file mode 100644 index 9edfccab9441..000000000000 --- a/jest/setupMockFullstoryLib.ts +++ /dev/null @@ -1,24 +0,0 @@ -type FSPageInterface = { - start: jest.Mock; -}; - -export default function mockFSLibrary() { - jest.mock('@fullstory/react-native', () => { - class Fullstory { - consent = jest.fn(); - - anonymize = jest.fn(); - - identify = jest.fn(); - } - - return { - FSPage(): FSPageInterface { - return { - start: jest.fn(), - }; - }, - default: Fullstory, - }; - }); -} diff --git a/package-lock.json b/package-lock.json index 054b669e1926..aac685eddef7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,8 +20,6 @@ "@formatjs/intl-locale": "^3.3.0", "@formatjs/intl-numberformat": "^8.5.0", "@formatjs/intl-pluralrules": "^5.2.2", - "@fullstory/browser": "^2.0.3", - "@fullstory/react-native": "^1.4.0", "@gorhom/portal": "^1.0.14", "@invertase/react-native-apple-authentication": "^2.2.2", "@kie/act-js": "^2.6.0", @@ -5590,52 +5588,6 @@ "tslib": "^2.4.0" } }, - "node_modules/@fullstory/babel-plugin-annotate-react": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@fullstory/babel-plugin-annotate-react/-/babel-plugin-annotate-react-2.3.0.tgz", - "integrity": "sha512-gYLUL6Tu0exbvTIhK9nSCaztmqBlQAm07Fvtl/nKTc+lxwFkcX9vR8RrdTbyjJZKbPaA5EMlExQ6GeLCXkfm5g==" - }, - "node_modules/@fullstory/babel-plugin-react-native": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@fullstory/babel-plugin-react-native/-/babel-plugin-react-native-1.1.0.tgz", - "integrity": "sha512-BqfSUdyrrYrZM286GzdHd3qCdbitxUAIM0Z+HpoOTGWVTLDpkFNNaRw5juq8YhYbcPm6BAtK0RMGY7CvcMNarA==", - "dependencies": { - "@babel/parser": "^7.0.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@fullstory/browser": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@fullstory/browser/-/browser-2.0.3.tgz", - "integrity": "sha512-usjH8FB1O2LiSWoblsuKhFhlYDGpIPuyQVOx4JXtxm9QmQARdKZdNq1vPijxuDvOGjhwtVZa4JmhvByRRuDPnQ==", - "dependencies": { - "@fullstory/snippet": "2.0.3" - } - }, - "node_modules/@fullstory/react-native": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@fullstory/react-native/-/react-native-1.4.2.tgz", - "integrity": "sha512-Ig85ghn5UN+Tc1JWL/y4hY9vleeaVHL3f6qH9W4odDNP4XAv29+G82nIYQhBOQGoVnIQ4oQFQftir/dqAbidSw==", - "dependencies": { - "@fullstory/babel-plugin-annotate-react": "^2.2.0", - "@fullstory/babel-plugin-react-native": "^1.1.0" - }, - "peerDependencies": { - "expo": ">=47.0.0", - "react": "*", - "react-native": ">=0.61.0" - }, - "peerDependenciesMeta": { - "expo": { - "optional": true - } - } - }, - "node_modules/@fullstory/snippet": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@fullstory/snippet/-/snippet-2.0.3.tgz", - "integrity": "sha512-EaCuTQSLv5FvnjHLbTxErn3sS1+nLqf1p6sA/c4PV49stBtkUakA0eLhJJdaw0WLdXyEzZXf86lRNsjEzrgGPw==" - }, "node_modules/@gar/promisify": { "version": "1.1.3", "license": "MIT" diff --git a/package.json b/package.json index 9a9ed16f6234..26f0eaf39464 100644 --- a/package.json +++ b/package.json @@ -72,8 +72,6 @@ "@formatjs/intl-locale": "^3.3.0", "@formatjs/intl-numberformat": "^8.5.0", "@formatjs/intl-pluralrules": "^5.2.2", - "@fullstory/browser": "^2.0.3", - "@fullstory/react-native": "^1.4.0", "@gorhom/portal": "^1.0.14", "@invertase/react-native-apple-authentication": "^2.2.2", "@kie/act-js": "^2.6.0", diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index 5760959c1b02..506eae2bdfd2 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -6,7 +6,6 @@ import useActiveWorkspace from '@hooks/useActiveWorkspace'; import useCurrentReportID from '@hooks/useCurrentReportID'; import useTheme from '@hooks/useTheme'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import {FSPage} from '@libs/fullstory'; import Log from '@libs/Log'; import {getPathFromURL} from '@libs/Url'; import {updateLastVisitedPath} from '@userActions/App'; @@ -58,8 +57,6 @@ function parseAndLogRoute(state: NavigationState) { } Navigation.setIsNavigationReady(); - // Fullstory Page navigation tracking - new FSPage(focusedRoute?.name ?? '', {path: currentPath}).start(); } function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: NavigationRootProps) { diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index cef66487a438..9fc1485cd6e5 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -23,7 +23,6 @@ import type SignInUserParams from '@libs/API/parameters/SignInUserParams'; import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as Authentication from '@libs/Authentication'; import * as ErrorUtils from '@libs/ErrorUtils'; -import Fullstory from '@libs/fullstory'; import HttpUtils from '@libs/HttpUtils'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; @@ -65,11 +64,6 @@ Onyx.connect({ }, }); -Onyx.connect({ - key: ONYXKEYS.SESSION, - callback: Fullstory.consentAndIdentify, -}); - let stashedSession: Session = {}; Onyx.connect({ key: ONYXKEYS.STASHED_SESSION, diff --git a/src/libs/fullstory/index.native.ts b/src/libs/fullstory/index.native.ts deleted file mode 100644 index 548598bf60bc..000000000000 --- a/src/libs/fullstory/index.native.ts +++ /dev/null @@ -1,59 +0,0 @@ -import FullStory, {FSPage} from '@fullstory/react-native'; -import type {OnyxEntry} from 'react-native-onyx'; -import type Session from '@src/types/onyx/Session'; -import type {UserSession} from './types'; - -/** - * Fullstory React-Native lib adapter - * Proxy function calls to React-Native lib - * */ -const FS = { - /** - * Sets the identity as anonymous using the FullStory library. - */ - anonymize: () => FullStory.anonymize(), - - /** - * Sets the identity consent status using the FullStory library. - */ - consent: (c: boolean) => FullStory.consent(c), - - /** - * Initializes the FullStory session with the provided session information. - */ - consentAndIdentify: (value: OnyxEntry) => { - try { - const session: UserSession = { - email: value?.email, - accountID: value?.accountID, - }; - // set consent - FullStory.consent(true); - FS.fsIdentify(session); - } catch (e) { - // error handler - } - }, - - /** - * Sets the FullStory user identity based on the provided session information. - * If the session is null or the email is 'undefined', the user identity is anonymized. - * If the session contains an email, the user identity is defined with the email and account ID. - */ - fsIdentify: (session: UserSession) => { - if (!session || session.email === 'undefined') { - // anonymize FullStory user identity session - FullStory.anonymize(); - } else { - // define FullStory user identity - FullStory.identify(String(session.accountID), { - properties: { - accountID: session.accountID, - }, - }); - } - }, -}; - -export default FS; -export {FSPage}; diff --git a/src/libs/fullstory/index.ts b/src/libs/fullstory/index.ts deleted file mode 100644 index 0cb849983c80..000000000000 --- a/src/libs/fullstory/index.ts +++ /dev/null @@ -1,89 +0,0 @@ -import {FullStory, init, isInitialized} from '@fullstory/browser'; -import type {OnyxEntry} from 'react-native-onyx'; -import type Session from '@src/types/onyx/Session'; -import type {NavigationProperties, UserSession} from './types'; - -// Placeholder Browser API does not support Manual Page definition -class FSPage { - private pageName; - - private properties; - - constructor(name: string, properties: NavigationProperties) { - this.pageName = name; - this.properties = properties; - } - - start() {} -} - -/** - * Web does not use Fullstory React-Native lib - * Proxy function calls to Browser Snippet instance - * */ -const FS = { - /** - * Executes a function when the FullStory library is ready, either by initialization or by observing the start event. - */ - onReady: () => - new Promise((resolve) => { - // Initialised via HEAD snippet - if (isInitialized()) { - init({orgId: ''}, resolve); - } else { - FullStory('observe', {type: 'start', callback: resolve}); - } - }), - - /** - * Sets the identity as anonymous using the FullStory library. - */ - anonymize: () => FullStory('setIdentity', {anonymous: true}), - - /** - * Sets the identity consent status using the FullStory library. - */ - consent: (c: boolean) => FullStory('setIdentity', {consent: c}), - - /** - * Initializes the FullStory session with the provided session information. - */ - consentAndIdentify: (value: OnyxEntry) => { - try { - FS.onReady().then(() => { - const session: UserSession = { - email: value?.email, - accountID: value?.accountID, - }; - // set consent - FS.consent(true); - FS.fsIdentify(session); - }); - } catch (e) { - // error handler - } - }, - - /** - * Sets the FullStory user identity based on the provided session information. - * If the session does not contain an email, the user identity is anonymized. - * If the session contains an email, the user identity is defined with the email and account ID. - */ - fsIdentify: (session: UserSession) => { - if (typeof session.email === 'undefined') { - // anonymize FullStory user identity session - FS.anonymize(); - } else { - // define FullStory user identity - FullStory('setIdentity', { - uid: String(session.accountID), - properties: { - accountID: session.accountID, - }, - }); - } - }, -}; - -export default FS; -export {FSPage}; diff --git a/src/libs/fullstory/types.ts b/src/libs/fullstory/types.ts deleted file mode 100644 index 386e35536d97..000000000000 --- a/src/libs/fullstory/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -type UserSession = { - email: string | undefined; - accountID: number | undefined; -}; - -type NavigationProperties = { - path: string; -}; - -export type {UserSession, NavigationProperties}; From dca062c662f89889cbef864dfd40e45f8b427347 Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Wed, 24 Apr 2024 16:18:33 +0200 Subject: [PATCH 16/19] Add missing icon to SearchFilters --- src/pages/Search/SearchFiltersNarrow.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/Search/SearchFiltersNarrow.tsx b/src/pages/Search/SearchFiltersNarrow.tsx index 6b353750f47d..530b7cd176db 100644 --- a/src/pages/Search/SearchFiltersNarrow.tsx +++ b/src/pages/Search/SearchFiltersNarrow.tsx @@ -33,6 +33,7 @@ function SearchFiltersNarrow({filterItems, activeItemLabel}: SearchFiltersNarrow const popoverMenuItems = filterItems.map((item) => ({ text: item.title, onSelected: singleExecution(() => Navigation.navigate(item.route)), + icon: item.icon, })); return ( From 83bb869d3353184c2efbc0c794b0dc4424369f18 Mon Sep 17 00:00:00 2001 From: Wojciech Lewicki Date: Wed, 24 Apr 2024 16:36:06 +0200 Subject: [PATCH 17/19] fix: copy state in reanimated commit hook --- ...eact-native-reanimated+3.7.2+002+copy-state.patch | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 patches/react-native-reanimated+3.7.2+002+copy-state.patch diff --git a/patches/react-native-reanimated+3.7.2+002+copy-state.patch b/patches/react-native-reanimated+3.7.2+002+copy-state.patch new file mode 100644 index 000000000000..bd5899977ea9 --- /dev/null +++ b/patches/react-native-reanimated+3.7.2+002+copy-state.patch @@ -0,0 +1,12 @@ +diff --git a/node_modules/react-native-reanimated/Common/cpp/Fabric/ShadowTreeCloner.cpp b/node_modules/react-native-reanimated/Common/cpp/Fabric/ShadowTreeCloner.cpp +index f913ceb..3f58247 100644 +--- a/node_modules/react-native-reanimated/Common/cpp/Fabric/ShadowTreeCloner.cpp ++++ b/node_modules/react-native-reanimated/Common/cpp/Fabric/ShadowTreeCloner.cpp +@@ -51,6 +51,7 @@ ShadowNode::Unshared cloneShadowTreeWithNewProps( + newChildNode = parentNode.clone({ + ShadowNodeFragment::propsPlaceholder(), + std::make_shared(children), ++ parentNode.getState() + }); + } + From 7e7b5adffc42147a8dcbdf2474d58f498430ed71 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Apr 2024 20:12:28 +0530 Subject: [PATCH 18/19] fix: remove web.js for lint errors --- .github/workflows/typecheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index f20939f9df0a..88d4d24a5723 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -30,7 +30,7 @@ jobs: # - git diff is used to see the files that were added on this branch # - gh pr view is used to list files touched by this PR. Git diff may give false positives if the branch isn't up-to-date with main # - wc counts the words in the result of the intersection - count_new_js=$(comm -1 -2 <(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/*.js' '__mocks__/*.js' '.storybook/*.js' 'assets/*.js' 'config/*.js' 'desktop/*.js' 'jest/*.js' 'scripts/*.js' 'tests/*.js' 'web/*.js' 'workflow_tests/*.js' '.github/libs/*.js' '.github/scripts/*.js') <(gh pr view ${{ github.event.pull_request.number }} --json files | jq -r '.files | map(.path) | .[]') | wc -l) + count_new_js=$(comm -1 -2 <(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/*.js' '__mocks__/*.js' '.storybook/*.js' 'assets/*.js' 'config/*.js' 'desktop/*.js' 'jest/*.js' 'scripts/*.js' 'tests/*.js' 'workflow_tests/*.js' '.github/libs/*.js' '.github/scripts/*.js') <(gh pr view ${{ github.event.pull_request.number }} --json files | jq -r '.files | map(.path) | .[]') | wc -l) if [ "$count_new_js" -gt "0" ]; then echo "ERROR: Found new JavaScript files in the project; use TypeScript instead." exit 1 From 5b1c240f69098f07fbbd7459235edcfc8f936111 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Wed, 24 Apr 2024 17:19:35 +0000 Subject: [PATCH 19/19] Update version to 1.4.65-4 --- 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 2264396ff9bf..641587e4f343 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 1001046503 - versionName "1.4.65-3" + versionCode 1001046504 + versionName "1.4.65-4" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 829ed3987bbd..5c489c59d7f4 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.65.3 + 1.4.65.4 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 51a3b8f830e8..ad64ce2e648a 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.65.3 + 1.4.65.4 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 362a79f18a3b..4c634c675ebb 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 1.4.65 CFBundleVersion - 1.4.65.3 + 1.4.65.4 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 1bc27e186d9f..b792015b1ac4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.65-3", + "version": "1.4.65-4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.65-3", + "version": "1.4.65-4", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index a7369c837c3b..1a8e0bd31852 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.65-3", + "version": "1.4.65-4", "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.",