Skip to content

Commit 6a9e959

Browse files
committed
Merge branch 'master' into release-1.0.9
2 parents a097342 + 4da383e commit 6a9e959

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+445
-226
lines changed

__tests__/todos.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe('Todos selector', () => {
3232
let s: RootState;
3333

3434
beforeAll(async () => {
35-
let res = await createNewWallet();
35+
const res = await createNewWallet();
3636
if (res.isErr()) {
3737
throw res.error;
3838
}
@@ -67,7 +67,7 @@ describe('Todos selector', () => {
6767

6868
it('should not return backupSeedPhraseTodo if backup is verified', () => {
6969
const state = cloneDeep(s);
70-
state.settings.backupVerified = true;
70+
state.user.backupVerified = true;
7171

7272
expect(todosFullSelector(state)).not.toEqual(
7373
expect.arrayContaining([backupSeedPhraseTodo]),

e2e/slashtags.e2e.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ d('Profile and Contacts', () => {
144144
await expect(element(by.text('WEBSITE'))).toExist();
145145
await expect(element(by.text(satoshi.website))).toExist();
146146
await element(by.id('NavigationBack')).tap();
147+
await element(by.id('NavigationBack')).tap();
147148

148149
if (device.getPlatform() === 'ios') {
149150
// FIXME: this bottom sheet should not appear

src/assets/tos.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const BUI = ({ children }: Props): ReactElement => {
7171
const TOS = (): ReactElement => (
7272
<View style={s.root}>
7373
<P>
74-
<B>Effective date: June 7, 2024</B>
74+
<B>Effective date: February 4, 2025</B>
7575
</P>
7676
<P>
7777
<B>
@@ -113,10 +113,9 @@ const TOS = (): ReactElement => (
113113
</P>
114114
<P>
115115
<B>
116-
FUNDS TRANSFERRED USING CAVEMAN JUST-IN-TIME CHANNELS BY THIRD PARTIES
117-
MAY NOT BE DELIVERED TO YOU BY THE THIRD PARTY. YOU ARE REFERRED TO
118-
CLAUSE 9.3 OF THE TERMS AS TO SYNONYM’S LIABILITY FOR THIRD PARTY
119-
SERVICES.
116+
FUNDS TRANSFERRED USING JUST-IN-TIME CHANNELS BY THIRD PARTIES MAY NOT
117+
BE DELIVERED TO YOU BY THE THIRD PARTY. YOU ARE REFERRED TO CLAUSE 9.3
118+
OF THE TERMS AS TO SYNONYM’S LIABILITY FOR THIRD PARTY SERVICES.
120119
</B>
121120
</P>
122121
<P>

src/components/widgets/CalculatorWidget.tsx

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { ReactElement, useState } from 'react';
1+
import React, { ReactElement, useEffect, useState } from 'react';
22
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
33

44
import { useCurrency } from '../../hooks/displayValues';
@@ -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,
@@ -30,16 +32,58 @@ const CalculatorWidget = ({
3032
return dv.fiatValue.toString();
3133
});
3234

35+
// biome-ignore lint/correctness/useExhaustiveDependencies: update fiat amount when currency changes
36+
useEffect(() => {
37+
updateFiatAmount(bitcoinAmount);
38+
}, [fiatTicker]);
39+
3340
const updateFiatAmount = (bitcoin: string) => {
34-
const amount = Number(bitcoin);
35-
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+
});
3650
setFiatAmount(dv.fiatValue.toString());
51+
// Update bitcoin amount if it was capped
52+
if (cappedAmount !== amount) {
53+
setBitcoinAmount(cappedAmount.toString());
54+
}
3755
};
3856

3957
const updateBitcoinAmount = (fiat: string) => {
40-
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);
4162
const sats = fiatToBitcoinUnit({ amount });
42-
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;
4387
};
4488

4589
return (
@@ -56,13 +100,16 @@ const CalculatorWidget = ({
56100
<View style={styles.amount}>
57101
<TextInput
58102
style={styles.input}
59-
value={bitcoinAmount}
103+
value={formatNumberWithSeparators(bitcoinAmount)}
60104
placeholder="0"
61105
keyboardType="number-pad"
62106
returnKeyType="done"
63107
onChangeText={(text) => {
64-
setBitcoinAmount(text);
65-
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);
66113
}}
67114
/>
68115
</View>
@@ -75,13 +122,36 @@ const CalculatorWidget = ({
75122
<View style={styles.amount}>
76123
<TextInput
77124
style={styles.input}
78-
value={fiatAmount}
125+
value={formatNumberWithSeparators(fiatAmount)}
79126
placeholder="0"
80127
keyboardType="decimal-pad"
81128
returnKeyType="done"
82129
onChangeText={(text) => {
83-
setFiatAmount(text);
84-
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+
}
85155
}}
86156
/>
87157
</View>

src/components/widgets/WeatherWidget.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ const WeatherWidget = ({
8787
</BodySSB>
8888
</View>
8989
<View style={styles.columnRight}>
90-
<BodyMSB numberOfLines={1}>{nextBlockFee} bitcoin/vB</BodyMSB>
90+
<BodyMSB numberOfLines={1}>{nextBlockFee} ₿/vByte</BodyMSB>
9191
</View>
9292
</View>
9393
)}

src/screens/Activity/ActivityListShort.tsx

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Button from '../../components/buttons/Button';
1313
import { useAppSelector } from '../../hooks/redux';
1414
import type { RootNavigationProp } from '../../navigation/types';
1515
import { activityItemsSelector } from '../../store/reselect/activity';
16-
import { EActivityType, IActivityItem } from '../../store/types/activity';
16+
import { IActivityItem } from '../../store/types/activity';
1717
import { showBottomSheet } from '../../store/utils/ui';
1818
import { Caption13Up } from '../../styles/text';
1919
import { groupActivityItems } from '../../utils/activity';
@@ -31,13 +31,6 @@ const ActivityListShort = (): ReactElement => {
3131
return groupActivityItems(sliced);
3232
}, [items]);
3333

34-
const droppedItems = useMemo(() => {
35-
const dropped = items.filter((item) => {
36-
return item.activityType === EActivityType.onchain && !item.exists;
37-
});
38-
return dropped;
39-
}, [items]);
40-
4134
const renderItem = useCallback(
4235
({
4336
item,
@@ -76,13 +69,6 @@ const ActivityListShort = (): ReactElement => {
7669
<View style={styles.content}>
7770
<Caption13Up style={styles.title} color="secondary">
7871
{t('activity')}
79-
80-
{droppedItems.length !== 0 && (
81-
<Caption13Up color="red">
82-
{' '}
83-
({droppedItems.length} {t('activity_removed')})
84-
</Caption13Up>
85-
)}
8672
</Caption13Up>
8773

8874
{groupedItems.length === 0 ? (

src/screens/Contacts/Contact.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,7 @@ const Contact = ({
135135
return (
136136
<View style={styles.root}>
137137
<SafeAreaInset type="top" />
138-
<NavigationHeader
139-
title={t('contact')}
140-
onBackPress={(): void => navigation.navigate('Contacts')}
141-
/>
138+
<NavigationHeader title={t('contact')} />
142139
<View style={styles.content}>
143140
<ProfileCard
144141
url={url}

src/screens/Onboarding/RestoreFromSeed.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ import VerticalShadow from '../../components/VerticalShadow';
2626
import Button from '../../components/buttons/Button';
2727
import { useAppDispatch } from '../../hooks/redux';
2828
import { OnboardingStackScreenProps } from '../../navigation/types';
29-
import { verifyBackup } from '../../store/slices/settings';
30-
import { updateUser } from '../../store/slices/user';
29+
import { updateUser, verifyBackup } from '../../store/slices/user';
3130
import {
3231
ScrollView,
3332
TextInput,

src/screens/Settings/AddressTypePreference/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const AddressTypeSettings = ({
5151
onPress: async (): Promise<void> => {
5252
navigation.goBack();
5353
await updateSelectedAddressType({ addressType: addressType.type });
54-
await refreshWallet({ lightning: false, onchain: true });
54+
await refreshWallet({ lightning: false });
5555
},
5656
testID: addressType.type,
5757
})),

src/screens/Settings/Backup/BackupPrompt.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import {
1010
} from '../../../hooks/bottomSheet';
1111
import { useAppDispatch, useAppSelector } from '../../../hooks/redux';
1212
import { useBalance } from '../../../hooks/wallet';
13-
import { backupVerifiedSelector } from '../../../store/reselect/settings';
1413
import { viewControllersSelector } from '../../../store/reselect/ui';
14+
import { backupVerifiedSelector } from '../../../store/reselect/user';
1515
import { ignoreBackupTimestampSelector } from '../../../store/reselect/user';
1616
import { closeSheet } from '../../../store/slices/ui';
1717
import { ignoreBackup } from '../../../store/slices/user';

0 commit comments

Comments
 (0)