Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
1import { TRANSFORMS } from "@hey/data/constants";
2import sanitizeDStorageUrl from "@hey/helpers/sanitizeDStorageUrl";
3import type { SyntheticEvent } from "react";
4import Cropper from "react-easy-crop";
5import ChooseFile from "@/components/Shared/ChooseFile";
6import { Button, Image, Modal } from "@/components/Shared/UI";
7import cn from "@/helpers/cn";
8import useImageCropUpload from "@/hooks/useImageCropUpload";
9
10interface AvatarUploadProps {
11 src: string;
12 setSrc: (src: string) => void;
13 isSmall?: boolean;
14}
15
16const AvatarUpload = ({ src, setSrc, isSmall = false }: AvatarUploadProps) => {
17 const {
18 pictureSrc,
19 crop,
20 setCrop,
21 zoom,
22 setZoom,
23 showModal,
24 uploading,
25 uploadedPicture,
26 renderPictureUrl,
27 onFileChange,
28 onCropComplete,
29 handleUploadAndSave,
30 handleModalClose
31 } = useImageCropUpload({
32 aspect: 1,
33 label: "avatar",
34 setSrc,
35 src,
36 transform: TRANSFORMS.AVATAR_BIG
37 });
38
39 return (
40 <>
41 <div className="space-y-1.5">
42 <div className="label">Avatar</div>
43 <div className="space-y-3">
44 <Image
45 alt="Account picture crop preview"
46 className={cn("rounded-lg", isSmall ? "max-w-44" : "size-56")}
47 onError={(event: SyntheticEvent<HTMLImageElement>) => {
48 const target = event.currentTarget;
49 target.src = sanitizeDStorageUrl(src);
50 }}
51 src={uploadedPicture || renderPictureUrl}
52 />
53 <ChooseFile onChange={(event) => onFileChange(event)} />
54 </div>
55 </div>
56 <Modal
57 onClose={handleModalClose}
58 show={showModal}
59 size="xs"
60 title="Crop picture"
61 >
62 <div className="space-y-5 p-5">
63 <div className="relative flex size-64 w-full">
64 <Cropper
65 aspect={1}
66 crop={crop}
67 cropShape="round"
68 image={pictureSrc}
69 onCropChange={setCrop}
70 onCropComplete={onCropComplete}
71 onZoomChange={setZoom}
72 zoom={zoom}
73 />
74 </div>
75 <Button
76 className="w-full"
77 disabled={uploading || !pictureSrc}
78 loading={uploading}
79 onClick={handleUploadAndSave}
80 type="submit"
81 >
82 Upload
83 </Button>
84 </div>
85 </Modal>
86 </>
87 );
88};
89
90export default AvatarUpload;