frontPanel/src/ui_kit/MediaSelectionAndDisplay.tsx

277 lines
7.7 KiB
TypeScript
Raw Normal View History

import { FC, useState } from "react";
import {
Box,
Button,
ButtonBase,
Skeleton,
Tooltip,
Typography,
useTheme,
} from "@mui/material";
2023-12-20 20:25:58 +00:00
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";
2024-01-04 21:42:05 +00:00
import UploadBox from "@ui_kit/UploadBox";
import UploadIcon from "@icons/UploadIcon";
import InfoIcon from "@icons/InfoIcon";
import { VideoElement } from "../pages/startPage/VideoElement";
2023-12-20 20:25:58 +00:00
interface Iprops {
resultData: AnyTypedQuizQuestion;
2024-04-01 17:09:54 +00:00
cropAspectRatio: {
width: number;
height: number;
};
2023-12-20 20:25:58 +00:00
}
2024-04-01 17:09:54 +00:00
export const MediaSelectionAndDisplay: FC<Iprops> = ({
resultData,
cropAspectRatio,
}) => {
2024-01-18 14:21:09 +00:00
const [pictureUploding, setPictureUploading] = useState<boolean>(false);
const [backgroundUploding, setBackgroundUploading] = useState<boolean>(false);
2023-12-20 20:25:58 +00:00
const quizQid = useCurrentQuiz()?.qid;
const theme = useTheme();
2023-12-31 02:53:25 +00:00
const {
isCropModalOpen,
openCropModal,
closeCropModal,
imageBlob,
originalImageUrl,
setCropModalImageBlob,
} = useCropModalState();
const [isImageUploadOpen, openImageUploadModal, closeImageUploadModal] =
useDisclosure();
2023-12-20 20:25:58 +00:00
async function handleImageUpload(file: File) {
2024-01-18 14:21:09 +00:00
setPictureUploading(true);
2024-01-19 11:22:48 +00:00
const url = await uploadQuestionImage(
resultData.id,
quizQid,
file,
(question, url) => {
question.content.back = url;
question.content.originalBack = url;
},
);
closeImageUploadModal();
openCropModal(file, url);
2024-01-18 14:21:09 +00:00
setPictureUploading(false);
2023-12-20 20:25:58 +00:00
}
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"
2023-12-31 02:53:25 +00:00
onClick={() =>
updateQuestion(
resultData.id,
(question) => (question.content.useImage = true),
)
}
2023-12-20 20:25:58 +00:00
>
Изображение
</Button>
<Button
sx={{
color: resultData.content.useImage ? "#9A9AAF" : "#7E2AEA",
fontSize: "16px",
"&:hover": {
background: "none",
},
}}
variant="text"
2023-12-31 02:53:25 +00:00
onClick={() =>
updateQuestion(
resultData.id,
(question) => (question.content.useImage = false),
)
}
2023-12-20 20:25:58 +00:00
>
Видео
</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}
2024-04-06 17:23:01 +00:00
onDeleteClick={() => {
updateQuestion(resultData.id, (question) => {
question.content.back = null;
question.content.originalBack = null;
});
}}
2024-04-01 17:09:54 +00:00
cropAspectRatio={cropAspectRatio}
2023-12-20 20:25:58 +00:00
/>
</Box>
{resultData.content.useImage && (
<Box
sx={{
cursor: "pointer",
display: "flex",
alignItems: "center",
gap: "20px",
mb: "30px",
}}
>
<AddOrEditImageButton
imageSrc={resultData.content.back}
2024-01-18 14:21:09 +00:00
uploading={pictureUploding}
2023-12-20 20:25:58 +00:00
onImageClick={() => {
if (resultData.content.back) {
2023-12-31 02:53:25 +00:00
return openCropModal(
resultData.content.back,
resultData.content.originalBack,
);
2023-12-20 20:25:58 +00:00
}
openImageUploadModal();
}}
onPlusClick={() => {
openImageUploadModal();
}}
/>
</Box>
)}
{!resultData.content.useImage && (
2024-01-04 21:42:05 +00:00
<>
{!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>
2024-01-04 21:42:05 +00:00
</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;
});
2024-01-04 21:42:05 +00:00
}}
/>
)}
2024-01-04 21:42:05 +00:00
</>
2023-12-20 20:25:58 +00:00
)}
</Box>
);
};