Skip to content

Commit e35a70b

Browse files
committed
fix(widgets): #2447 implement feedback for calculator widget
1 parent b1b4156 commit e35a70b

File tree

1 file changed

+75
-10
lines changed

1 file changed

+75
-10
lines changed

src/components/widgets/CalculatorWidget.tsx

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { fiatToBitcoinUnit } from '../../utils/conversion';
99
import { getDisplayValues } from '../../utils/displayValues';
1010
import BaseWidget from './BaseWidget';
1111

12+
const MAX_BITCOIN = 2_100_000_000_000_000; // Maximum bitcoin amount in sats
13+
1214
const CalculatorWidget = ({
1315
isEditing = false,
1416
style,
@@ -36,15 +38,52 @@ const CalculatorWidget = ({
3638
}, [fiatTicker]);
3739

3840
const updateFiatAmount = (bitcoin: string) => {
39-
const amount = Number(bitcoin);
40-
const dv = getDisplayValues({ satoshis: amount, shouldRoundUpFiat: true });
41+
// Remove leading zeros for positive numbers
42+
const sanitizedBitcoin = bitcoin.replace(/^0+(?=\d)/, '');
43+
const amount = Number(sanitizedBitcoin);
44+
// Cap the amount at maximum bitcoin
45+
const cappedAmount = Math.min(amount, MAX_BITCOIN);
46+
const dv = getDisplayValues({
47+
satoshis: cappedAmount,
48+
shouldRoundUpFiat: true,
49+
});
4150
setFiatAmount(dv.fiatValue.toString());
51+
// Update bitcoin amount if it was capped
52+
if (cappedAmount !== amount) {
53+
setBitcoinAmount(cappedAmount.toString());
54+
}
4255
};
4356

4457
const updateBitcoinAmount = (fiat: string) => {
45-
const amount = Number(fiat.replace(',', '.'));
58+
// Remove leading zeros and handle decimal separator
59+
const sanitizedFiat = fiat.replace(/^0+(?=\d)/, '');
60+
// Only convert to number if it's not just a decimal point
61+
const amount = sanitizedFiat === '.' ? 0 : Number(sanitizedFiat);
4662
const sats = fiatToBitcoinUnit({ amount });
47-
setBitcoinAmount(sats.toString());
63+
// Cap the amount at maximum bitcoin
64+
const cappedSats = Math.min(sats, MAX_BITCOIN);
65+
setBitcoinAmount(cappedSats.toString());
66+
// Update fiat amount if bitcoin was capped
67+
if (cappedSats !== sats) {
68+
const dv = getDisplayValues({
69+
satoshis: cappedSats,
70+
shouldRoundUpFiat: true,
71+
});
72+
setFiatAmount(dv.fiatValue.toString());
73+
}
74+
};
75+
76+
const formatNumberWithSeparators = (value: string): string => {
77+
const endsWithDecimal = value.endsWith('.');
78+
const cleanNumber = value.replace(/[^\d.]/g, '');
79+
const [integer, decimal] = cleanNumber.split('.');
80+
const formattedInteger = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
81+
82+
if (decimal !== undefined) {
83+
return `${formattedInteger}.${decimal}`;
84+
}
85+
86+
return endsWithDecimal ? `${formattedInteger}.` : formattedInteger;
4887
};
4988

5089
return (
@@ -61,13 +100,16 @@ const CalculatorWidget = ({
61100
<View style={styles.amount}>
62101
<TextInput
63102
style={styles.input}
64-
value={bitcoinAmount}
103+
value={formatNumberWithSeparators(bitcoinAmount)}
65104
placeholder="0"
66105
keyboardType="number-pad"
67106
returnKeyType="done"
68107
onChangeText={(text) => {
69-
setBitcoinAmount(text);
70-
updateFiatAmount(text);
108+
// Remove any spaces before processing
109+
const rawText = text.replace(/\s/g, '');
110+
const sanitizedText = rawText.replace(/^0+(?=\d)/, '');
111+
setBitcoinAmount(sanitizedText);
112+
updateFiatAmount(sanitizedText);
71113
}}
72114
/>
73115
</View>
@@ -80,13 +122,36 @@ const CalculatorWidget = ({
80122
<View style={styles.amount}>
81123
<TextInput
82124
style={styles.input}
83-
value={fiatAmount}
125+
value={formatNumberWithSeparators(fiatAmount)}
84126
placeholder="0"
85127
keyboardType="decimal-pad"
86128
returnKeyType="done"
87129
onChangeText={(text) => {
88-
setFiatAmount(text);
89-
updateBitcoinAmount(text);
130+
// Process the input text
131+
const processedText = text
132+
.replace(',', '.') // Convert comma to dot
133+
.replace(/\s/g, ''); // Remove spaces
134+
135+
// Split and clean the number parts
136+
const [integer, decimal] = processedText.split('.');
137+
const cleanInteger = integer.replace(/^0+(?=\d)/, '') || '0';
138+
139+
// Construct the final number
140+
const finalText =
141+
decimal !== undefined
142+
? `${cleanInteger}.${decimal.slice(0, 2)}`
143+
: cleanInteger;
144+
145+
// Update state if valid
146+
if (
147+
finalText === '' ||
148+
finalText === '.' ||
149+
finalText === '0.' ||
150+
/^\d*\.?\d{0,2}$/.test(finalText)
151+
) {
152+
setFiatAmount(finalText);
153+
updateBitcoinAmount(finalText);
154+
}
90155
}}
91156
/>
92157
</View>

0 commit comments

Comments
 (0)