GeneIT/geneit_app/src/widgets/forms/UploadPhotoButton.tsx

107 lines
2.7 KiB
TypeScript
Raw Normal View History

2023-08-10 10:10:09 +00:00
import { Button } from "@mui/material";
import { filesize } from "filesize";
import React from "react";
import { ServerApi } from "../../api/ServerApi";
import { ImageCropperDialog } from "../../dialogs/ImageCropperDialog";
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
import { Area } from "react-easy-crop";
import getCroppedImg from "../../utils/crop_image";
2023-08-10 11:53:23 +00:00
import UploadIcon from "@mui/icons-material/Upload";
import LinkIcon from "@mui/icons-material/Link";
import { isDebug } from "../../utils/debug_utils";
2023-08-18 13:27:29 +00:00
import { selectFileToUpload } from "../../utils/files_utils";
2023-08-10 10:10:09 +00:00
export function UploadPhotoButton(p: {
label: string;
onPhotoSelected: (b: Blob) => Promise<void>;
aspect?: number;
2023-08-10 10:10:09 +00:00
}): React.ReactElement {
const [processing, setProcessing] = React.useState(false);
const [imageBlob, setImageBlob] = React.useState<Blob>();
const [imageURL, setImageURL] = React.useState<string>();
const alert = useAlert();
const uploadPhoto = async () => {
try {
2023-08-18 13:27:29 +00:00
const file = await selectFileToUpload({
allowedTypes: ServerApi.Config.constraints.photo_allowed_types,
maxSize: ServerApi.Config.constraints.photo_max_size,
});
2023-08-10 10:10:09 +00:00
2023-08-18 13:27:29 +00:00
if (file === null) return;
2023-08-10 10:10:09 +00:00
2023-08-18 13:27:29 +00:00
const tempURL = URL.createObjectURL(file);
2023-08-10 10:10:09 +00:00
setImageBlob(file);
setImageURL(tempURL);
} catch (e) {
console.error(e);
2023-08-18 13:27:29 +00:00
alert(`Échec de l'envoi de l'image ! (${e})`);
2023-08-10 10:10:09 +00:00
}
};
const uploadPhotoFromURL = async () => {
const URL = prompt("Image URL ?");
if (URL === null || URL.length === 0) return;
setImageURL(URL);
};
2023-08-10 10:10:09 +00:00
const cancelCrop = () => {
setImageURL(undefined);
};
const submitCrop = async (a: Area | undefined) => {
setProcessing(true);
try {
let blob = imageBlob!;
if (a) {
blob = await getCroppedImg(imageURL!, a!);
}
await p.onPhotoSelected(blob);
setImageBlob(undefined);
setImageURL(undefined);
} catch (e) {
console.error(e);
alert("Echec du traitement de la photo !");
}
setProcessing(false);
};
return (
<>
{/* Upload button */}
2023-08-10 11:53:23 +00:00
<Button
onClick={uploadPhoto}
variant="outlined"
startIcon={<UploadIcon />}
>
{p.label}
</Button>
{/* Upload button (from URL) */}{" "}
{isDebug() && (
<Button
onClick={uploadPhotoFromURL}
variant="outlined"
startIcon={<LinkIcon />}
>
{p.label} from URL
</Button>
)}{" "}
2023-08-10 10:10:09 +00:00
{/* Crop image dialog */}
{imageURL && (
<ImageCropperDialog
processing={processing}
src={imageURL!}
onCancel={cancelCrop}
onSubmit={submitCrop}
aspect={p.aspect}
2023-08-10 10:10:09 +00:00
/>
)}
</>
);
}