Skip to content

Commit

Permalink
Merge branch 'main' into jsys/upgrade-react-native-pager-view
Browse files Browse the repository at this point in the history
  • Loading branch information
MrRefactor committed Nov 8, 2024
2 parents 63914be + d0133d1 commit 652956b
Show file tree
Hide file tree
Showing 31 changed files with 270 additions and 185 deletions.
71 changes: 43 additions & 28 deletions docs/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,70 +1,85 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
bigdecimal (3.1.8)
colorator (1.1.0)
concurrent-ruby (1.1.10)
concurrent-ruby (1.3.4)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
eventmachine (1.2.7)
ffi (1.15.5)
ffi (1.17.0-arm64-darwin)
ffi (1.17.0-x86_64-darwin)
forwardable-extended (2.6.0)
google-protobuf (4.28.3-arm64-darwin)
bigdecimal
rake (>= 13)
google-protobuf (4.28.3-x86_64-darwin)
bigdecimal
rake (>= 13)
http_parser.rb (0.8.0)
i18n (0.9.5)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
jekyll (3.9.3)
jekyll (4.3.4)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
i18n (>= 0.7, < 2)
jekyll-sass-converter (~> 1.0)
i18n (~> 1.0)
jekyll-sass-converter (>= 2.0, < 4.0)
jekyll-watch (~> 2.0)
kramdown (>= 1.17, < 3)
kramdown (~> 2.3, >= 2.3.1)
kramdown-parser-gfm (~> 1.0)
liquid (~> 4.0)
mercenary (~> 0.3.3)
mercenary (>= 0.3.6, < 0.5)
pathutil (~> 0.9)
rouge (>= 1.7, < 4)
rouge (>= 3.0, < 5.0)
safe_yaml (~> 1.0)
jekyll-feed (0.15.1)
terminal-table (>= 1.8, < 4.0)
webrick (~> 1.7)
jekyll-feed (0.17.0)
jekyll (>= 3.7, < 5.0)
jekyll-redirect-from (0.16.0)
jekyll (>= 3.3, < 5.0)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-sass-converter (3.0.0)
sass-embedded (~> 1.54)
jekyll-seo-tag (2.8.0)
jekyll (>= 3.8, < 5.0)
jekyll-watch (2.2.1)
listen (~> 3.0)
kramdown (2.3.2)
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.4)
listen (3.7.1)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mercenary (0.4.0)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (4.0.7)
rb-fsevent (0.11.1)
rb-inotify (0.10.1)
public_suffix (6.0.1)
rake (13.2.1)
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
rexml (3.2.5)
rouge (3.26.0)
rexml (3.3.9)
rouge (4.4.0)
safe_yaml (1.0.5)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
webrick (1.7.0)
sass-embedded (1.80.6-arm64-darwin)
google-protobuf (~> 4.28)
sass-embedded (1.80.6-x86_64-darwin)
google-protobuf (~> 4.28)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
unicode-display_width (2.6.0)
webrick (1.9.0)

PLATFORMS
arm64-darwin-22
arm64-darwin-23
arm64-darwin-24
x86_64-darwin-20
x86_64-darwin-21

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
title: Request the Card
description: Details on requesting the Expensify Card as an employee
---
_Note: The Expensify Card is currently only available to companies that have:_
_- A US Bank Account_
_- US documentation_
_- A private email domain i.e. we cannot provision Expensify cards for users with gmail.com, hotmail.com, yahoo.com etc_

