fix question background setting crop modal

add original image loading
This commit is contained in:
nflnkr 2023-10-24 18:18:31 +03:00
parent fe616ecf3a
commit cfe7858026
15 changed files with 122 additions and 61 deletions

@ -24,6 +24,7 @@ export const QUIZ_QUESTION_BASE: Omit<QuizQuestionInitial, "id"> = {
],
},
back: "",
originalBack: "",
autofill: false,
},
};

@ -18,6 +18,7 @@ export interface QuizQuestionDate extends QuizQuestionBase {
hint: QuestionHint;
rule: QuestionBranchingRule;
back: string;
originalBack: string;
autofill: boolean;
};
}

@ -22,6 +22,7 @@ export interface QuizQuestionEmoji extends QuizQuestionBase {
hint: QuestionHint;
rule: QuestionBranchingRule;
back: string;
originalBack: string;
autofill: boolean;
};
}

@ -29,5 +29,6 @@ export interface QuizQuestionFile extends QuizQuestionBase {
hint: QuestionHint;
rule: QuestionBranchingRule;
back: string;
originalBack: string;
};
}

@ -29,6 +29,7 @@ export interface QuizQuestionImages extends QuizQuestionBase {
hint: QuestionHint;
rule: QuestionBranchingRule;
back: string;
originalBack: string;
autofill: boolean;
largeCheck: boolean;
};

@ -27,6 +27,7 @@ export interface QuizQuestionNumber extends QuizQuestionBase {
hint: QuestionHint;
rule: QuestionBranchingRule;
back: string;
originalBack: string;
autofill: boolean;
form: "star" | "trophie" | "flag" | "heart" | "like" | "bubble" | "hashtag";
};

@ -18,6 +18,7 @@ export interface QuizQuestionPage extends QuizQuestionBase {
hint: QuestionHint;
rule: QuestionBranchingRule;
back: string;
originalBack: string;
autofill: boolean;
};
}

@ -20,6 +20,7 @@ export interface QuizQuestionRating extends QuizQuestionBase {
hint: QuestionHint;
rule: QuestionBranchingRule;
back: string;
originalBack: string;
autofill: boolean;
/** Позитивное описание рейтинга */
ratingPositiveDescription: string;

@ -22,6 +22,7 @@ export interface QuizQuestionSelect extends QuizQuestionBase {
rule: QuestionBranchingRule;
hint: QuestionHint;
back: string;
originalBack: string;
autofill: boolean;
};
}

@ -55,6 +55,7 @@ export interface QuizQuestionBase {
hint: QuestionHint;
rule: QuestionBranchingRule;
back: string;
originalBack: string;
autofill: boolean;
};
}

@ -20,5 +20,6 @@ export interface QuizQuestionText extends QuizQuestionBase {
hint: QuestionHint;
rule: QuestionBranchingRule;
back: string;
originalBack: string;
};
}

@ -25,6 +25,7 @@ export interface QuizQuestionVariant extends QuizQuestionBase {
hint: QuestionHint;
rule: QuestionBranchingRule;
back: string;
originalBack: string;
autofill: boolean;
};
}

