diff --git a/src/app/(marketing)/create-profile/(onboarding)/_components/StartProfile.tsx b/src/app/(marketing)/create-profile/(onboarding)/_components/StartProfile.tsx index f0ea1569d4..b50a9e33e6 100644 --- a/src/app/(marketing)/create-profile/(onboarding)/_components/StartProfile.tsx +++ b/src/app/(marketing)/create-profile/(onboarding)/_components/StartProfile.tsx @@ -2,7 +2,6 @@ import FarcasterImage from "@/../static/socialIcons/farcaster.svg" import { ConnectFarcasterButton } from "@/components/Account/components/AccountModal/components/FarcasterProfile" -import {} from "@/components/ui/Avatar" import { Button } from "@/components/ui/Button" import { FormControl, @@ -12,15 +11,15 @@ import { FormLabel, } from "@/components/ui/Form" import { Input } from "@/components/ui/Input" +import { uploadImageUrlToPinata } from "@/lib/uploadImageUrlToPinata" import { EditProfilePicture } from "@app/(marketing)/profile/_components/EditProfile/EditProfilePicture" import { Schemas, schemas } from "@guildxyz/types" import { zodResolver } from "@hookform/resolvers/zod" -import {} from "@phosphor-icons/react" import { ArrowRight } from "@phosphor-icons/react/dist/ssr" import useUser from "components/[guild]/hooks/useUser" import usePinata from "hooks/usePinata" import useSubmitWithUpload from "hooks/useSubmitWithUpload" -import { useEffect, useState } from "react" +import { useEffect, useRef, useState } from "react" import { FormProvider, useForm } from "react-hook-form" import { useCreateProfile } from "../_hooks/useCreateProfile" import { CreateProfileStep } from "../types" @@ -37,19 +36,6 @@ export const StartProfile: CreateProfileStep = ({ data: chainData }) => { farcasterProfile ? CreateMethod.FillByFarcaster : undefined ) - useEffect(() => { - if (!farcasterProfile) return - setMethod(CreateMethod.FillByFarcaster) - form.setValue( - "name", - farcasterProfile.username ?? form.getValues()?.name ?? "", - { shouldValidate: true } - ) - form.setValue("profileImageUrl", farcasterProfile.avatar, { - shouldValidate: true, - }) - }, [farcasterProfile]) - const form = useForm({ resolver: zodResolver( schemas.ProfileCreationSchema.omit({ referrerUserId: true }) @@ -84,6 +70,23 @@ export const StartProfile: CreateProfileStep = ({ data: chainData }) => { control: form.control, fieldToSetOnSuccess: "profileImageUrl", }) + const isFarcasterAvatarUploaded = useRef(false) + + useEffect(() => { + if (!farcasterProfile) return + setMethod(CreateMethod.FillByFarcaster) + form.setValue( + "name", + farcasterProfile.username ?? form.getValues()?.name ?? "", + { shouldValidate: true } + ) + if (!farcasterProfile.avatar || isFarcasterAvatarUploaded.current) return + uploadImageUrlToPinata({ + onUpload: profilePicUploader.onUpload, + image: new URL(farcasterProfile.avatar), + }) + isFarcasterAvatarUploaded.current = true + }, [farcasterProfile, profilePicUploader.onUpload, form.setValue, form.getValues]) const { handleSubmit, isUploadingShown, uploadLoadingText } = useSubmitWithUpload( form.handleSubmit(onSubmit), diff --git a/src/app/(marketing)/profile/_components/EditProfile/EditProfile.tsx b/src/app/(marketing)/profile/_components/EditProfile/EditProfile.tsx index a333ee3fd8..1ad732f88a 100644 --- a/src/app/(marketing)/profile/_components/EditProfile/EditProfile.tsx +++ b/src/app/(marketing)/profile/_components/EditProfile/EditProfile.tsx @@ -11,7 +11,6 @@ import { DialogTitle, DialogTrigger, } from "@/components/ui/Dialog" -import {} from "@/components/ui/DropdownMenu" import { FormControl, FormErrorMessage, @@ -77,7 +76,7 @@ export const EditProfile = ({ children }: PropsWithChildren) => { uploader={profilePicUploader} className="-bottom-2 absolute left-4 translate-y-1/2 bg-muted" /> - + { +export const EditProfileDropdown: FunctionComponent<{ uploader: Uploader }> = ({ + uploader, +}) => { const { farcasterProfiles } = useUser() const farcasterProfile = farcasterProfiles?.at(0) const { setValue } = useFormContext() - const deleteProfile = useDeleteProfile() return ( @@ -38,16 +42,16 @@ export const EditProfileDropdown = () => { { - if (farcasterProfile.avatar) { - setValue("profileImageUrl", farcasterProfile.avatar, { - shouldValidate: true, - }) - } if (farcasterProfile.username) { setValue("name", farcasterProfile.username, { shouldValidate: true, }) } + if (!farcasterProfile.avatar) return + uploadImageUrlToPinata({ + onUpload: uploader.onUpload, + image: new URL(farcasterProfile.avatar), + }) }} > Fill data by Farcaster diff --git a/src/app/(marketing)/profile/_components/EditProfile/EditProfilePicture.tsx b/src/app/(marketing)/profile/_components/EditProfile/EditProfilePicture.tsx index beb18a1cd1..1f7d08d2e3 100644 --- a/src/app/(marketing)/profile/_components/EditProfile/EditProfilePicture.tsx +++ b/src/app/(marketing)/profile/_components/EditProfile/EditProfilePicture.tsx @@ -5,7 +5,7 @@ import { Button } from "@/components/ui/Button" import { FormField } from "@/components/ui/Form" import { toast } from "@/components/ui/hooks/useToast" import { cn } from "@/lib/utils" -import { Image, UploadSimple, User } from "@phosphor-icons/react" +import { Image, Spinner, UploadSimple, User } from "@phosphor-icons/react" import { AvatarImage } from "@radix-ui/react-avatar" import useDropzone from "hooks/useDropzone" import { Uploader } from "hooks/usePinata/usePinata" @@ -74,7 +74,11 @@ export const EditProfilePicture = ({ )} > {isUploading ? ( -

{(uploadProgress * 100).toFixed(0)}%

+ uploadProgress ? ( +

{(uploadProgress * 100).toFixed(0)}%

+ ) : ( + + ) ) : isDragActive ? ( ) : ( diff --git a/src/v2/lib/uploadImageUrlToPinata.ts b/src/v2/lib/uploadImageUrlToPinata.ts new file mode 100644 index 0000000000..cf59940e31 --- /dev/null +++ b/src/v2/lib/uploadImageUrlToPinata.ts @@ -0,0 +1,13 @@ +import { Uploader } from "hooks/usePinata/usePinata" + +export const uploadImageUrlToPinata = async ({ + image, + onUpload, +}: { image: URL; onUpload: Uploader["onUpload"] }) => { + const data = await (await fetch(image)).blob() + const fileName = image.pathname.split("/").at(-1) || "unknown" + onUpload({ + data: [new File([data], fileName)], + fileNames: [fileName], + }) +}