Skip to content

Commit

Permalink
feat(amount-input-screen): allow for pasting values in amount input s… (
Browse files Browse the repository at this point in the history
#2854)

* feat(amount-input-screen): allow for pasting values in amount input screen

* refactor: eslint

* refactor: makin pasting its own action and better type safety

* refactor: linting

* fix: Removed type 'Keys'

* fix: added trim to pasted input
  • Loading branch information
MaxwellDG authored Dec 8, 2023
1 parent 781e8fb commit 0d49abe
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 14 deletions.
44 changes: 30 additions & 14 deletions app/components/amount-input-screen/amount-input-screen-ui.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from "react"
import { useI18nContext } from "@app/i18n/i18n-react"
import { makeStyles, Text } from "@rneui/themed"
import { Input, makeStyles, Text, useTheme } from "@rneui/themed"
import { View } from "react-native"
import { GaloyIconButton } from "../atomic/galoy-icon-button"
import { GaloyPrimaryButton } from "../atomic/galoy-primary-button"
Expand All @@ -18,6 +18,7 @@ export type AmountInputScreenUIProps = {
errorMessage?: string
setAmountDisabled?: boolean
onKeyPress: (key: Key) => void
onPaste: (keys: number) => void
onToggleCurrency?: () => void
onClearAmount: () => void
onSetAmountPress?: () => void
Expand All @@ -33,13 +34,15 @@ export const AmountInputScreenUI: React.FC<AmountInputScreenUIProps> = ({
secondaryCurrencyCode,
errorMessage,
onKeyPress,
onPaste,
onToggleCurrency,
onSetAmountPress,
setAmountDisabled,
goBack,
}) => {
const { LL } = useI18nContext()
const styles = useStyles()
const { theme } = useTheme()

return (
<View style={styles.amountInputScreenContainer}>
Expand All @@ -53,13 +56,27 @@ export const AmountInputScreenUI: React.FC<AmountInputScreenUIProps> = ({
{primaryCurrencySymbol && (
<Text style={styles.primaryCurrencySymbol}>{primaryCurrencySymbol}</Text>
)}
{primaryCurrencyFormattedAmount ? (
<Text style={styles.primaryNumberText}>
{primaryCurrencyFormattedAmount}
</Text>
) : (
<Text style={styles.faintPrimaryNumberText}>0</Text>
)}
<Input
value={primaryCurrencyFormattedAmount}
showSoftInputOnFocus={false}
onChangeText={(e) => {
// remove commas for ease of calculation later on
const val = e.replaceAll(",", "")
// TODO adjust for currencies that use commas instead of decimals

// test for string input that can be either numerical or float
if (/^\d*\.?\d*$/.test(val.trim())) {
const num = Number(val)
onPaste(num)
}
}}
containerStyle={styles.primaryNumberContainer}
inputStyle={styles.primaryNumberText}
placeholder="0"
placeholderTextColor={theme.colors.grey3}
inputContainerStyle={styles.primaryNumberInputContainer}
renderErrorMessage={false}
/>
<Text style={styles.primaryCurrencyCodeText}>{primaryCurrencyCode}</Text>
</View>
{Boolean(secondaryCurrencyFormattedAmount) && (
Expand Down Expand Up @@ -116,6 +133,9 @@ const useStyles = makeStyles(({ colors }) => ({
amountContainer: {
marginBottom: 16,
},
primaryNumberContainer: {
flex: 1,
},
primaryAmountContainer: {
flexDirection: "row",
alignItems: "center",
Expand All @@ -131,12 +151,8 @@ const useStyles = makeStyles(({ colors }) => ({
flex: 1,
fontWeight: "bold",
},
faintPrimaryNumberText: {
fontSize: 28,
lineHeight: 32,
flex: 1,
fontWeight: "bold",
color: colors.grey3,
primaryNumberInputContainer: {
borderBottomWidth: 0,
},
primaryCurrencyCodeText: {
fontSize: 28,
Expand Down
10 changes: 10 additions & 0 deletions app/components/amount-input-screen/amount-input-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,15 @@ export const AmountInputScreen: React.FC<AmountInputScreenProps> = ({
})
}

const onPaste = (keys: number) => {
dispatchNumberPadAction({
action: NumberPadReducerActionType.HandlePaste,
payload: {
keys,
},
})
}

const onClear = () => {
dispatchNumberPadAction({
action: NumberPadReducerActionType.ClearAmount,
Expand Down Expand Up @@ -253,6 +262,7 @@ export const AmountInputScreen: React.FC<AmountInputScreenProps> = ({
secondaryCurrencySymbol={secondaryCurrencyInfo?.symbol}
errorMessage={errorMessage}
onKeyPress={onKeyPress}
onPaste={onPaste}
onClearAmount={onClear}
onToggleCurrency={onToggleCurrency}
setAmountDisabled={Boolean(errorMessage)}
Expand Down
22 changes: 22 additions & 0 deletions app/components/amount-input-screen/number-pad-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const NumberPadReducerActionType = {
SetAmount: "SetAmount",
HandleKeyPress: "HandleKeyPress",
ClearAmount: "ClearAmount",
HandlePaste: "HandlePaste",
} as const

export type NumberPadReducerAction =
Expand All @@ -36,6 +37,12 @@ export type NumberPadReducerAction =
| {
action: typeof NumberPadReducerActionType.ClearAmount
}
| {
action: typeof NumberPadReducerActionType.HandlePaste
payload: {
keys: number
}
}

export const Key = {
Backspace: "⌫",
Expand Down Expand Up @@ -69,6 +76,21 @@ export const numberPadReducer = (
switch (action.action) {
case NumberPadReducerActionType.SetAmount:
return action.payload
case NumberPadReducerActionType.HandlePaste: {
const num = action.payload.keys
const formatted: string =
num % 1 === 0 ? num.toString() : num.toFixed(numberOfDecimalsAllowed)
const splitByDecimal = formatted.split(".")

return {
...state,
numberPadNumber: {
majorAmount: splitByDecimal[0],
hasDecimal: splitByDecimal.length > 1,
minorAmount: splitByDecimal[1] ?? "",
},
}
}
case NumberPadReducerActionType.HandleKeyPress:
if (action.payload.key === Key.Backspace) {
if (minorAmount.length > 0) {
Expand Down

0 comments on commit 0d49abe

Please sign in to comment.