mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-12-18 01:54:29 -05:00
feat(gui): Allow to select from recently used monero addresses (#139)
* feat(gui): Allow user to select from recently used monero addresses in textfield
This commit is contained in:
parent
4867d2713f
commit
bd3fca7e41
11 changed files with 271 additions and 78 deletions
|
|
@ -1,8 +1,18 @@
|
|||
import { TextField } from "@material-ui/core";
|
||||
import { Box, Button, Dialog, DialogActions, DialogContent, IconButton, List, ListItem, ListItemText, TextField } from "@material-ui/core";
|
||||
import { TextFieldProps } from "@material-ui/core/TextField/TextField";
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { getMoneroAddresses } from "renderer/rpc";
|
||||
import { isTestnet } from "store/config";
|
||||
import { isXmrAddressValid } from "utils/conversionUtils";
|
||||
import ImportContactsIcon from '@material-ui/icons/ImportContacts';
|
||||
import TruncatedText from "../other/TruncatedText";
|
||||
|
||||
type MoneroAddressTextFieldProps = TextFieldProps & {
|
||||
address: string;
|
||||
onAddressChange: (address: string) => void;
|
||||
onAddressValidityChange: (valid: boolean) => void;
|
||||
helperText: string;
|
||||
}
|
||||
|
||||
export default function MoneroAddressTextField({
|
||||
address,
|
||||
|
|
@ -10,30 +20,116 @@ export default function MoneroAddressTextField({
|
|||
onAddressValidityChange,
|
||||
helperText,
|
||||
...props
|
||||
}: {
|
||||
address: string;
|
||||
onAddressChange: (address: string) => void;
|
||||
onAddressValidityChange: (valid: boolean) => void;
|
||||
helperText: string;
|
||||
} & TextFieldProps) {
|
||||
}: MoneroAddressTextFieldProps) {
|
||||
const [addresses, setAddresses] = useState<string[]>([]);
|
||||
const [showDialog, setShowDialog] = useState(false);
|
||||
|
||||
// Validation
|
||||
const placeholder = isTestnet() ? "59McWTPGc745..." : "888tNkZrPN6J...";
|
||||
const errorText = isXmrAddressValid(address, isTestnet())
|
||||
? null
|
||||
: "Not a valid Monero address";
|
||||
|
||||
// Effects
|
||||
useEffect(() => {
|
||||
onAddressValidityChange(!errorText);
|
||||
}, [address, onAddressValidityChange, errorText]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchAddresses = async () => {
|
||||
const response = await getMoneroAddresses();
|
||||
setAddresses(response.addresses);
|
||||
};
|
||||
fetchAddresses();
|
||||
}, []);
|
||||
|
||||
// Event handlers
|
||||
const handleClose = () => setShowDialog(false);
|
||||
const handleAddressSelect = (selectedAddress: string) => {
|
||||
onAddressChange(selectedAddress);
|
||||
handleClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<TextField
|
||||
value={address}
|
||||
onChange={(e) => onAddressChange(e.target.value)}
|
||||
error={!!errorText && address.length > 0}
|
||||
helperText={address.length > 0 ? errorText || helperText : helperText}
|
||||
placeholder={placeholder}
|
||||
variant="outlined"
|
||||
{...props}
|
||||
/>
|
||||
<Box>
|
||||
<TextField
|
||||
value={address}
|
||||
onChange={(e) => onAddressChange(e.target.value)}
|
||||
error={!!errorText && address.length > 0}
|
||||
helperText={address.length > 0 ? errorText || helperText : helperText}
|
||||
placeholder={placeholder}
|
||||
variant="outlined"
|
||||
InputProps={{
|
||||
endAdornment: addresses?.length > 0 && (
|
||||
<IconButton onClick={() => setShowDialog(true)} size="small">
|
||||
<ImportContactsIcon />
|
||||
</IconButton>
|
||||
)
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
|
||||
<RecentlyUsedAddressesDialog
|
||||
open={showDialog}
|
||||
onClose={handleClose}
|
||||
addresses={addresses}
|
||||
onAddressSelect={handleAddressSelect}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
interface RecentlyUsedAddressesDialogProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
addresses: string[];
|
||||
onAddressSelect: (address: string) => void;
|
||||
}
|
||||
|
||||
function RecentlyUsedAddressesDialog({
|
||||
open,
|
||||
onClose,
|
||||
addresses,
|
||||
onAddressSelect
|
||||
}: RecentlyUsedAddressesDialogProps) {
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
maxWidth="sm"
|
||||
fullWidth
|
||||
>
|
||||
<DialogContent>
|
||||
<List>
|
||||
{addresses.map((addr) => (
|
||||
<ListItem
|
||||
button
|
||||
key={addr}
|
||||
onClick={() => onAddressSelect(addr)}
|
||||
>
|
||||
<ListItemText
|
||||
primary={
|
||||
<Box fontFamily="monospace">
|
||||
<TruncatedText limit={40} truncateMiddle>
|
||||
{addr}
|
||||
</TruncatedText>
|
||||
</Box>
|
||||
}
|
||||
secondary="Recently used as a redeem address"
|
||||
/>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={onClose}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue