diff --git a/public/locales/en.json b/public/locales/en.json index 8941b10..c1a7d2d 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -740,6 +740,7 @@ "errorInvalidAddressOnly": "Invalid address.", "errorInvalidRecipient": "Invalid recipient. Must be an address or name.", "errorInvalidWalletsOnly": "Invalid wallet address.", + "errorEqual": "Recipient cannot be the same as the sender.", "categoryWallets": "Wallets", "categoryOtherWallets": "Other wallets", diff --git a/src/components/addresses/picker/AddressPicker.tsx b/src/components/addresses/picker/AddressPicker.tsx index 16d1a46..aff7ad8 100644 --- a/src/components/addresses/picker/AddressPicker.tsx +++ b/src/components/addresses/picker/AddressPicker.tsx @@ -27,6 +27,7 @@ name: string; label?: string; value?: string; + otherPickerValue?: string; walletsOnly?: boolean; noNames?: boolean; @@ -38,6 +39,7 @@ name, label, value, + otherPickerValue, walletsOnly, noNames, @@ -153,6 +155,15 @@ type: "enum", enum: addressList, message: t("addressPicker.errorInvalidWalletsOnly") + } as Rule] : []), + + // If we have another address picker's value, assert that they are not + // equal (e.g. to/from in a transaction can't be equal) + ...(otherPickerValue ? [{ + async validator(_, value): Promise { + if (value === otherPickerValue) + throw t("addressPicker.errorEqual"); + } } as Rule] : []) ]} @@ -174,17 +185,28 @@ filterOption={(inputValue, option) => { // Returning false if the option contains children will allow the select // to run filterOption for each child of that option group. - if (option?.options || !inputValue) return false; + if (option?.options) return false; // TODO: Do we want to filter categories here too? + const address = option!.value?.toUpperCase(); + const walletLabel = option!["data-wallet-label"]?.toUpperCase(); + + // If we have another address picker's value, hide that option from the + // list (it will always be a wallet) + // FIXME: filterOption doesn't get called at all when inputValue is + // blank, which means this option will still appear until the + // user actually starts typing. + if (otherPickerValue?.toUpperCase() === address) + return false; + + // Now that we've filtered out the other picker's value, we can allow + // every other option if there's no input + if (!inputValue) return true; + const inp = inputValue.toUpperCase(); - const address = option!.value; - const walletLabel = option!["data-wallet-label"]; - - const matchedAddress = address.toUpperCase().indexOf(inp) !== -1; - const matchedLabel = walletLabel - && walletLabel.toUpperCase().indexOf(inp) !== -1; + const matchedAddress = address.indexOf(inp) !== -1; + const matchedLabel = walletLabel?.indexOf(inp) !== -1; return matchedAddress || matchedLabel; }} diff --git a/src/pages/transactions/send/SendTransactionForm.tsx b/src/pages/transactions/send/SendTransactionForm.tsx index 1c4271c..82a921e 100644 --- a/src/pages/transactions/send/SendTransactionForm.tsx +++ b/src/pages/transactions/send/SendTransactionForm.tsx @@ -36,6 +36,14 @@ // modal that says "You currently don't have any saved wallets" etc, // and prevents opening the sendTX modal/rendering the page + const [from, setFrom] = useState(initialFrom); + const [to, setTo] = useState(""); + + function onValuesChange(changed: Partial) { + if (changed.from !== undefined) setFrom(changed.from); + if (changed.to !== undefined) setTo(changed.to); + } + return
{/* From */} @@ -61,14 +69,15 @@ walletsOnly name="from" label={t("sendTransaction.labelFrom")} - value={form.getFieldValue("from")} + value={from} /> {/* To */} ; }