Skip to content

Commit

Permalink
add & edit contacts
Browse files Browse the repository at this point in the history
  • Loading branch information
rastajpa committed Apr 13, 2023
1 parent 0de5253 commit e858c56
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 42 deletions.
5 changes: 3 additions & 2 deletions src/components/list/ContactRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export interface ContactRowProps {
tag?: number; // backward compatibility
destinationTag?: number;
email?: string;
domain?: string;
}

interface Props {
Expand All @@ -49,7 +50,7 @@ interface Props {
const ContactRow = ({contact, onPress}: Props) => {
const theme = useTheme();
const underlayColor = theme.dark ? '#121212' : '#fbfbff';
const {coin: _coin, name, email, address, chain} = contact;
const {coin: _coin, name, email, address, chain, domain} = contact;
const coin = getCurrencyAbbreviation(_coin, chain);
return (
<ContactContainer underlayColor={underlayColor} onPress={onPress}>
Expand All @@ -60,7 +61,7 @@ const ContactRow = ({contact, onPress}: Props) => {
<ContactColumn>
<H5>{name}</H5>
<ListItemSubText numberOfLines={1} ellipsizeMode={'tail'}>
{email ? email : address}
{domain ? domain : email ? email : address}
</ListItemSubText>
</ContactColumn>
<AngleRight />
Expand Down
172 changes: 137 additions & 35 deletions src/navigation/tabs/contacts/screens/ContactsAdd.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ import {
import Checkbox from '../../../../components/checkbox/Checkbox';
import {IsERCToken} from '../../../../store/wallet/utils/currency';
import {Analytics} from '../../../../store/analytics/analytics.effects';
import {
getAddressByENSDomain,
getAddressByUnstoppableDomain,
getENSDomainByAddress,
} from '../../../../store/moralis/moralis.effects';

const InputContainer = styled.View<{hideInput?: boolean}>`
display: ${({hideInput}) => (!hideInput ? 'flex' : 'none')};
Expand Down Expand Up @@ -149,6 +154,7 @@ const schema = yup.object().shape({
email: yup.string().email().trim(),
destinationTag: yup.number(),
address: yup.string().required(),
domain: yup.string(),
});

const SearchImageContainer = styled.View`
Expand Down Expand Up @@ -193,6 +199,7 @@ const ContactsAdd = ({
const dispatch = useAppDispatch();

const [validAddress, setValidAddress] = useState(false);
const [validDomain, setValidDomain] = useState(false);
const [xrpValidAddress, setXrpValidAddress] = useState(false);
const [evmValidAddress, setEvmValidAddress] = useState(false);
const [searchInput, setSearchInput] = useState('');
Expand All @@ -201,6 +208,7 @@ const ContactsAdd = ({
const [coinValue, setCoinValue] = useState('');
const [networkValue, setNetworkValue] = useState('');
const [chainValue, setChainValue] = useState('');
const [domainValue, setDomainValue] = useState('');

const [tokenModalVisible, setTokenModalVisible] = useState(false);
const [currencyModalVisible, setCurrencyModalVisible] = useState(false);
Expand Down Expand Up @@ -298,12 +306,15 @@ const ContactsAdd = ({
coin: string,
network: string,
chain: string,
domain: string,
) => {
setValidAddress(true);
setAddressValue(address);
setCoinValue(coin);
setNetworkValue(network);
setChainValue(chain);
setValidDomain(true);
setDomainValue(domain);

_setSelectedCurrency(coin);

Expand All @@ -319,13 +330,19 @@ const ContactsAdd = ({
return;
}
};

const processAddress = (
address?: string,
coin?: string,
network?: string,
chain?: string,
) => {
const processAddressOrDomain = ({
address,
coin,
network,
chain,
domain,
}: {
address?: string;
coin?: string;
network?: string;
chain?: string;
domain?: string;
}) => {
if (address) {
const coinAndNetwork = GetCoinAndNetwork(address, undefined, chain);
if (coinAndNetwork) {
Expand All @@ -340,6 +357,7 @@ const ContactsAdd = ({
coin || coinAndNetwork.coin,
network || coinAndNetwork.network,
chain || coinAndNetwork.coin,
domain || '',
);
} else {
// try testnet
Expand All @@ -354,29 +372,79 @@ const ContactsAdd = ({
coin || coinAndNetwork.coin,
network || 'testnet',
chain || coinAndNetwork.coin,
domain || '',
);
}
}
} else {
setCoinValue('');
setNetworkValue('');
setAddressValue('');
setValidAddress(false);
setEvmValidAddress(false);
setXrpValidAddress(false);
processDomain({domain: address});
}
} else {
resetValues();
}
};

const processDomain = useMemo(
() =>
debounce(async ({domain}: {domain: string}) => {
try {
if (!domain) {
return;
}

const addressByENS = await dispatch(getAddressByENSDomain({domain}));
const addressByUnstoppableDomain = await dispatch(
getAddressByUnstoppableDomain({domain}),
);

if (addressByENS || addressByUnstoppableDomain) {
setValidDomain(true);
processAddressOrDomain({
address: addressByENS || addressByUnstoppableDomain,
domain,
});
} else {
resetValues();
}
} catch (e) {
resetValues();
}
}, 300),
[],
);

const resetValues = () => {
setCoinValue('');
setNetworkValue('');
setAddressValue('');
setValidAddress(false);
setEvmValidAddress(false);
setXrpValidAddress(false);
setValidDomain(false);
};

const onSubmit = handleSubmit((contact: ContactRowProps) => {
if (!validAddress) {
setError('address', {
type: 'manual',
message: t('Invalid address'),
message: t('Invalid address or domain'),
});
return;
}

if (!validDomain && domainValue) {
setError('domain', {
type: 'manual',
message: t('Invalid domain'),
});
return;
}

if (addressValue && domainValue) {
contact.address = addressValue;
contact.domain = domainValue;
}

if (coinValue && chainValue && networkValue) {
contact.coin = coinValue;
contact.chain = chainValue;
Expand Down Expand Up @@ -515,27 +583,47 @@ const ContactsAdd = ({
params: {
onScanComplete: address => {
setValue('address', address, {shouldDirty: true});
processAddress(address);
processAddressOrDomain({address});
},
},
});
};

const fetchENSDomainByAddress = async () => {
try {
const domain = await dispatch(
getENSDomainByAddress({address: addressValue}),
);
if (domain) {
setValue('domain', domain);
setDomainValue(domain);
setValidDomain(true);
}
} catch (err) {
console.error(err);
}
};

useEffect(() => {
if (contact) {
processAddress(
contact.address,
contact.coin,
contact.network,
contact.chain,
);
processAddressOrDomain({
address: contact.address,
coin: contact.coin,
network: contact.network,
chain: contact.chain,
domain: contact.domain,
});
setValue('address', contact.address!, {shouldDirty: true});
setValue('name', contact.name || '');
setValue('email', contact.email);
setValue('chain', contact.chain!);
setValue('destinationTag', contact.tag || contact.destinationTag);
setValue('domain', contact.domain);
if (context === 'edit' && evmValidAddress && !domainValue) {
fetchENSDomainByAddress();
}
}
}, [contact]);
}, [contact, evmValidAddress]);

return (
<Container keyboardShouldPersistTaps="handled">
Expand Down Expand Up @@ -580,12 +668,12 @@ const ContactsAdd = ({
control={control}
render={({field: {onChange, onBlur, value}}) => (
<BoxInput
placeholder={'Crypto address'}
label={t('ADDRESS')}
placeholder={'Crypto address or domain'}
label={t('ADDRESS OR DOMAIN')}
onBlur={onBlur}
onChangeText={(newValue: string) => {
onChange(newValue);
processAddress(newValue);
processAddressOrDomain({address: newValue});
}}
error={errors.address?.message}
value={value}
Expand All @@ -605,16 +693,30 @@ const ContactsAdd = ({
)}
</InputContainer>
) : (
<InputContainer>
<Controller
control={control}
render={({field: {value}}) => (
<BoxInput disabled={true} label={t('ADDRESS')} value={value} />
)}
name="address"
defaultValue=""
/>
</InputContainer>
<>
<InputContainer>
<Controller
control={control}
render={({field: {value}}) => (
<BoxInput disabled={true} label={t('ADDRESS')} value={value} />
)}
name="address"
defaultValue=""
/>
</InputContainer>
{evmValidAddress && domainValue ? (
<InputContainer>
<Controller
control={control}
render={({field: {value}}) => (
<BoxInput disabled={true} label={t('DOMAIN')} value={value} />
)}
name="domain"
defaultValue=""
/>
</InputContainer>
) : null}
</>
)}

{!contact && evmValidAddress ? (
Expand Down
9 changes: 9 additions & 0 deletions src/navigation/tabs/contacts/screens/ContactsDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,15 @@ const ContactsDetails = ({
</AddressContainer>
</DetailInfo>
</Detail>
{contact.domain ? (
<>
<Hr />
<Detail>
<Title>{t('Domain')}</Title>
<DetailInfo align="right">{contact.domain}</DetailInfo>
</Detail>
</>
) : null}
{contact.network !== 'livenet' ? (
<>
<Hr />
Expand Down
6 changes: 4 additions & 2 deletions src/navigation/tabs/contacts/screens/ContactsRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,10 @@ const ContactsRoot: React.FC = () => {

const updateSearchResults = debounce((text: string) => {
setSearchVal(text);
const results = contactList.filter(contact =>
contact.name.toLowerCase().includes(text.toLocaleLowerCase()),
const results = contactList.filter(
contact =>
contact.name.toLowerCase().includes(text.toLocaleLowerCase()) ||
contact.domain?.toLowerCase().includes(text.toLowerCase()),
);
setSearchResults(results);
}, 300);
Expand Down
1 change: 1 addition & 0 deletions src/store/contact/contact.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ interface DeleteContact {
coin: string;
network: string;
chain?: string;
domain?: string;
}

interface MigrateContacts {
Expand Down
Loading

0 comments on commit e858c56

Please sign in to comment.