diff --git a/src/hooks/use-input-upload-file.ts b/src/hooks/use-input-upload-file.ts new file mode 100644 index 000000000..4bdba1dea --- /dev/null +++ b/src/hooks/use-input-upload-file.ts @@ -0,0 +1,37 @@ +import { ChangeEventHandler, ClipboardEventHandler, useCallback } from "react"; +import useUploadFile from "./use-upload-file"; +import { UseFormSetValue } from "react-hook-form"; + +export function useInputUploadFileWithForm(setValue: UseFormSetValue, field: string) { + const setText = useCallback((text: string) => setValue(field, text), [setValue]); + return useInputUploadFile(setText); +} + +export default function useInputUploadFile(setText: (text: string) => void) { + const { uploadFile, uploading } = useUploadFile(); + + const privateUploadFile = useCallback(async (file: File) => { + const imageUrl = await uploadFile(file); + + if (imageUrl) + setText(imageUrl); + }, [uploadFile]) + + const onFileInputChange = useCallback>( + (e) => { + const img = e.target.files?.[0]; + if (img) privateUploadFile(img); + }, + [privateUploadFile], + ); + + const onPaste = useCallback>( + (e) => { + const imageFile = Array.from(e.clipboardData.files).find((f) => f.type.includes("image")); + if (imageFile) privateUploadFile(imageFile); + }, + [privateUploadFile], + ); + + return { uploadFile, uploading, onPaste, onFileInputChange }; +} diff --git a/src/views/profile/edit.tsx b/src/views/profile/edit.tsx index 3575f47a2..0e258baf8 100644 --- a/src/views/profile/edit.tsx +++ b/src/views/profile/edit.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo } from "react"; +import { useEffect, useMemo, useRef } from "react"; import { Avatar, Button, @@ -9,11 +9,15 @@ import { Input, Link, Textarea, + InputGroup, + InputRightElement, + IconButton, + VisuallyHiddenInput, } from "@chakra-ui/react"; import { useForm } from "react-hook-form"; import { ProfileContent, unixNow } from "applesauce-core/helpers"; -import { ExternalLinkIcon } from "../../components/icons"; +import { ExternalLinkIcon, OutboxIcon } from "../../components/icons"; import { isLNURL } from "../../helpers/lnurl"; import { useReadRelays } from "../../hooks/use-client-relays"; import { useActiveAccount } from "applesauce-react/hooks"; @@ -24,6 +28,7 @@ import lnurlMetadataService from "../../services/lnurl-metadata"; import VerticalPageLayout from "../../components/vertical-page-layout"; import { COMMON_CONTACT_RELAYS } from "../../const"; import { usePublishEvent } from "../../providers/global/publish-provider"; +import { useInputUploadFileWithForm } from "../../hooks/use-input-upload-file"; const isEmail = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; @@ -55,6 +60,7 @@ const MetadataForm = ({ defaultValues, onSubmit }: MetadataFormProps) => { reset, handleSubmit, watch, + setValue, formState: { errors, isSubmitting }, } = useForm({ mode: "onBlur", @@ -65,6 +71,12 @@ const MetadataForm = ({ defaultValues, onSubmit }: MetadataFormProps) => { reset(defaultValues); }, [defaultValues]); + const pictureUploadManage = useInputUploadFileWithForm(setValue, "picture"); + const pictureUploadRef = useRef(null); + + const bannerUploadManage = useInputUploadFileWithForm(setValue, "banner"); + const bannerUploadRef = useRef(null); + return ( @@ -113,24 +125,62 @@ const MetadataForm = ({ defaultValues, onSubmit }: MetadataFormProps) => { Picture - + + + + } + title="Upload picture" + aria-label="Upload picture" + onClick={() => pictureUploadRef.current?.click()} + /> + + + Banner - + + + + } + title="Upload baner" + aria-label="Upload banner" + onClick={() => bannerUploadRef.current?.click()} + /> + + +