mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-03-17 13:21:44 +01:00
Adding images uploading support in profile edit page
This commit is contained in:
parent
a0dfb6c076
commit
de6f39d3d1
37
src/hooks/use-input-upload-file.ts
Normal file
37
src/hooks/use-input-upload-file.ts
Normal file
@ -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<any>, 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<ChangeEventHandler<HTMLInputElement>>(
|
||||
(e) => {
|
||||
const img = e.target.files?.[0];
|
||||
if (img) privateUploadFile(img);
|
||||
},
|
||||
[privateUploadFile],
|
||||
);
|
||||
|
||||
const onPaste = useCallback<ClipboardEventHandler<HTMLInputElement>>(
|
||||
(e) => {
|
||||
const imageFile = Array.from(e.clipboardData.files).find((f) => f.type.includes("image"));
|
||||
if (imageFile) privateUploadFile(imageFile);
|
||||
},
|
||||
[privateUploadFile],
|
||||
);
|
||||
|
||||
return { uploadFile, uploading, onPaste, onFileInputChange };
|
||||
}
|
@ -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<FormData>({
|
||||
mode: "onBlur",
|
||||
@ -65,6 +71,12 @@ const MetadataForm = ({ defaultValues, onSubmit }: MetadataFormProps) => {
|
||||
reset(defaultValues);
|
||||
}, [defaultValues]);
|
||||
|
||||
const pictureUploadManage = useInputUploadFileWithForm(setValue, "picture");
|
||||
const pictureUploadRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
const bannerUploadManage = useInputUploadFileWithForm(setValue, "banner");
|
||||
const bannerUploadRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
return (
|
||||
<VerticalPageLayout as="form" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Flex gap="2">
|
||||
@ -113,24 +125,62 @@ const MetadataForm = ({ defaultValues, onSubmit }: MetadataFormProps) => {
|
||||
<Flex gap="2" alignItems="center">
|
||||
<FormControl isInvalid={!!errors.picture}>
|
||||
<FormLabel>Picture</FormLabel>
|
||||
<Input
|
||||
autoComplete="off"
|
||||
isDisabled={isSubmitting}
|
||||
placeholder="https://domain.com/path/picture.png"
|
||||
{...register("picture", { maxLength: 150 })}
|
||||
/>
|
||||
<InputGroup>
|
||||
<Input
|
||||
onPaste={pictureUploadManage.onPaste}
|
||||
autoComplete="off"
|
||||
isDisabled={isSubmitting}
|
||||
placeholder="https://domain.com/path/picture.png"
|
||||
{...register("picture", { maxLength: 150 })}
|
||||
/>
|
||||
<InputRightElement>
|
||||
<IconButton
|
||||
isLoading={pictureUploadManage.uploading}
|
||||
size="sm"
|
||||
icon={<OutboxIcon />}
|
||||
title="Upload picture"
|
||||
aria-label="Upload picture"
|
||||
onClick={() => pictureUploadRef.current?.click()}
|
||||
/>
|
||||
</InputRightElement>
|
||||
<VisuallyHiddenInput
|
||||
type="file"
|
||||
accept="image/*"
|
||||
ref={pictureUploadRef}
|
||||
onChange={pictureUploadManage.onFileInputChange}
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormControl>
|
||||
<Avatar src={watch("picture")} size="lg" ignoreFallback />
|
||||
</Flex>
|
||||
<Flex gap="2" alignItems="center">
|
||||
<FormControl isInvalid={!!errors.banner}>
|
||||
<FormLabel>Banner</FormLabel>
|
||||
<Input
|
||||
autoComplete="off"
|
||||
isDisabled={isSubmitting}
|
||||
placeholder="https://domain.com/path/banner.png"
|
||||
{...register("banner", { maxLength: 150 })}
|
||||
/>
|
||||
<InputGroup>
|
||||
<Input
|
||||
onPaste={bannerUploadManage.onPaste}
|
||||
autoComplete="off"
|
||||
isDisabled={isSubmitting}
|
||||
placeholder="https://domain.com/path/banner.png"
|
||||
{...register("banner", { maxLength: 150 })}
|
||||
/>
|
||||
<InputRightElement>
|
||||
<IconButton
|
||||
isLoading={bannerUploadManage.uploading}
|
||||
size="sm"
|
||||
icon={<OutboxIcon />}
|
||||
title="Upload baner"
|
||||
aria-label="Upload banner"
|
||||
onClick={() => bannerUploadRef.current?.click()}
|
||||
/>
|
||||
</InputRightElement>
|
||||
<VisuallyHiddenInput
|
||||
type="file"
|
||||
accept="image/*"
|
||||
ref={bannerUploadRef}
|
||||
onChange={bannerUploadManage.onFileInputChange}
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormControl>
|
||||
<Avatar src={watch("banner")} size="lg" ignoreFallback />
|
||||
</Flex>
|
||||
|
Loading…
x
Reference in New Issue
Block a user