diff --git a/android/app/build.gradle b/android/app/build.gradle index 6349f631faea8..1f0099a9f32ac 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001044109 - versionName "1.4.41-9" + versionCode 1001044111 + versionName "1.4.41-11" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 08b216f30224e..330006537d3d3 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.41.9 + 1.4.41.11 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 05310bade97e3..8e15d3eb3bca8 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.41.9 + 1.4.41.11 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index d3ff258cc7332..dc570054b7947 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 1.4.41 CFBundleVersion - 1.4.41.9 + 1.4.41.11 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 9d1a52b1cec96..ba68a832a572a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.41-9", + "version": "1.4.41-11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.41-9", + "version": "1.4.41-11", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 4f4178b8b6539..c324633cd3e51 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.41-9", + "version": "1.4.41-11", "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.", diff --git a/src/components/AmountForm.tsx b/src/components/AmountForm.tsx index 4214d804af068..0daeceb7c2c36 100644 --- a/src/components/AmountForm.tsx +++ b/src/components/AmountForm.tsx @@ -32,6 +32,9 @@ type AmountFormProps = { /** Fired when back button pressed, navigates to currency selection page */ onCurrencyButtonPress?: () => void; + + /** Whether the currency symbol is pressable */ + isCurrencyPressable?: boolean; }; /** @@ -47,8 +50,13 @@ const NUM_PAD_CONTAINER_VIEW_ID = 'numPadContainerView'; const NUM_PAD_VIEW_ID = 'numPadView'; function AmountForm( +<<<<<<< HEAD {value: amount, currency = CONST.CURRENCY.USD, extraDecimals = 0, errorText, onInputChange, onCurrencyButtonPress}: AmountFormProps, forwardedRef: ForwardedRef, +======= + {value: amount, currency = CONST.CURRENCY.USD, extraDecimals = 0, errorText, onInputChange, onCurrencyButtonPress, isCurrencyPressable = true}: AmountFormProps, + forwardedRef: ForwardedRef, +>>>>>>> af1026e (Merge pull request #36497 from shubham1206agra/fix-currency-ui) ) { const styles = useThemeStyles(); const {toLocaleDigit, numberFormat} = useLocalize(); @@ -210,10 +218,11 @@ function AmountForm( setSelection(e.nativeEvent.selection); }} onKeyPress={textInputKeyPress} + isCurrencyPressable={isCurrencyPressable} /> {!!errorText && ( diff --git a/src/components/CurrencySymbolButton.tsx b/src/components/CurrencySymbolButton.tsx index e913b415c3289..2b736c2ef5275 100644 --- a/src/components/CurrencySymbolButton.tsx +++ b/src/components/CurrencySymbolButton.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import {View} from 'react-native'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -15,13 +16,16 @@ type CurrencySymbolButtonProps = { /** Function to call when currency button is pressed */ onCurrencyButtonPress: () => void; + + /** Whether the currency button is pressable or not */ + isCurrencyPressable?: boolean; }; -function CurrencySymbolButton({onCurrencyButtonPress, currencySymbol}: CurrencySymbolButtonProps) { +function CurrencySymbolButton({onCurrencyButtonPress, currencySymbol, isCurrencyPressable = true}: CurrencySymbolButtonProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const theme = useTheme(); - return ( + return isCurrencyPressable ? ( {currencySymbol} + ) : ( + + {currencySymbol} + ); } diff --git a/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.tsx b/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.tsx new file mode 100644 index 0000000000000..b6509d5c3f474 --- /dev/null +++ b/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.tsx @@ -0,0 +1,83 @@ +import React from 'react'; +import type {NativeSyntheticEvent, TextInputSelectionChangeEventData} from 'react-native'; +import AmountTextInput from '@components/AmountTextInput'; +import CurrencySymbolButton from '@components/CurrencySymbolButton'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as CurrencyUtils from '@libs/CurrencyUtils'; +import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; +import type {BaseTextInputRef} from '@src/components/TextInput/BaseTextInput/types'; +import type TextInputWithCurrencySymbolProps from './types'; + +function BaseTextInputWithCurrencySymbol( + { + selectedCurrencyCode, + onCurrencyButtonPress = () => {}, + onChangeAmount = () => {}, + formattedAmount, + placeholder, + selection, + onSelectionChange = () => {}, + onKeyPress = () => {}, + isCurrencyPressable = true, + }: TextInputWithCurrencySymbolProps, + ref: React.ForwardedRef, +) { + const {fromLocaleDigit} = useLocalize(); + const currencySymbol = CurrencyUtils.getLocalizedCurrencySymbol(selectedCurrencyCode); + const isCurrencySymbolLTR = CurrencyUtils.isCurrencySymbolLTR(selectedCurrencyCode); + const styles = useThemeStyles(); + + const currencySymbolButton = ( + + ); + + /** + * Set a new amount value properly formatted + * + * @param text - Changed text from user input + */ + const setFormattedAmount = (text: string) => { + const newAmount = MoneyRequestUtils.addLeadingZero(MoneyRequestUtils.replaceAllDigits(text, fromLocaleDigit)); + onChangeAmount(newAmount); + }; + + const amountTextInput = ( + ) => { + onSelectionChange(event); + }} + onKeyPress={onKeyPress} + style={styles.pr1} + /> + ); + + if (isCurrencySymbolLTR) { + return ( + <> + {currencySymbolButton} + {amountTextInput} + + ); + } + + return ( + <> + {amountTextInput} + {currencySymbolButton} + + ); +} + +BaseTextInputWithCurrencySymbol.displayName = 'BaseTextInputWithCurrencySymbol'; + +export default React.forwardRef(BaseTextInputWithCurrencySymbol); diff --git a/src/components/TextInputWithCurrencySymbol/textInputWithCurrencySymbolPropTypes.js b/src/components/TextInputWithCurrencySymbol/textInputWithCurrencySymbolPropTypes.js index 656561c14b146..bf292b331b81d 100644 --- a/src/components/TextInputWithCurrencySymbol/textInputWithCurrencySymbolPropTypes.js +++ b/src/components/TextInputWithCurrencySymbol/textInputWithCurrencySymbolPropTypes.js @@ -31,6 +31,9 @@ const propTypes = { /** Function to call to handle key presses in the text input */ onKeyPress: PropTypes.func, + + /** Whether the currency symbol is pressable */ + isCurrencyPressable: PropTypes.bool, }; const defaultProps = { @@ -40,6 +43,7 @@ const defaultProps = { selection: undefined, onSelectionChange: () => {}, onKeyPress: () => {}, + isCurrencyPressable: true, }; export {propTypes, defaultProps}; diff --git a/src/components/TextInputWithCurrencySymbol/types.ts b/src/components/TextInputWithCurrencySymbol/types.ts new file mode 100644 index 0000000000000..5cd088a10edb2 --- /dev/null +++ b/src/components/TextInputWithCurrencySymbol/types.ts @@ -0,0 +1,33 @@ +import type {NativeSyntheticEvent, TextInputSelectionChangeEventData} from 'react-native'; +import type {TextSelection} from '@components/Composer/types'; + +type TextInputWithCurrencySymbolProps = { + /** Formatted amount in local currency */ + formattedAmount: string; + + /** Function to call when amount in text input is changed */ + onChangeAmount?: (value: string) => void; + + /** Function to call when currency button is pressed */ + onCurrencyButtonPress?: () => void; + + /** Placeholder value for amount text input */ + placeholder: string; + + /** Currency code of user's selected currency */ + selectedCurrencyCode: string; + + /** Selection Object */ + selection?: TextSelection; + + /** Function to call when selection in text input is changed */ + onSelectionChange?: (event: NativeSyntheticEvent) => void; + + /** Function to call to handle key presses in the text input */ + onKeyPress?: (event: NativeSyntheticEvent) => void; + + /** Whether the currency symbol is pressable */ + isCurrencyPressable: boolean; +}; + +export default TextInputWithCurrencySymbolProps; diff --git a/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage/RatePage.tsx b/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage/RatePage.tsx index 37723fe654c0d..8ae2a67ee6849 100644 --- a/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage/RatePage.tsx +++ b/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage/RatePage.tsx @@ -100,6 +100,7 @@ function WorkspaceRatePage(props: WorkspaceRatePageProps) { defaultValue={( (typeof props.workspaceRateAndUnit?.rate === 'string' ? parseFloat(props.workspaceRateAndUnit.rate) : defaultValue) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET ).toFixed(3)} + isCurrencyPressable={false} /> )}