To start using the Expensify Card, do the following:
1. **Enable Expensify Cards:** An admin must first enable the cards. Then, an admin can assign you a card by setting a limit, which allows access to the card.
2. **Request the Card:**
Expand Down
9 changes: 5 additions & 4 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
Expand Up @@ -152,7 +152,7 @@
"react-native-launch-arguments": "^4.0.2",
"react-native-localize": "^2.2.6",
"react-native-modal": "^13.0.0",
"react-native-onyx": "2.0.73",
"react-native-onyx": "2.0.78",
"react-native-pager-view": "6.5.0",
"react-native-pdf": "6.7.3",
"react-native-performance": "^5.1.0",
Expand Down
2 changes: 2 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2806,6 +2806,7 @@ const CONST = {
RESTRICT: 'corporate',
ALLOW: 'personal',
},
CARD_LIST_THRESHOLD: 8,
EXPORT_CARD_TYPES: {
/**
* Name of Card NVP for QBO custom export accounts
Expand Down Expand Up @@ -5839,6 +5840,7 @@ const CONST = {

MAX_TAX_RATE_INTEGER_PLACES: 4,
MAX_TAX_RATE_DECIMAL_PLACES: 4,
MIN_TAX_RATE_DECIMAL_PLACES: 2,

DOWNLOADS_PATH: '/Downloads',
DOWNLOADS_TIMEOUT: 5000,
Expand Down
4 changes: 4 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,9 @@ const ONYXKEYS = {
/** Company cards custom names */
NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES: 'nvp_expensify_ccCustomNames',

/** The user's Concierge reportID */
CONCIERGE_REPORT_ID: 'conciergeReportID',

/** Collection Keys */
COLLECTION: {
DOWNLOAD: 'download_',
Expand Down Expand Up @@ -1025,6 +1028,7 @@ type OnyxValuesMapping = {
[ONYXKEYS.IS_USING_IMPORTED_STATE]: boolean;
[ONYXKEYS.SHOULD_SHOW_SAVED_SEARCH_RENAME_TOOLTIP]: boolean;
[ONYXKEYS.NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES]: Record<string, string>;
[ONYXKEYS.CONCIERGE_REPORT_ID]: string;
};
type OnyxValues = OnyxValuesMapping & OnyxCollectionValuesMapping & OnyxFormValuesMapping & OnyxFormDraftValuesMapping;

Expand Down
28 changes: 16 additions & 12 deletions src/components/EmojiPicker/EmojiPickerMenu/index.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import type {ListRenderItem} from '@shopify/flash-list';
import lodashDebounce from 'lodash/debounce';
import React, {useCallback} from 'react';
import type {ForwardedRef} from 'react';
import {View} from 'react-native';
import {InteractionManager, View} from 'react-native';
import type {Emoji} from '@assets/emojis/types';
import EmojiPickerMenuItem from '@components/EmojiPicker/EmojiPickerMenuItem';
import Text from '@components/Text';
import TextInput from '@components/TextInput';
Expand Down Expand Up @@ -43,25 +44,28 @@ function EmojiPickerMenu({onEmojiSelected, activeEmoji}: EmojiPickerMenuProps, r
} = useEmojiPickerMenu();
const StyleUtils = useStyleUtils();

const updateEmojiList = (emojiData: EmojiUtils.EmojiPickerList | Emoji[], headerData: number[] = []) => {
setFilteredEmojis(emojiData);
setHeaderIndices(headerData);

InteractionManager.runAfterInteractions(() => {
requestAnimationFrame(() => {
emojiListRef.current?.scrollToOffset({offset: 0, animated: false});
});
});
};

/**
* Filter the entire list of emojis to only emojis that have the search term in their keywords
*/
const filterEmojis = lodashDebounce((searchTerm: string) => {
const [normalizedSearchTerm, newFilteredEmojiList] = suggestEmojis(searchTerm);

if (emojiListRef.current) {
emojiListRef.current.scrollToOffset({offset: 0, animated: false});
}

if (normalizedSearchTerm === '') {
setFilteredEmojis(allEmojis);
setHeaderIndices(headerRowIndices);

return;
updateEmojiList(allEmojis, headerRowIndices);
} else {
updateEmojiList(newFilteredEmojiList ?? [], []);
}

setFilteredEmojis(newFilteredEmojiList ?? []);
setHeaderIndices([]);
}, 300);

const scrollToHeader = (headerIndex: number) => {
Expand Down
97 changes: 56 additions & 41 deletions src/components/SelectionList/BaseSelectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ function BaseSelectionList<TItem extends ListItem>(
textInputIconLeft,
sectionTitleStyles,
textInputAutoFocus = true,
shouldShowTextInputAfterHeader = false,
includeSafeAreaPaddingBottom = true,
shouldTextInputInterceptSwipe = false,
listHeaderContent,
onEndReached = () => {},
Expand Down Expand Up @@ -531,6 +533,48 @@ function BaseSelectionList<TItem extends ListItem>(
return null;
};

const renderInput = () => {
return (
<View style={[styles.ph5, styles.pb3]}>
<TextInput
ref={(element) => {
innerTextInputRef.current = element as RNTextInput;

if (!textInputRef) {
return;
}

if (typeof textInputRef === 'function') {
textInputRef(element as RNTextInput);
} else {
// eslint-disable-next-line no-param-reassign
textInputRef.current = element as RNTextInput;
}
}}
onFocus={() => (isTextInputFocusedRef.current = true)}
onBlur={() => (isTextInputFocusedRef.current = false)}
label={textInputLabel}
accessibilityLabel={textInputLabel}
hint={textInputHint}
role={CONST.ROLE.PRESENTATION}
value={textInputValue}
placeholder={textInputPlaceholder}
maxLength={textInputMaxLength}
onChangeText={onChangeText}
inputMode={inputMode}
selectTextOnFocus
spellCheck={false}
iconLeft={textInputIconLeft}
onSubmitEditing={selectFocusedOption}
blurOnSubmit={!!flattenedSections.allOptions.length}
isLoading={isLoadingNewOptions}
testID="selection-list-text-input"
shouldInterceptSwipe={shouldTextInputInterceptSwipe}
/>
</View>
);
};

const scrollToFocusedIndexOnFirstRender = useCallback(
(nativeEvent: LayoutChangeEvent) => {
if (shouldUseDynamicMaxToRenderPerBatch) {
Expand Down Expand Up @@ -707,46 +751,8 @@ function BaseSelectionList<TItem extends ListItem>(
return (
<SafeAreaConsumer>
{({safeAreaPaddingBottomStyle}) => (
<View style={[styles.flex1, (!isKeyboardShown || !!footerContent || showConfirmButton) && safeAreaPaddingBottomStyle, containerStyle]}>
{shouldShowTextInput && (
<View style={[styles.ph5, styles.pb3]}>
<TextInput
ref={(element) => {
innerTextInputRef.current = element as RNTextInput;

if (!textInputRef) {
return;
}

if (typeof textInputRef === 'function') {
textInputRef(element as RNTextInput);
} else {
// eslint-disable-next-line no-param-reassign
textInputRef.current = element as RNTextInput;
}
}}
onFocus={() => (isTextInputFocusedRef.current = true)}
onBlur={() => (isTextInputFocusedRef.current = false)}
label={textInputLabel}
accessibilityLabel={textInputLabel}
hint={textInputHint}
role={CONST.ROLE.PRESENTATION}
value={textInputValue}
placeholder={textInputPlaceholder}
maxLength={textInputMaxLength}
onChangeText={onChangeText}
inputMode={inputMode}
selectTextOnFocus
spellCheck={false}
iconLeft={textInputIconLeft}
onSubmitEditing={selectFocusedOption}
blurOnSubmit={!!flattenedSections.allOptions.length}
isLoading={isLoadingNewOptions}
testID="selection-list-text-input"
shouldInterceptSwipe={shouldTextInputInterceptSwipe}
/>
</View>
)}
<View style={[styles.flex1, (!isKeyboardShown || !!footerContent || showConfirmButton) && includeSafeAreaPaddingBottom && safeAreaPaddingBottomStyle, containerStyle]}>
{shouldShowTextInput && !shouldShowTextInputAfterHeader && renderInput()}
{/* If we are loading new options we will avoid showing any header message. This is mostly because one of the header messages says there are no options. */}
{/* This is misleading because we might be in the process of loading fresh options from the server. */}
{(!isLoadingNewOptions || headerMessage !== translate('common.noResultsFound') || (flattenedSections.allOptions.length === 0 && !showLoadingPlaceholder)) &&
Expand Down Expand Up @@ -790,7 +796,16 @@ function BaseSelectionList<TItem extends ListItem>(
testID="selection-list"
onLayout={onSectionListLayout}
style={[(!maxToRenderPerBatch || (shouldHideListOnInitialRender && isInitialSectionListRender)) && styles.opacity0, sectionListStyle]}
ListHeaderComponent={listHeaderContent}
ListHeaderComponent={
shouldShowTextInput && shouldShowTextInputAfterHeader ? (
<>
{listHeaderContent}
{renderInput()}
</>
) : (
listHeaderContent
)
}
ListFooterComponent={listFooterContent ?? ShowMoreButtonInstance}
onEndReached={onEndReached}
onEndReachedThreshold={onEndReachedThreshold}
Expand Down
6 changes: 6 additions & 0 deletions src/components/SelectionList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,12 @@ type BaseSelectionListProps<TItem extends ListItem> = Partial<ChildrenProps> & {
/** Item `keyForList` to focus initially */
initiallyFocusedOptionKey?: string | null;

/** Whether the text input should be shown after list header */
shouldShowTextInputAfterHeader?: boolean;

/** Whether to include padding bottom */
includeSafeAreaPaddingBottom?: boolean;

/** Callback to fire when the list is scrolled */
onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;

Expand Down
1 change: 0 additions & 1 deletion src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3199,7 +3199,6 @@ const translations = {
confirmationDescription: 'We’ll begin importing transactions immediately.',
cardholder: 'Cardholder',
card: 'Card',
startTransactionDate: 'Start transaction date',
cardName: 'Card name',
brokenConnectionErrorFirstPart: `Card feed connection is broken. Please `,
brokenConnectionErrorLink: 'log into your bank ',
Expand Down
1 change: 0 additions & 1 deletion src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3238,7 +3238,6 @@ const translations = {
confirmationDescription: 'Comenzaremos a importar transacciones inmediatamente.',
cardholder: 'Titular de la tarjeta',
card: 'Tarjeta',
startTransactionDate: 'Fecha de inicio de transacciones',
cardName: 'Nombre de la tarjeta',
brokenConnectionErrorFirstPart: `La conexión de la fuente de tarjetas está rota. Por favor, `,
brokenConnectionErrorLink: 'inicia sesión en tu banco ',
Expand Down
Loading

0 comments on commit 652956b

Please sign in to comment.