frontPanel/src/ui_kit/MediaSelectionAndDisplay.tsx

277 lines
7.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { FC, useState } from "react";
import {
Box,
Button,
ButtonBase,
Skeleton,
Tooltip,
Typography,
useTheme,
} from "@mui/material";
import { updateQuestion, uploadQuestionImage } from "@root/questions/actions";
import { CropModal, useCropModalState } from "@ui_kit/Modal/CropModal";
import AddOrEditImageButton from "@ui_kit/AddOrEditImageButton";
import { UploadImageModal } from "../pages/Questions/UploadImage/UploadImageModal";
import { useDisclosure } from "../utils/useDisclosure";
import { useCurrentQuiz } from "../stores/quizes/hooks";
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
import UploadBox from "@ui_kit/UploadBox";
import UploadIcon from "@icons/UploadIcon";
import InfoIcon from "@icons/InfoIcon";
import { VideoElement } from "../pages/startPage/VideoElement";
interface Iprops {
resultData: AnyTypedQuizQuestion;
cropAspectRatio: {
width: number;
height: number;
};
}
export const MediaSelectionAndDisplay: FC<Iprops> = ({
resultData,
cropAspectRatio,
}) => {
const [pictureUploding, setPictureUploading] = useState<boolean>(false);
const [backgroundUploding, setBackgroundUploading] = useState<boolean>(false);
const quizQid = useCurrentQuiz()?.qid;
const theme = useTheme();
const {
isCropModalOpen,
openCropModal,
closeCropModal,
imageBlob,
originalImageUrl,
setCropModalImageBlob,
} = useCropModalState();
const [isImageUploadOpen, openImageUploadModal, closeImageUploadModal] =
useDisclosure();
async function handleImageUpload(file: File) {
setPictureUploading(true);
const url = await uploadQuestionImage(
resultData.id,
quizQid,
file,
(question, url) => {
question.content.back = url;
question.content.originalBack = url;
},
);
closeImageUploadModal();
openCropModal(file, url);
setPictureUploading(false);
}
function handleCropModalSaveClick(imageBlob: Blob) {
uploadQuestionImage(resultData.id, quizQid, imageBlob, (question, url) => {
question.content.back = url;
});
}
return (
<Box
sx={{
mt: "20px",
display: "flex",
gap: "10px",
flexDirection: "column",
}}
>
<Box
sx={{
display: "flex",
}}
>
<Button
sx={{
color: resultData.content.useImage ? "#7E2AEA" : "#9A9AAF",
fontSize: "16px",
"&:hover": {
background: "none",
},
}}
variant="text"
onClick={() =>
updateQuestion(
resultData.id,
(question) => (question.content.useImage = true),
)
}
>
Изображение
</Button>
<Button
sx={{
color: resultData.content.useImage ? "#9A9AAF" : "#7E2AEA",
fontSize: "16px",
"&:hover": {
background: "none",
},
}}
variant="text"
onClick={() =>
updateQuestion(
resultData.id,
(question) => (question.content.useImage = false),
)
}
>
Видео
</Button>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
}}
>
<UploadImageModal
isOpen={isImageUploadOpen}
onClose={closeImageUploadModal}
handleImageChange={handleImageUpload}
/>
<CropModal
isOpen={isCropModalOpen}
imageBlob={imageBlob}
originalImageUrl={originalImageUrl}
setCropModalImageBlob={setCropModalImageBlob}
onClose={closeCropModal}
onSaveImageClick={handleCropModalSaveClick}
onDeleteClick={() => {
updateQuestion(resultData.id, (question) => {
question.content.back = null;
question.content.originalBack = null;
});
}}
cropAspectRatio={cropAspectRatio}
/>
</Box>
{resultData.content.useImage && (
<Box
sx={{
cursor: "pointer",
display: "flex",
alignItems: "center",
gap: "20px",
mb: "30px",
}}
>
<AddOrEditImageButton
imageSrc={resultData.content.back}
uploading={pictureUploding}
onImageClick={() => {
if (resultData.content.back) {
return openCropModal(
resultData.content.back,
resultData.content.originalBack,
);
}
openImageUploadModal();
}}
onPlusClick={() => {
openImageUploadModal();
}}
/>
</Box>
)}
{!resultData.content.useImage && (
<>
{!resultData.content.video ? (
<>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "7px",
mt: "20px",
mb: "14px",
}}
>
<Typography
sx={{ fontWeight: 500, color: theme.palette.grey3.main }}
>
Добавить видео
</Typography>
<Tooltip title="Можно загрузить видео." placement="top">
<Box>
<InfoIcon />
</Box>
</Tooltip>
</Box>
{backgroundUploding ? (
<Skeleton
sx={{
width: "48px",
height: "48px",
transform: "none",
margin: "20px 0",
}}
/>
) : (
<>
<ButtonBase
component="label"
sx={{
justifyContent: "center",
height: "48px",
width: "48px",
display: "flex",
alignItems: "center",
my: "20px",
}}
>
<input
onChange={async (event) => {
setBackgroundUploading(true);
const file = event.target.files?.[0];
if (file) {
await uploadQuestionImage(
resultData.id,
quizQid,
file,
(question, url) => {
question.content.video = url;
},
);
}
setBackgroundUploading(false);
}}
hidden
accept=".mp4"
multiple
type="file"
/>
<UploadBox
icon={<UploadIcon />}
sx={{
height: "48px",
width: "48px",
}}
/>
</ButtonBase>
</>
)}
</>
) : (
<VideoElement
videoSrc={resultData.content.video}
theme={theme}
onDeleteClick={() => {
updateQuestion(resultData.id, (question) => {
question.content.video = null;
});
}}
/>
)}
</>
)}
</Box>
);
};