diff --git a/Mobile-Expensify b/Mobile-Expensify index 7ffe8a7f1b47..ddda89a75246 160000 --- a/Mobile-Expensify +++ b/Mobile-Expensify @@ -1 +1 @@ -Subproject commit 7ffe8a7f1b471c697f9823b8cd4a2c19b200fa6f +Subproject commit ddda89a75246cb1e2706d67f03a1485f481d1c7d diff --git a/android/app/build.gradle b/android/app/build.gradle index 7fd4fd9dd59d..faf2c2221b7d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -110,8 +110,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009007802 - versionName "9.0.78-2" + versionCode 1009007902 + versionName "9.0.79-2" // 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" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 3374f9c36b3f..750a68e41fb9 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 9.0.78 + 9.0.79 CFBundleSignature ???? CFBundleURLTypes @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.78.2 + 9.0.79.2 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 6f72c68b009d..dfe29bdcf8e8 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 9.0.78 + 9.0.79 CFBundleSignature ???? CFBundleVersion - 9.0.78.2 + 9.0.79.2 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 328278e16cf3..b840c6d54ed6 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -11,9 +11,9 @@ CFBundleName $(PRODUCT_NAME) CFBundleShortVersionString - 9.0.78 + 9.0.79 CFBundleVersion - 9.0.78.2 + 9.0.79.2 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index ae031453f883..d93fa91f928f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "new.expensify", - "version": "9.0.78-2", + "version": "9.0.79-2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.78-2", + "version": "9.0.79-2", "hasInstallScript": true, "license": "MIT", "dependencies": { "@dotlottie/react-player": "^1.6.3", - "@expensify/react-native-live-markdown": "0.1.209", + "@expensify/react-native-live-markdown": "0.1.210", "@expo/metro-runtime": "~3.2.3", "@firebase/app": "^0.10.10", "@firebase/performance": "^0.6.8", @@ -3498,9 +3498,9 @@ } }, "node_modules/@expensify/react-native-live-markdown": { - "version": "0.1.209", - "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.209.tgz", - "integrity": "sha512-u+RRY+Jog/llEu9T1v0okSLgRhG5jGlX9H1Je0A8HWv0439XFLnAWSvN2eQ2T7bvT8Yjdj5CcC0hkgJiB9oCQw==", + "version": "0.1.210", + "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.210.tgz", + "integrity": "sha512-CW9DY2yN/QJrqkD6+74s+kWQ9bhWQwd2jT+x5RCgyy5N2SdcoE8G8DGQQvmo6q94KcRkHIr/HsTVOyzACQ/nrw==", "hasInstallScript": true, "license": "MIT", "workspaces": [ diff --git a/package.json b/package.json index 3b5a25abb224..f40db686a0db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.78-2", + "version": "9.0.79-2", "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.", @@ -76,7 +76,7 @@ }, "dependencies": { "@dotlottie/react-player": "^1.6.3", - "@expensify/react-native-live-markdown": "0.1.209", + "@expensify/react-native-live-markdown": "0.1.210", "@expo/metro-runtime": "~3.2.3", "@firebase/app": "^0.10.10", "@firebase/performance": "^0.6.8", diff --git a/src/components/AmountTextInput.tsx b/src/components/AmountTextInput.tsx index 6be2b43c09d7..12189d22dba0 100644 --- a/src/components/AmountTextInput.tsx +++ b/src/components/AmountTextInput.tsx @@ -39,7 +39,7 @@ type AmountTextInputProps = { /** Hide the focus styles on TextInput */ hideFocusedState?: boolean; -} & Pick; +} & Pick; function AmountTextInput( { diff --git a/src/components/EmptySelectionListContent.tsx b/src/components/EmptySelectionListContent.tsx index 5281b1c33b4b..313b5d620f42 100644 --- a/src/components/EmptySelectionListContent.tsx +++ b/src/components/EmptySelectionListContent.tsx @@ -48,7 +48,7 @@ function EmptySelectionListContent({contentType}: EmptySelectionListContentProps ); return ( - + ; type Selection = { start: number; @@ -126,6 +127,7 @@ function MoneyRequestAmountInput( hideFocusedState = true, shouldKeepUserInput = false, autoGrow = true, + autoGrowExtraSpace, contentWidth, ...props }: MoneyRequestAmountInputProps, @@ -289,6 +291,7 @@ function MoneyRequestAmountInput( return ( { - return shouldRenderTooltip(tooltipName); - }, [shouldRenderTooltip, tooltipName]); + return shouldShow && shouldRenderTooltip(tooltipName); + }, [shouldRenderTooltip, tooltipName, shouldShow]); const hideProductTrainingTooltip = useCallback(() => { const tooltip = TOOLTIPS[tooltipName]; diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index e3f2eb7966e3..86196f13d662 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -74,9 +74,9 @@ function MoneyRequestPreviewContent({ const route = useRoute>(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); - const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`); + const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID || CONST.DEFAULT_NUMBER_ID}`); const [session] = useOnyx(ONYXKEYS.SESSION); - const [iouReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`); + const [iouReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${iouReportID || CONST.DEFAULT_NUMBER_ID}`); const policy = PolicyUtils.getPolicy(iouReport?.policyID); const isMoneyRequestAction = ReportActionsUtils.isMoneyRequestAction(action); diff --git a/src/components/ScreenWrapper.tsx b/src/components/ScreenWrapper.tsx index bb20b4abae11..464509b0a947 100644 --- a/src/components/ScreenWrapper.tsx +++ b/src/components/ScreenWrapper.tsx @@ -7,7 +7,6 @@ import {PickerAvoidingView} from 'react-native-picker-select'; import type {EdgeInsets} from 'react-native-safe-area-context'; import useEnvironment from '@hooks/useEnvironment'; import useInitialDimensions from '@hooks/useInitialWindowDimensions'; -import useNetwork from '@hooks/useNetwork'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useStyledSafeAreaInsets from '@hooks/useStyledSafeAreaInsets'; import useTackInputFocus from '@hooks/useTackInputFocus'; @@ -158,7 +157,6 @@ function ScreenWrapper( const {initialHeight} = useInitialDimensions(); const styles = useThemeStyles(); const {isDevelopment} = useEnvironment(); - const {isOffline} = useNetwork(); const [didScreenTransitionEnd, setDidScreenTransitionEnd] = useState(false); const maxHeight = shouldEnableMaxHeight ? windowHeight : undefined; const minHeight = shouldEnableMinHeight && !Browser.isSafari() ? initialHeight : undefined; @@ -244,18 +242,17 @@ function ScreenWrapper( } // We always need the safe area padding bottom if we're showing the offline indicator since it is bottom-docked. - const isSafeAreaBottomPaddingApplied = includeSafeAreaPaddingBottom || (isOffline && shouldShowOfflineIndicator); - if (isSafeAreaBottomPaddingApplied) { + if (includeSafeAreaPaddingBottom) { paddingStyle.paddingBottom = paddingBottom; } - if (isSafeAreaBottomPaddingApplied && ignoreInsetsConsumption) { + if (includeSafeAreaPaddingBottom && ignoreInsetsConsumption) { paddingStyle.paddingBottom = unmodifiedPaddings.bottom; } const isAvoidingViewportScroll = useTackInputFocus(isFocused && shouldEnableMaxHeight && shouldAvoidScrollOnVirtualViewport && Browser.isMobileWebKit()); const contextValue = useMemo( - () => ({didScreenTransitionEnd, isSafeAreaTopPaddingApplied, isSafeAreaBottomPaddingApplied}), - [didScreenTransitionEnd, isSafeAreaBottomPaddingApplied, isSafeAreaTopPaddingApplied], + () => ({didScreenTransitionEnd, isSafeAreaTopPaddingApplied, isSafeAreaBottomPaddingApplied: includeSafeAreaPaddingBottom}), + [didScreenTransitionEnd, includeSafeAreaPaddingBottom, isSafeAreaTopPaddingApplied], ); return ( @@ -297,7 +294,14 @@ function ScreenWrapper( } {isSmallScreenWidth && shouldShowOfflineIndicator && ( <> - + {/* Since import state is tightly coupled to the offline state, it is safe to display it when showing offline indicator */} diff --git a/src/components/TextInput/BaseTextInput/index.native.tsx b/src/components/TextInput/BaseTextInput/index.native.tsx index 605fb284bf24..7cc451809ee5 100644 --- a/src/components/TextInput/BaseTextInput/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/index.native.tsx @@ -50,6 +50,7 @@ function BaseTextInput( autoFocus = false, disableKeyboard = false, autoGrow = false, + autoGrowExtraSpace = 0, autoGrowHeight = false, maxAutoGrowHeight, hideFocusedState = false, @@ -60,12 +61,15 @@ function BaseTextInput( multiline = false, autoCorrect = true, prefixCharacter = '', + suffixCharacter = '', inputID, isMarkdownEnabled = false, excludedMarkdownStyles = [], shouldShowClearButton = false, prefixContainerStyle = [], prefixStyle = [], + suffixContainerStyle = [], + suffixStyle = [], contentWidth, loadingSpinnerStyle, ...props @@ -86,7 +90,7 @@ function BaseTextInput( // Disabling this line for safeness as nullish coalescing works only if the value is undefined or null // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const initialValue = value || defaultValue || ''; - const initialActiveLabel = !!forceActiveLabel || initialValue.length > 0 || !!prefixCharacter; + const initialActiveLabel = !!forceActiveLabel || initialValue.length > 0 || !!prefixCharacter || !!suffixCharacter; const isMultiline = multiline || autoGrowHeight; const [isFocused, setIsFocused] = useState(false); @@ -140,13 +144,13 @@ function BaseTextInput( const deactivateLabel = useCallback(() => { const inputValue = value ?? ''; - if (!!forceActiveLabel || inputValue.length !== 0 || prefixCharacter) { + if (!!forceActiveLabel || inputValue.length !== 0 || prefixCharacter || suffixCharacter) { return; } animateLabel(styleConst.INACTIVE_LABEL_TRANSLATE_Y, styleConst.INACTIVE_LABEL_SCALE); isLabelActive.current = false; - }, [animateLabel, forceActiveLabel, prefixCharacter, value]); + }, [animateLabel, forceActiveLabel, prefixCharacter, suffixCharacter, value]); const onFocus = (event: NativeSyntheticEvent) => { inputProps.onFocus?.(event); @@ -249,11 +253,12 @@ function BaseTextInput( // Disabling this line for safeness as nullish coalescing works only if the value is undefined or null, and errorText can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const inputHelpText = errorText || hint; - const placeholderValue = !!prefixCharacter || isFocused || !hasLabel || (hasLabel && forceActiveLabel) ? placeholder : undefined; + const placeholderValue = !!prefixCharacter || !!suffixCharacter || isFocused || !hasLabel || (hasLabel && forceActiveLabel) ? placeholder : undefined; const newTextInputContainerStyles: StyleProp = StyleSheet.flatten([ styles.textInputContainer, textInputContainerStyles, - (autoGrow || !!contentWidth) && StyleUtils.getWidthStyle(textInputWidth), + !!contentWidth && StyleUtils.getWidthStyle(textInputWidth), + autoGrow && StyleUtils.getAutoGrowWidthInputContainerStyles(textInputWidth, autoGrowExtraSpace), !hideFocusedState && isFocused && styles.borderColorFocus, (!!hasError || !!errorText) && styles.borderColorDanger, autoGrowHeight && {scrollPaddingTop: typeof maxAutoGrowHeight === 'number' ? 2 * maxAutoGrowHeight : undefined}, @@ -261,7 +266,7 @@ function BaseTextInput( ]); const inputPaddingLeft = !!prefixCharacter && StyleUtils.getPaddingLeft(StyleUtils.getCharacterPadding(prefixCharacter) + styles.pl1.paddingLeft); - + const inputPaddingRight = !!suffixCharacter && StyleUtils.getPaddingRight(StyleUtils.getCharacterPadding(suffixCharacter) + styles.pr1.paddingRight); return ( <> @@ -349,6 +354,7 @@ function BaseTextInput( inputStyle, (!hasLabel || isMultiline) && styles.pv0, inputPaddingLeft, + inputPaddingRight, inputProps.secureTextEntry && styles.secureInput, !isMultiline && {height, lineHeight: undefined}, @@ -378,6 +384,17 @@ function BaseTextInput( defaultValue={defaultValue} markdownStyle={markdownStyle} /> + {!!suffixCharacter && ( + + + {suffixCharacter} + + + )} {isFocused && !isReadOnly && shouldShowClearButton && !!value && setValue('')} />} {!!inputProps.isLoading && (