This commit is contained in:
Nastya 2024-12-21 21:44:57 +03:00
parent 2f7f89e8b2
commit f358a959bf
14 changed files with 172 additions and 16 deletions

@ -21,12 +21,10 @@ import ViewPublicationPage from "./ViewPublicationPage/ViewPublicationPage";
import { HelmetProvider } from "react-helmet-async";
import "moment/dist/locale/ru";
import unscreen from "@/ui_kit/unscreen";
moment.locale("ru");
const localeText = ruRU.components.MuiLocalizationProvider.defaultProps.localeText;
console.log(localeText);
console.log(moment);
type Props = {
quizSettings?: QuizSettings;
quizId: string;
@ -128,8 +126,17 @@ function QuizAnswererInner({
</QuizViewContext.Provider>
);
}
export default function QuizAnswerer(props: Props) {
useEffect(() => {
const root = document.getElementById("root");
const overlay = document.getElementById("hideoverlay");
if (root !== null && overlay !== null && props.quizSettings?.settings.cfg?.isUnSc) {
overlay.style.cssText =
"position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: black; z-index:999; opacity: 0;";
unscreen(overlay, root);
}
}, []);
return (
<HelmetProvider>
<LocalizationProvider
@ -142,6 +149,7 @@ export default function QuizAnswerer(props: Props) {
preventDuplicate={true}
style={{ backgroundColor: lightTheme.palette.brightPurple.main }}
>
<div id="hideoverlay" />
<QuizAnswererInner {...props} />
</SnackbarProvider>
</ThemeProvider>

@ -183,6 +183,7 @@ export const ResultForm = ({ resultQuestion }: ResultFormProps) => {
display: "flex",
justifyContent: "center",
}}
onClick={(event) => event.preventDefault()}
>
<img
alt="resultImage"

@ -87,6 +87,7 @@ const StandartLayout = ({ alignType, quizHeaderBlock, quizMainBlock, backgroundB
justifyContent: "center",
"& > img": { width: "100%", borderRadius: "12px" },
}}
onClick={(event) => event.preventDefault()}
>
{backgroundBlock}
</Box>
@ -204,6 +205,7 @@ const CenteredLayout = ({ quizHeaderBlock, quizMainBlock, backgroundBlock }: Lay
justifyContent: "center",
"& > img": { width: "100%", borderRadius: "12px" },
}}
onClick={(event) => event.preventDefault()}
>
{backgroundBlock}
</Box>

@ -73,6 +73,7 @@ const StandartMobileLayout = ({ quizHeaderBlock, quizMainBlock, backgroundBlock
borderRadius: "12px",
},
}}
onClick={(event) => event.preventDefault()}
>
{backgroundBlock}
</Box>
@ -154,6 +155,7 @@ const ExpandedMobileLayout = ({ quizHeaderBlock, quizMainBlock, backgroundBlock
minHeight: "100%",
},
}}
onClick={(event) => event.preventDefault()}
>
{backgroundBlock}
</Box>
@ -205,6 +207,7 @@ const CenteredMobileLayout = ({ quizHeaderBlock, quizMainBlock, backgroundBlock
overflow: "hidden",
"& > img": { width: "100%", borderRadius: "12px" },
}}
onClick={(event) => event.preventDefault()}
>
{backgroundBlock}
</Box>

