mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-03-13 19:16:52 +01:00
Update SendDetails.tsx
This commit is contained in:
parent
2f3ac6e972
commit
fb1a30191d
1 changed files with 114 additions and 96 deletions
|
@ -136,7 +136,6 @@ const SendDetails = () => {
|
|||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [colors, wallet, isTransactionReplaceable, balance, addresses, isEditable, isLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
// decode route params
|
||||
const currentAddress = addresses[scrollIndex.current];
|
||||
|
@ -209,7 +208,6 @@ const SendDetails = () => {
|
|||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [routeParams.uri, routeParams.address, routeParams.addRecipientParams]);
|
||||
|
||||
useEffect(() => {
|
||||
// check if we have a suitable wallet
|
||||
const suitable = wallets.filter(w => w.chain === Chain.ONCHAIN && w.allowSend());
|
||||
|
@ -247,7 +245,6 @@ const SendDetails = () => {
|
|||
})
|
||||
.catch(e => console.log('loading recommendedFees error', e))
|
||||
.finally(() => {
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
||||
setNetworkTransactionFeesIsLoading(false);
|
||||
});
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
@ -355,7 +352,6 @@ const SendDetails = () => {
|
|||
setFeePrecalc(newFeePrecalc);
|
||||
setParams({ frozenBalance: frozen });
|
||||
}, [wallet, networkTransactionFees, utxos, addresses, feeRate, dumb]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
// we need to re-calculate fees if user opens-closes coin control
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
|
@ -532,7 +528,9 @@ const SendDetails = () => {
|
|||
setIsLoading(false);
|
||||
presentAlert({
|
||||
title:
|
||||
addresses.length > 1 ? loc.formatString(loc.send.details_recipient_title, { number: index + 1, total: addresses.length }) : '',
|
||||
addresses.length > 1
|
||||
? loc.formatString(loc.send.details_recipient_title, { number: index + 1, total: addresses.length })
|
||||
: undefined,
|
||||
message: error,
|
||||
});
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
||||
|
@ -548,6 +546,11 @@ const SendDetails = () => {
|
|||
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
||||
}
|
||||
};
|
||||
const navigateToQRCodeScanner = useCallback(() => {
|
||||
navigation.navigate('ScanQRCode', {
|
||||
showFileImportButton: true,
|
||||
});
|
||||
}, [navigation]);
|
||||
|
||||
const createPsbtTransaction = async () => {
|
||||
if (!wallet) return;
|
||||
|
@ -655,8 +658,7 @@ const SendDetails = () => {
|
|||
if (newWallet) {
|
||||
setWallet(newWallet);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [routeParams.walletID]);
|
||||
}, [routeParams.walletID, wallets]);
|
||||
|
||||
const setTransactionMemo = (memo: string) => {
|
||||
setParams({ transactionMemo: memo });
|
||||
|
@ -667,13 +669,13 @@ const SendDetails = () => {
|
|||
*
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const importQrTransaction = async () => {
|
||||
const importQrTransaction = useCallback(async () => {
|
||||
if (wallet?.type !== WatchOnlyWallet.type) {
|
||||
return presentAlert({ title: loc.errors.error, message: 'Importing transaction in non-watchonly wallet (this should never happen)' });
|
||||
}
|
||||
|
||||
navigateToQRCodeScanner();
|
||||
};
|
||||
}, [navigateToQRCodeScanner, wallet?.type]);
|
||||
|
||||
const importQrTransactionOnBarScanned = useCallback(
|
||||
(ret: any) => {
|
||||
|
@ -711,7 +713,7 @@ const SendDetails = () => {
|
|||
*
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const importTransaction = async () => {
|
||||
const importTransaction = useCallback(async () => {
|
||||
if (wallet?.type !== WatchOnlyWallet.type) {
|
||||
return presentAlert({ title: loc.errors.error, message: 'Importing transaction in non-watchonly wallet (this should never happen)' });
|
||||
}
|
||||
|
@ -764,7 +766,7 @@ const SendDetails = () => {
|
|||
presentAlert({ title: loc.errors.error, message: loc.send.details_no_signed_tx });
|
||||
}
|
||||
}
|
||||
};
|
||||
}, [navigation, setIsLoading, transactionMemo, wallet]);
|
||||
|
||||
const askCosignThisTransaction = async () => {
|
||||
return new Promise(resolve => {
|
||||
|
@ -818,9 +820,9 @@ const SendDetails = () => {
|
|||
[navigation, sleep, transactionMemo, wallet],
|
||||
);
|
||||
|
||||
const importTransactionMultisig = () => {
|
||||
const importTransactionMultisig = useCallback(() => {
|
||||
return _importTransactionMultisig(false);
|
||||
};
|
||||
}, [_importTransactionMultisig]);
|
||||
|
||||
const onBarScanned = useCallback(
|
||||
(ret: any) => {
|
||||
|
@ -914,13 +916,7 @@ const SendDetails = () => {
|
|||
handlePsbtSign,
|
||||
]);
|
||||
|
||||
const navigateToQRCodeScanner = () => {
|
||||
navigation.navigate('ScanQRCode', {
|
||||
showFileImportButton: true,
|
||||
});
|
||||
};
|
||||
|
||||
const handleAddRecipient = () => {
|
||||
const handleAddRecipient = useCallback(() => {
|
||||
// Check if any recipient is incomplete (missing address or amount)
|
||||
const incompleteIndex = addresses.findIndex(item => !item.address || !item.amount);
|
||||
if (incompleteIndex !== -1) {
|
||||
|
@ -942,7 +938,7 @@ const SendDetails = () => {
|
|||
animated: true,
|
||||
});
|
||||
}, 0);
|
||||
};
|
||||
}, [addresses]);
|
||||
|
||||
const onRemoveAllRecipientsConfirmed = useCallback(() => {
|
||||
setAddresses([{ address: '', key: String(Math.random()) } as IPaymentDestinations]);
|
||||
|
@ -962,7 +958,7 @@ const SendDetails = () => {
|
|||
]);
|
||||
}, [onRemoveAllRecipientsConfirmed]);
|
||||
|
||||
const handleRemoveRecipient = () => {
|
||||
const handleRemoveRecipient = useCallback(() => {
|
||||
if (addresses.length > 1) {
|
||||
const newAddresses = [...addresses];
|
||||
newAddresses.splice(scrollIndex.current, 1);
|
||||
|
@ -983,56 +979,107 @@ const SendDetails = () => {
|
|||
// Update the scroll index reference
|
||||
scrollIndex.current = newIndex;
|
||||
}
|
||||
};
|
||||
}, [addresses]);
|
||||
|
||||
const handleCoinControl = async () => {
|
||||
const handleCoinControl = useCallback(() => {
|
||||
if (!wallet) return;
|
||||
navigation.navigate('CoinControl', {
|
||||
walletID: wallet?.getID(),
|
||||
});
|
||||
};
|
||||
}, [navigation, wallet]);
|
||||
|
||||
const handleInsertContact = async () => {
|
||||
const handleInsertContact = useCallback(() => {
|
||||
if (!wallet) return;
|
||||
navigation.navigate('PaymentCodeList', { walletID: wallet.getID() });
|
||||
};
|
||||
}, [navigation, wallet]);
|
||||
|
||||
const onReplaceableFeeSwitchValueChanged = useCallback(
|
||||
(value: boolean) => {
|
||||
setParams({ isTransactionReplaceable: value });
|
||||
},
|
||||
[setParams],
|
||||
);
|
||||
|
||||
const onUseAllPressed = useCallback(() => {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationWarning);
|
||||
const message = frozenBalance > 0 ? loc.send.details_adv_full_sure_frozen : loc.send.details_adv_full_sure;
|
||||
|
||||
const anchor = findNodeHandle(scrollView.current);
|
||||
const options = {
|
||||
title: loc.send.details_adv_full,
|
||||
message,
|
||||
options: [loc._.cancel, loc._.ok],
|
||||
cancelButtonIndex: 0,
|
||||
anchor: anchor ?? undefined,
|
||||
};
|
||||
|
||||
ActionSheet.showActionSheetWithOptions(options, buttonIndex => {
|
||||
if (buttonIndex === 1) {
|
||||
Keyboard.dismiss();
|
||||
setAddresses(addrs => {
|
||||
addrs[scrollIndex.current].amount = BitcoinUnit.MAX;
|
||||
addrs[scrollIndex.current].amountSats = BitcoinUnit.MAX;
|
||||
return [...addrs];
|
||||
});
|
||||
setAddresses(addrs => {
|
||||
addrs[scrollIndex.current].unit = BitcoinUnit.BTC;
|
||||
return [...addrs];
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [frozenBalance]);
|
||||
// Header Right Button
|
||||
|
||||
const headerRightOnPress = (id: string) => {
|
||||
if (id === CommonToolTipActions.AddRecipient.id) {
|
||||
handleAddRecipient();
|
||||
} else if (id === CommonToolTipActions.RemoveRecipient.id) {
|
||||
handleRemoveRecipient();
|
||||
} else if (id === CommonToolTipActions.SignPSBT.id) {
|
||||
selectedDataProcessor.current = CommonToolTipActions.SignPSBT;
|
||||
navigateToQRCodeScanner();
|
||||
} else if (id === CommonToolTipActions.SendMax.id) {
|
||||
onUseAllPressed();
|
||||
} else if (id === CommonToolTipActions.AllowRBF.id) {
|
||||
onReplaceableFeeSwitchValueChanged(!isTransactionReplaceable);
|
||||
} else if (id === CommonToolTipActions.ImportTransaction.id) {
|
||||
selectedDataProcessor.current = CommonToolTipActions.ImportTransaction;
|
||||
importTransaction();
|
||||
} else if (id === CommonToolTipActions.ImportTransactionQR.id) {
|
||||
selectedDataProcessor.current = CommonToolTipActions.ImportTransactionQR;
|
||||
importQrTransaction();
|
||||
} else if (id === CommonToolTipActions.ImportTransactionMultsig.id) {
|
||||
selectedDataProcessor.current = CommonToolTipActions.ImportTransactionMultsig;
|
||||
importTransactionMultisig();
|
||||
} else if (id === CommonToolTipActions.CoSignTransaction.id) {
|
||||
selectedDataProcessor.current = CommonToolTipActions.CoSignTransaction;
|
||||
navigateToQRCodeScanner();
|
||||
} else if (id === CommonToolTipActions.CoinControl.id) {
|
||||
handleCoinControl();
|
||||
} else if (id === CommonToolTipActions.InsertContact.id) {
|
||||
handleInsertContact();
|
||||
} else if (id === CommonToolTipActions.RemoveAllRecipients.id) {
|
||||
handleRemoveAllRecipients();
|
||||
}
|
||||
};
|
||||
const headerRightOnPress = useCallback(
|
||||
(id: string) => {
|
||||
if (id === CommonToolTipActions.AddRecipient.id) {
|
||||
handleAddRecipient();
|
||||
} else if (id === CommonToolTipActions.RemoveRecipient.id) {
|
||||
handleRemoveRecipient();
|
||||
} else if (id === CommonToolTipActions.SignPSBT.id) {
|
||||
selectedDataProcessor.current = CommonToolTipActions.SignPSBT;
|
||||
navigateToQRCodeScanner();
|
||||
} else if (id === CommonToolTipActions.SendMax.id) {
|
||||
onUseAllPressed();
|
||||
} else if (id === CommonToolTipActions.AllowRBF.id) {
|
||||
onReplaceableFeeSwitchValueChanged(!isTransactionReplaceable);
|
||||
} else if (id === CommonToolTipActions.ImportTransaction.id) {
|
||||
selectedDataProcessor.current = CommonToolTipActions.ImportTransaction;
|
||||
importTransaction();
|
||||
} else if (id === CommonToolTipActions.ImportTransactionQR.id) {
|
||||
selectedDataProcessor.current = CommonToolTipActions.ImportTransactionQR;
|
||||
importQrTransaction();
|
||||
} else if (id === CommonToolTipActions.ImportTransactionMultsig.id) {
|
||||
selectedDataProcessor.current = CommonToolTipActions.ImportTransactionMultsig;
|
||||
importTransactionMultisig();
|
||||
} else if (id === CommonToolTipActions.CoSignTransaction.id) {
|
||||
selectedDataProcessor.current = CommonToolTipActions.CoSignTransaction;
|
||||
navigateToQRCodeScanner();
|
||||
} else if (id === CommonToolTipActions.CoinControl.id) {
|
||||
handleCoinControl();
|
||||
} else if (id === CommonToolTipActions.InsertContact.id) {
|
||||
handleInsertContact();
|
||||
} else if (id === CommonToolTipActions.RemoveAllRecipients.id) {
|
||||
handleRemoveAllRecipients();
|
||||
}
|
||||
},
|
||||
[
|
||||
handleAddRecipient,
|
||||
handleRemoveRecipient,
|
||||
navigateToQRCodeScanner,
|
||||
onUseAllPressed,
|
||||
onReplaceableFeeSwitchValueChanged,
|
||||
isTransactionReplaceable,
|
||||
importTransaction,
|
||||
importQrTransaction,
|
||||
importTransactionMultisig,
|
||||
handleCoinControl,
|
||||
handleInsertContact,
|
||||
handleRemoveAllRecipients,
|
||||
],
|
||||
);
|
||||
|
||||
const headerRightActions = () => {
|
||||
const headerRightActions = useCallback(() => {
|
||||
if (!wallet) return [];
|
||||
|
||||
const walletActions: Action[][] = [];
|
||||
|
@ -1103,19 +1150,19 @@ const SendDetails = () => {
|
|||
walletActions.push(specificWalletActions);
|
||||
|
||||
return walletActions;
|
||||
};
|
||||
}, [addresses, isEditable, wallet, isTransactionReplaceable]);
|
||||
|
||||
const HeaderRight = useCallback(
|
||||
() => <HeaderMenuButton disabled={isLoading} onPressMenuItem={headerRightOnPress} actions={headerRightActions()} />,
|
||||
[headerRightOnPress, isLoading, headerRightActions],
|
||||
);
|
||||
|
||||
const setHeaderRightOptions = () => {
|
||||
navigation.setOptions({
|
||||
// eslint-disable-next-line react/no-unstable-nested-components
|
||||
headerRight: () => <HeaderMenuButton disabled={isLoading} onPressMenuItem={headerRightOnPress} actions={headerRightActions()} />,
|
||||
headerRight: HeaderRight,
|
||||
});
|
||||
};
|
||||
|
||||
const onReplaceableFeeSwitchValueChanged = (value: boolean) => {
|
||||
setParams({ isTransactionReplaceable: value });
|
||||
};
|
||||
|
||||
const handleRecipientsScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
||||
const contentOffset = e.nativeEvent.contentOffset;
|
||||
const viewSize = e.nativeEvent.layoutMeasurement;
|
||||
|
@ -1123,35 +1170,6 @@ const SendDetails = () => {
|
|||
scrollIndex.current = index;
|
||||
};
|
||||
|
||||
const onUseAllPressed = () => {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationWarning);
|
||||
const message = frozenBalance > 0 ? loc.send.details_adv_full_sure_frozen : loc.send.details_adv_full_sure;
|
||||
|
||||
const anchor = findNodeHandle(scrollView.current);
|
||||
const options = {
|
||||
title: loc.send.details_adv_full,
|
||||
message,
|
||||
options: [loc._.cancel, loc._.ok],
|
||||
cancelButtonIndex: 0,
|
||||
anchor: anchor ?? undefined,
|
||||
};
|
||||
|
||||
ActionSheet.showActionSheetWithOptions(options, buttonIndex => {
|
||||
if (buttonIndex === 1) {
|
||||
Keyboard.dismiss();
|
||||
setAddresses(addrs => {
|
||||
addrs[scrollIndex.current].amount = BitcoinUnit.MAX;
|
||||
addrs[scrollIndex.current].amountSats = BitcoinUnit.MAX;
|
||||
return [...addrs];
|
||||
});
|
||||
setAddresses(addrs => {
|
||||
addrs[scrollIndex.current].unit = BitcoinUnit.BTC;
|
||||
return [...addrs];
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const formatFee = (fee: number) => formatBalance(fee, feeUnit!, true);
|
||||
|
||||
const stylesHook = StyleSheet.create({
|
||||
|
|
Loading…
Add table
Reference in a new issue