Skip to content

Commit

Permalink
Merge branch 'main' into update-rn-live-markdown-0176
Browse files Browse the repository at this point in the history
  • Loading branch information
fabOnReact committed May 23, 2024
2 parents 9713061 + aa9bbcf commit ef1e2f6
Show file tree
Hide file tree
Showing 91 changed files with 2,214 additions and 2,331 deletions.
2 changes: 1 addition & 1 deletion .github/libs/sanitizeStringForJSONParse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const replacer = (str: string): string =>
* Solution partly taken from SO user Gabriel Rodríguez Flores 🙇
* https://stackoverflow.com/questions/52789718/how-to-remove-special-characters-before-json-parse-while-file-reading
*/
const sanitizeStringForJSONParse = (inputString: string): string => {
const sanitizeStringForJSONParse = (inputString: string | number | boolean | null | undefined): string => {
if (typeof inputString !== 'string') {
throw new TypeError('Input must me of type String');
}
Expand Down
4 changes: 1 addition & 3 deletions __mocks__/@react-navigation/native/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import {useIsFocused as realUseIsFocused, useTheme as realUseTheme} from '@react
// We only want these mocked for storybook, not jest
const useIsFocused: typeof realUseIsFocused = process.env.NODE_ENV === 'test' ? realUseIsFocused : () => true;

// @ts-expect-error as we're mocking this function
const useTheme: typeof realUseTheme = process.env.NODE_ENV === 'test' ? realUseTheme : () => ({});
const useTheme = process.env.NODE_ENV === 'test' ? realUseTheme : () => ({});

export * from '@react-navigation/core';
export * from '@react-navigation/native';
export {useIsFocused, useTheme};
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001047401
versionName "1.4.74-1"
versionCode 1001047500
versionName "1.4.75-0"
// 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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ After adopting the new Expensify Card, domain admins can issue virtual cards to

**To assign a virtual card:**

1. Head to **Settings** > **Domains** > [**Company Cards**](https://www.expensify.com/domain_companycards).
2. Click the **Issue Virtual Cards** button.
3. Enter a card name (i.e., "Google Ads").
4. Select a domain member to assign the card to.
5. Enter a card limit.
6. Select a **Limit Type** of _Fixed_ or _Monthly_.
7. Click **Issue Card**.
Head to **Settings** > **Domains** > [**Company Cards**](https://www.expensify.com/domain_companycards) and click the **Issue Virtual Cards** button. From there:

1. Enter a card name (i.e., "Google Ads").
2. Select a domain member to assign the card to.
3. Enter a card limit.
4. Select a **Limit Type** of _Fixed_ or _Monthly_.
5. Click **Issue Card**.

![The Issue Virtual Cards modal is open in the middle of the screen. There are four options to set; Card Name, Assignee, Card Limit, and Limit type. A cancel (left) and save (right) button are at the bottom right of the modal.]({{site.url}}/assets/images/AdminissuedVirtualCards.png){:width="100%"}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ The sky's the limit for this referral program! Your referral can be anyone - a f

1. There are a bunch of different ways to refer someone to New Expensify:
- Start a chat
- Request money
- Send money
- Split a bill
- Submit an expense to them
- Split an expense with them
- Pay someone (them)
- Assign them a task
- @ mention them
- Invite them to a room
Expand Down
31 changes: 0 additions & 31 deletions docs/articles/expensify-classic/workspaces/reports/Currency.md

This file was deleted.

1 change: 1 addition & 0 deletions docs/redirects.csv
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,4 @@ https://help.expensify.com/articles/new-expensify/getting-started/Free-plan-upgr
https://help.expensify.com/articles/new-expensify/bank-accounts-and-payments/Connect-a-Bank-Account,https://help.expensify.com/new-expensify/hubs/expenses/Connect-a-Bank-Account
https://help.expensify.com/articles/new-expensify/settings/Profile,https://help.expensify.com/new-expensify/hubs/settings/
https://help.expensify.com/articles/new-expensify/expenses/Referral-Program.html,https://help.expensify.com/articles/expensify-classic/expensify-partner-program/Referral-Program
https://help.expensify.com/articles/expensify-classic/workspaces/reports/Currency,https://help.expensify.com/articles/expensify-classic/workspaces/Currency
4 changes: 2 additions & 2 deletions ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.4.74</string>
<string>1.4.75</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.4.74.1</string>
<string>1.4.75.0</string>
<key>FullStory</key>
<dict>
<key>OrgId</key>
Expand Down
4 changes: 2 additions & 2 deletions ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.4.74</string>
<string>1.4.75</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.4.74.1</string>
<string>1.4.75.0</string>
</dict>
</plist>
4 changes: 2 additions & 2 deletions ios/NotificationServiceExtension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundleShortVersionString</key>
<string>1.4.74</string>
<string>1.4.75</string>
<key>CFBundleVersion</key>
<string>1.4.74.1</string>
<string>1.4.75.0</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "1.4.74-1",
"version": "1.4.75-0",
"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.",
Expand Down
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4767,6 +4767,7 @@ const CONST = {
DISTANCE: 'distance',
},

SEARCH_RESULTS_PAGE_SIZE: 50,
SEARCH_BOTTOM_TAB_URL: '/Search_Bottom_Tab',

SEARCH_DATA_TYPES: {
Expand Down
4 changes: 3 additions & 1 deletion src/Expensify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ type ExpensifyOnyxProps = {

type ExpensifyProps = ExpensifyOnyxProps;

const SplashScreenHiddenContext = React.createContext({});
type SplashScreenHiddenContextType = {isSplashHidden?: boolean};

const SplashScreenHiddenContext = React.createContext<SplashScreenHiddenContextType>({});

function Expensify({
isCheckingPublicRoom = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ function BaseAnchorForAttachmentsOnly({style, source = '', displayName = '', dow
}}
onPressIn={onPressIn}
onPressOut={onPressOut}
// @ts-expect-error TODO: Remove this once ShowContextMenuContext (https://github.com/Expensify/App/issues/24980) is migrated to TypeScript.
onLongPress={(event) => showContextMenuForReport(event, anchor, report.reportID, action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))}
onLongPress={(event) => showContextMenuForReport(event, anchor, report?.reportID ?? '', action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))}
shouldUseHapticsOnLongPress
accessibilityLabel={displayName}
role={CONST.ROLE.BUTTON}
Expand Down
1 change: 1 addition & 0 deletions src/components/MoneyRequestAmountInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ function MoneyRequestAmountInput(
touchableInputWrapperStyle={props.touchableInputWrapperStyle}
maxLength={maxLength}
hideFocusedState={hideFocusedState}
onMouseDown={(event) => event.stopPropagation()}
/>
);
}
Expand Down
1 change: 1 addition & 0 deletions src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1233,6 +1233,7 @@ function MoneyRequestConfirmationList({
shouldPreventDefaultFocusOnSelectRow
footerContent={footerContent}
listFooterContent={listFooterContent}
containerStyle={[styles.flexBasisAuto]}
/>
);
}
Expand Down
7 changes: 5 additions & 2 deletions src/components/MoneyRequestHeaderStatusBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ type MoneyRequestHeaderStatusBarProps = {

/** Whether we should use the danger theme color */
danger?: boolean;

/** Whether we style flex grow */
shouldStyleFlexGrow?: boolean;
};

function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom, danger = false}: MoneyRequestHeaderStatusBarProps) {
function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom, danger = false, shouldStyleFlexGrow = true}: MoneyRequestHeaderStatusBarProps) {
const styles = useThemeStyles();
const borderBottomStyle = shouldShowBorderBottom ? styles.borderBottom : {};
return (
Expand All @@ -28,7 +31,7 @@ function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom
styles.dFlex,
styles.flexRow,
styles.alignItemsCenter,
styles.flexGrow1,
shouldStyleFlexGrow && styles.flexGrow1,
styles.overflowHidden,
styles.ph5,
styles.pb3,
Expand Down
2 changes: 1 addition & 1 deletion src/components/OptionListContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function OptionsListContextProvider({reports, children}: OptionsListProviderProp
return;
}

const newReports = OptionsListUtils.createOptionList({}, reports).reports;
const newReports = OptionsListUtils.createOptionList(personalDetails, reports).reports;

setOptions((prevOptions) => {
const newOptions = {...prevOptions};
Expand Down
1 change: 0 additions & 1 deletion src/components/PDFThumbnail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// @ts-expect-error - This line imports a module from 'pdfjs-dist' package which lacks TypeScript typings.
import pdfWorkerSource from 'pdfjs-dist/legacy/build/pdf.worker';
import React, {useMemo} from 'react';
import {View} from 'react-native';
Expand Down
3 changes: 2 additions & 1 deletion src/components/ReportActionItem/ReportPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ function ReportPreview({
const lastThreeTransactionsWithReceipts = transactionsWithReceipts.slice(-3);
const lastThreeReceipts = lastThreeTransactionsWithReceipts.map((transaction) => ReceiptUtils.getThumbnailAndImageURIs(transaction));
const showRTERViolationMessage =
numberOfRequests === 1 && TransactionUtils.hasPendingUI(allTransactions[0], TransactionUtils.getTransactionViolations(allTransactions[0].transactionID, transactionViolations));
numberOfRequests === 1 &&
TransactionUtils.hasPendingUI(allTransactions[0], TransactionUtils.getTransactionViolations(allTransactions[0]?.transactionID ?? '', transactionViolations));

let formattedMerchant = numberOfRequests === 1 ? TransactionUtils.getMerchant(allTransactions[0]) : null;
const formattedDescription = numberOfRequests === 1 ? TransactionUtils.getDescription(allTransactions[0]) : null;
Expand Down
28 changes: 24 additions & 4 deletions src/components/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as SearchUtils from '@libs/SearchUtils';
import Navigation from '@navigation/Navigation';
import EmptySearchView from '@pages/Search/EmptySearchView';
import useCustomBackHandler from '@pages/Search/useCustomBackHandler';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
Expand All @@ -35,14 +36,15 @@ function Search({query, policyIDs}: SearchProps) {
return;
}

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

const isLoading = (!isOffline && isLoadingOnyxValue(searchResultsMeta)) || searchResults?.data === undefined;
const shouldShowEmptyState = !isLoading && isEmptyObject(searchResults?.data);
const isLoadingInitialItems = (!isOffline && isLoadingOnyxValue(searchResultsMeta)) || searchResults?.data === undefined;
const isLoadingMoreItems = !isLoadingInitialItems && searchResults?.search?.isLoading;
const shouldShowEmptyState = !isLoadingInitialItems && isEmptyObject(searchResults?.data);

if (isLoading) {
if (isLoadingInitialItems) {
return <TableListItemSkeleton shouldAnimate />;
}

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

const fetchMoreResults = () => {
if (!searchResults?.search?.hasMoreResults || isLoadingInitialItems || isLoadingMoreItems) {
return;
}
const currentOffset = searchResults?.search?.offset ?? 0;
SearchActions.search(hash, query, currentOffset + CONST.SEARCH_RESULTS_PAGE_SIZE);
};

const type = SearchUtils.getSearchType(searchResults?.search);

if (type === undefined) {
Expand All @@ -80,6 +90,16 @@ function Search({query, policyIDs}: SearchProps) {
listHeaderWrapperStyle={[styles.ph9, styles.pv3, styles.pb5]}
containerStyle={[styles.pv0]}
showScrollIndicator={false}
onEndReachedThreshold={0.75}
onEndReached={fetchMoreResults}
listFooterContent={
isLoadingMoreItems ? (
<TableListItemSkeleton
shouldAnimate
fixedNumItems={5}
/>
) : undefined
}
/>
);
}
Expand Down
4 changes: 4 additions & 0 deletions src/components/SelectionList/BaseSelectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ function BaseSelectionList<TItem extends ListItem>(
sectionTitleStyles,
textInputAutoFocus = true,
shouldTextInputInterceptSwipe = false,
onEndReached = () => {},
onEndReachedThreshold,
}: BaseSelectionListProps<TItem>,
ref: ForwardedRef<SelectionListHandle>,
) {
Expand Down Expand Up @@ -618,6 +620,8 @@ function BaseSelectionList<TItem extends ListItem>(
onLayout={onSectionListLayout}
style={(!maxToRenderPerBatch || (shouldHideListOnInitialRender && isInitialSectionListRender)) && styles.opacity0}
ListFooterComponent={listFooterContent ?? ShowMoreButtonInstance}
onEndReached={onEndReached}
onEndReachedThreshold={onEndReachedThreshold}
/>
{children}
</>
Expand Down
11 changes: 11 additions & 0 deletions src/components/SelectionList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,17 @@ type BaseSelectionListProps<TItem extends ListItem> = Partial<ChildrenProps> & {
* When false, the list will render immediately and scroll to the bottom which works great for small lists.
*/
shouldHideListOnInitialRender?: boolean;

/** Called once when the scroll position gets within onEndReachedThreshold of the rendered content. */
onEndReached?: () => void;

/**
* How far from the end (in units of visible length of the list) the bottom edge of the
* list must be from the end of the content to trigger the `onEndReached` callback.
* Thus a value of 0.5 will trigger `onEndReached` when the end of the content is
* within half the visible length of the list.
*/
onEndReachedThreshold?: number;
} & TRightHandSideComponent<TItem>;

type SelectionListHandle = {
Expand Down
9 changes: 7 additions & 2 deletions src/components/Skeletons/ItemListSkeletonView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import CONST from '@src/CONST';
type ListItemSkeletonProps = {
shouldAnimate?: boolean;
renderSkeletonItem: (args: {itemIndex: number}) => React.ReactNode;
fixedNumItems?: number;
};

function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem}: ListItemSkeletonProps) {
function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem, fixedNumItems}: ListItemSkeletonProps) {
const theme = useTheme();
const themeStyles = useThemeStyles();

const [numItems, setNumItems] = useState(0);
const [numItems, setNumItems] = useState(fixedNumItems ?? 0);
const skeletonViewItems = useMemo(() => {
const items = [];
for (let i = 0; i < numItems; i++) {
Expand All @@ -38,6 +39,10 @@ function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem}: ListIt
<View
style={[themeStyles.flex1, themeStyles.overflowHidden]}
onLayout={(event) => {
if (fixedNumItems) {
return;
}

const newNumItems = Math.ceil(event.nativeEvent.layout.height / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT);
if (newNumItems === numItems) {
return;
Expand Down
Loading

0 comments on commit ef1e2f6

Please sign in to comment.