fix question background setting crop modal
add original image loading
This commit is contained in:
parent
fe616ecf3a
commit
cfe7858026
@ -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[]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user