diff --git a/assets/default-images/tns-profile-cover.png b/assets/default-images/tns-profile-cover.png
new file mode 100644
index 0000000000..81cfe808d0
Binary files /dev/null and b/assets/default-images/tns-profile-cover.png differ
diff --git a/assets/icons/upload-cloud.svg b/assets/icons/upload-cloud.svg
new file mode 100644
index 0000000000..99540948f5
--- /dev/null
+++ b/assets/icons/upload-cloud.svg
@@ -0,0 +1,11 @@
+
diff --git a/package.json b/package.json
index 59359bce07..6c1bb445ba 100644
--- a/package.json
+++ b/package.json
@@ -71,6 +71,7 @@
"expo": "^49.0.16",
"expo-av": "~13.4.1",
"expo-barcode-scanner": "~12.5.3",
+ "expo-document-picker": "~11.5.4",
"expo-font": "~11.4.0",
"expo-linear-gradient": "~12.3.0",
"expo-optimize": "^0.2.20",
diff --git a/packages/components/OptimizedImage.tsx b/packages/components/OptimizedImage.tsx
index 7baade4989..87ef21296f 100644
--- a/packages/components/OptimizedImage.tsx
+++ b/packages/components/OptimizedImage.tsx
@@ -1,5 +1,5 @@
import { CID } from "multiformats";
-import React, { memo } from "react";
+import React, { memo, useEffect } from "react";
import { Image, ImageProps, View, StyleSheet, PixelRatio } from "react-native";
import { neutral33 } from "../utils/style/colors";
@@ -22,12 +22,27 @@ export const OptimizedImage: React.FC<
const sourceWidth = PixelRatio.getPixelSizeForLayoutSize(width);
const sourceHeight = PixelRatio.getPixelSizeForLayoutSize(height);
+ useEffect(() => {
+ setIsError(false);
+ }, [baseSourceURI]);
+
+ useEffect(() => {
+ setIsFallbackError(false);
+ }, [fallbackURI]);
+
if ((shouldUseFallback && !fallbackURI) || isFallbackError) {
return (
extends Omit {
label: string;
variant?: "regular" | "labelOutside" | "noStyle";
iconSVG?: React.FC;
+ onPressChildren?: () => void;
placeHolder?: string;
squaresBackgroundColor?: string;
style?: StyleProp;
@@ -139,6 +143,7 @@ export const TextInputCustom = ({
subtitle,
labelStyle,
iconSVG,
+ onPressChildren,
hideLabel,
valueModifier,
errorStyle,
@@ -292,9 +297,10 @@ export const TextInputCustom = ({
{...restProps}
/>
-
{isLoading ? (
+ ) : onPressChildren ? (
+ {children}
) : (
<>{children}>
)}
diff --git a/packages/components/modals/teritoriNameService/TNSNameFinderModal.tsx b/packages/components/modals/teritoriNameService/TNSNameFinderModal.tsx
index d8ededb4d1..b4ee13a381 100644
--- a/packages/components/modals/teritoriNameService/TNSNameFinderModal.tsx
+++ b/packages/components/modals/teritoriNameService/TNSNameFinderModal.tsx
@@ -120,7 +120,7 @@ export const TNSNameFinderModal: React.FC<{
}
width={372}
>
diff --git a/packages/components/teritoriNameService/MediaPreview.tsx b/packages/components/teritoriNameService/MediaPreview.tsx
new file mode 100644
index 0000000000..07f85e7c4c
--- /dev/null
+++ b/packages/components/teritoriNameService/MediaPreview.tsx
@@ -0,0 +1,182 @@
+import * as DocumentPicker from "expo-document-picker";
+import { DocumentPickerResult } from "expo-document-picker";
+import React, { Dispatch, SetStateAction, useState } from "react";
+import { ActivityIndicator, View, ViewStyle } from "react-native";
+import { useSelector } from "react-redux";
+
+import tnsProfileAvatar from "../../../assets/default-images/default-name-nft.png";
+import tnsProfileCover from "../../../assets/default-images/tns-profile-cover.png";
+import uploadCloudIcon from "../../../assets/icons/upload-cloud.svg";
+import { useFeedbacks } from "../../context/FeedbacksProvider";
+import { Metadata } from "../../contracts-clients/teritori-name-service/TeritoriNameService.types";
+import { PinataFileProps, useIpfs } from "../../hooks/useIpfs";
+import { useSelectedNetworkInfo } from "../../hooks/useSelectedNetwork";
+import useSelectedWallet from "../../hooks/useSelectedWallet";
+import { selectNFTStorageAPI } from "../../store/slices/settings";
+import { generateIpfsKey } from "../../utils/ipfs";
+import {
+ neutral00,
+ neutral17,
+ neutral33,
+ secondaryColor,
+} from "../../utils/style/colors";
+import { layout } from "../../utils/style/layout";
+import { OptimizedImage } from "../OptimizedImage";
+import { SVG } from "../SVG";
+import { TextInputCustom } from "../inputs/TextInputCustom";
+
+export const MediaPreview: React.FC<{
+ style: ViewStyle;
+ avatarImageUrl: string;
+ setAvatarImageUrl: Dispatch>;
+ bannerImageUrl: string;
+ setBannerImageUrl: Dispatch>;
+}> = ({
+ style,
+ avatarImageUrl,
+ setAvatarImageUrl,
+ bannerImageUrl,
+ setBannerImageUrl,
+}) => {
+ const selectedNetwork = useSelectedNetworkInfo();
+ const selectedWallet = useSelectedWallet();
+ const { setToastError } = useFeedbacks();
+ const { pinataPinFileToIPFS } = useIpfs();
+ const userId = selectedWallet?.userId;
+ const [isAvatarImageUploadLoading, setAvatarImageUploadLoading] =
+ useState(false);
+ const [isBannerImageUploadLoading, setBannerImageUploadLoading] =
+ useState(false);
+ const userIPFSKey = useSelector(selectNFTStorageAPI);
+
+ const upload = async (
+ callback: Dispatch>,
+ documentPickerResult: DocumentPickerResult,
+ ) => {
+ const pinataJWTKey =
+ userIPFSKey || (await generateIpfsKey(selectedNetwork?.id || "", userId));
+ if (!pinataJWTKey) {
+ console.error("upload file err : No Pinata JWT");
+ setToastError({
+ title: "File upload failed",
+ message: "No Pinata JWT",
+ });
+ return;
+ }
+ if (documentPickerResult.output) {
+ const fileIpfsHash = await pinataPinFileToIPFS({
+ pinataJWTKey,
+ file: { file: documentPickerResult.output[0] },
+ } as PinataFileProps);
+ callback(`ipfs://${fileIpfsHash}`);
+ }
+ };
+
+ const onPressUploadAvatar = async () => {
+ const documentPickerResult = await DocumentPicker.getDocumentAsync({
+ multiple: false,
+ });
+ setAvatarImageUploadLoading(true);
+ await upload(setAvatarImageUrl, documentPickerResult);
+ setAvatarImageUploadLoading(false);
+ };
+
+ const onPressUploadBanner = async () => {
+ const documentPickerResult = await DocumentPicker.getDocumentAsync({
+ multiple: false,
+ });
+ setBannerImageUploadLoading(true);
+ await upload(setBannerImageUrl, documentPickerResult);
+ setBannerImageUploadLoading(false);
+ };
+
+ return (
+
+
+ name="image"
+ style={style}
+ label="Avatar URL"
+ noBrokenCorners
+ variant="labelOutside"
+ placeHolder="https://website.com/avatar.jpg"
+ onPressChildren={onPressUploadAvatar}
+ value={avatarImageUrl}
+ onChangeText={setAvatarImageUrl}
+ squaresBackgroundColor={neutral17}
+ >
+ {isAvatarImageUploadLoading ? (
+
+ ) : (
+
+ )}
+
+
+
+ name="public_profile_header"
+ style={style}
+ label="Cover Image URL"
+ noBrokenCorners
+ onPressChildren={onPressUploadBanner}
+ variant="labelOutside"
+ placeHolder="https://website.com/coverimage.jpg"
+ value={bannerImageUrl}
+ onChangeText={setBannerImageUrl}
+ squaresBackgroundColor={neutral17}
+ >
+ {isBannerImageUploadLoading ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+
+
+ );
+};
diff --git a/packages/components/teritoriNameService/NameData.tsx b/packages/components/teritoriNameService/NameData.tsx
deleted file mode 100644
index 35f2eca1ea..0000000000
--- a/packages/components/teritoriNameService/NameData.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-import React from "react";
-import { View, ViewStyle } from "react-native";
-
-import { neutral17, neutral77 } from "../../utils/style/colors";
-import { imageDisplayLabel, prettyTokenData } from "../../utils/teritori";
-import { BrandText } from "../BrandText";
-import { ExternalLink } from "../ExternalLink";
-import { LegacyTertiaryBox } from "../boxes/LegacyTertiaryBox";
-
-export const NameData: React.FC<{
- token: any;
- name: string;
- style?: ViewStyle;
-}> = ({ token, name, style }) => {
- const width = 396;
-
- return (
-
- {token ? (
- <>
-
-
- Name
-
-
- {name}
-
-
-
-
- {prettyTokenData(token)
- // We display only the raw if there is a value
- .filter((data) => data.value)
- .map((data, i) => (
-
-
- {data.displayLabel}
-
- {/*---- We want some style depending on the data type*/}
- {data.displayLabel === imageDisplayLabel ? (
-
- {data.value}
-
- ) : (
-
- {data.value}
-
- )}
-
- ))}
-
- >
- ) : (
- Loading
- )}
-
- );
-};
diff --git a/packages/components/teritoriNameService/NameDataForm.tsx b/packages/components/teritoriNameService/NameDataForm.tsx
index 4f72753a14..8d0b1b5040 100644
--- a/packages/components/teritoriNameService/NameDataForm.tsx
+++ b/packages/components/teritoriNameService/NameDataForm.tsx
@@ -1,15 +1,15 @@
import React, { useEffect, useState } from "react";
import { View, ViewStyle } from "react-native";
+import { MediaPreview } from "./MediaPreview";
import { Metadata } from "../../contracts-clients/teritori-name-service/TeritoriNameService.types";
import { neutral17, neutral77 } from "../../utils/style/colors";
+import { layout } from "../../utils/style/layout";
import { BrandText } from "../BrandText";
import { ExternalLink } from "../ExternalLink";
import { PrimaryButton } from "../buttons/PrimaryButton";
import { TextInputCustom } from "../inputs/TextInputCustom";
-// TODO: Later, create a reusable FormBase cpt to avoid writing too much code and call it in NameDataForm.tsx. Maybe use react-hook-form ?
-
export const NameDataForm: React.FC<{
isMintPath?: boolean;
btnLabel: string;
@@ -20,8 +20,8 @@ export const NameDataForm: React.FC<{
const [pathId, setPathId] = useState("");
const [publicName, setPublicName] = useState("");
const [public_bio, setBio] = useState("");
- const [image, setImageUrl] = useState("");
- const [bannerImage, setBannerImage] = useState("");
+ const [avatarImageUrl, setAvatarImageUrl] = useState("");
+ const [bannerImageUrl, setBannerImageUrl] = useState("");
const [email, setEmail] = useState("");
const [external_url, setWebsite] = useState("");
const [twitter_id, setTwitter] = useState("");
@@ -40,8 +40,8 @@ export const NameDataForm: React.FC<{
pathId,
public_name: publicName,
public_bio,
- image,
- public_profile_header: bannerImage,
+ image: avatarImageUrl,
+ public_profile_header: bannerImageUrl,
email,
external_url,
twitter_id,
@@ -54,8 +54,8 @@ export const NameDataForm: React.FC<{
// Setting initial inputs values (Pre-filled values if existing token)
useEffect(() => {
setBio(initialData.public_bio || "");
- setImageUrl(initialData.image || "");
- setBannerImage(initialData.public_profile_header || "");
+ setAvatarImageUrl(initialData.image || "");
+ setBannerImageUrl(initialData.public_profile_header || "");
setEmail(initialData.email || "");
setWebsite(initialData.external_url || "");
setTwitter(initialData.twitter_id || "");
@@ -70,6 +70,7 @@ export const NameDataForm: React.FC<{
{isMintPath ? (
@@ -97,9 +98,12 @@ export const NameDataForm: React.FC<{
.
+
+ {/*// TODO: Refacto TextInputCustom and fix usages*/}
+
name="pathId"
- style={inputStyle}
+ containerStyle={inputStyle}
label="Path ID (must be unique)"
placeHolder="Type path ID here"
value={pathId}
@@ -110,8 +114,11 @@ export const NameDataForm: React.FC<{
) : null}
name="name"
- style={[inputStyle, !isMintPath && { marginTop: 4 }]}
- label="NAME"
+ containerStyle={inputStyle}
+ label="Name"
+ rules={{ required: true }}
+ noBrokenCorners
+ variant="labelOutside"
placeHolder="Type name here"
value={publicName}
onChangeText={setPublicName}
@@ -120,35 +127,29 @@ export const NameDataForm: React.FC<{
/>
name="public_bio"
- style={inputStyle}
- label="BIO"
+ containerStyle={inputStyle}
+ label="Bio"
+ noBrokenCorners
+ variant="labelOutside"
placeHolder="Type bio here"
value={public_bio}
onChangeText={setBio}
squaresBackgroundColor={neutral17}
/>
-
- name="image"
- style={inputStyle}
- label="AVATAR IMAGE URL"
- placeHolder="Insert image URL here"
- value={image}
- onChangeText={setImageUrl}
- squaresBackgroundColor={neutral17}
- />
-
- name="public_profile_header"
+
+
name="email"
- style={inputStyle}
- label="EMAIL"
+ containerStyle={inputStyle}
+ label="Email"
+ noBrokenCorners
+ variant="labelOutside"
placeHolder="Type email here"
value={email}
onChangeText={setEmail}
@@ -156,8 +157,10 @@ export const NameDataForm: React.FC<{
/>
name="external_url"
- style={inputStyle}
- label="WEBSITE"
+ containerStyle={inputStyle}
+ label="Website"
+ noBrokenCorners
+ variant="labelOutside"
placeHolder="Type/insert link here"
value={external_url}
onChangeText={setWebsite}
@@ -165,8 +168,10 @@ export const NameDataForm: React.FC<{
/>
name="twitter_id"
- style={inputStyle}
- label="TWITTER"
+ containerStyle={inputStyle}
+ label="Twitter (X)"
+ noBrokenCorners
+ variant="labelOutside"
placeHolder="Link to Twitter account"
value={twitter_id}
onChangeText={setTwitter}
@@ -174,8 +179,10 @@ export const NameDataForm: React.FC<{
/>
name="discord_id"
- style={inputStyle}
- label="DISCORD"
+ containerStyle={inputStyle}
+ label="Discord"
+ noBrokenCorners
+ variant="labelOutside"
placeHolder="Link to Discord"
value={discord_id}
onChangeText={setDiscord}
@@ -183,8 +190,10 @@ export const NameDataForm: React.FC<{
/>
name="telegram_id"
- style={inputStyle}
- label="TELEGRAM USERNAME"
+ containerStyle={inputStyle}
+ label="Telegram Username"
+ noBrokenCorners
+ variant="labelOutside"
placeHolder="@nickname"
value={telegram_id}
onChangeText={setTelegrameUsername}
@@ -192,8 +201,10 @@ export const NameDataForm: React.FC<{
/>
name="keybase_id"
- style={inputStyle}
- label="KEYBASE.IO"
+ containerStyle={inputStyle}
+ label="Keybase.io"
+ noBrokenCorners
+ variant="labelOutside"
placeHolder="Type/insert link here"
value={keybase_id}
onChangeText={setKeybaseIo}
@@ -201,19 +212,21 @@ export const NameDataForm: React.FC<{
/>
name="validator_operator_address"
- style={inputStyle}
- label="VALIDATOR OPERATOR ADDRESS"
+ containerStyle={inputStyle}
+ label="Validator Operator Address"
+ noBrokenCorners
+ variant="labelOutside"
placeHolder="Type/insert link here"
value={validator_operator_address}
onChangeText={setValidatorOperatorAddress}
squaresBackgroundColor={neutral17}
/>
diff --git a/packages/components/teritoriNameService/NameStatus.tsx b/packages/components/teritoriNameService/NameStatus.tsx
index 3d554709de..5b37e0956b 100644
--- a/packages/components/teritoriNameService/NameStatus.tsx
+++ b/packages/components/teritoriNameService/NameStatus.tsx
@@ -7,7 +7,6 @@ import { BrandText } from "../BrandText";
import { SVG } from "../SVG";
import { LegacyTertiaryBox } from "../boxes/LegacyTertiaryBox";
-// A custom TextInput. You can add children (Ex: An icon or a small container)
export const NameStatus: React.FC<{
available?: boolean;
hasError?: boolean;
diff --git a/packages/hooks/useIpfs.ts b/packages/hooks/useIpfs.ts
index 30ec447eae..5a398073b5 100644
--- a/packages/hooks/useIpfs.ts
+++ b/packages/hooks/useIpfs.ts
@@ -5,11 +5,6 @@ import { useState } from "react";
import { LocalFileData, RemoteFileData } from "../utils/types/files";
-interface PinataFileProps {
- file: LocalFileData;
- pinataJWTKey: string;
-}
-
interface UploadPostFilesToPinataParams {
files: LocalFileData[];
pinataJWTKey: string;
@@ -20,6 +15,11 @@ interface IPFSUploadProgress {
progress: number; // 0 to 1
}
+export interface PinataFileProps {
+ file: LocalFileData;
+ pinataJWTKey: string;
+}
+
export const useIpfs = () => {
const [ipfsUploadProgresses, setIpfsUploadProgresses] = useState<
IPFSUploadProgress[]
@@ -57,7 +57,7 @@ export const useIpfs = () => {
"Content-Type": "multipart/form-data",
},
});
- return responseFile.data.IpfsHash;
+ return CID.parse(responseFile.data.IpfsHash).toV1().toString();
} catch (err) {
console.error("Error pinning " + file.fileName + " to IPFS", err);
}
@@ -74,9 +74,7 @@ export const useIpfs = () => {
file,
pinataJWTKey,
});
- const url = !fileIpfsHash
- ? ""
- : "ipfs://" + CID.parse(fileIpfsHash).toV1().toString();
+ const url = !fileIpfsHash ? "" : "ipfs://" + fileIpfsHash;
if (file.thumbnailFileData) {
const thumbnailFileIpfsHash = await pinataPinFileToIPFS({
@@ -85,7 +83,7 @@ export const useIpfs = () => {
});
const thumbnailUrl = !thumbnailFileIpfsHash
? ""
- : "ipfs://" + CID.parse(thumbnailFileIpfsHash).toV1().toString();
+ : "ipfs://" + thumbnailFileIpfsHash;
return {
...omit(file, "file"),
@@ -128,5 +126,9 @@ export const useIpfs = () => {
0,
) / ipfsUploadProgresses.length;
- return { uploadFilesToPinata, ipfsUploadProgress: finalProgress };
+ return {
+ uploadFilesToPinata,
+ pinataPinFileToIPFS,
+ ipfsUploadProgress: finalProgress,
+ };
};
diff --git a/packages/screens/TeritoriNameService/TNSBurnNameScreen.tsx b/packages/screens/TeritoriNameService/TNSBurnNameScreen.tsx
index 3cb2a34473..e91ec16604 100644
--- a/packages/screens/TeritoriNameService/TNSBurnNameScreen.tsx
+++ b/packages/screens/TeritoriNameService/TNSBurnNameScreen.tsx
@@ -16,10 +16,12 @@ import { nsNameInfoQueryKey } from "../../hooks/useNSNameInfo";
import { useNSTokensByOwner } from "../../hooks/useNSTokensByOwner";
import useSelectedWallet from "../../hooks/useSelectedWallet";
import {
+ getCosmosNetwork,
getKeplrSigningCosmWasmClient,
mustGetCosmosNetwork,
} from "../../networks";
-import { neutral17 } from "../../utils/style/colors";
+import { neutral17, neutralA3 } from "../../utils/style/colors";
+import { layout } from "../../utils/style/layout";
interface TNSBurnNameScreenProps extends TNSModalCommonProps {}
@@ -29,10 +31,12 @@ export const TNSBurnNameScreen: React.FC = ({
const { name } = useTNS();
const { setToastError, setToastSuccess } = useFeedbacks();
const selectedWallet = useSelectedWallet();
- const network = mustGetCosmosNetwork(selectedWallet?.networkId);
+ const network = getCosmosNetwork(selectedWallet?.networkId);
const { tokens } = useNSTokensByOwner(selectedWallet?.userId);
const walletAddress = selectedWallet?.address;
- const normalizedTokenId = (name + network.nameServiceTLD || "").toLowerCase();
+ const normalizedTokenId = (
+ name + network?.nameServiceTLD || ""
+ ).toLowerCase();
const queryClient = useQueryClient();
@@ -53,6 +57,7 @@ export const TNSBurnNameScreen: React.FC = ({
}
try {
+ const network = mustGetCosmosNetwork(selectedWallet?.networkId);
if (!network.nameServiceContractAddress) {
throw new Error("network not supported");
}
@@ -93,6 +98,7 @@ export const TNSBurnNameScreen: React.FC = ({
onClose()}
+ label="Burn Name NFT"
width={457}
boxStyle={{
backgroundColor: neutral17,
@@ -131,7 +137,7 @@ export const TNSBurnNameScreen: React.FC = ({
style={{
fontSize: 16,
lineHeight: 20,
- color: "#A3A3A3",
+ color: neutralA3,
marginTop: 16,
marginBottom: 20,
}}
@@ -145,7 +151,7 @@ export const TNSBurnNameScreen: React.FC = ({
size="XS"
text="I understand, burn it"
onPress={onSubmit}
- style={{ marginBottom: 80 }}
+ style={{ marginBottom: layout.spacing_x4 }}
loader
/>
diff --git a/packages/screens/TeritoriNameService/TNSConsultNameScreen.tsx b/packages/screens/TeritoriNameService/TNSConsultNameScreen.tsx
index 551b02cea0..696a49222d 100644
--- a/packages/screens/TeritoriNameService/TNSConsultNameScreen.tsx
+++ b/packages/screens/TeritoriNameService/TNSConsultNameScreen.tsx
@@ -4,12 +4,10 @@ import { View } from "react-native";
import { TNSModalCommonProps } from "./TNSHomeScreen";
import { BrandText } from "../../components/BrandText";
-import { CopyToClipboard } from "../../components/CopyToClipboard";
import { PrimaryButton } from "../../components/buttons/PrimaryButton";
import { SecondaryButton } from "../../components/buttons/SecondaryButton";
import ModalBase from "../../components/modals/ModalBase";
import { TNSSendFundsModal } from "../../components/modals/teritoriNameService/TNSSendFundsModal";
-import { NameData } from "../../components/teritoriNameService/NameData";
import { NameNFT } from "../../components/teritoriNameService/NameNFT";
import { useFeedbacks } from "../../context/FeedbacksProvider";
import { useTNS } from "../../context/TNSProvider";
@@ -33,6 +31,7 @@ import {
} from "../../networks";
import { useAppNavigation } from "../../utils/navigation";
import { neutral17, neutral33 } from "../../utils/style/colors";
+import { layout } from "../../utils/style/layout";
const NotOwnerActions: React.FC<{
tokenId: string;
@@ -57,8 +56,8 @@ const NotOwnerActions: React.FC<{
{isPrimary && (
{
onClose();
navigation.navigate("UserPublicProfile", { id: ownerId });
@@ -68,7 +67,7 @@ const NotOwnerActions: React.FC<{
setSendFundsModalVisible(true)}
/>
@@ -95,24 +94,25 @@ const OwnerActions: React.FC<{
style={{
flexDirection: "row",
alignItems: "center",
- marginBottom: 42,
+ justifyContent: "center",
+ marginBottom: layout.spacing_x3,
alignSelf: "center",
}}
>
{isPrimary && (
{
+ onClose();
navigation.navigate("UserPublicProfile", { id: ownerId });
}}
/>
)}
{
onClose("TNSUpdateName");
}}
@@ -120,7 +120,7 @@ const OwnerActions: React.FC<{
{
onClose("TNSBurnName");
}}
@@ -130,7 +130,7 @@ const OwnerActions: React.FC<{
size="M"
text="Set as Primary"
loader
- style={{ marginLeft: 24 }}
+ style={{ marginLeft: layout.spacing_x3 }}
onPress={async () => {
try {
const network = mustGetCosmosNetwork(wallet?.networkId);
@@ -178,11 +178,12 @@ export const TNSConsultNameScreen: React.FC = ({
const networkId = useSelectedNetworkId();
const network = getCosmosNetwork(networkId);
const tokenId = (name + network?.nameServiceTLD || "").toLowerCase();
- const { nsInfo: token, notFound } = useNSNameInfo(
+ const { notFound } = useNSNameInfo(
networkId,
tokenId,
!!network?.nameServiceTLD,
);
+
const { nameOwner } = useNSNameOwner(networkId, tokenId);
const ownerId = getUserId(networkId, nameOwner);
const { daos } = useDAOs({ networkId, memberAddress: wallet?.address });
@@ -213,14 +214,16 @@ export const TNSConsultNameScreen: React.FC = ({
{notFound ? (
Not found
) : (
<>
-
+
{!notFound &&
(isOwnedByUser ? (
= ({
onClose={onClose}
/>
))}
- {!!token && !!name && (
-
- {isOwnedByUser ? (
-
- ) : (
- <>
- {!!token.extension.contract_address && (
-
- )}
- >
- )}
-
-
- )}
>
)}
diff --git a/packages/screens/TeritoriNameService/TNSExploreScreen.tsx b/packages/screens/TeritoriNameService/TNSExploreScreen.tsx
index 924edbfa75..f98983d0e3 100644
--- a/packages/screens/TeritoriNameService/TNSExploreScreen.tsx
+++ b/packages/screens/TeritoriNameService/TNSExploreScreen.tsx
@@ -9,10 +9,12 @@ import { TNSSendFundsModal } from "../../components/modals/teritoriNameService/T
import { FindAName } from "../../components/teritoriNameService/FindAName";
import { useTNS } from "../../context/TNSProvider";
import { useNSMintAvailability } from "../../hooks/useNSMintAvailability";
+import { useNSNameOwner } from "../../hooks/useNSNameOwner";
import { useNSTokensByOwner } from "../../hooks/useNSTokensByOwner";
import { useSelectedNetworkId } from "../../hooks/useSelectedNetwork";
import useSelectedWallet from "../../hooks/useSelectedWallet";
-import { getCosmosNetwork } from "../../networks";
+import { getCosmosNetwork, getUserId } from "../../networks";
+import { useAppNavigation } from "../../utils/navigation";
import { neutral17 } from "../../utils/style/colors";
interface TNSExploreScreenProps extends TNSModalCommonProps {}
@@ -25,6 +27,11 @@ export const TNSExploreScreen: React.FC = ({
const selectedWallet = useSelectedWallet();
const networkId = useSelectedNetworkId();
const network = getCosmosNetwork(networkId);
+ const navigation = useAppNavigation();
+ const { nameOwner } = useNSNameOwner(
+ networkId,
+ name + network?.nameServiceTLD || "",
+ );
const { tokens } = useNSTokensByOwner(selectedWallet?.userId);
const tokenId = (name + network?.nameServiceTLD || "").toLowerCase();
const { nameAvailable, nameError, loading } = useNSMintAvailability(
@@ -34,7 +41,7 @@ export const TNSExploreScreen: React.FC = ({
return (
onClose()}
modalStatus={name && nameAvailable ? "success" : "danger"}
@@ -66,16 +73,18 @@ export const TNSExploreScreen: React.FC = ({
{
- onClose("TNSConsultName");
+ navigation.navigate("UserPublicProfile", {
+ id: getUserId(networkId, nameOwner),
+ });
}}
/>
setSendFundsModalVisible(true)}
squaresBackgroundColor={neutral17}
/>
diff --git a/packages/screens/TeritoriNameService/TNSRegisterScreen.tsx b/packages/screens/TeritoriNameService/TNSRegisterScreen.tsx
index 8c26098d6a..e881646b16 100644
--- a/packages/screens/TeritoriNameService/TNSRegisterScreen.tsx
+++ b/packages/screens/TeritoriNameService/TNSRegisterScreen.tsx
@@ -29,7 +29,7 @@ export const TNSRegisterScreen: React.FC = ({
return (
onClose()}
- label="Find a name"
+ label="Find a Name"
width={457}
modalStatus={name && nameAvailable ? "success" : "danger"}
hideMainSeparator
diff --git a/packages/screens/TeritoriNameService/TNSUpdateNameScreen.tsx b/packages/screens/TeritoriNameService/TNSUpdateNameScreen.tsx
index dd8cb5f683..25d472fe8a 100644
--- a/packages/screens/TeritoriNameService/TNSUpdateNameScreen.tsx
+++ b/packages/screens/TeritoriNameService/TNSUpdateNameScreen.tsx
@@ -6,7 +6,6 @@ import { View } from "react-native";
import { TNSModalCommonProps } from "./TNSHomeScreen";
import ModalBase from "../../components/modals/ModalBase";
import { NameDataForm } from "../../components/teritoriNameService/NameDataForm";
-import { NameNFT } from "../../components/teritoriNameService/NameNFT";
import { useFeedbacks } from "../../context/FeedbacksProvider";
import { useTNS } from "../../context/TNSProvider";
import { TeritoriNameServiceQueryClient } from "../../contracts-clients/teritori-name-service/TeritoriNameService.client";
@@ -18,10 +17,10 @@ import { useNSNameOwner } from "../../hooks/useNSNameOwner";
import { useNSTokensByOwner } from "../../hooks/useNSTokensByOwner";
import useSelectedWallet from "../../hooks/useSelectedWallet";
import {
+ getCosmosNetwork,
getKeplrSigningCosmWasmClient,
- mustGetNonSigningCosmWasmClient,
mustGetCosmosNetwork,
- getCosmosNetwork,
+ mustGetNonSigningCosmWasmClient,
} from "../../networks";
import { neutral17 } from "../../utils/style/colors";
import { defaultMetaData } from "../../utils/types/tns";
@@ -197,16 +196,16 @@ export const TNSUpdateNameScreen: React.FC = ({
onClose()}
+ label="Edit profile"
scrollable
width={457}
boxStyle={{
backgroundColor: neutral17,
}}
>
-
{
- const finalDatas: PrettyTokenData[] = [];
- Object.entries(tokenData).map(([key, value], i) => {
- switch (key) {
- case "email":
- finalDatas[0] = { displayLabel: "Email", value: value as string };
- break;
- case "public_name":
- finalDatas[1] = {
- displayLabel: publicNameDisplayLabel,
- value: value as string,
- };
- break;
- case "public_bio":
- finalDatas[2] = { displayLabel: "Bio", value: value as string };
- break;
- case "image":
- finalDatas[3] = {
- displayLabel: imageDisplayLabel,
- value: value as string,
- };
- break;
- case "external_url":
- finalDatas[4] = {
- displayLabel: "External URL",
- value: value as string,
- };
- break;
- case "discord_id":
- finalDatas[5] = {
- displayLabel: "Discord",
- value: value as string,
- };
- break;
- case "twitter_id":
- finalDatas[6] = { displayLabel: "Twitter", value: value as string };
- break;
- case "telegram_id":
- finalDatas[7] = {
- displayLabel: "Telegram username",
- value: value as string,
- };
- break;
- case "keybase_id":
- finalDatas[8] = { displayLabel: "Keybase", value: value as string };
- break;
- case "validator_operator_address":
- finalDatas[9] = { displayLabel: "Validator", value: value as string };
- break;
- }
- });
- return finalDatas;
-};
diff --git a/yarn.lock b/yarn.lock
index 4d160c3a82..c9b183c9db 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10682,6 +10682,15 @@ __metadata:
languageName: node
linkType: hard
+"expo-document-picker@npm:~11.5.4":
+ version: 11.5.4
+ resolution: "expo-document-picker@npm:11.5.4"
+ peerDependencies:
+ expo: "*"
+ checksum: a59571a356830b698ebeeb29cf1b33e42dcd05b348fe1125c5c52f0ef0bae410d9e6e57d62b7f9e9a699b38d824e90f787282d80b3feeddb35dcc319a389e546
+ languageName: node
+ linkType: hard
+
"expo-file-system@npm:~15.4.0, expo-file-system@npm:~15.4.4":
version: 15.4.4
resolution: "expo-file-system@npm:15.4.4"
@@ -19548,6 +19557,7 @@ __metadata:
expo-barcode-scanner: ~12.5.3
expo-dev-client: ~2.4.12
expo-doctor: ^1.1.3
+ expo-document-picker: ~11.5.4
expo-font: ~11.4.0
expo-linear-gradient: ~12.3.0
expo-optimize: ^0.2.20