diff --git a/patches/react-native-reanimated+3.16.4+004+fix-transform-animation-gitter.patch b/patches/react-native-reanimated+3.16.4+004+fix-transform-animation-gitter.patch new file mode 100644 index 000000000000..9e7657c2dda4 --- /dev/null +++ b/patches/react-native-reanimated+3.16.4+004+fix-transform-animation-gitter.patch @@ -0,0 +1,20 @@ +diff --git a/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/NativeReanimatedModule.cpp b/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/NativeReanimatedModule.cpp +index 673ebd1..08d65fe 100644 +--- a/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/NativeReanimatedModule.cpp ++++ b/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/NativeReanimatedModule.cpp +@@ -710,6 +710,15 @@ void NativeReanimatedModule::performOperations() { + jsPropsUpdater.call(rt, viewTag, nonAnimatableProps); + } + ++ if (propsRegistry_->shouldReanimatedSkipCommit()) { ++ // It may happen that `performOperations` is called on the UI thread ++ // while React Native tries to commit a new tree on the JS thread. ++ // In this case, we should skip the commit here and let React Native do ++ // it. The commit will include the current values from PropsRegistry which ++ // will be applied in ReanimatedCommitHook. ++ return; ++ } ++ + bool hasLayoutUpdates = false; + for (const auto &[shadowNode, props] : copiedOperationsQueue) { + if (isThereAnyLayoutProp(rt, props->asObject(rt))) { diff --git a/src/components/Search/SearchPageHeader.tsx b/src/components/Search/SearchPageHeader/SearchPageHeader.tsx similarity index 76% rename from src/components/Search/SearchPageHeader.tsx rename to src/components/Search/SearchPageHeader/SearchPageHeader.tsx index a36368293cb2..8072db12f1c6 100644 --- a/src/components/Search/SearchPageHeader.tsx +++ b/src/components/Search/SearchPageHeader/SearchPageHeader.tsx @@ -1,4 +1,3 @@ -import {useFocusEffect} from '@react-navigation/native'; import React, {useCallback, useMemo, useState} from 'react'; import {InteractionManager, View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; @@ -10,6 +9,8 @@ import DecisionModal from '@components/DecisionModal'; import * as Expensicons from '@components/Icon/Expensicons'; import {usePersonalDetails} from '@components/OnyxProvider'; import {useProductTrainingContext} from '@components/ProductTrainingContext'; +import {useSearchContext} from '@components/Search/SearchContext'; +import type {PaymentData, SearchQueryJSON} from '@components/Search/types'; import EducationalTooltip from '@components/Tooltip/EducationalTooltip'; import useActiveWorkspace from '@hooks/useActiveWorkspace'; import useLocalize from '@hooks/useLocalize'; @@ -28,22 +29,20 @@ import { import {mergeCardListWithWorkspaceFeeds} from '@libs/CardUtils'; import Navigation from '@libs/Navigation/Navigation'; import {getAllTaxRates, hasVBBA} from '@libs/PolicyUtils'; -import {buildFilterFormValuesFromQuery, isCannedSearchQuery} from '@libs/SearchQueryUtils'; +import {buildFilterFormValuesFromQuery} from '@libs/SearchQueryUtils'; import SearchSelectedNarrow from '@pages/Search/SearchSelectedNarrow'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; -import {useSearchContext} from './SearchContext'; import SearchPageHeaderInput from './SearchPageHeaderInput'; -import type {PaymentData, SearchQueryJSON} from './types'; -type SearchPageHeaderProps = {queryJSON: SearchQueryJSON}; +type SearchPageHeaderProps = {queryJSON: SearchQueryJSON; searchRouterListVisible?: boolean; onSearchRouterFocus?: () => void}; type SearchHeaderOptionValue = DeepValueOf | undefined; -function SearchPageHeader({queryJSON}: SearchPageHeaderProps) { +function SearchPageHeader({queryJSON, searchRouterListVisible, onSearchRouterFocus}: SearchPageHeaderProps) { const {translate} = useLocalize(); const theme = useTheme(); const styles = useThemeStyles(); @@ -68,24 +67,12 @@ function SearchPageHeader({queryJSON}: SearchPageHeaderProps) { const [isOfflineModalVisible, setIsOfflineModalVisible] = useState(false); const [isDownloadErrorModalVisible, setIsDownloadErrorModalVisible] = useState(false); - const [isScreenFocused, setIsScreenFocused] = useState(false); - const {renderProductTrainingTooltip, shouldShowProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext( CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SEARCH_FILTER_BUTTON_TOOLTIP, - isScreenFocused, ); const {status, hash} = queryJSON; - useFocusEffect( - useCallback(() => { - setIsScreenFocused(true); - return () => { - setIsScreenFocused(false); - }; - }, []), - ); - const selectedTransactionsKeys = Object.keys(selectedTransactions ?? {}); const handleDeleteExpenses = () => { @@ -315,94 +302,106 @@ function SearchPageHeader({queryJSON}: SearchPageHeaderProps) { styles.textWrap, ]); - if (shouldUseNarrowLayout) { - if (selectionMode?.isEnabled) { - return ( - - - { - setIsDeleteExpensesConfirmModalVisible(false); - }} - title={translate('iou.deleteExpense', {count: selectedTransactionsKeys.length})} - prompt={translate('iou.deleteConfirmation', {count: selectedTransactionsKeys.length})} - confirmText={translate('common.delete')} - cancelText={translate('common.cancel')} - danger - /> - setIsOfflineModalVisible(false)} - secondOptionText={translate('common.buttonConfirm')} - isVisible={isOfflineModalVisible} - onClose={() => setIsOfflineModalVisible(false)} - /> - setIsDownloadErrorModalVisible(false)} - secondOptionText={translate('common.buttonConfirm')} - isVisible={isDownloadErrorModalVisible} - onClose={() => setIsDownloadErrorModalVisible(false)} - /> - - ); - } - return null; - } - - const onFiltersButtonPress = () => { + const onFiltersButtonPress = useCallback(() => { hideProductTrainingTooltip(); const filterFormValues = buildFilterFormValuesFromQuery(queryJSON, policyCategories, policyTagsLists, currencyList, personalDetails, allCards, reports, taxRates); updateAdvancedFilters(filterFormValues); Navigation.navigate(ROUTES.SEARCH_ADVANCED_FILTERS); - }; + }, [allCards, currencyList, hideProductTrainingTooltip, personalDetails, policyCategories, policyTagsLists, queryJSON, reports, taxRates]); + + const InputRightComponent = useMemo(() => { + return headerButtonsOptions.length > 0 ? ( + null} + shouldAlwaysShowDropdownMenu + buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} + customText={translate('workspace.common.selected', {count: selectedTransactionsKeys.length})} + options={headerButtonsOptions} + isSplitButton={false} + shouldUseStyleUtilityForAnchorPosition + /> + ) : ( + +