Update SendDetails.tsx

This commit is contained in:
Marcos Rodriguez Velez 2025-02-19 09:57:59 -04:00
parent 2f3ac6e972
commit fb1a30191d

View file

@ -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({