mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-01-19 05:45:15 +01:00
Merge branch 'master' into receietab
This commit is contained in:
commit
67fc8ee053
@ -11,10 +11,12 @@ import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
import android.util.Log;
|
||||
|
||||
public class CustomSegmentedControlManager extends SimpleViewManager<CustomSegmentedControlManager.CustomSegmentedControlView> {
|
||||
public static final String REACT_CLASS = "CustomSegmentedControl";
|
||||
private static boolean isRegistered = false;
|
||||
private static final String TAG = "CustomSegmentedControlManager";
|
||||
|
||||
public static class CustomSegmentedControlView extends LinearLayout {
|
||||
private TabLayout tabLayout;
|
||||
@ -46,18 +48,26 @@ public class CustomSegmentedControlManager extends SimpleViewManager<CustomSegme
|
||||
}
|
||||
|
||||
public void setValues(ReadableArray values) {
|
||||
tabLayout.removeAllTabs();
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
tabLayout.addTab(tabLayout.newTab().setText(values.getString(i)));
|
||||
try {
|
||||
tabLayout.removeAllTabs();
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
tabLayout.addTab(tabLayout.newTab().setText(values.getString(i)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error setting property 'values': " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedIndex(int selectedIndex) {
|
||||
if (selectedIndex >= 0 && selectedIndex < tabLayout.getTabCount()) {
|
||||
TabLayout.Tab tab = tabLayout.getTabAt(selectedIndex);
|
||||
if (tab != null) {
|
||||
tab.select();
|
||||
try {
|
||||
if (selectedIndex >= 0 && selectedIndex < tabLayout.getTabCount()) {
|
||||
TabLayout.Tab tab = tabLayout.getTabAt(selectedIndex);
|
||||
if (tab != null) {
|
||||
tab.select();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error setting property 'selectedIndex': " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,14 +20,22 @@
|
||||
}
|
||||
|
||||
- (void)setValues:(NSArray<NSString *> *)values {
|
||||
[self removeAllSegments];
|
||||
for (NSUInteger i = 0; i < values.count; i++) {
|
||||
[self insertSegmentWithTitle:values[i] atIndex:i animated:NO];
|
||||
@try {
|
||||
[self removeAllSegments];
|
||||
for (NSUInteger i = 0; i < values.count; i++) {
|
||||
[self insertSegmentWithTitle:values[i] atIndex:i animated:NO];
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Error setting property 'values': %@", exception.reason);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSelectedIndex:(NSNumber *)selectedIndex {
|
||||
self.selectedSegmentIndex = selectedIndex.integerValue;
|
||||
@try {
|
||||
self.selectedSegmentIndex = selectedIndex.integerValue;
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Error setting property 'selectedIndex': %@", exception.reason);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onChange:(UISegmentedControl *)sender {
|
||||
|
31
package-lock.json
generated
31
package-lock.json
generated
@ -11,7 +11,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/preset-env": "^7.20.0",
|
||||
"@bugsnag/react-native": "7.23.0",
|
||||
"@bugsnag/react-native": "7.24.0",
|
||||
"@bugsnag/source-maps": "2.3.3",
|
||||
"@keystonehq/bc-ur-registry": "0.6.4",
|
||||
"@ngraveio/bc-ur": "1.1.12",
|
||||
@ -2197,9 +2197,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@bugsnag/plugin-react": {
|
||||
"version": "7.22.7",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react/-/plugin-react-7.22.7.tgz",
|
||||
"integrity": "sha512-CDyCHK5+KMkpf/2vmVC7xqqP4ys25Yuj9M8xVrmP7LC02nFUPt/UzEIt43MSO4Jfw254ZimbsQrhIweabQNyxQ==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react/-/plugin-react-7.24.0.tgz",
|
||||
"integrity": "sha512-YAoS3FPSmz/iiDuOzyr9bYMagv5/9Hdi70BMOVp5mUKaFHlx+wK4shTAFJdnTZr0534mfJMk2NXnY62CN1k28Q==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@bugsnag/core": "^7.0.0"
|
||||
},
|
||||
@ -2259,16 +2260,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@bugsnag/react-native": {
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/react-native/-/react-native-7.23.0.tgz",
|
||||
"integrity": "sha512-4xw0BDUBYPYxxBM0rbRr+uI+8IA/22p2JdzW+DMzLjue9e5PY+dTGZgREllGLuE27NtMBvnaA0rlWSYfxE04cQ==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/react-native/-/react-native-7.24.0.tgz",
|
||||
"integrity": "sha512-Yp3glQV8+mzIITuCXmfk5k2+Q8Nx8+9XO5PD10ogBAzsy5NU6NSzuYvKX1t8nPeY9S9kqfK/wSU7lcYhKRUg8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@bugsnag/core": "^7.22.7",
|
||||
"@bugsnag/delivery-react-native": "^7.22.7",
|
||||
"@bugsnag/plugin-console-breadcrumbs": "^7.22.7",
|
||||
"@bugsnag/plugin-network-breadcrumbs": "^7.22.7",
|
||||
"@bugsnag/plugin-react": "^7.22.7",
|
||||
"@bugsnag/plugin-react": "^7.24.0",
|
||||
"@bugsnag/plugin-react-native-client-sync": "^7.22.7",
|
||||
"@bugsnag/plugin-react-native-event-sync": "^7.22.7",
|
||||
"@bugsnag/plugin-react-native-global-error-handler": "^7.22.7",
|
||||
@ -24183,9 +24184,9 @@
|
||||
"integrity": "sha512-+zAq9D0G58+b/IJ/LGE2eNOIYrgIgQltJPMWdAyQFZcJWTqulN61ggt9yD2dO5PfSpAE/7KhNsR9TVbRPMb/qA=="
|
||||
},
|
||||
"@bugsnag/plugin-react": {
|
||||
"version": "7.22.7",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react/-/plugin-react-7.22.7.tgz",
|
||||
"integrity": "sha512-CDyCHK5+KMkpf/2vmVC7xqqP4ys25Yuj9M8xVrmP7LC02nFUPt/UzEIt43MSO4Jfw254ZimbsQrhIweabQNyxQ=="
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react/-/plugin-react-7.24.0.tgz",
|
||||
"integrity": "sha512-YAoS3FPSmz/iiDuOzyr9bYMagv5/9Hdi70BMOVp5mUKaFHlx+wK4shTAFJdnTZr0534mfJMk2NXnY62CN1k28Q=="
|
||||
},
|
||||
"@bugsnag/plugin-react-native-client-sync": {
|
||||
"version": "7.22.7",
|
||||
@ -24218,15 +24219,15 @@
|
||||
"integrity": "sha512-z0Nlqir3nnBcXVffw8uau12SS7vVUu0yS65SS5uWUn9cNIwNSTqZ/40pHVGh1VQBbpXlYrw7RVbPtufWmS20EA=="
|
||||
},
|
||||
"@bugsnag/react-native": {
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/react-native/-/react-native-7.23.0.tgz",
|
||||
"integrity": "sha512-4xw0BDUBYPYxxBM0rbRr+uI+8IA/22p2JdzW+DMzLjue9e5PY+dTGZgREllGLuE27NtMBvnaA0rlWSYfxE04cQ==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/react-native/-/react-native-7.24.0.tgz",
|
||||
"integrity": "sha512-Yp3glQV8+mzIITuCXmfk5k2+Q8Nx8+9XO5PD10ogBAzsy5NU6NSzuYvKX1t8nPeY9S9kqfK/wSU7lcYhKRUg8A==",
|
||||
"requires": {
|
||||
"@bugsnag/core": "^7.22.7",
|
||||
"@bugsnag/delivery-react-native": "^7.22.7",
|
||||
"@bugsnag/plugin-console-breadcrumbs": "^7.22.7",
|
||||
"@bugsnag/plugin-network-breadcrumbs": "^7.22.7",
|
||||
"@bugsnag/plugin-react": "^7.22.7",
|
||||
"@bugsnag/plugin-react": "^7.24.0",
|
||||
"@bugsnag/plugin-react-native-client-sync": "^7.22.7",
|
||||
"@bugsnag/plugin-react-native-event-sync": "^7.22.7",
|
||||
"@bugsnag/plugin-react-native-global-error-handler": "^7.22.7",
|
||||
|
@ -96,7 +96,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/preset-env": "^7.20.0",
|
||||
"@bugsnag/react-native": "7.23.0",
|
||||
"@bugsnag/react-native": "7.24.0",
|
||||
"@bugsnag/source-maps": "2.3.3",
|
||||
"@keystonehq/bc-ur-registry": "0.6.4",
|
||||
"@ngraveio/bc-ur": "1.1.12",
|
||||
|
@ -33,8 +33,10 @@ import loc, { formatBalance } from '../../loc';
|
||||
import { BitcoinUnit, Chain } from '../../models/bitcoinUnits';
|
||||
import { SuccessView } from '../send/success';
|
||||
import { useStorage } from '../../hooks/context/useStorage';
|
||||
import { AddressTypeTabs, TABS } from '../../components/addresses/AddressTypeTabs';
|
||||
import { HandOffActivityType } from '../../components/types';
|
||||
import SegmentedControl from '../../components/SegmentControl';
|
||||
|
||||
const segmentControlValues = [loc.wallets.details_address, loc.bip47.payment_code];
|
||||
|
||||
const ReceiveDetails = () => {
|
||||
const { walletID, address } = useRoute().params;
|
||||
@ -49,7 +51,7 @@ const ReceiveDetails = () => {
|
||||
const [showPendingBalance, setShowPendingBalance] = useState(false);
|
||||
const [showConfirmedBalance, setShowConfirmedBalance] = useState(false);
|
||||
const [showAddress, setShowAddress] = useState(false);
|
||||
const [currentTab, setCurrentTab] = useState(TABS.EXTERNAL);
|
||||
const [currentTab, setCurrentTab] = useState(segmentControlValues[0]);
|
||||
const { goBack, setParams } = useExtendedNavigation();
|
||||
const { colors } = useTheme();
|
||||
const [intervalMs, setIntervalMs] = useState(5000);
|
||||
@ -76,9 +78,6 @@ const ReceiveDetails = () => {
|
||||
root: {
|
||||
backgroundColor: colors.elevated,
|
||||
},
|
||||
rootBackgroundColor: {
|
||||
backgroundColor: colors.elevated,
|
||||
},
|
||||
amount: {
|
||||
color: colors.foregroundColor,
|
||||
},
|
||||
@ -180,45 +179,41 @@ const ReceiveDetails = () => {
|
||||
|
||||
const renderConfirmedBalance = () => {
|
||||
return (
|
||||
<ScrollView style={stylesHook.rootBackgroundColor} centerContent keyboardShouldPersistTaps="always">
|
||||
<View style={styles.scrollBody}>
|
||||
{isCustom && (
|
||||
<>
|
||||
<BlueText style={[styles.label, stylesHook.label]} numberOfLines={1}>
|
||||
{customLabel}
|
||||
</BlueText>
|
||||
</>
|
||||
)}
|
||||
<SuccessView />
|
||||
<BlueText style={[styles.label, stylesHook.label]} numberOfLines={1}>
|
||||
{displayBalance}
|
||||
</BlueText>
|
||||
</View>
|
||||
</ScrollView>
|
||||
<View style={styles.scrollBody}>
|
||||
{isCustom && (
|
||||
<>
|
||||
<BlueText style={[styles.label, stylesHook.label]} numberOfLines={1}>
|
||||
{customLabel}
|
||||
</BlueText>
|
||||
</>
|
||||
)}
|
||||
<SuccessView />
|
||||
<BlueText style={[styles.label, stylesHook.label]} numberOfLines={1}>
|
||||
{displayBalance}
|
||||
</BlueText>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const renderPendingBalance = () => {
|
||||
return (
|
||||
<ScrollView contentContainerStyle={stylesHook.rootBackgroundColor} centerContent keyboardShouldPersistTaps="always">
|
||||
<View style={styles.scrollBody}>
|
||||
{isCustom && (
|
||||
<>
|
||||
<BlueText style={[styles.label, stylesHook.label]} numberOfLines={1}>
|
||||
{customLabel}
|
||||
</BlueText>
|
||||
</>
|
||||
)}
|
||||
<TransactionPendingIconBig />
|
||||
<BlueSpacing40 />
|
||||
<BlueText style={[styles.label, stylesHook.label]} numberOfLines={1}>
|
||||
{displayBalance}
|
||||
</BlueText>
|
||||
<BlueText style={[styles.label, stylesHook.label]} numberOfLines={1}>
|
||||
{eta}
|
||||
</BlueText>
|
||||
</View>
|
||||
</ScrollView>
|
||||
<View style={styles.scrollBody}>
|
||||
{isCustom && (
|
||||
<>
|
||||
<BlueText style={[styles.label, stylesHook.label]} numberOfLines={1}>
|
||||
{customLabel}
|
||||
</BlueText>
|
||||
</>
|
||||
)}
|
||||
<TransactionPendingIconBig />
|
||||
<BlueSpacing40 />
|
||||
<BlueText style={[styles.label, stylesHook.label]} numberOfLines={1}>
|
||||
{displayBalance}
|
||||
</BlueText>
|
||||
<BlueText style={[styles.label, stylesHook.label]} numberOfLines={1}>
|
||||
{eta}
|
||||
</BlueText>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@ -250,7 +245,7 @@ const ReceiveDetails = () => {
|
||||
|
||||
const renderReceiveDetails = () => {
|
||||
return (
|
||||
<ScrollView contentContainerStyle={[styles.root, stylesHook.root]} keyboardShouldPersistTaps="always">
|
||||
<>
|
||||
<View style={styles.scrollBody}>
|
||||
{isCustom && (
|
||||
<>
|
||||
@ -270,24 +265,14 @@ const ReceiveDetails = () => {
|
||||
<QRCodeComponent value={bip21encoded} />
|
||||
<CopyTextToClipboard text={isCustom ? bip21encoded : address} ref={receiveAddressButton} />
|
||||
</View>
|
||||
<View style={styles.share}>
|
||||
<BlueCard>
|
||||
<BlueButtonLink
|
||||
style={styles.link}
|
||||
testID="SetCustomAmountButton"
|
||||
title={loc.receive.details_setAmount}
|
||||
onPress={showCustomAmountModal}
|
||||
/>
|
||||
</BlueCard>
|
||||
</View>
|
||||
{renderCustomAmountModal()}
|
||||
</ScrollView>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const obtainWalletAddress = useCallback(async () => {
|
||||
console.log('receive/details - componentDidMount');
|
||||
wallet.setUserHasSavedExport(true);
|
||||
await saveToDisk();
|
||||
let newAddress;
|
||||
if (address) {
|
||||
setAddressBIP21Encoded(address);
|
||||
@ -407,7 +392,9 @@ const ReceiveDetails = () => {
|
||||
};
|
||||
|
||||
const handleShareButtonPressed = () => {
|
||||
Share.open({ message: bip21encoded }).catch(error => console.log(error));
|
||||
Share.open({ message: currentTab === loc.wallets.details_address ? bip21encoded : wallet.getBIP47PaymentCode() }).catch(error =>
|
||||
console.log(error),
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -430,15 +417,10 @@ const ReceiveDetails = () => {
|
||||
};
|
||||
|
||||
const renderTabContent = () => {
|
||||
const qrValue = currentTab === TABS.EXTERNAL ? address : wallet.getBIP47PaymentCode();
|
||||
const qrValue = currentTab === segmentControlValues[0] ? bip21encoded : wallet.getBIP47PaymentCode();
|
||||
|
||||
if (currentTab === TABS.EXTERNAL) {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{!address && <Text>{loc.bip47.not_found}</Text>}
|
||||
{address && renderReceiveDetails()}
|
||||
</View>
|
||||
);
|
||||
if (currentTab === segmentControlValues[0]) {
|
||||
return <View style={styles.container}>{address && renderReceiveDetails()}</View>;
|
||||
} else {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
@ -458,29 +440,41 @@ const ReceiveDetails = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={[styles.root, stylesHook.root]}>
|
||||
<ScrollView contentContainerStyle={[styles.root, stylesHook.root]} keyboardShouldPersistTaps="always">
|
||||
{wallet.isBIP47Enabled() && (
|
||||
<View style={styles.tabsContainer}>
|
||||
<AddressTypeTabs
|
||||
currentTab={currentTab}
|
||||
setCurrentTab={setCurrentTab}
|
||||
customTabText={{ EXTERNAL: 'Address', INTERNAL: 'Payment Code' }}
|
||||
<SegmentedControl
|
||||
values={Object.values(segmentControlValues).map(tab => tab)}
|
||||
selectedIndex={Object.values(segmentControlValues).findIndex(tab => tab === currentTab)}
|
||||
onChange={index => {
|
||||
const tabKey = Object.keys(segmentControlValues)[index];
|
||||
setCurrentTab(segmentControlValues[tabKey]);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
{renderTabContent()}
|
||||
<View style={styles.share}>
|
||||
<BlueCard>
|
||||
<Button onPress={handleShareButtonPressed} title={loc.receive.details_share} />
|
||||
</BlueCard>
|
||||
</View>
|
||||
{showAddress && renderTabContent()}
|
||||
{renderCustomAmountModal()}
|
||||
{address !== undefined && showAddress && (
|
||||
<HandOffComponent title={loc.send.details_address} type={HandOffActivityType.ReceiveOnchain} userInfo={{ address }} />
|
||||
)}
|
||||
{showConfirmedBalance ? renderConfirmedBalance() : null}
|
||||
{showPendingBalance ? renderPendingBalance() : null}
|
||||
{!showAddress && !showPendingBalance && !showConfirmedBalance ? <BlueLoading /> : null}
|
||||
</View>
|
||||
<View style={styles.share}>
|
||||
<BlueCard>
|
||||
{showAddress && currentTab === loc.wallets.details_address && (
|
||||
<BlueButtonLink
|
||||
style={styles.link}
|
||||
testID="SetCustomAmountButton"
|
||||
title={loc.receive.details_setAmount}
|
||||
onPress={showCustomAmountModal}
|
||||
/>
|
||||
)}
|
||||
<Button onPress={handleShareButtonPressed} title={loc.receive.details_share} />
|
||||
</BlueCard>
|
||||
</View>
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
@ -510,7 +504,9 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
tabsContainer: {
|
||||
height: 65,
|
||||
margin: 40,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
scrollBody: {
|
||||
marginTop: 32,
|
||||
@ -520,12 +516,11 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
share: {
|
||||
justifyContent: 'flex-end',
|
||||
paddingVertical: 16,
|
||||
alignItems: 'center',
|
||||
marginBottom: 8,
|
||||
paddingHorizontal: 32,
|
||||
marginVertical: 16,
|
||||
},
|
||||
link: {
|
||||
marginVertical: 16,
|
||||
marginVertical: 32,
|
||||
paddingHorizontal: 32,
|
||||
},
|
||||
amount: {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useCallback, useEffect, useLayoutEffect, useRef, useReducer, useMemo } from 'react';
|
||||
import { useFocusEffect, useRoute, RouteProp } from '@react-navigation/native';
|
||||
import { ActivityIndicator, FlatList, StyleSheet, View } from 'react-native';
|
||||
import { ActivityIndicator, FlatList, Platform, StyleSheet, View } from 'react-native';
|
||||
import { WatchOnlyWallet } from '../../class';
|
||||
import { AddressItem } from '../../components/addresses/AddressItem';
|
||||
import { useTheme } from '../../components/themes';
|
||||
@ -200,6 +200,8 @@ const WalletAddresses: React.FC = () => {
|
||||
);
|
||||
}
|
||||
|
||||
const segmentControlMargin = { marginHorizontal: Platform.OS === 'ios' ? 40 : 0 };
|
||||
|
||||
return (
|
||||
<View style={[styles.root, stylesHook.root]}>
|
||||
<FlatList
|
||||
@ -213,7 +215,7 @@ const WalletAddresses: React.FC = () => {
|
||||
centerContent={!showAddresses}
|
||||
contentInsetAdjustmentBehavior="automatic"
|
||||
ListHeaderComponent={
|
||||
<View style={styles.segmentController}>
|
||||
<View style={[styles.segmentController, segmentControlMargin]}>
|
||||
<SegmentedControl
|
||||
values={Object.values(TABS).map(tab => loc.addresses[`type_${tab}`])}
|
||||
selectedIndex={Object.values(TABS).findIndex(tab => tab === currentTab)}
|
||||
@ -236,8 +238,6 @@ const styles = StyleSheet.create({
|
||||
flex: 1,
|
||||
},
|
||||
segmentController: {
|
||||
margin: 40,
|
||||
height: 40,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user