Skip to content

Commit 813d740

Browse files
committed
Merge branch 'main' into @szymczak/revert-revert-Flatten-transaction-item-row-view-hierarchy-to-improve-performance
2 parents 38986a1 + 836eebd commit 813d740

13 files changed

Lines changed: 43 additions & 31 deletions

File tree

src/components/Navigation/SearchSidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function SearchSidebar({state}: SearchSidebarProps) {
5858
}, [lastSearchType, queryJSON, setLastSearchType, currentSearchResults]);
5959

6060
const isDataLoaded = isSearchDataLoaded(currentSearchResults?.data ? currentSearchResults : lastNonEmptySearchResults, queryJSON);
61-
const shouldShowLoadingState = route?.name === SCREENS.SEARCH.MONEY_REQUEST_REPORT ? false : !isOffline && !isDataLoaded;
61+
const shouldShowLoadingState = route?.name === SCREENS.SEARCH.MONEY_REQUEST_REPORT ? false : !isOffline && (!isDataLoaded || !!currentSearchResults?.search?.isLoading);
6262

6363
if (shouldUseNarrowLayout) {
6464
return null;

src/components/PushRowWithModal/PushRowModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ function PushRowModal({isVisible, selectedOption, onOptionChange, onClose, optio
7777
type={CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED}
7878
onModalHide={handleClose}
7979
shouldUseCustomBackdrop
80-
useNativeDriver
80+
shouldUseReanimatedModal
8181
>
8282
<ScreenWrapper
8383
includePaddingTop={false}

src/components/TimeModalPicker.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ function TimeModalPicker({value, errorText, label, onInputChange = () => {}}: Ti
5555
isVisible={isPickerVisible}
5656
onClose={hidePickerModal}
5757
onModalHide={hidePickerModal}
58-
hideModalContentWhileAnimating
59-
useNativeDriver
6058
enableEdgeToEdgeBottomSafeAreaPadding
59+
shouldUseReanimatedModal
6160
>
6261
<ScreenWrapper
6362
style={styles.pb0}

src/components/ValuePicker/ValueSelectorModal.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@ function ValueSelectorModal({
2323
isVisible={isVisible}
2424
onClose={() => onClose?.()}
2525
onModalHide={onClose}
26-
hideModalContentWhileAnimating
27-
useNativeDriver
2826
onBackdropPress={onBackdropPress}
2927
shouldHandleNavigationBack
3028
enableEdgeToEdgeBottomSafeAreaPadding
29+
shouldUseReanimatedModal
3130
>
3231
<ScreenWrapper
3332
includePaddingTop={false}

src/libs/actions/OnyxDerived/configs/reportAttributes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {generateIsEmptyReport, generateReportAttributes, generateReportName, isValidReport} from '@libs/ReportUtils';
22
import SidebarUtils from '@libs/SidebarUtils';
33
import createOnyxDerivedValueConfig from '@userActions/OnyxDerived/createOnyxDerivedValueConfig';
4-
import hasKeyTriggeredCompute from '@userActions/OnyxDerived/utils';
4+
import {hasKeyTriggeredCompute} from '@userActions/OnyxDerived/utils';
55
import CONST from '@src/CONST';
66
import ONYXKEYS from '@src/ONYXKEYS';
77
import type {ReportAttributesDerivedValue} from '@src/types/onyx';

src/libs/actions/OnyxDerived/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
1313
import ObjectUtils from '@src/types/utils/ObjectUtils';
1414
import ONYX_DERIVED_VALUES from './ONYX_DERIVED_VALUES';
1515
import type {DerivedValueContext} from './types';
16+
import {setDerivedValue} from './utils';
1617

1718
/**
1819
* Initialize all Onyx derived values, store them in Onyx, and setup listeners to update them when dependencies change.
@@ -42,7 +43,7 @@ function init() {
4243
// @ts-expect-error TypeScript can't confirm the shape of dependencyValues matches the compute function's parameters
4344
derivedValue = compute(dependencyValues, initialContext);
4445
dependencyValues = values;
45-
Onyx.set(key, derivedValue ?? null);
46+
setDerivedValue(key, derivedValue ?? null);
4647
});
4748
}
4849

@@ -84,7 +85,7 @@ function init() {
8485
const newDerivedValue = compute(dependencyValues, context);
8586
Log.info(`[OnyxDerived] updating value for ${key} in Onyx`);
8687
derivedValue = newDerivedValue;
87-
Onyx.set(key, derivedValue ?? null);
88+
setDerivedValue(key, derivedValue);
8889
};
8990

9091
for (let i = 0; i < dependencies.length; i++) {

src/libs/actions/OnyxDerived/utils.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import Onyx from 'react-native-onyx';
2+
import type {OnyxInput} from 'react-native-onyx';
13
import type {NonEmptyTuple} from 'type-fest';
2-
import type {OnyxKey} from '@src/ONYXKEYS';
4+
import type {OnyxDerivedKey, OnyxKey} from '@src/ONYXKEYS';
35
import type {DerivedValueContext} from './types';
46

57
/**
@@ -12,4 +14,16 @@ const hasKeyTriggeredCompute = <K extends OnyxKey, Deps extends NonEmptyTuple<Ex
1214
return Object.keys(sourceValues).some((sourceKey) => sourceKey === key);
1315
};
1416

15-
export default hasKeyTriggeredCompute;
17+
/**
18+
* Set a derived value in Onyx
19+
* As a performance optimization, it skips the cache check and null removal
20+
* For derived values, we fully control their lifecycle and recompute them when any dependency changes - so we don’t need a deep comparison
21+
* Also, null may be a legitimate result of the computation, so pruning it is unnecessary
22+
*/
23+
const setDerivedValue = (key: OnyxDerivedKey, value: OnyxInput<OnyxDerivedKey>) =>
24+
Onyx.set(key, value, {
25+
skipCacheCheck: true,
26+
skipNullRemoval: true,
27+
});
28+
29+
export {hasKeyTriggeredCompute, setDerivedValue};

src/pages/ScheduleCall/ScheduleCallConfirmationPage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {useRoute} from '@react-navigation/native';
2-
import {addMinutes, format} from 'date-fns';
2+
import {addMinutes} from 'date-fns';
33
import React, {useCallback, useMemo} from 'react';
44
import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView';
55
import Button from '@components/Button';
@@ -71,7 +71,7 @@ function ScheduleCallConfirmationPage() {
7171
if (!scheduleCallDraft?.timeSlot || !scheduleCallDraft.date) {
7272
return '';
7373
}
74-
const dateString = format(scheduleCallDraft.date, CONST.DATE.MONTH_DAY_YEAR_FORMAT);
74+
const dateString = DateUtils.formatInTimeZoneWithFallback(scheduleCallDraft.date, userTimezone, CONST.DATE.MONTH_DAY_YEAR_FORMAT);
7575
const timeString = `${DateUtils.formatInTimeZoneWithFallback(scheduleCallDraft?.timeSlot, userTimezone, CONST.DATE.LOCAL_TIME_FORMAT)} - ${DateUtils.formatInTimeZoneWithFallback(
7676
addMinutes(scheduleCallDraft?.timeSlot, 30),
7777
userTimezone,

src/pages/ScheduleCall/ScheduleCallPage.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {useFocusEffect, useRoute} from '@react-navigation/native';
2-
import {compareAsc, format, parse} from 'date-fns';
2+
import {compareAsc, parse} from 'date-fns';
33
import React, {useCallback, useEffect, useMemo} from 'react';
44
import {View} from 'react-native';
55
import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView';
@@ -187,7 +187,9 @@ function ScheduleCallPage() {
187187
<View style={[styles.ph5, styles.mb5]}>
188188
<Text style={[styles.mb5, styles.colorMuted]}>
189189
{translate('scheduledCall.book.slots')}
190-
<Text style={[styles.textStrong, styles.colorMuted]}>{format(scheduleCallDraft.date, CONST.DATE.MONTH_DAY_YEAR_FORMAT)}</Text>
190+
<Text style={[styles.textStrong, styles.colorMuted]}>
191+
{DateUtils.formatInTimeZoneWithFallback(scheduleCallDraft.date, userTimezone, CONST.DATE.MONTH_DAY_YEAR_FORMAT)}
192+
</Text>
191193
</Text>
192194
<View style={[styles.flexRow, styles.flexWrap, styles.justifyContentStart, styles.gap2]}>
193195
{timeSlotsForSelectedData.map((timeSlot: TimeSlot) => (

src/pages/Search/SearchPageNarrow.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type {SearchParams, SearchQueryJSON} from '@components/Search/types';
1717
import useHandleBackButton from '@hooks/useHandleBackButton';
1818
import useLocalize from '@hooks/useLocalize';
1919
import useNetwork from '@hooks/useNetwork';
20+
import useOnyx from '@hooks/useOnyx';
2021
import useResponsiveLayout from '@hooks/useResponsiveLayout';
2122
import useScrollEventEmitter from '@hooks/useScrollEventEmitter';
2223
import useStyleUtils from '@hooks/useStyleUtils';
@@ -29,6 +30,8 @@ import {isSearchDataLoaded} from '@libs/SearchUIUtils';
2930
import variables from '@styles/variables';
3031
import {searchInServer} from '@userActions/Report';
3132
import {search} from '@userActions/Search';
33+
import CONST from '@src/CONST';
34+
import ONYXKEYS from '@src/ONYXKEYS';
3235
import ROUTES from '@src/ROUTES';
3336
import type {SearchResults} from '@src/types/onyx';
3437

@@ -52,7 +55,8 @@ function SearchPageNarrow({queryJSON, headerButtonsOptions, searchResults, isMob
5255
const {clearSelectedTransactions} = useSearchContext();
5356
const [searchRouterListVisible, setSearchRouterListVisible] = useState(false);
5457
const {isOffline} = useNetwork();
55-
58+
const currentSearchResultsKey = queryJSON?.hash ?? CONST.DEFAULT_NUMBER_ID;
59+
const [currentSearchResults] = useOnyx(`${ONYXKEYS.COLLECTION.SNAPSHOT}${currentSearchResultsKey}`, {canBeMissing: true});
5660
// Controls the visibility of the educational tooltip based on user scrolling.
5761
// Hides the tooltip when the user is scrolling and displays it once scrolling stops.
5862
const triggerScrollEvent = useScrollEventEmitter();
@@ -136,7 +140,7 @@ function SearchPageNarrow({queryJSON, headerButtonsOptions, searchResults, isMob
136140
}
137141

138142
const isDataLoaded = isSearchDataLoaded(searchResults, queryJSON);
139-
const shouldShowLoadingState = !isOffline && !isDataLoaded;
143+
const shouldShowLoadingState = !isOffline && (!isDataLoaded || !!currentSearchResults?.search?.isLoading);
140144

141145
return (
142146
<ScreenWrapper

0 commit comments

Comments
 (0)