add quiz startpage video iframe

This commit is contained in:
nflnkr 2023-12-08 19:23:06 +03:00
parent 6fb6b7dae3
commit 1bbfe804d3
4 changed files with 64 additions and 85 deletions

@ -2,7 +2,6 @@ import AlignCenterIcon from "@icons/AlignCenterIcon";
import AlignLeftIcon from "@icons/AlignLeftIcon"; import AlignLeftIcon from "@icons/AlignLeftIcon";
import AlignRightIcon from "@icons/AlignRightIcon"; import AlignRightIcon from "@icons/AlignRightIcon";
import ArrowDown from "@icons/ArrowDownIcon"; import ArrowDown from "@icons/ArrowDownIcon";
import InfoIcon from "@icons/InfoIcon";
import LayoutCenteredIcon from "@icons/LayoutCenteredIcon"; import LayoutCenteredIcon from "@icons/LayoutCenteredIcon";
import LayoutExpandedIcon from "@icons/LayoutExpandedIcon"; import LayoutExpandedIcon from "@icons/LayoutExpandedIcon";
import LayoutStandartIcon from "@icons/LayoutStandartIcon"; import LayoutStandartIcon from "@icons/LayoutStandartIcon";
@ -11,16 +10,14 @@ import { QuizStartpageType } from "@model/quizSettings";
import { import {
Box, Box,
Button, Button,
ButtonBase,
Checkbox, Checkbox,
FormControl, FormControl,
FormControlLabel, FormControlLabel,
MenuItem, MenuItem,
Select, Select,
Tooltip,
Typography, Typography,
useMediaQuery, useMediaQuery,
useTheme, useTheme
} from "@mui/material"; } from "@mui/material";
import { incrementCurrentStep, updateQuiz, uploadQuizImage } from "@root/quizes/actions"; import { incrementCurrentStep, updateQuiz, uploadQuizImage } from "@root/quizes/actions";
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
@ -28,16 +25,14 @@ import CustomCheckbox from "@ui_kit/CustomCheckbox";
import CustomTextField from "@ui_kit/CustomTextField"; import CustomTextField from "@ui_kit/CustomTextField";
import SelectableButton from "@ui_kit/SelectableButton"; import SelectableButton from "@ui_kit/SelectableButton";
import { StartPagePreview } from "@ui_kit/StartPagePreview"; import { StartPagePreview } from "@ui_kit/StartPagePreview";
import UploadBox from "@ui_kit/UploadBox"; import { resizeFavIcon } from "@ui_kit/reactImageFileResizer";
import { useState } from "react"; import { useState } from "react";
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import UploadIcon from "../../assets/icons/UploadIcon"; import FaviconDropZone from "./FaviconDropZone";
import ModalSizeImage from "./ModalSizeImage"; import ModalSizeImage from "./ModalSizeImage";
import SelectableIconButton from "./SelectableIconButton"; import SelectableIconButton from "./SelectableIconButton";
import { DropZone } from "./dropZone"; import { DropZone } from "./dropZone";
import Extra from "./extra"; import Extra from "./extra";
import { resizeFavIcon } from "@ui_kit/reactImageFileResizer";
import FaviconDropZone from "./FaviconDropZone";
const designTypes = [ const designTypes = [
@ -66,25 +61,15 @@ export default function StartPageSettings() {
const isTablet = useMediaQuery(theme.breakpoints.down(950)); const isTablet = useMediaQuery(theme.breakpoints.down(950));
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const [formState, setFormState] = useState<"design" | "content">("design"); const [formState, setFormState] = useState<"design" | "content">("design");
const designType = quiz?.config?.startpageType;
const videoHC = (videoInp: HTMLInputElement) => {
const file = videoInp.files?.[0];
if (file) {
setVideo(URL.createObjectURL(file));
}
};
const [video, setVideo] = useState("");
const [mobileVersion, setMobileVersion] = useState(false); const [mobileVersion, setMobileVersion] = useState(false);
if (!quiz) return null; // TODO throw and catch with error boundary
const MobileVersionHC = (bool: boolean) => { const MobileVersionHC = (bool: boolean) => {
setMobileVersion(bool); setMobileVersion(bool);
}; };
if (!quiz) return null; // TODO throw and catch with error boundary const designType = quiz?.config?.startpageType;
const favIconDropZoneElement = ( const favIconDropZoneElement = (
<FaviconDropZone <FaviconDropZone
@ -420,49 +405,16 @@ export default function StartPageSettings() {
sx={{ sx={{
display: quiz.config.startpage.background.type === "image" ? "none" : "flex", display: quiz.config.startpage.background.type === "image" ? "none" : "flex",
flexDirection: "column", flexDirection: "column",
mt: "20px",
}} }}
> >
<Box <CustomTextField
sx={{ placeholder="URL видео"
display: "flex", text={quiz.config.startpage.background.video ?? ""}
alignItems: "center", onChange={e => updateQuiz(quiz.id, quiz => {
gap: "7px", quiz.config.startpage.background.video = e.target.value;
mt: "20px", })}
mb: "14px", />
}}
>
<Typography
sx={{ fontWeight: 500, color: theme.palette.grey3.main }}
>
Добавить видео
</Typography>
<Tooltip title="Можно загрузить видео." placement="top">
<Box>
<InfoIcon />
</Box>
</Tooltip>
</Box>
<ButtonBase
component="label"
sx={{ justifyContent: "flex-start" }}
>
<input
onChange={(event) => videoHC(event.target)}
hidden
accept=".mp4"
multiple
type="file"
/>
<UploadBox
icon={<UploadIcon />}
sx={{
height: "48px",
width: "48px",
marginBottom: "20px",
}}
/>
</ButtonBase>
{video ? <video src={video} width="400" controls /> : null}
<Typography <Typography
sx={{ sx={{
fontWeight: 500, fontWeight: 500,

@ -107,7 +107,7 @@ const REQUEST_DEBOUNCE = 200;
const requestQueue = new RequestQueue(); const requestQueue = new RequestQueue();
let requestTimeoutId: ReturnType<typeof setTimeout>; let requestTimeoutId: ReturnType<typeof setTimeout>;
export const updateQuiz = async ( export const updateQuiz = (
quizId: string | null | undefined, quizId: string | null | undefined,
updateFn: (quiz: Quiz) => void, updateFn: (quiz: Quiz) => void,
) => { ) => {

@ -7,6 +7,7 @@ import {
useTheme, useTheme,
} from "@mui/material"; } from "@mui/material";
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
import YoutubeEmbedIframe from "./YoutubeEmbedIframe";
export default function QuizPreviewLayout() { export default function QuizPreviewLayout() {
@ -52,18 +53,17 @@ export default function QuizPreviewLayout() {
gap: "20px", gap: "20px",
}} }}
> >
{quiz.config.startpage.background.type === "image" && {quiz.config.startpage.logo && (
quiz.config.startpage.logo && ( <img
<img src={quiz.config.startpage.logo}
src={quiz.config.startpage.logo} style={{
style={{ height: "30px",
height: "30px", maxWidth: "50px",
maxWidth: "50px", objectFit: "cover",
objectFit: "cover", }}
}} alt=""
alt="" />
/> )}
)}
<Typography sx={{ fontSize: "12px" }}> <Typography sx={{ fontSize: "12px" }}>
{quiz.config.info.orgname} {quiz.config.info.orgname}
</Typography> </Typography>
@ -122,14 +122,7 @@ export default function QuizPreviewLayout() {
)} )}
{quiz.config.startpage.background.type === "video" && {quiz.config.startpage.background.type === "video" &&
quiz.config.startpage.background.video && ( quiz.config.startpage.background.video && (
<video <YoutubeEmbedIframe videoUrl={quiz.config.startpage.background.video} />
src={quiz.config.startpage.background.video}
style={{
width: "100%",
height: "100%",
objectFit: "cover",
}}
/>
)} )}
</Box> </Box>
)} )}

@ -0,0 +1,34 @@
import { Box } from "@mui/material";
interface Props {
videoUrl: string;
}
export default function YoutubeEmbedIframe({ videoUrl }: Props) {
const extractYoutubeVideoId = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/gi;
const videoId = extractYoutubeVideoId.exec(videoUrl)?.[1];
if (!videoId) return null;
const embedUrl = `https://www.youtube.com/embed/${videoId}?controls=0&autoplay=1&modestbranding=0&showinfo=0&disablekb=1&mute=1&loop=1`;
return (
<Box sx={{
width: "100%",
height: "100%",
"& iframe": {
width: "100%",
height: "100%",
}
}}>
<iframe
src={embedUrl}
title="YouTube video player"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
/>
</Box>
);
}