mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-19 01:40:12 +01:00
REF: Move to params for better predictability
This commit is contained in:
parent
cebdea6d25
commit
60fb4ef9bf
@ -5,6 +5,9 @@ import { scanQrHelper } from '../helpers/scan-qr';
|
||||
import loc from '../loc';
|
||||
import presentAlert from './Alert';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
import { showFilePickerAndReadFile, showImagePickerAndReadImage } from '../blue_modules/fs';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import { useTheme } from './themes';
|
||||
|
||||
interface AddressInputProps {
|
||||
isLoading?: boolean;
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
} from './LazyLoadSendDetailsStack';
|
||||
import { SendDetailsStackParamList } from './SendDetailsStackParamList';
|
||||
import HeaderRightButton from '../components/HeaderRightButton';
|
||||
import { BitcoinUnit } from '../models/bitcoinUnits';
|
||||
|
||||
const Stack = createNativeStackNavigator<SendDetailsStackParamList>();
|
||||
|
||||
@ -37,7 +38,7 @@ const SendDetailsStack = () => {
|
||||
statusBarStyle: 'light',
|
||||
closeButtonPosition: CloseButtonPosition.Left,
|
||||
})(theme)}
|
||||
initialParams={{ isEditable: true }} // Correctly typed now
|
||||
initialParams={{ isEditable: true, feeUnit: BitcoinUnit.BTC, amountUnit: BitcoinUnit.BTC }} // Correctly typed now
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="Confirm"
|
||||
|
@ -3,7 +3,12 @@ import { CreateTransactionTarget, CreateTransactionUtxo, TWallet } from '../clas
|
||||
import { BitcoinUnit, Chain } from '../models/bitcoinUnits';
|
||||
|
||||
export type SendDetailsParams = {
|
||||
memo?: string;
|
||||
transactionMemo?: string;
|
||||
isTransactionReplaceable?: boolean;
|
||||
payjoinUrl?: string;
|
||||
feeUnit?: BitcoinUnit;
|
||||
frozenBalance?: number;
|
||||
amountUnit?: BitcoinUnit;
|
||||
address?: string;
|
||||
amount?: number;
|
||||
amountSats?: number;
|
||||
@ -11,6 +16,7 @@ export type SendDetailsParams = {
|
||||
noRbf?: boolean;
|
||||
walletID: string;
|
||||
launchedBy?: string;
|
||||
utxos?: CreateTransactionUtxo[] | null;
|
||||
isEditable?: boolean;
|
||||
uri?: string;
|
||||
addRecipientParams?: {
|
||||
@ -74,7 +80,6 @@ export type SendDetailsStackParamList = {
|
||||
};
|
||||
CoinControl: {
|
||||
walletID: string;
|
||||
onUTXOChoose: (u: CreateTransactionUtxo[]) => void;
|
||||
};
|
||||
PaymentCodeList: {
|
||||
walletID: string;
|
||||
|
@ -340,7 +340,11 @@ const Confirm: React.FC = () => {
|
||||
{state.isLoading ? (
|
||||
<ActivityIndicator />
|
||||
) : (
|
||||
<Button disabled={isElectrumDisabled || state.isButtonDisabled} onPress={handleSendTransaction} title={loc.send.confirm_sendNow} />
|
||||
<Button
|
||||
disabled={isElectrumDisabled || state.isButtonDisabled}
|
||||
onPress={handleSendTransaction}
|
||||
title={loc.send.confirm_sendNow}
|
||||
/>
|
||||
)}
|
||||
</BlueCard>
|
||||
</View>
|
||||
|
@ -81,6 +81,13 @@ const SendDetails = () => {
|
||||
const setParams = navigation.setParams;
|
||||
const route = useRoute<RouteProps>();
|
||||
const name = route.name;
|
||||
const feeUnit = route.params?.feeUnit ?? BitcoinUnit.BTC;
|
||||
const amountUnit = route.params?.amountUnit ?? BitcoinUnit.BTC;
|
||||
const frozenBalance = route.params?.frozenBalance ?? 0;
|
||||
const transactionMemo = route.params?.transactionMemo;
|
||||
const utxos = route.params?.utxos;
|
||||
const payjoinUrl = route.params?.payjoinUrl;
|
||||
const isTransactionReplaceable = route.params?.isTransactionReplaceable;
|
||||
const routeParams = route.params;
|
||||
const scrollView = useRef<FlatList<any>>(null);
|
||||
const scrollIndex = useRef(0);
|
||||
@ -92,26 +99,18 @@ const SendDetails = () => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [wallet, setWallet] = useState<TWallet | null>(null);
|
||||
const feeModalRef = useRef<BottomModalHandle>(null);
|
||||
const [walletSelectionOrCoinsSelectedHidden, setWalletSelectionOrCoinsSelectedHidden] = useState(false);
|
||||
const [isAmountToolbarVisibleForAndroid, setIsAmountToolbarVisibleForAndroid] = useState(false);
|
||||
const [isTransactionReplaceable, setIsTransactionReplaceable] = useState<boolean | undefined>(false);
|
||||
const { isVisible } = useKeyboard();
|
||||
const [addresses, setAddresses] = useState<IPaymentDestinations[]>([]);
|
||||
const [units, setUnits] = useState<BitcoinUnit[]>([]);
|
||||
const [transactionMemo, setTransactionMemo] = useState<string>('');
|
||||
const [networkTransactionFees, setNetworkTransactionFees] = useState(new NetworkTransactionFee(3, 2, 1));
|
||||
const [networkTransactionFeesIsLoading, setNetworkTransactionFeesIsLoading] = useState(false);
|
||||
const [customFee, setCustomFee] = useState<string | null>(null);
|
||||
const [feePrecalc, setFeePrecalc] = useState<IFee>({ current: null, slowFee: null, mediumFee: null, fastestFee: null });
|
||||
const [feeUnit, setFeeUnit] = useState<BitcoinUnit>();
|
||||
const [amountUnit, setAmountUnit] = useState<BitcoinUnit>();
|
||||
const [utxo, setUtxo] = useState<CreateTransactionUtxo[] | null>(null);
|
||||
const [frozenBalance, setFrozenBlance] = useState<number>(0);
|
||||
const [payjoinUrl, setPayjoinUrl] = useState<string | null>(null);
|
||||
const [changeAddress, setChangeAddress] = useState<string | null>(null);
|
||||
const [dumb, setDumb] = useState(false);
|
||||
const { isEditable } = routeParams;
|
||||
// if utxo is limited we use it to calculate available balance
|
||||
const balance: number = utxo ? utxo.reduce((prev, curr) => prev + curr.value, 0) : (wallet?.getBalance() ?? 0);
|
||||
const balance: number = utxos ? utxos.reduce((prev, curr) => prev + curr.value, 0) : (wallet?.getBalance() ?? 0);
|
||||
const allBalance = formatBalanceWithoutSuffix(balance, BitcoinUnit.BTC, true);
|
||||
|
||||
// if cutomFee is not set, we need to choose highest possible fee for wallet balance
|
||||
@ -138,17 +137,6 @@ const SendDetails = () => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [colors, wallet, isTransactionReplaceable, balance, addresses, isEditable, isLoading]);
|
||||
|
||||
useKeyboard({
|
||||
onKeyboardDidShow: () => {
|
||||
setWalletSelectionOrCoinsSelectedHidden(true);
|
||||
setIsAmountToolbarVisibleForAndroid(true);
|
||||
},
|
||||
onKeyboardDidHide: () => {
|
||||
setWalletSelectionOrCoinsSelectedHidden(false);
|
||||
setIsAmountToolbarVisibleForAndroid(false);
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
// decode route params
|
||||
const currentAddress = addresses[scrollIndex.current];
|
||||
@ -176,10 +164,9 @@ const SendDetails = () => {
|
||||
});
|
||||
|
||||
if (memo?.trim().length > 0) {
|
||||
setTransactionMemo(memo);
|
||||
setParams({ transactionMemo: memo });
|
||||
}
|
||||
setAmountUnit(BitcoinUnit.BTC);
|
||||
setPayjoinUrl(pjUrl);
|
||||
setParams({ payjoinUrl: pjUrl, amountUnit: BitcoinUnit.BTC });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
presentAlert({ title: loc.errors.error, message: loc.send.details_error_decode });
|
||||
@ -196,9 +183,6 @@ const SendDetails = () => {
|
||||
return [...value, { address: routeParams.address, key: String(Math.random()), amount, amountSats }];
|
||||
}
|
||||
});
|
||||
if (routeParams.memo && routeParams.memo?.trim().length > 0) {
|
||||
setTransactionMemo(routeParams.memo);
|
||||
}
|
||||
setUnits(u => {
|
||||
u[scrollIndex.current] = unit;
|
||||
return [...u];
|
||||
@ -238,8 +222,7 @@ const SendDetails = () => {
|
||||
}
|
||||
const newWallet = (routeParams.walletID && wallets.find(w => w.getID() === routeParams.walletID)) || suitable[0];
|
||||
setWallet(newWallet);
|
||||
setFeeUnit(newWallet.getPreferredBalanceUnit());
|
||||
setAmountUnit(newWallet.preferredBalanceUnit); // default for whole screen
|
||||
setParams({ feeUnit: newWallet.getPreferredBalanceUnit(), amountUnit: newWallet.getPreferredBalanceUnit() });
|
||||
|
||||
// we are ready!
|
||||
setIsLoading(false);
|
||||
@ -276,9 +259,11 @@ const SendDetails = () => {
|
||||
setSelectedWalletID(wallet.getID());
|
||||
|
||||
// reset other values
|
||||
setUtxo(null);
|
||||
setChangeAddress(null);
|
||||
setIsTransactionReplaceable(wallet.type === HDSegwitBech32Wallet.type && !routeParams.noRbf ? true : undefined);
|
||||
setParams({
|
||||
utxos: null,
|
||||
isTransactionReplaceable: wallet.type === HDSegwitBech32Wallet.type && !routeParams.noRbf ? true : undefined,
|
||||
});
|
||||
// update wallet UTXO
|
||||
wallet
|
||||
.fetchUtxo()
|
||||
@ -294,9 +279,9 @@ const SendDetails = () => {
|
||||
if (!wallet) return; // wait for it
|
||||
const fees = networkTransactionFees;
|
||||
const requestedSatPerByte = Number(feeRate);
|
||||
const lutxo = utxo || wallet.getUtxo();
|
||||
const lutxo = utxos || wallet.getUtxo();
|
||||
let frozen = 0;
|
||||
if (!utxo) {
|
||||
if (!utxos) {
|
||||
// if utxo is not limited search for frozen outputs and calc it's balance
|
||||
frozen = wallet
|
||||
.getUtxo(true)
|
||||
@ -369,8 +354,8 @@ const SendDetails = () => {
|
||||
}
|
||||
|
||||
setFeePrecalc(newFeePrecalc);
|
||||
setFrozenBlance(frozen);
|
||||
}, [wallet, networkTransactionFees, utxo, addresses, feeRate, dumb]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
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(
|
||||
@ -470,9 +455,8 @@ const SendDetails = () => {
|
||||
u[scrollIndex.current] = BitcoinUnit.BTC; // also resetting current unit to BTC
|
||||
return [...u];
|
||||
});
|
||||
setTransactionMemo(options.label || ''); // there used to be `options.message` here as well. bug?
|
||||
setAmountUnit(BitcoinUnit.BTC);
|
||||
setPayjoinUrl(options.pj || '');
|
||||
setParams({ transactionMemo: options.label || '', amountUnit: BitcoinUnit.BTC }); // there used to be `options.message` here as well. bug?
|
||||
setParams({ payjoinUrl: options.pj || '' });
|
||||
// RN Bug: contentOffset gets reset to 0 when state changes. Remove code once this bug is resolved.
|
||||
setTimeout(() => scrollView.current?.scrollToIndex({ index: currentIndex, animated: false }), 50);
|
||||
}
|
||||
@ -565,7 +549,7 @@ const SendDetails = () => {
|
||||
const change = await getChangeAddressAsync();
|
||||
assert(change, 'Could not get change address');
|
||||
const requestedSatPerByte = Number(feeRate);
|
||||
const lutxo: CreateTransactionUtxo[] = utxo || (wallet?.getUtxo() ?? []);
|
||||
const lutxo: CreateTransactionUtxo[] = utxos || (wallet?.getUtxo() ?? []);
|
||||
console.log({ requestedSatPerByte, lutxo: lutxo.length });
|
||||
|
||||
const targets: CreateTransactionTarget[] = [];
|
||||
@ -669,6 +653,10 @@ const SendDetails = () => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [routeParams.walletID]);
|
||||
|
||||
const setTransactionMemo = (memo: string) => {
|
||||
setParams({ transactionMemo: memo });
|
||||
};
|
||||
|
||||
/**
|
||||
* same as `importTransaction`, but opens camera instead.
|
||||
*
|
||||
@ -898,7 +886,6 @@ const SendDetails = () => {
|
||||
if (!wallet) return;
|
||||
navigation.navigate('CoinControl', {
|
||||
walletID: wallet?.getID(),
|
||||
onUTXOChoose: (u: CreateTransactionUtxo[]) => setUtxo(u),
|
||||
});
|
||||
};
|
||||
|
||||
@ -1050,7 +1037,7 @@ const SendDetails = () => {
|
||||
};
|
||||
|
||||
const onReplaceableFeeSwitchValueChanged = (value: boolean) => {
|
||||
setIsTransactionReplaceable(value);
|
||||
setParams({ isTransactionReplaceable: value });
|
||||
};
|
||||
|
||||
const handleRecipientsScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
||||
@ -1141,16 +1128,16 @@ const SendDetails = () => {
|
||||
};
|
||||
|
||||
const renderWalletSelectionOrCoinsSelected = () => {
|
||||
if (walletSelectionOrCoinsSelectedHidden) return null;
|
||||
if (utxo !== null) {
|
||||
if (isVisible) return null;
|
||||
if (utxos !== null) {
|
||||
return (
|
||||
<View style={styles.select}>
|
||||
<CoinsSelected
|
||||
number={utxo.length}
|
||||
number={utxos?.length || 0}
|
||||
onContainerPress={handleCoinControl}
|
||||
onClose={() => {
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
||||
setUtxo(null);
|
||||
setParams({ utxos: null });
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
@ -1262,9 +1249,11 @@ const SendDetails = () => {
|
||||
addrs[index] = item;
|
||||
return [...addrs];
|
||||
});
|
||||
setTransactionMemo(memo || transactionMemo);
|
||||
if (memo) {
|
||||
setParams({ transactionMemo: memo });
|
||||
}
|
||||
setIsLoading(false);
|
||||
setPayjoinUrl(pjUrl);
|
||||
setParams({ payjoinUrl: pjUrl });
|
||||
}}
|
||||
onBarScanned={processAddressData}
|
||||
address={item.address}
|
||||
@ -1354,7 +1343,7 @@ const SendDetails = () => {
|
||||
<DismissKeyboardInputAccessory />
|
||||
{Platform.select({
|
||||
ios: <InputAccessoryAllFunds canUseAll={balance > 0} onUseAllPressed={onUseAllPressed} balance={String(allBalance)} />,
|
||||
android: isAmountToolbarVisibleForAndroid && (
|
||||
android: isVisible && (
|
||||
<InputAccessoryAllFunds canUseAll={balance > 0} onUseAllPressed={onUseAllPressed} balance={String(allBalance)} />
|
||||
),
|
||||
})}
|
||||
|
@ -260,7 +260,7 @@ const CoinControl = () => {
|
||||
const navigation = useExtendedNavigation();
|
||||
const { width } = useWindowDimensions();
|
||||
const bottomModalRef = useRef(null);
|
||||
const { walletID, onUTXOChoose } = useRoute().params;
|
||||
const { walletID } = useRoute().params;
|
||||
const { wallets, saveToDisk, sleep } = useStorage();
|
||||
const wallet = wallets.find(w => w.getID() === walletID);
|
||||
// sort by height ascending, txid , vout ascending
|
||||
@ -329,8 +329,13 @@ const CoinControl = () => {
|
||||
|
||||
const handleUseCoin = async u => {
|
||||
setOutput(null);
|
||||
navigation.pop();
|
||||
onUTXOChoose(u);
|
||||
navigation.navigate('SendDetailsRoot', {
|
||||
screen: 'SendDetails',
|
||||
params: {
|
||||
utxos: u,
|
||||
},
|
||||
merge: true,
|
||||
});
|
||||
};
|
||||
|
||||
const handleMassFreeze = () => {
|
||||
@ -476,7 +481,7 @@ const styles = StyleSheet.create({
|
||||
padding: {
|
||||
padding: 16,
|
||||
},
|
||||
modalMinHeight: Platform.OS === 'android' ? { minHeight: 490 } : {},
|
||||
modalMinHeight: Platform.OS === 'android' ? { minHeight: 530 } : {},
|
||||
empty: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
|
Loading…
Reference in New Issue
Block a user