Skip to content

Commit 049838b

Browse files
committedMay 23, 2024··
Merge branch 'main' into fix/35906-blank-screen-when-open-chat
2 parents 01509e2 + aa9bbcf commit 049838b

28 files changed

+140
-107
lines changed
 

‎android/app/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ android {
9898
minSdkVersion rootProject.ext.minSdkVersion
9999
targetSdkVersion rootProject.ext.targetSdkVersion
100100
multiDexEnabled rootProject.ext.multiDexEnabled
101-
versionCode 1001047404
102-
versionName "1.4.74-4"
101+
versionCode 1001047500
102+
versionName "1.4.75-0"
103103
// Supported language variants must be declared here to avoid from being removed during the compilation.
104104
// This also helps us to not include unnecessary language variants in the APK.
105105
resConfigs "en", "es"

‎docs/articles/expensify-classic/workspaces/reports/Currency.md

-31
This file was deleted.

‎ios/NewExpensify/Info.plist

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<key>CFBundlePackageType</key>
2020
<string>APPL</string>
2121
<key>CFBundleShortVersionString</key>
22-
<string>1.4.74</string>
22+
<string>1.4.75</string>
2323
<key>CFBundleSignature</key>
2424
<string>????</string>
2525
<key>CFBundleURLTypes</key>
@@ -40,7 +40,7 @@
4040
</dict>
4141
</array>
4242
<key>CFBundleVersion</key>
43-
<string>1.4.74.4</string>
43+
<string>1.4.75.0</string>
4444
<key>FullStory</key>
4545
<dict>
4646
<key>OrgId</key>

‎ios/NewExpensifyTests/Info.plist

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
<key>CFBundlePackageType</key>
1616
<string>BNDL</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>1.4.74</string>
18+
<string>1.4.75</string>
1919
<key>CFBundleSignature</key>
2020
<string>????</string>
2121
<key>CFBundleVersion</key>
22-
<string>1.4.74.4</string>
22+
<string>1.4.75.0</string>
2323
</dict>
2424
</plist>

‎ios/NotificationServiceExtension/Info.plist

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
<key>CFBundleName</key>
1212
<string>$(PRODUCT_NAME)</string>
1313
<key>CFBundleShortVersionString</key>
14-
<string>1.4.74</string>
14+
<string>1.4.75</string>
1515
<key>CFBundleVersion</key>
16-
<string>1.4.74.4</string>
16+
<string>1.4.75.0</string>
1717
<key>NSExtension</key>
1818
<dict>
1919
<key>NSExtensionPointIdentifier</key>

‎package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "new.expensify",
3-
"version": "1.4.74-4",
3+
"version": "1.4.75-0",
44
"author": "Expensify, Inc.",
55
"homepage": "https://new.expensify.com",
66
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",

‎src/CONST.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4767,6 +4767,7 @@ const CONST = {
47674767
DISTANCE: 'distance',
47684768
},
47694769

4770+
SEARCH_RESULTS_PAGE_SIZE: 50,
47704771
SEARCH_BOTTOM_TAB_URL: '/Search_Bottom_Tab',
47714772

47724773
SEARCH_DATA_TYPES: {

‎src/components/MoneyRequestConfirmationList.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,7 @@ function MoneyRequestConfirmationList({
12331233
shouldPreventDefaultFocusOnSelectRow
12341234
footerContent={footerContent}
12351235
listFooterContent={listFooterContent}
1236+
containerStyle={[styles.flexBasisAuto]}
12361237
/>
12371238
);
12381239
}

‎src/components/MoneyRequestHeaderStatusBar.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ type MoneyRequestHeaderStatusBarProps = {
1717

1818
/** Whether we should use the danger theme color */
1919
danger?: boolean;
20+
21+
/** Whether we style flex grow */
22+
shouldStyleFlexGrow?: boolean;
2023
};
2124

22-
function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom, danger = false}: MoneyRequestHeaderStatusBarProps) {
25+
function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom, danger = false, shouldStyleFlexGrow = true}: MoneyRequestHeaderStatusBarProps) {
2326
const styles = useThemeStyles();
2427
const borderBottomStyle = shouldShowBorderBottom ? styles.borderBottom : {};
2528
return (
@@ -28,7 +31,7 @@ function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom
2831
styles.dFlex,
2932
styles.flexRow,
3033
styles.alignItemsCenter,
31-
styles.flexGrow1,
34+
shouldStyleFlexGrow && styles.flexGrow1,
3235
styles.overflowHidden,
3336
styles.ph5,
3437
styles.pb3,

‎src/components/ReportActionItem/ReportPreview.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ function ReportPreview({
142142
const lastThreeTransactionsWithReceipts = transactionsWithReceipts.slice(-3);
143143
const lastThreeReceipts = lastThreeTransactionsWithReceipts.map((transaction) => ReceiptUtils.getThumbnailAndImageURIs(transaction));
144144
const showRTERViolationMessage =
145-
numberOfRequests === 1 && TransactionUtils.hasPendingUI(allTransactions[0], TransactionUtils.getTransactionViolations(allTransactions[0].transactionID, transactionViolations));
145+
numberOfRequests === 1 &&
146+
TransactionUtils.hasPendingUI(allTransactions[0], TransactionUtils.getTransactionViolations(allTransactions[0]?.transactionID ?? '', transactionViolations));
146147

147148
let formattedMerchant = numberOfRequests === 1 ? TransactionUtils.getMerchant(allTransactions[0]) : null;
148149
const formattedDescription = numberOfRequests === 1 ? TransactionUtils.getDescription(allTransactions[0]) : null;

‎src/components/Search.tsx

+24-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as SearchUtils from '@libs/SearchUtils';
99
import Navigation from '@navigation/Navigation';
1010
import EmptySearchView from '@pages/Search/EmptySearchView';
1111
import useCustomBackHandler from '@pages/Search/useCustomBackHandler';
12+
import CONST from '@src/CONST';
1213
import ONYXKEYS from '@src/ONYXKEYS';
1314
import ROUTES from '@src/ROUTES';
1415
import {isEmptyObject} from '@src/types/utils/EmptyObject';
@@ -35,14 +36,15 @@ function Search({query, policyIDs}: SearchProps) {
3536
return;
3637
}
3738

38-
SearchActions.search(hash, query, policyIDs);
39+
SearchActions.search(hash, query, 0, policyIDs);
3940
// eslint-disable-next-line react-hooks/exhaustive-deps
4041
}, [hash, isOffline]);
4142

42-
const isLoading = (!isOffline && isLoadingOnyxValue(searchResultsMeta)) || searchResults?.data === undefined;
43-
const shouldShowEmptyState = !isLoading && isEmptyObject(searchResults?.data);
43+
const isLoadingInitialItems = (!isOffline && isLoadingOnyxValue(searchResultsMeta)) || searchResults?.data === undefined;
44+
const isLoadingMoreItems = !isLoadingInitialItems && searchResults?.search?.isLoading;
45+
const shouldShowEmptyState = !isLoadingInitialItems && isEmptyObject(searchResults?.data);
4446

45-
if (isLoading) {
47+
if (isLoadingInitialItems) {
4648
return <TableListItemSkeleton shouldAnimate />;
4749
}
4850

@@ -58,6 +60,14 @@ function Search({query, policyIDs}: SearchProps) {
5860
Navigation.navigate(ROUTES.SEARCH_REPORT.getRoute(query, reportID));
5961
};
6062

63+
const fetchMoreResults = () => {
64+
if (!searchResults?.search?.hasMoreResults || isLoadingInitialItems || isLoadingMoreItems) {
65+
return;
66+
}
67+
const currentOffset = searchResults?.search?.offset ?? 0;
68+
SearchActions.search(hash, query, currentOffset + CONST.SEARCH_RESULTS_PAGE_SIZE);
69+
};
70+
6171
const type = SearchUtils.getSearchType(searchResults?.search);
6272

6373
if (type === undefined) {
@@ -80,6 +90,16 @@ function Search({query, policyIDs}: SearchProps) {
8090
listHeaderWrapperStyle={[styles.ph9, styles.pv3, styles.pb5]}
8191
containerStyle={[styles.pv0]}
8292
showScrollIndicator={false}
93+
onEndReachedThreshold={0.75}
94+
onEndReached={fetchMoreResults}
95+
listFooterContent={
96+
isLoadingMoreItems ? (
97+
<TableListItemSkeleton
98+
shouldAnimate
99+
fixedNumItems={5}
100+
/>
101+
) : undefined
102+
}
83103
/>
84104
);
85105
}

‎src/components/SelectionList/BaseSelectionList.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ function BaseSelectionList<TItem extends ListItem>(
7676
sectionTitleStyles,
7777
textInputAutoFocus = true,
7878
shouldTextInputInterceptSwipe = false,
79+
onEndReached = () => {},
80+
onEndReachedThreshold,
7981
}: BaseSelectionListProps<TItem>,
8082
ref: ForwardedRef<SelectionListHandle>,
8183
) {
@@ -618,6 +620,8 @@ function BaseSelectionList<TItem extends ListItem>(
618620
onLayout={onSectionListLayout}
619621
style={(!maxToRenderPerBatch || (shouldHideListOnInitialRender && isInitialSectionListRender)) && styles.opacity0}
620622
ListFooterComponent={listFooterContent ?? ShowMoreButtonInstance}
623+
onEndReached={onEndReached}
624+
onEndReachedThreshold={onEndReachedThreshold}
621625
/>
622626
{children}
623627
</>

‎src/components/SelectionList/types.ts

+11
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,17 @@ type BaseSelectionListProps<TItem extends ListItem> = Partial<ChildrenProps> & {
365365
* When false, the list will render immediately and scroll to the bottom which works great for small lists.
366366
*/
367367
shouldHideListOnInitialRender?: boolean;
368+
369+
/** Called once when the scroll position gets within onEndReachedThreshold of the rendered content. */
370+
onEndReached?: () => void;
371+
372+
/**
373+
* How far from the end (in units of visible length of the list) the bottom edge of the
374+
* list must be from the end of the content to trigger the `onEndReached` callback.
375+
* Thus a value of 0.5 will trigger `onEndReached` when the end of the content is
376+
* within half the visible length of the list.
377+
*/
378+
onEndReachedThreshold?: number;
368379
} & TRightHandSideComponent<TItem>;
369380

370381
type SelectionListHandle = {

‎src/components/Skeletons/ItemListSkeletonView.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ import CONST from '@src/CONST';
88
type ListItemSkeletonProps = {
99
shouldAnimate?: boolean;
1010
renderSkeletonItem: (args: {itemIndex: number}) => React.ReactNode;
11+
fixedNumItems?: number;
1112
};
1213

13-
function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem}: ListItemSkeletonProps) {
14+
function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem, fixedNumItems}: ListItemSkeletonProps) {
1415
const theme = useTheme();
1516
const themeStyles = useThemeStyles();
1617

17-
const [numItems, setNumItems] = useState(0);
18+
const [numItems, setNumItems] = useState(fixedNumItems ?? 0);
1819
const skeletonViewItems = useMemo(() => {
1920
const items = [];
2021
for (let i = 0; i < numItems; i++) {
@@ -38,6 +39,10 @@ function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem}: ListIt
3839
<View
3940
style={[themeStyles.flex1, themeStyles.overflowHidden]}
4041
onLayout={(event) => {
42+
if (fixedNumItems) {
43+
return;
44+
}
45+
4146
const newNumItems = Math.ceil(event.nativeEvent.layout.height / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT);
4247
if (newNumItems === numItems) {
4348
return;

‎src/components/Skeletons/TableListItemSkeleton.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@ import ItemListSkeletonView from './ItemListSkeletonView';
44

55
type TableListItemSkeletonProps = {
66
shouldAnimate?: boolean;
7+
fixedNumItems?: number;
78
};
89

910
const barHeight = '10';
1011
const shortBarWidth = '40';
1112
const longBarWidth = '120';
1213

13-
function TableListItemSkeleton({shouldAnimate = true}: TableListItemSkeletonProps) {
14+
function TableListItemSkeleton({shouldAnimate = true, fixedNumItems}: TableListItemSkeletonProps) {
1415
return (
1516
<ItemListSkeletonView
1617
shouldAnimate={shouldAnimate}
18+
fixedNumItems={fixedNumItems}
1719
renderSkeletonItem={() => (
1820
<>
1921
<Rect

‎src/libs/API/parameters/Search.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ type SearchParams = {
22
query: string;
33
policyIDs?: string;
44
hash: number;
5+
offset: number;
56
};
67

78
export default SearchParams;

‎src/libs/actions/Report.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3136,7 +3136,7 @@ function completeOnboarding(
31363136
currentTask,
31373137
taskCreatedAction,
31383138
taskReportAction,
3139-
taskDescription,
3139+
taskDescription: currentTask.description,
31403140
completedTaskReportAction,
31413141
};
31423142
});
@@ -3151,7 +3151,7 @@ function completeOnboarding(
31513151
createdTaskReportActionID: taskCreatedAction.reportActionID,
31523152
completedTaskReportActionID: completedTaskReportAction?.reportActionID ?? undefined,
31533153
title: currentTask.reportName ?? '',
3154-
description: taskDescription,
3154+
description: taskDescription ?? '',
31553155
}));
31563156

31573157
const tasksForOptimisticData = tasksData.reduce<OnyxUpdate[]>((acc, {currentTask, taskCreatedAction, taskReportAction, taskDescription, completedTaskReportAction}) => {

‎src/libs/actions/Search.ts

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,35 @@
1+
import Onyx from 'react-native-onyx';
2+
import type {OnyxUpdate} from 'react-native-onyx';
13
import * as API from '@libs/API';
24
import {READ_COMMANDS} from '@libs/API/types';
5+
import ONYXKEYS from '@src/ONYXKEYS';
36

4-
function search(hash: number, query: string, policyIDs?: string) {
5-
API.read(READ_COMMANDS.SEARCH, {hash, query, policyIDs});
7+
function search(hash: number, query: string, offset = 0, policyIDs?: string) {
8+
const optimisticData: OnyxUpdate[] = [
9+
{
10+
onyxMethod: Onyx.METHOD.MERGE,
11+
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`,
12+
value: {
13+
search: {
14+
isLoading: true,
15+
},
16+
},
17+
},
18+
];
19+
20+
const finallyData: OnyxUpdate[] = [
21+
{
22+
onyxMethod: Onyx.METHOD.MERGE,
23+
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`,
24+
value: {
25+
search: {
26+
isLoading: false,
27+
},
28+
},
29+
},
30+
];
31+
32+
API.read(READ_COMMANDS.SEARCH, {hash, query, offset, policyIDs}, {optimisticData, finallyData});
633
}
734

835
export {

‎src/pages/iou/SplitBillDetailsPage.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ function SplitBillDetailsPage({personalDetails, report, route, reportActions, tr
103103
title={translate('iou.receiptStatusTitle')}
104104
description={translate('iou.receiptStatusText')}
105105
shouldShowBorderBottom
106+
shouldStyleFlexGrow={false}
106107
/>
107108
)}
108109
{!!participants.length && (

‎src/pages/iou/request/step/IOURequestStepMerchant.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ function IOURequestStepMerchant({
9797
navigateBack();
9898
return;
9999
}
100-
IOU.setMoneyRequestMerchant(transactionID, newMerchant ?? '', !isEditing);
100+
// When creating/editing an expense, newMerchant can be blank so we fall back on PARTIAL_TRANSACTION_MERCHANT
101+
IOU.setMoneyRequestMerchant(transactionID, newMerchant || CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, !isEditing);
101102
if (isEditing) {
102-
// When creating a new expense, newMerchant can be blank so we fall back on PARTIAL_TRANSACTION_MERCHANT
103103
IOU.updateMoneyRequestMerchant(transactionID, reportID, newMerchant || CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, policy, policyTags, policyCategories);
104104
}
105105
navigateBack();

0 commit comments

Comments
 (0)
Please sign in to comment.