@ -20,6 +20,7 @@ export interface QuizQuestionVarImg extends QuizQuestionBase {
hint: QuestionHint;
rule: QuestionBranchingRule;
back: string;
originalBack: string;
autofill: boolean;
largeCheck: boolean;
replText: string;

@ -1,77 +1,97 @@
import { useParams } from "react-router-dom";
import { Typography, Box, useTheme, ButtonBase } from "@mui/material";
import UploadBox from "@ui_kit/UploadBox";
import { Box, ButtonBase, Typography, useTheme } from "@mui/material";
import { questionStore, setQuestionBackgroundImage, setQuestionOriginalBackgroundImage } from "@root/questions";
import { CropModal } from "@ui_kit/Modal/CropModal";
import UploadIcon from "../../../assets/icons/UploadIcon";
import UploadBox from "@ui_kit/UploadBox";
import * as React from "react";
import { questionStore, updateQuestionsList } from "@root/questions";
import { useParams } from "react-router-dom";
import UploadIcon from "../../../assets/icons/UploadIcon";
import { UploadImageModal } from "./UploadImageModal";
import type { DragEvent } from "react";
import type { QuizQuestionImages } from "../../../model/questionTypes/images";
import { openCropModal } from "@root/cropModal";
import { QuizQuestionBase } from "model/questionTypes/shared";
import type { DragEvent } from "react";
type UploadImageProps = {
totalIndex: number;
totalIndex: number;
};
export default function UploadImage({ totalIndex }: UploadImageProps) {
const quizId = Number(useParams().quizId);
const theme = useTheme();
const [open, setOpen] = React.useState(false);
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionImages;
const quizId = Number(useParams().quizId);
const theme = useTheme();
const [isUploadImageModalOpen, setIsUploadImageModalOpen] = React.useState(false);
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionBase;
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
const imgHC = (files: FileList | null) => {
if (files?.length) {
const [file] = Array.from(files);
const handleImageUpload = (files: FileList | null) => {
if (!files?.length) return;
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
content: {
...question.content,
back: URL.createObjectURL(file),
},
});
const [file] = Array.from(files);
handleClose();
openCropModal(question.content.back, question.content.back);
const url = URL.createObjectURL(file);
setQuestionBackgroundImage(quizId, totalIndex, url);
setQuestionOriginalBackgroundImage(quizId, totalIndex, url);
setIsUploadImageModalOpen(false);
openCropModal(url, url);
};
const handleDrop = (event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
handleImageUpload(event.dataTransfer.files);
};
function handleCropModalSaveClick(url: string) {
setQuestionBackgroundImage(quizId, totalIndex, url);
}
};
const handleDrop = (event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
imgHC(event.dataTransfer.files);
};
return (
<Box sx={{ padding: "20px" }}>
<Typography
sx={{
fontWeight: 500,
color: theme.palette.grey3.main,
mt: "11px",
mb: "14px",
}}
>
Загрузить изображение
</Typography>
<ButtonBase
onClick={handleOpen}
sx={{ width: "100%", maxWidth: "260px" }}
>
<UploadBox
handleDrop={handleDrop}
sx={{ maxWidth: "260px" }}
icon={<UploadIcon />}
text="5 MB максимум"
/>
</ButtonBase>
<UploadImageModal open={open} onClose={handleClose} imgHC={imgHC} />
<CropModal />
</Box>
);
return (
<Box sx={{ padding: "20px" }}>
<Typography
sx={{
fontWeight: 500,
color: theme.palette.grey3.main,
mt: "11px",
mb: "14px",
}}
>
Загрузить изображение
</Typography>
<ButtonBase
onClick={() => setIsUploadImageModalOpen(true)}
sx={{
width: "100%",
maxWidth: "260px",
height: "120px",
}}
>
{question.content.back ?
<img
src={question.content.back}
alt="question background"
style={{
width: "100%",
height: "100%",
objectFit: "scale-down",
display: "block",
}}
/>
:
<UploadBox
handleDrop={handleDrop}
sx={{ maxWidth: "260px" }}
icon={<UploadIcon />}
text="5 MB максимум"
/>
}
</ButtonBase>
<UploadImageModal
open={isUploadImageModalOpen}
onClose={() => setIsUploadImageModalOpen(false)}
imgHC={handleImageUpload}
/>
<CropModal onSaveImageClick={handleCropModalSaveClick} />
</Box>
);
}

@ -217,6 +217,34 @@ export const setPageQuestionOriginalPicture = (
question.content.originalPicture = url;
});
export const setQuestionBackgroundImage = (
quizId: number,
questionIndex: number,
url: string,
) => setProducedState(state => {
const question = state.listQuestions[quizId][questionIndex];
if (question.content.back === url) return;
if (
question.content.back !== question.content.originalBack
) URL.revokeObjectURL(question.content.back);
question.content.back = url;
})
export const setQuestionOriginalBackgroundImage = (
quizId: number,
questionIndex: number,
url: string,
) => setProducedState(state => {
const question = state.listQuestions[quizId][questionIndex];
if (question.content.originalBack === url) return;
URL.revokeObjectURL(question.content.originalBack);
question.content.originalBack = url;
})
export const updateQuestionsListDragAndDrop = (
quizId: number,
updatedQuestions: AnyQuizQuestion[]