From c04be520af0eb51b8fc0f3398c0cf48de9f0c7e9 Mon Sep 17 00:00:00 2001 From: WaDadidou Date: Tue, 11 Jul 2023 12:40:03 +0200 Subject: [PATCH] feat: add searching by TNS on wallet address inputs --- .../inputs/SearchNSInputContainer.tsx | 50 +++++++++++++++++++ packages/components/modals/SendModal.tsx | 37 ++++++++------ packages/components/user/AvatarWithName.tsx | 8 +-- 3 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 packages/components/inputs/SearchNSInputContainer.tsx diff --git a/packages/components/inputs/SearchNSInputContainer.tsx b/packages/components/inputs/SearchNSInputContainer.tsx new file mode 100644 index 0000000000..2b5d54fce9 --- /dev/null +++ b/packages/components/inputs/SearchNSInputContainer.tsx @@ -0,0 +1,50 @@ +import React, { FC } from "react"; +import { StyleProp, View, ViewStyle } from "react-native"; + +import { useNameSearch } from "../../hooks/search/useNameSearch"; +import { useSelectedNetworkId } from "../../hooks/useSelectedNetwork"; +import { layout } from "../../utils/style/layout"; +import { AvatarWithName } from "../user/AvatarWithName"; + +// Used as a wrapper on a TextInput or something like. It allows to search a name in TNS and returns the address. +export const SearchNSInputContainer: FC<{ + searchText: string; + onPressName: (userId: string) => void; + style?: StyleProp; +}> = ({ searchText, onPressName, style, children }) => { + const selectedNetworkId = useSelectedNetworkId(); + const { names } = useNameSearch({ + networkId: selectedNetworkId, + input: searchText, + limit: 12, + }); + const hasNames = !!names.length; + + return ( + <> + {children} + {hasNames && ( + + {names.map((n) => ( + onPressName(userId)} + style={{ marginRight: layout.padding_x1 }} + /> + ))} + + )} + + ); +}; diff --git a/packages/components/modals/SendModal.tsx b/packages/components/modals/SendModal.tsx index 308c6715d6..066f846bcf 100644 --- a/packages/components/modals/SendModal.tsx +++ b/packages/components/modals/SendModal.tsx @@ -36,6 +36,7 @@ import { SVG } from "../SVG"; import { MaxButton } from "../buttons/MaxButton"; import { PrimaryButton } from "../buttons/PrimaryButton"; import { DAOSelector } from "../dao/DAOSelector"; +import { SearchNSInputContainer } from "../inputs/SearchNSInputContainer"; import { TextInputCustom } from "../inputs/TextInputCustom"; import { SpacerColumn, SpacerRow } from "../spacer"; @@ -64,7 +65,7 @@ export const SendModal: React.FC = ({ }) => { const { setToastError, setToastSuccess } = useFeedbacks(); const selectedWallet = useSelectedWallet(); - const { control, setValue, handleSubmit } = useForm(); + const { control, setValue, handleSubmit, watch } = useForm(); const [selectedDAOId, setSelectedDAOId] = useState(""); const makeProposal = useDAOMakeProposal(selectedDAOId); const [, daoAddress] = parseUserId(selectedDAOId); @@ -206,19 +207,27 @@ export const SendModal: React.FC = ({ > - - height={48} - width={320} - control={control} - variant="labelOutside" - label="Receiver" - name="toAddress" - rules={{ required: true }} - placeHolder={`Enter a ${ - getNetwork(networkId)?.displayName || networkId - } address`} - defaultValue="" - /> + { + const [, userAddress] = parseUserId(userId); + setValue("toAddress", userAddress); + }} + searchText={watch("toAddress")} + > + + height={48} + width={320} + control={control} + variant="labelOutside" + label="Receiver" + name="toAddress" + rules={{ required: true }} + placeHolder={`Enter a ${ + getNetwork(networkId)?.displayName || networkId + } address`} + defaultValue="" + /> + diff --git a/packages/components/user/AvatarWithName.tsx b/packages/components/user/AvatarWithName.tsx index 3b585d5292..f2a83d4ca8 100644 --- a/packages/components/user/AvatarWithName.tsx +++ b/packages/components/user/AvatarWithName.tsx @@ -18,7 +18,7 @@ export const AvatarWithName: React.FC< userId: string | undefined; } ) & { - style: StyleProp; + style?: StyleProp; onPress: (userId: string) => void; } > = (props) => { @@ -31,7 +31,7 @@ export const AvatarWithName: React.FC< export const AvatarWithNameFromName: React.FC<{ networkId: string | undefined; name: string | undefined; - style: StyleProp; + style?: StyleProp; onPress: (userId: string) => void; }> = ({ networkId, name, style, onPress }) => { const { nameOwner } = useNSNameOwner(networkId, name); @@ -47,7 +47,7 @@ export const AvatarWithNameFromName: React.FC<{ export const AvatarWithNameFromUserId: React.FC<{ userId: string | undefined; - style: StyleProp; + style?: StyleProp; onPress: (userId: string) => void; }> = ({ userId, style, onPress }) => { const { primaryAlias } = useNSPrimaryAlias(userId); @@ -64,7 +64,7 @@ export const AvatarWithNameFromUserId: React.FC<{ export const AvatarWithNameView: React.FC<{ name: string | undefined; userId: string | undefined; - style: StyleProp; + style?: StyleProp; onPress: (userId: string) => void; }> = ({ name, userId, style, onPress }) => { const [, userAddress] = parseUserId(userId);