154 lines
4.6 KiB
TypeScript
154 lines
4.6 KiB
TypeScript
import { QuizAnswerer } from "@frontend/squzanswerer";
|
|
import ResizeIcon from "@icons/ResizeIcon";
|
|
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
|
|
import { Box, ThemeProvider } from "@mui/material";
|
|
import { useQuestionsStore } from "@root/questions/store";
|
|
import { useQuizPreviewStore } from "@root/quizPreview";
|
|
import { useCurrentQuiz } from "@root/quizes/hooks";
|
|
import { themesPublication } from "@utils/themes/Publication/themePublication";
|
|
import { useLayoutEffect, useRef } from "react";
|
|
import { Rnd } from "react-rnd";
|
|
|
|
interface RndPositionAndSize {
|
|
x: number;
|
|
y: number;
|
|
width: string;
|
|
height: string;
|
|
}
|
|
|
|
export default function QuizPreview() {
|
|
const isPreviewShown = useQuizPreviewStore((state) => state.isPreviewShown);
|
|
const rndParentRef = useRef<HTMLDivElement>(null);
|
|
const quiz = useCurrentQuiz();
|
|
const questions = useQuestionsStore((state) => state.questions).filter(
|
|
(q): q is AnyTypedQuizQuestion => q.type !== null,
|
|
);
|
|
const rndRef = useRef<Rnd | null>(null);
|
|
const rndPositionAndSizeRef = useRef<RndPositionAndSize>({
|
|
x: 0,
|
|
y: 0,
|
|
width: "340",
|
|
height: "480",
|
|
});
|
|
const isFirstShowRef = useRef<boolean>(true);
|
|
|
|
if (!quiz) return null;
|
|
|
|
useLayoutEffect(
|
|
function stickPreviewToBottomRight() {
|
|
const rnd = rndRef.current;
|
|
const rndSelfElement = rnd?.getSelfElement();
|
|
if (
|
|
!rnd ||
|
|
!rndSelfElement ||
|
|
!rndParentRef.current ||
|
|
!isFirstShowRef.current
|
|
)
|
|
return;
|
|
|
|
const rndParentRect = rndParentRef.current.getBoundingClientRect();
|
|
const rndRect = rndSelfElement.getBoundingClientRect();
|
|
|
|
const x = rndParentRect.width - rndRect.width;
|
|
const y = rndParentRect.height - rndRect.height;
|
|
|
|
rnd.updatePosition({ x, y });
|
|
rndPositionAndSizeRef.current.x = x;
|
|
rndPositionAndSizeRef.current.y = y;
|
|
|
|
isFirstShowRef.current = false;
|
|
},
|
|
[isPreviewShown],
|
|
);
|
|
|
|
return (
|
|
<ThemeProvider
|
|
theme={themesPublication?.[quiz?.config.theme || "StandardTheme"]}
|
|
>
|
|
<Box
|
|
ref={rndParentRef}
|
|
data-cy="quiz-preview-container"
|
|
sx={{
|
|
position: "fixed",
|
|
top: 0,
|
|
left: 0,
|
|
bottom: 70,
|
|
right: 70,
|
|
pointerEvents: "none",
|
|
zIndex: 100,
|
|
}}
|
|
>
|
|
{isPreviewShown && (
|
|
<Rnd
|
|
minHeight={20}
|
|
minWidth={20}
|
|
bounds="parent"
|
|
ref={rndRef}
|
|
dragHandleClassName="quiz-preview-draghandle"
|
|
default={{
|
|
x: rndPositionAndSizeRef.current.x,
|
|
y: rndPositionAndSizeRef.current.y,
|
|
width: rndPositionAndSizeRef.current.width,
|
|
height: rndPositionAndSizeRef.current.height,
|
|
}}
|
|
onResizeStop={(e, direction, ref, delta, position) => {
|
|
rndPositionAndSizeRef.current.x = position.x;
|
|
rndPositionAndSizeRef.current.y = position.y;
|
|
rndPositionAndSizeRef.current.width = ref.style.width;
|
|
rndPositionAndSizeRef.current.height = ref.style.height;
|
|
}}
|
|
onDragStop={(e, d) => {
|
|
rndPositionAndSizeRef.current.x = d.x;
|
|
rndPositionAndSizeRef.current.y = d.y;
|
|
}}
|
|
onDragStart={(e, d) => {
|
|
e.preventDefault();
|
|
}}
|
|
enableResizing={{
|
|
topLeft: isPreviewShown,
|
|
}}
|
|
resizeHandleComponent={{
|
|
topLeft: <ResizeIcon />,
|
|
}}
|
|
resizeHandleStyles={{
|
|
topLeft: {
|
|
top: "-1px",
|
|
left: "-1px",
|
|
},
|
|
}}
|
|
style={{
|
|
overflow: "hidden",
|
|
pointerEvents: "auto",
|
|
boxShadow: "0px 5px 10px 2px rgba(34, 60, 80, 0.2)",
|
|
backgroundColor: "white",
|
|
}}
|
|
cancel=".cancel"
|
|
>
|
|
<QuizAnswerer
|
|
className="quiz-preview-draghandle"
|
|
quizSettings={{
|
|
cnt: questions.length,
|
|
questions,
|
|
recentlyCompleted: false,
|
|
settings: {
|
|
fp: quiz.fingerprinting,
|
|
delay: 0,
|
|
due: quiz.due_to,
|
|
lim: quiz.limit,
|
|
name: quiz.name,
|
|
pausable: quiz.pausable,
|
|
rep: quiz.repeatable,
|
|
cfg: quiz.config,
|
|
},
|
|
show_badge: true,
|
|
}}
|
|
quizId={quiz.qid}
|
|
preview
|
|
/>
|
|
</Rnd>
|
|
)}
|
|
</Box>
|
|
</ThemeProvider>
|
|
);
|
|
}
|