@ -105,6 +105,7 @@ export const StartPageViewPublication = () => {
? "center"
: undefined,
}}
onClick={(event) => event.preventDefault()}
>
{settings.cfg.startpage.logo && (
<img
@ -220,6 +221,7 @@ export const StartPageViewPublication = () => {
color: settings.cfg.startpageType === "expanded" ? "white" : "black",
}}
onClick={(event) => event.preventDefault()}
>
<QuizPreviewLayoutByType
quizHeaderBlock={quizHeaderBlock}

@ -28,7 +28,11 @@ export const File = ({ currentQuestion }: FileProps) => {
return (
<Box>
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
<Typography
variant="h5"
color={theme.palette.text.primary}
sx={{ wordBreak: "break-word" }}
>
{currentQuestion.title}
</Typography>
<Box
@ -39,9 +43,13 @@ export const File = ({ currentQuestion }: FileProps) => {
marginTop: "20px",
maxWidth: answer?.split("|")[0] ? "640px" : "600px",
}}
onClick={(event) => event.preventDefault()}
>
{answer?.split("|")[0] ? (
<UploadedFile currentQuestion={currentQuestion} setIsSending={setIsSending} />
<UploadedFile
currentQuestion={currentQuestion}
setIsSending={setIsSending}
/>
) : (
<UploadFile
currentQuestion={currentQuestion}
@ -51,7 +59,11 @@ export const File = ({ currentQuestion }: FileProps) => {
/>
)}
{answer && currentQuestion.content.type === "picture" && (
<img src={answer.split("|")[1]} style={{ marginTop: "15px", maxWidth: "300px", maxHeight: "300px" }} alt="" />
<img
src={answer.split("|")[1]}
style={{ marginTop: "15px", maxWidth: "300px", maxHeight: "300px" }}
alt=""
/>
)}
{answer && currentQuestion.content.type === "video" && (
<video
@ -65,7 +77,10 @@ export const File = ({ currentQuestion }: FileProps) => {
/>
)}
</Box>
<Modal open={modalWarningType !== null} onClose={() => setModalWarningType(null)}>
<Modal
open={modalWarningType !== null}
onClose={() => setModalWarningType(null)}
>
<Box
sx={{
position: "absolute",

@ -6,7 +6,7 @@ import { useQuizViewStore } from "@stores/quizView";
import RadioCheck from "@ui_kit/RadioCheck";
import RadioIcon from "@ui_kit/RadioIcon";
import { quizThemes } from "@utils/themes/Publication/themePublication";
import { useMemo, type MouseEvent } from "react";
import { useMemo, type MouseEvent, useRef, useEffect } from "react";
import { useRootContainerSize } from "@contexts/RootContainerWidthContext";
type ImagesProps = {
@ -99,6 +99,9 @@ export const ImageVariant = ({
const isMobile = useRootContainerSize() < 450;
const isTablet = useRootContainerSize() < 850;
const canvasRef = useRef<HTMLCanvasElement | null>(null);
const containerCanvasRef = useRef<HTMLDivElement | null>(null);
const onVariantClick = async (event: MouseEvent<HTMLDivElement>) => {
event.preventDefault();
@ -130,6 +133,23 @@ export const ImageVariant = ({
}
}, []);
useEffect(() => {
if (canvasRef.current !== null) {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
if (ctx !== null) {
const img = new Image();
img.src = choiceImgUrl;
img.onload = () => {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
}
}
}, []);
return (
<Box
sx={{
@ -151,9 +171,8 @@ export const ImageVariant = ({
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
<Box sx={{ width: "100%", height: "300px" }}>
{variant.extendedText && (
<img
src={choiceImgUrl}
alt=""
<canvas
ref={canvasRef}
style={{
display: "block",
width: "100%",
@ -162,6 +181,18 @@ export const ImageVariant = ({
borderRadius: "12px 12px 0 0",
}}
/>
// <img
// src={choiceImgUrl}
// alt=""
// style={{
// display: "block",
// width: "100%",
// height: "100%",
// objectFit: "cover",
// borderRadius: "12px 12px 0 0",
// }}
// />
)}
</Box>
</Box>

@ -21,7 +21,10 @@ export const Page = ({ currentQuestion }: PageProps) => {
>
{currentQuestion.title}
</Typography>
<Typography color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
<Typography
color={theme.palette.text.primary}
sx={{ wordBreak: "break-word" }}
>
{currentQuestion.content.text}
</Typography>
<Box
@ -40,6 +43,7 @@ export const Page = ({ currentQuestion }: PageProps) => {
border: "1px solid #9A9AAF",
overflow: "hidden",
}}
onClick={(event) => event.preventDefault()}
>
<img
key={currentQuestion.id}

@ -79,6 +79,7 @@ export const TextNormal = ({ currentQuestion, answer }: TextNormalProps) => {
height: "300px",
margin: "15px",
}}
onClick={(event) => event.preventDefault()}
>
<img
key={currentQuestion.id}

@ -81,7 +81,10 @@ export const TextSpecial = ({ currentQuestion, answer, stepNumber }: TextSpecial
{currentQuestion.title}
</Typography>
{isHorizontal && currentQuestion.content.back && currentQuestion.content.back !== " " && (
<Box sx={{ margin: "30px", width: "50vw", maxHeight: "550px" }}>
<Box
sx={{ margin: "30px", width: "50vw", maxHeight: "550px" }}
onClick={(event) => event.preventDefault()}
>
<img
key={currentQuestion.id}
src={currentQuestion.content.back}
@ -119,7 +122,10 @@ export const TextSpecial = ({ currentQuestion, answer, stepNumber }: TextSpecial
}
</Box>
{!isHorizontal && currentQuestion.content.back && currentQuestion.content.back !== " " && (
<Box sx={{ margin: "15px", width: "40vw" }}>
<Box
sx={{ margin: "15px", width: "40vw" }}
onClick={(event) => event.preventDefault()}
>
<img
key={currentQuestion.id}
src={currentQuestion.content.back}

@ -105,7 +105,10 @@ export const Variant = ({ currentQuestion }: VariantProps) => {
</Box>
</Group>
{choiceImgUrlQuestion && choiceImgUrlQuestion !== " " && choiceImgUrlQuestion !== null && (
<Box sx={{ maxWidth: "400px", width: "100%", height: "300px" }}>
<Box
sx={{ maxWidth: "400px", width: "100%", height: "300px" }}
onClick={(event) => event.preventDefault()}
>
<img
key={currentQuestion.id}
src={choiceImgUrlQuestion}

@ -134,6 +134,7 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
color: theme.palette.text.primary,
textAlign: "center",
}}
onClick={(event) => event.preventDefault()}
>
{answer ? (
choiceImgUrlAnswer ? (

@ -61,6 +61,7 @@ export type QuizSettings = {
};
export interface QuizConfig {
isUnSc?: boolean;
spec: undefined | true;
type: QuizType;
noStartPage: boolean;

78
lib/ui_kit/unscreen.ts Normal file

@ -0,0 +1,78 @@
function addOverlay(overlay: HTMLElement) {
// const overlay = document.getElementById('overlay');
overlay.style.opacity = "1"; // Затемнено
overlay.style.pointerEvents = "auto"; // Включить клики
}
function removeOverlay(overlay: HTMLElement) {
overlay.style.opacity = "0"; // Вернуть в исходное состояние
overlay.style.pointerEvents = "none"; // Игнорировать клики
}
function addRemoveOverlayTimer(overlay: HTMLElement, time = 1000) {
addOverlay(overlay);
setTimeout(() => {
removeOverlay(overlay);
}, time); // 1 секунда затемнения
}
// Флаги для отслеживания состояния
let isMouseInside = true;
let isWindowFocused = true;
export default function unscreen(overlay: HTMLElement, root: HTMLElement) {
let focusTimeout: NodeJS.Timeout | undefined;
// Проверка состояния и выполнение нужного действия
function checkFocusAndMouse() {
if (!isWindowFocused || !isMouseInside) {
// ИЛИ
addOverlay(overlay);
} else if (isWindowFocused && isMouseInside) {
// И
removeOverlay(overlay);
}
}
// Добавляем обработчики событий
window.addEventListener("blur", () => {
console.log("blur");
isWindowFocused = false;
checkFocusAndMouse(); // Проверяем состояние
}); // Когда окно теряет фокус
window.addEventListener("focus", () => {
isWindowFocused = true;
checkFocusAndMouse(); // Проверяем состояние
}); // Когда окно получает фокус
window.addEventListener("mouseleave", () => {
console.log("mouseleave");
isMouseInside = false;
checkFocusAndMouse(); // Проверяем состояние
}); // Когда мышка покидает окно
window.addEventListener("mouseenter", () => {
console.log("mouseenter");
isMouseInside = true;
checkFocusAndMouse(); // Проверяем состояние
}); // Когда мышка возвращается в окно
root.addEventListener("contextmenu", (event) => event.preventDefault());
window.addEventListener("keydown", function (event) {
event.preventDefault();
if (event.key === "PrintScreen" || (event.ctrlKey && event.key === "p")) {
addRemoveOverlayTimer(overlay);
}
});
// Проверка для мобильных устройств
root.addEventListener("touchstart", function (event) {
// Пример: если есть более чем один жест
if (event.touches.length > 1) {
addRemoveOverlayTimer(overlay);
}
});
window.addEventListener("beforeprint", function () {
addRemoveOverlayTimer(overlay);
});
}