diff --git a/packages/components/FilePreview/AudioView.tsx b/packages/components/FilePreview/AudioView.tsx index b101c3b02c..a2f3050deb 100644 --- a/packages/components/FilePreview/AudioView.tsx +++ b/packages/components/FilePreview/AudioView.tsx @@ -4,11 +4,11 @@ import { View, Image, TouchableOpacity } from "react-native"; import { ActivityIndicator } from "react-native-paper"; import { AudioWaveform } from "./AudioWaveform"; -import { ipfsURLToHTTPURL } from "./ipfs"; import pauseSVG from "../../../assets/icons/pause.svg"; import playSVG from "../../../assets/icons/play.svg"; import { useMaxResolution } from "../../hooks/useMaxResolution"; import { getAudioDuration } from "../../utils/audio"; +import { ipfsURLToHTTPURL } from "../../utils/ipfs"; import { errorColor, neutral00, diff --git a/packages/components/FilePreview/ImagesFullViewModal.tsx b/packages/components/FilePreview/ImagesFullViewModal.tsx index 3314a058af..8e1efc94a4 100644 --- a/packages/components/FilePreview/ImagesFullViewModal.tsx +++ b/packages/components/FilePreview/ImagesFullViewModal.tsx @@ -7,9 +7,9 @@ import { } from "react-native"; import { SvgProps } from "react-native-svg"; -import { ipfsURLToHTTPURL } from "./ipfs"; import chevronLeft from "../../../assets/icons/chevron-left.svg"; import chevronRight from "../../../assets/icons/chevron-right.svg"; +import { ipfsURLToHTTPURL } from "../../utils/ipfs"; import { neutral22, neutral33 } from "../../utils/style/colors"; import { SVG } from "../SVG"; import ModalBase from "../modals/ModalBase"; diff --git a/packages/components/FilePreview/ImagesViews.tsx b/packages/components/FilePreview/ImagesViews.tsx index 34fa33f385..15ffc8edf9 100644 --- a/packages/components/FilePreview/ImagesViews.tsx +++ b/packages/components/FilePreview/ImagesViews.tsx @@ -3,7 +3,7 @@ import { Image, TouchableOpacity, View } from "react-native"; import { DeleteButton } from "./DeleteButton"; import { ImagesFullViewModal } from "./ImagesFullViewModal"; -import { ipfsURLToHTTPURL } from "./ipfs"; +import { ipfsURLToHTTPURL } from "../../utils/ipfs"; import { errorColor } from "../../utils/style/colors"; import { fontSemibold13 } from "../../utils/style/fonts"; import { layout } from "../../utils/style/layout"; diff --git a/packages/components/FilePreview/VideoView.tsx b/packages/components/FilePreview/VideoView.tsx index b552186393..8796c18fa9 100644 --- a/packages/components/FilePreview/VideoView.tsx +++ b/packages/components/FilePreview/VideoView.tsx @@ -3,7 +3,7 @@ import React from "react"; import { View } from "react-native"; import { DeleteButton } from "./DeleteButton"; -import { ipfsURLToHTTPURL } from "./ipfs"; +import { ipfsURLToHTTPURL } from "../../utils/ipfs"; import { errorColor } from "../../utils/style/colors"; import { fontSemibold13 } from "../../utils/style/fonts"; import { layout } from "../../utils/style/layout"; diff --git a/packages/components/FilePreview/ipfs.ts b/packages/components/FilePreview/ipfs.ts deleted file mode 100644 index 8469975bd8..0000000000 --- a/packages/components/FilePreview/ipfs.ts +++ /dev/null @@ -1,15 +0,0 @@ -// temporary hotfix -// pinata-pinned files are weirdly handled by nft.storage gateway - -export const ipfsURLToHTTPURL = (ipfsURL: string | undefined) => { - if (!ipfsURL) { - return ""; - } - if (ipfsURL.startsWith("https://") || ipfsURL.startsWith("blob:")) { - return ipfsURL; - } - if (ipfsURL.startsWith("ipfs://")) { - return ipfsURL.replace("ipfs://", "https://cloudflare-ipfs.com/ipfs/"); - } - return "https://cloudflare-ipfs.com/ipfs/" + ipfsURL; -}; diff --git a/packages/components/freelanceServices/Cards/ServiceCard.tsx b/packages/components/freelanceServices/Cards/ServiceCard.tsx index 543a32dd90..19b000bd78 100644 --- a/packages/components/freelanceServices/Cards/ServiceCard.tsx +++ b/packages/components/freelanceServices/Cards/ServiceCard.tsx @@ -10,7 +10,7 @@ import { import dotsCircle from "../../../../assets/icons/dots-circle.svg"; import star from "../../../../assets/icons/yellow-star.svg"; import { GigData } from "../../../screens/FreelanceServices/types/fields"; -import { ipfsPinataUrl } from "../../../utils/ipfs"; +import { ipfsURLToHTTPURL } from "../../../utils/ipfs"; import { neutral77, yellowDefault } from "../../../utils/style/colors"; import { fontMedium10, @@ -57,7 +57,7 @@ export const ServiceCard: React.FC<{ > diff --git a/packages/components/freelanceServices/FreelanceServicesScreen/FreelanceServicesHeader.tsx b/packages/components/freelanceServices/FreelanceServicesScreen/FreelanceServicesHeader.tsx index a43caa577b..1d39bda89a 100644 --- a/packages/components/freelanceServices/FreelanceServicesScreen/FreelanceServicesHeader.tsx +++ b/packages/components/freelanceServices/FreelanceServicesScreen/FreelanceServicesHeader.tsx @@ -2,6 +2,8 @@ import React from "react"; import { useWindowDimensions, View } from "react-native"; import searchSVG from "../../../../assets/icons/search.svg"; +import { fontSemibold28 } from "../../../utils/style/fonts"; +import { layout } from "../../../utils/style/layout"; import { BrandText } from "../../BrandText"; import { SVG } from "../../SVG"; import { Separator } from "../../Separator"; @@ -12,7 +14,9 @@ export const FreelanceServicesHeader: React.FC = () => { return ( - + Find the Perfect Freelance Services for your Business @@ -20,7 +24,7 @@ export const FreelanceServicesHeader: React.FC = () => { name="Search" width={width > 1024 ? 480 : 300} placeHolder="Search..." - style={{ alignSelf: "center", marginTop: 30 }} + style={{ alignSelf: "center", marginTop: layout.padding_x3_5 }} > { style={{ marginRight: 12 }} /> - + ); }; diff --git a/packages/components/freelanceServices/FreelanceServicesScreen/FreelanceServicesSellerHeader.tsx b/packages/components/freelanceServices/FreelanceServicesScreen/FreelanceServicesSellerHeader.tsx index 1a2215756a..a0d559ca69 100644 --- a/packages/components/freelanceServices/FreelanceServicesScreen/FreelanceServicesSellerHeader.tsx +++ b/packages/components/freelanceServices/FreelanceServicesScreen/FreelanceServicesSellerHeader.tsx @@ -9,6 +9,8 @@ import { mustGetCosmosNetwork, } from "../../../networks"; import { useAppNavigation } from "../../../utils/navigation"; +import { fontSemibold28 } from "../../../utils/style/fonts"; +import { layout } from "../../../utils/style/layout"; import { BrandText } from "../../BrandText"; import { Separator } from "../../Separator"; import { SecondaryButton } from "../../buttons/SecondaryButton"; @@ -16,44 +18,48 @@ import { SecondaryButton } from "../../buttons/SecondaryButton"; export const FreelanceServicesSellerHeader: React.FC = () => { const navigation = useAppNavigation(); const selectedWallet = useSelectedWallet(); - const [isSeller, setIsSeller] = useState(true); - // const [canCreateGig, setCanCreateGig] = useState(false); + const [isSeller, setIsSeller] = useState(true); const networkId = useSelectedNetworkId(); useEffect(() => { const checkIsSeller = async () => { - const cosmwasmClient = await mustGetNonSigningCosmWasmClient(networkId); - const network = mustGetCosmosNetwork(networkId); - const sellerQueryClient = new TeritoriSellerQueryClient( - cosmwasmClient, - network.freelanceSellerAddress! - ); - const profileHash = await sellerQueryClient.getSellerProfile( - selectedWallet?.address! - ); - setIsSeller(!!profileHash); + try { + const cosmwasmClient = await mustGetNonSigningCosmWasmClient(networkId); + const network = mustGetCosmosNetwork(networkId); + const sellerQueryClient = new TeritoriSellerQueryClient( + cosmwasmClient, + network.freelanceSellerAddress! + ); + const profileHash = await sellerQueryClient.getSellerProfile( + selectedWallet?.address! + ); + setIsSeller(!!profileHash); + } catch (e) { + console.error("Fail checking isSeller:", e); + setIsSeller(false); + } }; checkIsSeller(); }, [networkId, selectedWallet]); return ( - + Progress through your Efforts - - {!isSeller && ( - { - navigation.navigate("FreelanceServicesProfileSeller"); - }} - /> - )} - - + {!isSeller && ( + { + navigation.navigate("FreelanceServicesProfileSeller"); + }} + /> + )} + ); }; diff --git a/packages/components/freelanceServices/GigCreation/GigCreationGallery.tsx b/packages/components/freelanceServices/GigCreation/GigCreationGallery.tsx index 3d7c7bc91c..06e0088c0d 100644 --- a/packages/components/freelanceServices/GigCreation/GigCreationGallery.tsx +++ b/packages/components/freelanceServices/GigCreation/GigCreationGallery.tsx @@ -5,8 +5,12 @@ import PdfIcon from "../../../../assets/icons/pdf.svg"; import PicIcon from "../../../../assets/icons/pic.svg"; import VideoIcon from "../../../../assets/icons/video.svg"; import WarningIcon from "../../../../assets/icons/warning.svg"; +import { useFeedbacks } from "../../../context/FeedbacksProvider"; +import { useSelectedNetworkId } from "../../../hooks/useSelectedNetwork"; +import useSelectedWallet from "../../../hooks/useSelectedWallet"; +import { getUserId } from "../../../networks"; import { GigInfo } from "../../../screens/FreelanceServices/types/fields"; -import { ipfsPinataUrl, uploadFileToIPFS } from "../../../utils/ipfs"; +import { ipfsURLToHTTPURL, uploadFileToIPFS } from "../../../utils/ipfs"; import { neutralA3, neutral33, @@ -21,6 +25,7 @@ import { fontSemibold14, } from "../../../utils/style/fonts"; import { layout } from "../../../utils/style/layout"; +import { LocalFileData } from "../../../utils/types/feed"; import { BrandText } from "../../BrandText"; import { SVG } from "../../SVG"; import { CheckBox } from "../../checkbox/CheckBox"; @@ -34,20 +39,47 @@ export const GigCreationGallery: React.FC<{ gigInfo: GigInfo; setGig: React.Dispatch>; }> = ({ gigInfo, setGig }) => { - const uploadImageFile = async (file: File) => { + const selectedNetworkId = useSelectedNetworkId(); + const selectedWallet = useSelectedWallet(); + const userId = getUserId(selectedNetworkId, selectedWallet?.address); + const { setToastError } = useFeedbacks(); + + const uploadImageFile = async (file: LocalFileData) => { if (file) { - const ipfsHash = await uploadFileToIPFS(file); + const uploadedFile = await uploadFileToIPFS( + file, + selectedNetworkId, + userId + ); + if (!uploadedFile) { + setToastError({ + title: "File upload failed", + message: "Fail to pin to IPFS, please try to Publish again", + }); + return; + } const images = gigInfo.images; - images.push(ipfsHash); + images.push(uploadedFile?.url || ""); setGig({ ...gigInfo, images }); } }; - const uploadPdfFile = async (file: File) => { + const uploadPdfFile = async (file: LocalFileData) => { if (file) { - const ipfsHash = await uploadFileToIPFS(file); + const uploadedFile = await uploadFileToIPFS( + file, + selectedNetworkId, + userId + ); + if (!uploadedFile) { + setToastError({ + title: "File upload failed", + message: "Fail to pin to IPFS, please try to Publish again", + }); + return; + } const documents = gigInfo.documents; - documents.push(ipfsHash); + documents.push(uploadedFile?.url || ""); setGig({ ...gigInfo, documents }); } }; @@ -70,7 +102,9 @@ export const GigCreationGallery: React.FC<{ = 1 ? ipfsPinataUrl(gigInfo.images[0]) : "" + gigInfo.images.length >= 1 + ? ipfsURLToHTTPURL(gigInfo.images[0]) + : "" } > @@ -79,7 +113,9 @@ export const GigCreationGallery: React.FC<{ = 2 ? ipfsPinataUrl(gigInfo.images[1]) : "" + gigInfo.images.length >= 2 + ? ipfsURLToHTTPURL(gigInfo.images[1]) + : "" } > @@ -88,7 +124,9 @@ export const GigCreationGallery: React.FC<{ = 3 ? ipfsPinataUrl(gigInfo.images[2]) : "" + gigInfo.images.length >= 3 + ? ipfsURLToHTTPURL(gigInfo.images[2]) + : "" } > @@ -108,7 +146,7 @@ export const GigCreationGallery: React.FC<{ accept={"video/*"} url={ gigInfo.documents.length >= 1 - ? ipfsPinataUrl(gigInfo.documents[0]) + ? ipfsURLToHTTPURL(gigInfo.documents[0]) : "" } fileType={GigUploadFileType.PDF} @@ -126,7 +164,7 @@ export const GigCreationGallery: React.FC<{ accept="application/pdf" url={ gigInfo.documents.length >= 1 - ? ipfsPinataUrl(gigInfo.documents[0]) + ? ipfsURLToHTTPURL(gigInfo.documents[0]) : "" } fileType={GigUploadFileType.PDF} @@ -139,7 +177,7 @@ export const GigCreationGallery: React.FC<{ accept="application/pdf" url={ gigInfo.documents.length >= 2 - ? ipfsPinataUrl(gigInfo.documents[1]) + ? ipfsURLToHTTPURL(gigInfo.documents[1]) : "" } fileType={GigUploadFileType.PDF} diff --git a/packages/components/freelanceServices/Profile/PersonalInfoPanel.tsx b/packages/components/freelanceServices/Profile/PersonalInfoPanel.tsx index 29c3097937..284474ea59 100644 --- a/packages/components/freelanceServices/Profile/PersonalInfoPanel.tsx +++ b/packages/components/freelanceServices/Profile/PersonalInfoPanel.tsx @@ -1,4 +1,4 @@ -import React, { createRef } from "react"; +import React from "react"; import { StyleSheet, TextInput, @@ -8,8 +8,13 @@ import { } from "react-native"; import emptySVG from "../../../../assets/icons/empty-list.svg"; +import { useFeedbacks } from "../../../context/FeedbacksProvider"; +import { useSelectedNetworkId } from "../../../hooks/useSelectedNetwork"; +import useSelectedWallet from "../../../hooks/useSelectedWallet"; +import { getUserId } from "../../../networks"; import { SellerInfo } from "../../../screens/FreelanceServices/types/fields"; -import { ipfsPinataUrl, uploadFileToIPFS } from "../../../utils/ipfs"; +import { ipfsURLToHTTPURL, uploadFileToIPFS } from "../../../utils/ipfs"; +import { IMAGE_MIME_TYPES } from "../../../utils/mime"; import { additionalRed, neutral33, @@ -22,40 +27,53 @@ import { fontSemibold20, fontSemibold28, } from "../../../utils/style/fonts"; +import { LocalFileData } from "../../../utils/types/feed"; import { BrandText } from "../../BrandText"; import { SVG } from "../../SVG"; +import { FileUploader } from "../../fileUploader"; export const PersonalInfoPanel: React.FC<{ seller: SellerInfo; setSeller: React.Dispatch>; }> = ({ seller, setSeller }) => { - const userPictureRef = createRef(); - const profilePictureRef = createRef(); + const selectedNetworkId = useSelectedNetworkId(); + const selectedWallet = useSelectedWallet(); + const userId = getUserId(selectedNetworkId, selectedWallet?.address); + const { setToastError } = useFeedbacks(); - const uploadFile = async (file: File) => { - const ipfsHash = await uploadFileToIPFS(file); - return ipfsHash; - }; - - const onUserPictureChange: React.ChangeEventHandler = ( - e - ) => { - const file = e.target?.files?.[0]; + const onUserPictureChange = async (file: LocalFileData) => { if (file) { - uploadFile(file).then((ipfsHash) => { - setSeller({ ...seller, avatar: ipfsHash }); - }); + const uploadedFile = await uploadFileToIPFS( + file, + selectedNetworkId, + userId + ); + if (!uploadedFile) { + setToastError({ + title: "File upload failed", + message: "Fail to pin to IPFS, please try to Publish again", + }); + return; + } + setSeller({ ...seller, avatar: uploadedFile?.url || "" }); } }; - const onProfilePictureChange: React.ChangeEventHandler = ( - e - ) => { - const file = e.target?.files?.[0]; + const onProfilePictureChange = async (file: LocalFileData) => { if (file) { - uploadFile(file).then((ipfsHash) => { - setSeller({ ...seller, profilePicture: ipfsHash }); - }); + const uploadedFile = await uploadFileToIPFS( + file, + selectedNetworkId, + userId + ); + if (!uploadedFile) { + setToastError({ + title: "File upload failed", + message: "Fail to pin to IPFS, please try to Publish again", + }); + return; + } + setSeller({ ...seller, profilePicture: uploadedFile?.url || "" }); } }; @@ -116,28 +134,23 @@ export const PersonalInfoPanel: React.FC<{ User Picture - { - userPictureRef.current?.click(); - }} + onUserPictureChange(files[0])} + mimeTypes={IMAGE_MIME_TYPES} > - - {seller.avatar === "" && ( - + {({ onPress }) => ( + + {!seller.avatar ? ( + + ) : ( + + )} + )} - {seller.avatar !== "" && ( - - )} - + @@ -145,28 +158,23 @@ export const PersonalInfoPanel: React.FC<{ Profile Picture - { - profilePictureRef.current?.click(); - }} + onProfilePictureChange(files[0])} + mimeTypes={IMAGE_MIME_TYPES} > - - {seller.profilePicture === "" && ( - - )} - {seller.profilePicture !== "" && ( - + {({ onPress }) => ( + + {!seller.profilePicture ? ( + + ) : ( + + )} + )} - + diff --git a/packages/components/freelanceServices/SellerDetails/GigItemCard.tsx b/packages/components/freelanceServices/SellerDetails/GigItemCard.tsx index 31f231a056..d45597a07d 100644 --- a/packages/components/freelanceServices/SellerDetails/GigItemCard.tsx +++ b/packages/components/freelanceServices/SellerDetails/GigItemCard.tsx @@ -11,7 +11,7 @@ import { import dotsCircle from "../../../../assets/icons/dots-circle.svg"; import { GigInfo } from "../../../screens/FreelanceServices/types/fields"; -import { ipfsPinataUrl } from "../../../utils/ipfs"; +import { ipfsURLToHTTPURL } from "../../../utils/ipfs"; import { useAppNavigation } from "../../../utils/navigation"; import { neutral33, neutralA3 } from "../../../utils/style/colors"; import { @@ -47,7 +47,7 @@ export const GigItemCard: React.FC<{ > {data.images.length > 0 && ( )} diff --git a/packages/components/inputs/AvatarImage.tsx b/packages/components/inputs/AvatarImage.tsx index cd80042a79..bcb527238a 100644 --- a/packages/components/inputs/AvatarImage.tsx +++ b/packages/components/inputs/AvatarImage.tsx @@ -1,7 +1,14 @@ -import React, { useState, createRef } from "react"; +import React, { useState } from "react"; import { TouchableOpacity, Image } from "react-native"; -import { uploadFileToIPFS, ipfsPinataUrl } from "../../utils/ipfs"; +import { useFeedbacks } from "../../context/FeedbacksProvider"; +import { useSelectedNetworkId } from "../../hooks/useSelectedNetwork"; +import useSelectedWallet from "../../hooks/useSelectedWallet"; +import { getUserId } from "../../networks"; +import { uploadFileToIPFS, ipfsURLToHTTPURL } from "../../utils/ipfs"; +import { IMAGE_MIME_TYPES } from "../../utils/mime"; +import { LocalFileData } from "../../utils/types/feed"; +import { FileUploader } from "../fileUploader"; export const AvatarImage: React.FC<{ source: any; @@ -9,43 +16,48 @@ export const AvatarImage: React.FC<{ onUpdate?: (url: string) => void; }> = ({ source, style, onUpdate }) => { const [sourceData, setSourceData] = useState(source); - const fileRef = createRef(); + const selectedNetworkId = useSelectedNetworkId(); + const selectedWallet = useSelectedWallet(); + const userId = getUserId(selectedNetworkId, selectedWallet?.address); + const { setToastError } = useFeedbacks(); - const uploadFile = async (file: File) => { - const ipfsHash = await uploadFileToIPFS(file); - if (ipfsHash) { - setSourceData(ipfsHash); - onUpdate!(ipfsHash); - } - }; - - const onFileInputChange: React.ChangeEventHandler = (e) => { - const file = e.target?.files?.[0]; + const onFileInputChange = async (file: LocalFileData) => { if (file) { - uploadFile(file); + const uploadedFile = await uploadFileToIPFS( + file, + selectedNetworkId, + userId + ); + if (!uploadedFile) { + setToastError({ + title: "File upload failed", + message: "Fail to pin to IPFS, please try to Publish again", + }); + return; + } + setSourceData(uploadedFile.url); + onUpdate!(uploadedFile.url); } }; return ( <> - {onUpdate && ( - { - fileRef.current?.click(); - }} + {onUpdate ? ( + onFileInputChange(files[0])} + mimeTypes={IMAGE_MIME_TYPES} > - - - - )} - {!onUpdate && ( - + {({ onPress }) => ( + + + + )} + + ) : ( + )} ); diff --git a/packages/components/inputs/PortfolioImage.tsx b/packages/components/inputs/PortfolioImage.tsx index 7198a6d94d..0f6f6d76a6 100644 --- a/packages/components/inputs/PortfolioImage.tsx +++ b/packages/components/inputs/PortfolioImage.tsx @@ -1,11 +1,18 @@ -import React, { createRef } from "react"; +import React from "react"; import { TouchableOpacity, View, Image } from "react-native"; import penSVG from "../../../assets/icons/manage.svg"; import trashSVG from "../../../assets/icons/trash.svg"; import { SVG } from "../../components/SVG"; import { TertiaryBox } from "../../components/boxes/TertiaryBox"; -import { uploadFileToIPFS, ipfsPinataUrl } from "../../utils/ipfs"; +import { useFeedbacks } from "../../context/FeedbacksProvider"; +import { useSelectedNetworkId } from "../../hooks/useSelectedNetwork"; +import useSelectedWallet from "../../hooks/useSelectedWallet"; +import { getUserId } from "../../networks"; +import { uploadFileToIPFS, ipfsURLToHTTPURL } from "../../utils/ipfs"; +import { IMAGE_MIME_TYPES } from "../../utils/mime"; +import { LocalFileData } from "../../utils/types/feed"; +import { FileUploader } from "../fileUploader"; export const PortfolioImage: React.FC<{ width: number; @@ -15,18 +22,26 @@ export const PortfolioImage: React.FC<{ onRemove?: () => void; style?: any; }> = ({ width, height, source, onUpdate, onRemove, style }) => { - const fileRef = createRef(); - const onFileInputChange: React.ChangeEventHandler = (e) => { - const file = e.target?.files?.[0]; - if (file) { - uploadFile(file); - } - }; + const selectedNetworkId = useSelectedNetworkId(); + const selectedWallet = useSelectedWallet(); + const userId = getUserId(selectedNetworkId, selectedWallet?.address); + const { setToastError } = useFeedbacks(); - const uploadFile = async (file: File) => { - const ipfsHash = await uploadFileToIPFS(file); - if (ipfsHash) { - onUpdate!(ipfsHash); + const onFileInputChange = async (file: LocalFileData) => { + if (file) { + const uploadedFile = await uploadFileToIPFS( + file, + selectedNetworkId, + userId + ); + if (!uploadedFile) { + setToastError({ + title: "File upload failed", + message: "Fail to pin to IPFS, please try to Publish again", + }); + return; + } + onUpdate!(uploadedFile?.url); } }; @@ -41,20 +56,6 @@ export const PortfolioImage: React.FC<{ zIndex: 1, }} > - {onUpdate && ( - { - fileRef.current?.click(); - }} - > - - - )} {onRemove && ( )} - {onUpdate && ( - { - fileRef.current?.click(); - }} + + {onUpdate ? ( + onFileInputChange(files[0])} + mimeTypes={IMAGE_MIME_TYPES} > - - - - )} - {!onUpdate && ( - // @ts-ignore - + {({ onPress }) => ( + + + + + )} + + ) : ( + )} ); diff --git a/packages/components/socialFeed/SocialThread/ArticleRenderer.tsx b/packages/components/socialFeed/SocialThread/ArticleRenderer.tsx index ce37069805..ef1f41ead0 100644 --- a/packages/components/socialFeed/SocialThread/ArticleRenderer.tsx +++ b/packages/components/socialFeed/SocialThread/ArticleRenderer.tsx @@ -1,11 +1,11 @@ import React from "react"; import { Image } from "react-native"; +import { ipfsURLToHTTPURL } from "../../../utils/ipfs"; import { ARTICLE_COVER_IMAGE_HEIGHT } from "../../../utils/social-feed"; import { layout } from "../../../utils/style/layout"; import { RemoteFileData } from "../../../utils/types/feed"; import { BrandText } from "../../BrandText"; -import { ipfsURLToHTTPURL } from "../../FilePreview/ipfs"; import { SocialFeedMetadata } from "../NewsFeed/NewsFeed.type"; import { RichText } from "../RichText"; diff --git a/packages/screens/FreelanceServices/FreelanceServicesProfileSeller.tsx b/packages/screens/FreelanceServices/FreelanceServicesProfileSeller.tsx index 0033b4b934..cc0ee403d1 100644 --- a/packages/screens/FreelanceServices/FreelanceServicesProfileSeller.tsx +++ b/packages/screens/FreelanceServices/FreelanceServicesProfileSeller.tsx @@ -19,7 +19,7 @@ import { mustGetCosmosNetwork, getKeplrSigningCosmWasmClient, } from "../../networks"; -import { ipfsPinataUrl, uploadJSONToIPFS } from "../../utils/ipfs"; +import { ipfsURLToHTTPURL, uploadJSONToIPFS } from "../../utils/ipfs"; import { ScreenFC, useAppNavigation } from "../../utils/navigation"; import { ProfileStep } from "../../utils/types/freelance"; @@ -50,7 +50,7 @@ export const FreelanceServicesProfileSeller: ScreenFC< if (!profileHash) return; - const profile_json_res = await axios.get(ipfsPinataUrl(profileHash)); + const profile_json_res = await axios.get(ipfsURLToHTTPURL(profileHash)); if (profile_json_res.status !== 200) return; const profile_json = profile_json_res.data; setSellerInfo({ diff --git a/packages/screens/FreelanceServices/FreelanceServicesScreenWrapper.tsx b/packages/screens/FreelanceServices/FreelanceServicesScreenWrapper.tsx index f47c55e81d..6e03d15ec5 100644 --- a/packages/screens/FreelanceServices/FreelanceServicesScreenWrapper.tsx +++ b/packages/screens/FreelanceServices/FreelanceServicesScreenWrapper.tsx @@ -29,11 +29,8 @@ export const FreelanceServicesScreenWrapper: React.FC<{ noMargin headerChildren={ <> - - Freelance Service - {showBuyerSeller && ( = ({ > @@ -301,7 +300,7 @@ export const GigDetailScreen: ScreenFC<"FreelanceServicesGigDetail"> = ({ => { - const profile_json_res = await axios.get(ipfsPinataUrl(ipfsHash)); + const profile_json_res = await axios.get(ipfsURLToHTTPURL(ipfsHash)); const sellerProfile = profile_json_res.data as SellerInfo; return { id: ipfsHash, diff --git a/packages/utils/ipfs.ts b/packages/utils/ipfs.ts index cdf3b59ef3..423f02ffd2 100644 --- a/packages/utils/ipfs.ts +++ b/packages/utils/ipfs.ts @@ -1,5 +1,9 @@ import axios from "axios"; +import { generateIpfsKey } from "./social-feed"; +import { LocalFileData, RemoteFileData } from "./types/feed"; +import { uploadPostFilesToPinata } from "../components/socialFeed/NewsFeed/NewsFeedQueries"; + export const ipfsURLToHTTPURL = (ipfsURL: string | undefined) => { if (!ipfsURL) { return ""; @@ -13,29 +17,23 @@ export const ipfsURLToHTTPURL = (ipfsURL: string | undefined) => { return "https://nftstorage.link/ipfs/" + ipfsURL; }; -export const ipfsPinataUrl = (ipfsHash: string): string => { - return `${process.env.PINATA_GATEWAY}/${ipfsHash}`; -}; +export const uploadFileToIPFS = async ( + file: LocalFileData, + networkId: string, + userId: string +) => { + let uploadedFiles: RemoteFileData[] = []; + const pinataJWTKey = await generateIpfsKey(networkId, userId); -export const uploadFileToIPFS = async (file: File): Promise => { - try { - const formData = new FormData(); - formData.append("file", file, file.name); - const res = await axios.post( - "https://api.pinata.cloud/pinning/pinFileToIPFS", - formData, - { - headers: { - pinata_api_key: process.env.PINATA_API_KEY, - pinata_secret_api_key: process.env.PINATA_SECRET_API_KEY, - }, - } - ); - return res.data.IpfsHash; - } catch (exception) { - console.log(exception); - return ""; + if (pinataJWTKey) { + uploadedFiles = await uploadPostFilesToPinata({ + files: [file], + pinataJWTKey, + }); } + if (!uploadedFiles.find((file) => file.url)) { + console.error("upload file err : Fail to pin to IPFS"); + } else return uploadedFiles[0]; }; export const uploadJSONToIPFS = async (data: object): Promise => { diff --git a/packages/utils/navigation.ts b/packages/utils/navigation.ts index 227cccb717..316e68f3e2 100644 --- a/packages/utils/navigation.ts +++ b/packages/utils/navigation.ts @@ -99,16 +99,16 @@ const navConfig: { FreelanceServicesHomeSeller: "freelance-services/seller", FreelanceServicesGigDetail: "freelance-services/gig/:gigId", - // FreelanceServicesMyAccountProfile: "freelance-services/profile_seller", - // FreelanceServicesManageGigList: "freelance-services/manage_gigs", - // FreelanceServicesManageGigCreation: "freelance-services/manage_gigs/new", - // FreelanceServicesManageGigEdit: "freelance-services/manage_gigs/edit/:gigId", - // FreelanceServicesManageOrders: "freelance-services/manage_orders" + // FreelanceServicesMyAccountProfile: "freelance-services/profile-seller", + // FreelanceServicesManageGigList: "freelance-services/manage-gigs", + // FreelanceServicesManageGigCreation: "freelance-services/manage-gigs/new", + // FreelanceServicesManageGigEdit: "freelance-services/manage-gigs/edit/:gigId", + // FreelanceServicesManageOrders: "freelance-services/manage-orders" // FreelanceServicesHome: "freelance-services/buyer", - FreelanceServicesProfileSeller: "freelance-services/profile_seller", - FreelanceServicesGigCreation: "freelance-services/gig_creation/:gigId?", + FreelanceServicesProfileSeller: "freelance-services/profile-seller", + FreelanceServicesGigCreation: "freelance-services/gig-creation/:gigId?", FreelanceServicesSellerDetails: "freelance-services/seller-details/:address", FreelanceServicesOrder: