fix crop modal open state
This commit is contained in:
parent
52bf638baf
commit
1c2f9c2d5e
@ -14,19 +14,19 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme
|
||||
} from "@mui/material";
|
||||
import { openCropModal } from "@root/cropModal";
|
||||
import { closeImageUploadModal, openImageUploadModal } from "@root/imageUploadModal";
|
||||
import { setCropModal } from "@root/cropModal";
|
||||
import { addQuestionVariant, uploadQuestionImage } from "@root/questions/actions";
|
||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||
import AddOrEditImageButton from "@ui_kit/AddOrEditImageButton";
|
||||
import { CropModal } from "@ui_kit/Modal/CropModal";
|
||||
import { useState } from "react";
|
||||
import { useDisclosure } from "../../../utils/useDisclosure";
|
||||
import { EnterIcon } from "../../../assets/icons/questionsPage/enterIcon";
|
||||
import type { QuizQuestionVarImg } from "../../../model/questionTypes/varimg";
|
||||
import { AnswerDraggableList } from "../AnswerDraggableList";
|
||||
import ButtonsOptionsAndPict from "../ButtonsOptionsAndPict";
|
||||
import { UploadImageModal } from "../UploadImage/UploadImageModal";
|
||||
import SwitchOptionsAndPict from "./switchOptionsAndPict";
|
||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||
|
||||
|
||||
interface Props {
|
||||
@ -40,6 +40,8 @@ export default function OptionsAndPicture({ question }: Props) {
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const quizQid = useCurrentQuiz()?.qid;
|
||||
const [isCropModalOpen, openCropModal, closeCropModal] = useDisclosure();
|
||||
const [isImageUploadOpen, openImageUploadModal, closeImageUploadModal] = useDisclosure();
|
||||
|
||||
const SSHC = (data: string) => {
|
||||
setSwitchState(data);
|
||||
@ -60,7 +62,8 @@ export default function OptionsAndPicture({ question }: Props) {
|
||||
variant.originalImageUrl = url;
|
||||
});
|
||||
closeImageUploadModal();
|
||||
openCropModal(file, url);
|
||||
setCropModal(file, url);
|
||||
openCropModal();
|
||||
};
|
||||
|
||||
function handleCropModalSaveClick(imageBlob: Blob) {
|
||||
@ -87,13 +90,16 @@ export default function OptionsAndPicture({ question }: Props) {
|
||||
<AddOrEditImageButton
|
||||
imageSrc={variant.extendedText}
|
||||
onImageClick={() => {
|
||||
if (!("originalImageUrl" in variant)) return;
|
||||
|
||||
setSelectedVariantId(variant.id);
|
||||
if (variant.extendedText) return openCropModal(
|
||||
variant.extendedText,
|
||||
variant.originalImageUrl
|
||||
);
|
||||
if (variant.extendedText) {
|
||||
openCropModal();
|
||||
setCropModal(
|
||||
variant.extendedText,
|
||||
variant.originalImageUrl
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
openImageUploadModal();
|
||||
}}
|
||||
@ -112,13 +118,16 @@ export default function OptionsAndPicture({ question }: Props) {
|
||||
<AddOrEditImageButton
|
||||
imageSrc={variant.extendedText}
|
||||
onImageClick={() => {
|
||||
if (!("originalImageUrl" in variant)) return;
|
||||
|
||||
setSelectedVariantId(variant.id);
|
||||
if (variant.extendedText) return openCropModal(
|
||||
variant.extendedText,
|
||||
variant.originalImageUrl
|
||||
);
|
||||
if (variant.extendedText) {
|
||||
openCropModal();
|
||||
setCropModal(
|
||||
variant.extendedText,
|
||||
variant.originalImageUrl
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
openImageUploadModal();
|
||||
}}
|
||||
@ -132,8 +141,8 @@ export default function OptionsAndPicture({ question }: Props) {
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
<UploadImageModal imgHC={handleImageUpload} />
|
||||
<CropModal onSaveImageClick={handleCropModalSaveClick} />
|
||||
<UploadImageModal isOpen={isImageUploadOpen} onClose={closeImageUploadModal} imgHC={handleImageUpload} />
|
||||
<CropModal isOpen={isCropModalOpen} onClose={closeCropModal} onSaveImageClick={handleCropModalSaveClick} />
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
|
||||
@ -5,8 +5,7 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme
|
||||
} from "@mui/material";
|
||||
import { openCropModal } from "@root/cropModal";
|
||||
import { closeImageUploadModal, openImageUploadModal } from "@root/imageUploadModal";
|
||||
import { setCropModal } from "@root/cropModal";
|
||||
import { addQuestionVariant, uploadQuestionImage } from "@root/questions/actions";
|
||||
import AddOrEditImageButton from "@ui_kit/AddOrEditImageButton";
|
||||
import { CropModal } from "@ui_kit/Modal/CropModal";
|
||||
@ -18,6 +17,7 @@ import ButtonsOptions from "../ButtonsOptions";
|
||||
import { UploadImageModal } from "../UploadImage/UploadImageModal";
|
||||
import SwitchAnswerOptionsPict from "./switchOptionsPict";
|
||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||
import { useDisclosure } from "../../../utils/useDisclosure";
|
||||
|
||||
|
||||
interface Props {
|
||||
@ -30,6 +30,8 @@ export default function OptionsPicture({ question }: Props) {
|
||||
const [selectedVariantId, setSelectedVariantId] = useState<string | null>(null);
|
||||
const [switchState, setSwitchState] = useState("setting");
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const [isCropModalOpen, openCropModal, closeCropModal] = useDisclosure();
|
||||
const [isImageUploadOpen, openImageUploadModal, closeImageUploadModal] = useDisclosure();
|
||||
|
||||
const SSHC = (data: string) => {
|
||||
setSwitchState(data);
|
||||
@ -50,7 +52,8 @@ export default function OptionsPicture({ question }: Props) {
|
||||
variant.originalImageUrl = url;
|
||||
});
|
||||
closeImageUploadModal();
|
||||
openCropModal(file, url);
|
||||
setCropModal(file, url);
|
||||
openCropModal();
|
||||
};
|
||||
|
||||
function handleCropModalSaveClick(imageBlob: Blob) {
|
||||
@ -77,14 +80,15 @@ export default function OptionsPicture({ question }: Props) {
|
||||
<AddOrEditImageButton
|
||||
imageSrc={variant.extendedText}
|
||||
onImageClick={() => {
|
||||
if (!("originalImageUrl" in variant)) return;
|
||||
|
||||
setSelectedVariantId(variant.id);
|
||||
if (variant.extendedText) {
|
||||
return openCropModal(
|
||||
openCropModal();
|
||||
setCropModal(
|
||||
variant.extendedText,
|
||||
variant.originalImageUrl
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
openImageUploadModal();
|
||||
@ -104,14 +108,15 @@ export default function OptionsPicture({ question }: Props) {
|
||||
<AddOrEditImageButton
|
||||
imageSrc={variant.extendedText}
|
||||
onImageClick={() => {
|
||||
if (!("originalImageUrl" in variant)) return;
|
||||
|
||||
setSelectedVariantId(variant.id);
|
||||
if (variant.extendedText) {
|
||||
return openCropModal(
|
||||
openCropModal();
|
||||
setCropModal(
|
||||
variant.extendedText,
|
||||
variant.originalImageUrl
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
openImageUploadModal();
|
||||
@ -126,8 +131,8 @@ export default function OptionsPicture({ question }: Props) {
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
<UploadImageModal imgHC={handleImageUpload} />
|
||||
<CropModal onSaveImageClick={handleCropModalSaveClick} />
|
||||
<UploadImageModal isOpen={isImageUploadOpen} onClose={closeImageUploadModal} imgHC={handleImageUpload} />
|
||||
<CropModal isOpen={isCropModalOpen} onClose={closeCropModal} onSaveImageClick={handleCropModalSaveClick} />
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
|
||||
<Link
|
||||
component="button"
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { VideofileIcon } from "@icons/questionsPage/VideofileIcon";
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { openCropModal } from "@root/cropModal";
|
||||
import { closeImageUploadModal, openImageUploadModal } from "@root/imageUploadModal";
|
||||
import { setCropModal } from "@root/cropModal";
|
||||
import { updateQuestion, uploadQuestionImage } from "@root/questions/actions";
|
||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||
import AddOrEditImageButton from "@ui_kit/AddOrEditImageButton";
|
||||
@ -14,6 +13,7 @@ import ButtonsOptions from "../ButtonsOptions";
|
||||
import { UploadImageModal } from "../UploadImage/UploadImageModal";
|
||||
import { UploadVideoModal } from "../UploadVideoModal";
|
||||
import SwitchPageOptions from "./switchPageOptions";
|
||||
import { useDisclosure } from "../../../utils/useDisclosure";
|
||||
|
||||
|
||||
type Props = {
|
||||
@ -29,6 +29,8 @@ export default function PageOptions({ disableInput, question }: Props) {
|
||||
const isFigmaTablet = useMediaQuery(theme.breakpoints.down(990));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(780));
|
||||
const quizQid = useCurrentQuiz()?.qid;
|
||||
const [isCropModalOpen, openCropModal, closeCropModal] = useDisclosure();
|
||||
const [isImageUploadOpen, openImageUploadModal, closeImageUploadModal] = useDisclosure();
|
||||
|
||||
const setText = useDebouncedCallback((value) => {
|
||||
updateQuestion(question.id, question => {
|
||||
@ -52,7 +54,8 @@ export default function PageOptions({ disableInput, question }: Props) {
|
||||
question.content.originalPicture = url;
|
||||
});
|
||||
closeImageUploadModal();
|
||||
openCropModal(fileList[0], url);
|
||||
setCropModal(fileList[0], url);
|
||||
openCropModal();
|
||||
}
|
||||
|
||||
function handleCropModalSaveClick(imageBlob: Blob) {
|
||||
@ -105,7 +108,7 @@ export default function PageOptions({ disableInput, question }: Props) {
|
||||
imageSrc={question.content.picture}
|
||||
onImageClick={() => {
|
||||
if (question.content.picture) {
|
||||
return openCropModal(
|
||||
return setCropModal(
|
||||
question.content.picture,
|
||||
question.content.originalPicture
|
||||
);
|
||||
@ -130,8 +133,8 @@ export default function PageOptions({ disableInput, question }: Props) {
|
||||
Изображение
|
||||
</Typography>
|
||||
</Box>
|
||||
<UploadImageModal imgHC={handleImageUpload} />
|
||||
<CropModal onSaveImageClick={handleCropModalSaveClick} />
|
||||
<UploadImageModal isOpen={isImageUploadOpen} onClose={closeImageUploadModal} imgHC={handleImageUpload} />
|
||||
<CropModal isOpen={isCropModalOpen} onClose={closeCropModal} onSaveImageClick={handleCropModalSaveClick} />
|
||||
<Typography> или</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
|
||||
@ -14,17 +14,19 @@ import * as React from "react";
|
||||
import UnsplashIcon from "../../../assets/icons/Unsplash.svg";
|
||||
|
||||
import type { DragEvent } from "react";
|
||||
import { closeImageUploadModal, useImageUploadModalStore } from "@root/imageUploadModal";
|
||||
|
||||
interface ModalkaProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
imgHC: (imgInp: FileList | null) => void;
|
||||
}
|
||||
|
||||
export const UploadImageModal: React.FC<ModalkaProps> = ({
|
||||
imgHC,
|
||||
isOpen,
|
||||
onClose,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const isOpen = useImageUploadModalStore(state => state.isOpen)
|
||||
|
||||
const dropZone = React.useRef<HTMLDivElement>(null);
|
||||
const [ready, setReady] = React.useState(false);
|
||||
@ -44,7 +46,7 @@ export const UploadImageModal: React.FC<ModalkaProps> = ({
|
||||
return (
|
||||
<Modal
|
||||
open={isOpen}
|
||||
onClose={closeImageUploadModal}
|
||||
onClose={onClose}
|
||||
aria-labelledby="modal-modal-title"
|
||||
aria-describedby="modal-modal-description"
|
||||
>
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
|
||||
import { Box, ButtonBase, Typography, useTheme } from "@mui/material";
|
||||
import { closeImageUploadModal, openImageUploadModal } from "@root/imageUploadModal";
|
||||
import { uploadQuestionImage } from "@root/questions/actions";
|
||||
import { CropModal } from "@ui_kit/Modal/CropModal";
|
||||
import UploadBox from "@ui_kit/UploadBox";
|
||||
import { type DragEvent } from "react";
|
||||
import UploadIcon from "../../../assets/icons/UploadIcon";
|
||||
import { UploadImageModal } from "./UploadImageModal";
|
||||
import { openCropModal } from "@root/cropModal";
|
||||
import { setCropModal } from "@root/cropModal";
|
||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||
import { useDisclosure } from "../../../utils/useDisclosure";
|
||||
|
||||
|
||||
type UploadImageProps = {
|
||||
@ -18,6 +18,8 @@ type UploadImageProps = {
|
||||
export default function UploadImage({ question }: UploadImageProps) {
|
||||
const theme = useTheme();
|
||||
const quizQid = useCurrentQuiz()?.qid;
|
||||
const [isCropModalOpen, openCropModal, closeCropModal] = useDisclosure();
|
||||
const [isImageUploadOpen, openImageUploadModal, closeImageUploadModal] = useDisclosure();
|
||||
|
||||
const handleImageUpload = async (files: FileList | null) => {
|
||||
if (!files?.length) return;
|
||||
@ -27,7 +29,8 @@ export default function UploadImage({ question }: UploadImageProps) {
|
||||
question.content.originalBack = url;
|
||||
});
|
||||
closeImageUploadModal();
|
||||
openCropModal(files[0], url);
|
||||
setCropModal(files[0], url);
|
||||
openCropModal();
|
||||
};
|
||||
|
||||
const handleDrop = (event: DragEvent<HTMLDivElement>) => {
|
||||
@ -83,8 +86,8 @@ export default function UploadImage({ question }: UploadImageProps) {
|
||||
/>
|
||||
}
|
||||
</ButtonBase>
|
||||
<UploadImageModal imgHC={handleImageUpload} />
|
||||
<CropModal onSaveImageClick={handleCropModalSaveClick} />
|
||||
<UploadImageModal isOpen={isImageUploadOpen} onClose={closeImageUploadModal} imgHC={handleImageUpload} />
|
||||
<CropModal isOpen={isCropModalOpen} onClose={closeCropModal} onSaveImageClick={handleCropModalSaveClick} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import { Box, Typography, useTheme, useMediaQuery } from "@mui/material";
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
|
||||
import AddImage from "@icons/questionsPage/addImage";
|
||||
import AddVideofile from "@icons/questionsPage/addVideofile";
|
||||
import { CropModal } from "@ui_kit/Modal/CropModal";
|
||||
import { openCropModal } from "@root/cropModal";
|
||||
|
||||
export default function ImageAndVideoButtons() {
|
||||
const theme = useTheme();
|
||||
@ -12,7 +10,6 @@ export default function ImageAndVideoButtons() {
|
||||
return (
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "12px", mt: "20px", mb: "20px" }}>
|
||||
<AddImage onClick={undefined/* TODO () => openCropModal("", "") */} />
|
||||
<CropModal />
|
||||
<Typography
|
||||
sx={{
|
||||
fontWeight: 400,
|
||||
|
||||
@ -3,13 +3,11 @@ import { devtools } from "zustand/middleware";
|
||||
|
||||
|
||||
type CropModalStore = {
|
||||
isCropModalOpen: boolean;
|
||||
imageBlob: Blob | null;
|
||||
originalImageUrl: string | null;
|
||||
};
|
||||
|
||||
const initialState: CropModalStore = {
|
||||
isCropModalOpen: false,
|
||||
export const initialState: CropModalStore = {
|
||||
imageBlob: null,
|
||||
originalImageUrl: null,
|
||||
};
|
||||
@ -25,23 +23,23 @@ export const useCropModalStore = create<CropModalStore>()(
|
||||
),
|
||||
);
|
||||
|
||||
export const openCropModal = async (image: Blob | string, originalImageUrl: string | null | undefined) => {
|
||||
if (typeof image === "string") {
|
||||
const response = await fetch(image);
|
||||
const blob = await response.blob();
|
||||
|
||||
useCropModalStore.setState({
|
||||
isCropModalOpen: true,
|
||||
imageBlob: blob,
|
||||
originalImageUrl,
|
||||
}, false, "openCropModal");
|
||||
return;
|
||||
export const setCropModal = async (
|
||||
imageBlob: Blob | string | null,
|
||||
originalImageUrl: string | null | undefined,
|
||||
) => {
|
||||
if (typeof imageBlob === "string") {
|
||||
const response = await fetch(imageBlob);
|
||||
imageBlob = await response.blob();
|
||||
}
|
||||
|
||||
useCropModalStore.setState({
|
||||
isCropModalOpen: true,
|
||||
imageBlob: image,
|
||||
}, false, "openCropModal");
|
||||
imageBlob,
|
||||
originalImageUrl: originalImageUrl ?? null,
|
||||
}, false, {
|
||||
type: "setCropModal",
|
||||
imageBlob,
|
||||
originalImageUrl,
|
||||
});
|
||||
};
|
||||
|
||||
export const closeCropModal = () => useCropModalStore.setState(
|
||||
@ -50,14 +48,22 @@ export const closeCropModal = () => useCropModalStore.setState(
|
||||
"closeCropModal"
|
||||
);
|
||||
|
||||
export const setCropModalImageBlob = (imageBlob: Blob | null) => useCropModalStore.setState(
|
||||
{ imageBlob },
|
||||
false,
|
||||
"setCropModalImageUrl"
|
||||
);
|
||||
export const setCropModalImageBlob = async (image: Blob | string | null) => {
|
||||
if (typeof image === "string") {
|
||||
const response = await fetch(image);
|
||||
image = await response.blob();
|
||||
}
|
||||
|
||||
export const setCropModalOriginalImageUrl = (originalImageUrl: string | null) => useCropModalStore.setState(
|
||||
{ originalImageUrl },
|
||||
useCropModalStore.setState({
|
||||
imageBlob: image,
|
||||
}, false, {
|
||||
type: "setCropModalImageBlob",
|
||||
image,
|
||||
});
|
||||
};
|
||||
|
||||
export const setCropModalOriginalImageUrl = (originalImageUrl: string | null | undefined) => useCropModalStore.setState(
|
||||
{ originalImageUrl: originalImageUrl ?? null },
|
||||
false,
|
||||
"setCropModalOriginalImageUrl"
|
||||
);
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
import { create } from "zustand";
|
||||
import { devtools, persist } from "zustand/middleware";
|
||||
|
||||
|
||||
type ImageUploadModalStore = {
|
||||
isOpen: boolean;
|
||||
};
|
||||
|
||||
const initialState: ImageUploadModalStore = {
|
||||
isOpen: false,
|
||||
};
|
||||
|
||||
export const useImageUploadModalStore = create<ImageUploadModalStore>()(
|
||||
persist(
|
||||
devtools(
|
||||
() => initialState,
|
||||
{
|
||||
name: "ImageUploadModalStore",
|
||||
}
|
||||
),
|
||||
{
|
||||
name: "ImageUploadModalStore",
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export const openImageUploadModal = () => useImageUploadModalStore.setState({ isOpen: true });
|
||||
|
||||
export const closeImageUploadModal = () => useImageUploadModalStore.setState({ isOpen: false });
|
||||
@ -152,7 +152,6 @@ export const setVariantImageUrl = (
|
||||
if (!("variants" in question.content)) return;
|
||||
|
||||
const variant = question.content.variants[variantIndex];
|
||||
if (!("originalImageUrl" in variant)) return;
|
||||
|
||||
if (variant.extendedText === url) return;
|
||||
|
||||
@ -177,7 +176,6 @@ export const setVariantOriginalImageUrl = (
|
||||
if (!("variants" in question.content)) return;
|
||||
|
||||
const variant = question.content.variants[variantIndex];
|
||||
if (!("originalImageUrl" in variant)) return;
|
||||
|
||||
if (variant.originalImageUrl === url) return;
|
||||
|
||||
|
||||
@ -12,11 +12,11 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { closeCropModal, setCropModalImageBlob, useCropModalStore } from "@root/cropModal";
|
||||
import { FC, useMemo, useRef, useState } from "react";
|
||||
import ReactCrop, { Crop, PixelCrop } from "react-image-crop";
|
||||
import "react-image-crop/dist/ReactCrop.css";
|
||||
import { canvasPreview } from "./utils/canvasPreview";
|
||||
import { setCropModalImageBlob, useCropModalStore } from "@root/cropModal";
|
||||
|
||||
|
||||
const styleSlider: SxProps<Theme> = {
|
||||
@ -44,16 +44,17 @@ const styleSlider: SxProps<Theme> = {
|
||||
};
|
||||
|
||||
interface Props {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
onSaveImageClick?: (imageBlob: Blob) => void;
|
||||
}
|
||||
|
||||
export const CropModal: FC<Props> = ({ onSaveImageClick }) => {
|
||||
export const CropModal: FC<Props> = ({isOpen, onSaveImageClick, onClose }) => {
|
||||
const theme = useTheme();
|
||||
const isCropModalOpen = useCropModalStore(state => state.isCropModalOpen);
|
||||
const imageBlob = useCropModalStore(state => state.imageBlob);
|
||||
const originalImageUrl = useCropModalStore(state => state.originalImageUrl);
|
||||
const [crop, setCrop] = useState<Crop>();
|
||||
const [completedCrop, setCompletedCrop] = useState<PixelCrop>();
|
||||
const imageBlob = useCropModalStore(state => state.imageBlob);
|
||||
const originalImageUrl = useCropModalStore(state => state.originalImageUrl);
|
||||
const [darken, setDarken] = useState(0);
|
||||
const [rotate, setRotate] = useState(0);
|
||||
const [width, setWidth] = useState<number>(0);
|
||||
@ -89,7 +90,7 @@ export const CropModal: FC<Props> = ({ onSaveImageClick }) => {
|
||||
if (imageBlob) onSaveImageClick?.(imageBlob);
|
||||
setCrop(undefined);
|
||||
setCompletedCrop(undefined);
|
||||
closeCropModal();
|
||||
onClose();
|
||||
}
|
||||
|
||||
async function handleLoadOriginalImage() {
|
||||
@ -125,8 +126,8 @@ export const CropModal: FC<Props> = ({ onSaveImageClick }) => {
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={isCropModalOpen}
|
||||
onClose={closeCropModal}
|
||||
open={ isOpen}
|
||||
onClose={onClose}
|
||||
aria-labelledby="modal-modal-title"
|
||||
aria-describedby="modal-modal-description"
|
||||
>
|
||||
@ -295,4 +296,4 @@ export const CropModal: FC<Props> = ({ onSaveImageClick }) => {
|
||||
</Box>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
import { Box, Button } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { CropModal } from "./CropModal";
|
||||
|
||||
const ImageCrop: FC = () => {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Button onClick={undefined}>Открыть модалку</Button>
|
||||
<CropModal />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@ -8,11 +8,7 @@ export class RequestQueue<T = unknown> {
|
||||
|
||||
enqueue(action: () => Promise<T>) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.items.length === 2) {
|
||||
this.items[1] = { action, resolve, reject };
|
||||
} else {
|
||||
this.items.push({ action, resolve, reject });
|
||||
}
|
||||
this.items.push({ action, resolve, reject });
|
||||
this.dequeue();
|
||||
});
|
||||
}
|
||||
|
||||
13
src/utils/useDisclosure.ts
Normal file
13
src/utils/useDisclosure.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { useState, useCallback } from "react";
|
||||
|
||||
|
||||
export function useDisclosure(initialState = false) {
|
||||
const [opened, setOpened] = useState(initialState);
|
||||
|
||||
return [
|
||||
opened,
|
||||
useCallback(() => setOpened(true), []),
|
||||
useCallback(() => setOpened(false), []),
|
||||
useCallback(() => setOpened(prev => !prev), []),
|
||||
] as const;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user