reza added Test

temp
Reza_ashrafi 3 years ago
parent 4b9baecab0
commit 0fe08f3825
  1. 8
      src/assets/icons/timer.svg
  2. BIN
      src/assets/videos/COD.mp4
  3. 27
      src/components/JolPlayer/index.js
  4. 42
      src/utils/scroll.js
  5. 19
      src/views/Home/Page2/Mobile/index.js
  6. 17
      src/views/Home/Page2/index.js
  7. 62
      src/views/Home/Test/Question.js
  8. 114
      src/views/Home/Test/index.js
  9. 42
      src/views/Home/VideoTube/LessonPlayList/index.js
  10. 49
      src/views/Home/VideoTube/index.js
  11. 26
      src/views/Home/index.js
  12. 6
      tailwind.config.js

@ -0,0 +1,8 @@
<svg id="vuesax_linear_timer" data-name="vuesax/linear/timer" xmlns="http://www.w3.org/2000/svg" width="15.827" height="15.827" viewBox="0 0 15.827 15.827">
<g id="timer">
<path id="Vector" d="M11.54,5.77A5.77,5.77,0,1,1,5.77,0,5.772,5.772,0,0,1,11.54,5.77Z" transform="translate(2.143 2.967)" fill="none" stroke="#067182" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<path id="Vector-2" data-name="Vector" d="M0,0V3.3" transform="translate(7.913 5.276)" fill="none" stroke="#067182" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<path id="Vector-3" data-name="Vector" d="M0,0H3.957" transform="translate(5.935 1.319)" fill="none" stroke="#067182" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<path id="Vector-4" data-name="Vector" d="M0,0H15.827V15.827H0Z" fill="none" opacity="0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

@ -1,7 +1,9 @@
import React, { useEffect } from "react";
import React, { useEffect, useRef, useState } from "react";
import JoLPlayer from "jol-player";
function Video({ fileIds, posterId }) {
function Video({ fileIds, posterId, autoPlay }) {
const videoRef = useRef(null);
const [flag, setFlag] = useState(false);
useEffect(() => {
window.addEventListener("scroll", () => {
if (window.scrollY > 500) {
@ -15,6 +17,25 @@ function Video({ fileIds, posterId }) {
});
}, []);
const videoMethod = (status) => {
if (status === "play") {
videoRef.current.play();
setFlag(() => true);
}
};
// useEffect(() => {
// console.log(`videoRef.current`, videoRef.current);
// }, [videoRef.current]);
useEffect(() => {
if (window.scrollY > 3 * window.innerHeight) {
if (autoPlay && !flag) {
videoMethod("play");
}
}
}, [autoPlay]);
return (
<div
style={{
@ -26,6 +47,7 @@ function Video({ fileIds, posterId }) {
id="video-joi"
>
<JoLPlayer
ref={videoRef}
option={{
videoSrc: `https://dnvn.ir/api/v1/file/${fileIds}`,
width: "100%",
@ -48,6 +70,7 @@ function Video({ fileIds, posterId }) {
},
],
isShowWebFullScreen: false,
// auto : true
}}
/>
</div>

@ -94,7 +94,7 @@ class scroll {
return currectPosition;
};
doubleLinearFormula = (currentScroll) => {
videoLinearFormula = (currentScroll) => {
if(!localStorage.getItem("htmlRect")){
localStorage.setItem("htmlRect", JSON.stringify(document.getElementById("video").getBoundingClientRect()));
}
@ -138,6 +138,46 @@ class scroll {
left: currentLeft,
};
};
testLinearFolmula = (currentScroll) => {
const testRect = JSON.parse(localStorage.getItem("testRect"));
const currentWidth = this.linearFormula(
currentScroll,
testRect.width,
window.innerWidth,
5.5 * window.innerHeight,
6 * window.innerHeight
);
const currentHeight = this.linearFormula(
currentScroll,
testRect.height,
window.innerHeight,
5.5 * window.innerHeight,
6 * window.innerHeight
);
const currentLeft = this.linearFormula(
currentScroll,
testRect.left,
0,
5.5 * window.innerHeight,
6 * window.innerHeight
);
const currentTop = this.linearFormula(
currentScroll,
testRect.top,
0,
5.5 * window.innerHeight,
6 * window.innerHeight
);
return {
width: currentWidth,
height: currentHeight,
top: currentTop,
left: currentLeft,
};
}
}
const _scroll = new scroll();

@ -1,9 +1,8 @@
import React, { useEffect, useState } from "react";
import _ from "lodash";
import codVideo from "../../../../assets/videos/COD.mp4";
import scroll from "../../../../utils/scroll";
import {connect} from 'react-redux';
export default function Mobile({ mobilePosition, videoPosition }) {
function Mobile({ mobilePosition, videoPosition, autoPlay, selectedVideo }) {
const [checked, setChecked] = useState(mobilePosition > 0 ? true : false);
useEffect(() => {
if (mobilePosition > 0) {
@ -13,9 +12,6 @@ export default function Mobile({ mobilePosition, videoPosition }) {
}
}, [mobilePosition]);
useEffect(async () => {
console.log(videoPosition);
}, []);
return (
<div
className={_.join(
@ -88,7 +84,7 @@ export default function Mobile({ mobilePosition, videoPosition }) {
id="video"
className={_.join(
[
"video outline-none animation-puls",
"video outline-none animation-puls bg-black",
window.scrollY > 3 * window.innerHeight ? "fixed" : "static",
],
" "
@ -100,12 +96,15 @@ export default function Mobile({ mobilePosition, videoPosition }) {
top : window.scrollY > 3 * window.innerHeight ? videoPosition?.top : 'auto',
}}
controls
autoPlay={false}
muted
autoPlay={'true'}
>
<source src={`https://dnvn.ir/api/v1/file/${20680}`} type={"video/mp4"} />
<source src={`https://dnvn.ir/api/v1/file/${selectedVideo?.fileIds}`} type={"video/mp4"} />
</video>
) : null}
</div>
);
}
export default connect((state) => ({
selectedVideo : state.publicApi.selectedVideo
}), {})(Mobile);

@ -4,7 +4,7 @@ import scroll from "../../../utils/scroll";
import Mobile from "./Mobile";
import qrImage from "../../../assets/images/qrImage.png";
export default function Page2({ list, page }) {
export default function Page2({ list, page, autoPlay }) {
const height = window.innerHeight;
const [top, setTop] = useState(window.innerHeight);
const [videoPosition, setVideoPosition] = useState(null);
@ -17,16 +17,16 @@ export default function Page2({ list, page }) {
useEffect(() => {
setMobilePosition(
scroll.linearFormula(
window.scrollY > 3 * height ? 3 * height : window.scrollY,
window.scrollY > 2.5 * height ? 2.5 * height : window.scrollY,
-(((window.innerHeight * 10) / 20 / window.innerWidth) * 100),
6,
2 * height,
3 * height
2.5 * height
)
);
setVideoPosition(
window.scrollY > 3 * height
? scroll.doubleLinearFormula(window.scrollY)
? scroll.videoLinearFormula(window.scrollY)
: null
);
if (window.scrollY < 2.5 * height) {
@ -149,12 +149,13 @@ export default function Page2({ list, page }) {
if (scrollY <= 3 * height) {
setVideoPosition(() => null);
} else if (scrollY > 3 * height && scrollY < 4 * height) {
setVideoPosition(scroll.doubleLinearFormula(scrollY));
setVideoPosition(scroll.videoLinearFormula(scrollY));
} else {
}
};
return (
<div
onClick={(e) => e.stopPropagation()}
className={_.join(
["home-page2 h-screen w-full fixed left-0 origin-top overflow-hidden"],
" "
@ -196,7 +197,11 @@ export default function Page2({ list, page }) {
></div>
</div>
{/* mobile phone */}
<Mobile mobilePosition={mobilePosition} videoPosition={videoPosition} />
<Mobile
mobilePosition={mobilePosition}
videoPosition={videoPosition}
autoPlay={autoPlay}
/>
{/* video */}
</div>
);

@ -0,0 +1,62 @@
import React, { useState } from "react";
import _ from "lodash";
export default function Question({ question }) {
const [select, setSelect] = useState("");
return (
<div className="w-3/4 flex flex-col my-3">
<span
className="inline text-semibold py-2 px-3 rounded-sm bg-blueFF text-blue52"
style={{ width: "fit-content" }}
>
سوال ۱
</span>
<p className="text-white text-sm my-2">{question.text}</p>
<ul className="list-none m-0 p-0 w-full">
{question.options.map((option, index) => (
<li
onClick={() => setSelect(option)}
className={_.join(
[
"rounded-md w-full overflow-hidden flex flex-row items-center my-2 cursor-pointer transition-all duration-500",
],
" "
)}
style={{
backgroundColor: select === option ? "#32af00" : "transparent",
borderColor: select === option ? "transparent" : "#f5f5f5",
borderWidth: 1,
borderStyle: "solid",
}}
key={index}
>
<span
className={_.join(
["h-full py-3 px-5 text-xs transition-all duration-500"],
" "
)}
style={{
color: select === option ? "white" : "#E7E7E7",
backgroundColor: select === option ? "#329f00" : "#444",
}}
>
الف
</span>
<p
className={_.join(
[
"text-xs mr-4 transition-all duration-500",
select === option ? "#66CD22" : "#E7E7E7",
],
" "
)}
style={{ color: select === option ? "white" : "#E7E7E7" }}
>
{option}
</p>
</li>
))}
</ul>
</div>
);
}

@ -0,0 +1,114 @@
import React, { useEffect, useState } from "react";
import _ from "lodash";
import timerIcon from "../../../assets/icons/timer.svg";
import QuestionBox from "./Question";
import scroll from "../../../utils/scroll";
export default function Test({ title, duration, questions }) {
const [translateY, setTranslateY] = useState(0);
const [testPosition, setTestPosition] = useState(null);
useEffect(() => {
setTranslateY(() =>
scroll.linearFormula(
window.scrollY > 5 * window.innerHeight
? 5 * window.innerHeight
: window.scrollY,
0,
-101,
4.5 * window.innerHeight,
5 * window.innerHeight
)
);
window.addEventListener("scroll", () => {
testTransformHandler(window.scrollY);
if (window.scrollY > 1000) {
localStorage.setItem(
"testRect",
JSON.stringify(
document.getElementById("test").getBoundingClientRect()
)
);
}
});
}, []);
const testTransformHandler = (scrollY) => {
const height = window.innerHeight;
if (scrollY <= 4.5 * height) {
setTranslateY(() => 0);
setTestPosition(() => null)
} else if (scrollY > 4.5 * height && scrollY < 5 * height) {
setTranslateY(() =>
scroll.linearFormula(scrollY, 0, -101, 4.5 * height, 5 * height)
);
setTestPosition(() => null);
} else if(scrollY > 5.5 * height && scrollY < 6 * height) {
setTestPosition(() => scroll.testLinearFolmula(scrollY));
setTranslateY(() => 0);
}else{
}
};
return (
<div
onClick={(e) => e.stopPropagation()}
id="test"
className="w-full flex flex-col items-center justify-center bg-black bg-opacity-80 backdrop-filter backdrop-blur-2xl z-50"
style={{
minHeight: window.innerHeight - 180,
transform: `translateY(${translateY}%)`,
position : testPosition ? 'fixed' : 'static',
left : testPosition?.left ? testPosition?.left : 'auto',
top : testPosition?.top ? testPosition?.top : 'auto',
width : testPosition?.width ? testPosition?.width : 'auto',
height : testPosition?.height ? testPosition?.height : 'auto'
}}
>
<header
className="w-3/4 flex flex-row justify-between py-3 px-3 rounded-md"
style={{ border: "1px solid #F1F1F1" }}
>
<div className="flex flex-row items-center">
<span
className="w-2 h-2 rounded-full ml-2"
style={{ backgroundColor: "#CEFDFF" }}
></span>
<h1 className="text-blueE8 text-md font-medium">{title}</h1>
</div>
<div className="flex flex-row items-center">
<img src={timerIcon} className="w-4 h-4 ml-1" />
<div className="text-sm text-green71">
{_.join(["زمان باقیمانده", duration], " ")}
</div>
</div>
</header>
{questions.map((question, index) => (
<QuestionBox question={question} key={index} />
))}
</div>
);
}
Test.defaultProps = {
title: "آزمون شیمی پایه دوازدهم متوسطه",
duration: "48:29",
questions: [
{
text: "نظر شما نسبت به تحولات جنوب غرب آسیا به ویژه حوزه دریای عمان و خلیج فارس چیست؟",
options: [
"امکان دارد شاید و یا یک چیز دیگر",
"امکان دارد شاید و یا یک چیز دیگرر",
"امکان دارد شاید و یا یک چیز دیگرر",
"امکان دارد شاید و یا یک چیز دیگررر",
],
},
{
text: "نظر شما نسبت به تحولات جنوب غرب آسیا به ویژه حوزه دریای عمان و خلیج فارس چیست؟",
options: [
"امکان دارد شاید و یا یک چیز دیگر",
"امکان دارد شاید و یا یک چیز دیگرر",
"امکان دارد شاید و یا یک چیز دیگرر",
"امکان دارد شاید و یا یک چیز دیگررر",
],
},
],
};

@ -1,6 +1,6 @@
import React, { useEffect } from "react";
import { connect } from "react-redux";
// import { publicApi } from "../../../redux/actions";
import { publicApi } from "../../../../redux/actions";
import { Link } from "react-router-dom";
import _ from "lodash";
@ -37,35 +37,36 @@ function LessonPlayList({
{
<div className={_.join(["w-full mb-2.5 flex flex-col border"], " ")}>
{bookId && (
<header className="mb-1">
<h3 className="py-1 px-2.5 m-0">
<header className="mb-1 flex flex-row items-center">
<h3 className="py-1 px-2.5 m-0 bg-white inline">
{
realCategories.filter(
(item) => item.id === category[0].categoryId
)[0].name
}
</h3>
<span className="flex flex-1" style={{ height: 1 }}></span>
<span
className="flex flex-1 bg-white"
style={{ height: 2 }}
></span>
</header>
)}
{bookId ? (
category.map((video, i) => (
<Link
to={"/video/" + video.id}
className={
"flex flex-row items-center py-2" +
" " +
(video?.id === selectedVideo?.id &&
"lesson-playlist__item--active")
}
<div
className={_.join(
[
"flex flex-row items-center py-2",
video?.id === selectedVideo?.id ? "bg-white" : "",
],
" "
)}
key={i}
id={"listItem" + video.id}
onClick={() => setVideoActive(video)}
>
<span className="w-8 text-center">
{Number(i) + 1}
</span>
<span className={"w-8 text-center"}>{Number(i) + 1}</span>
<div className="relative">
{/* <video>
<source
@ -76,7 +77,7 @@ function LessonPlayList({
className="m-0 rounded-sm"
src={`https://dnvn.ir/api/v1/file/${video.posterId}`}
alt=""
style={{ width : 150 }}
style={{ width: 150 }}
/>
<span className="py-0 px-1 absolute left-1 bottom-2.5">
22:05
@ -86,11 +87,10 @@ function LessonPlayList({
<h4 className="m-0">{video.name}</h4>
{/* <p>{file.text}</p> */}
</div>
</Link>
</div>
))
) : (
<Link
to={"/video/" + category.id}
<div
className={
"lesson-playlist__item flex align-items-center" +
" " +
@ -117,7 +117,7 @@ function LessonPlayList({
<h4>{category.name}</h4>
{/* <p>{file.text}</p> */}
</div>
</Link>
</div>
)}
</div>
}
@ -132,6 +132,6 @@ export default connect(
vods: state.publicApi.bookSection?.vods,
}),
{
// setVideoActive: publicApi.setVideoActive,
setVideoActive: publicApi.setVideoActive,
}
)(LessonPlayList);

@ -6,7 +6,7 @@ import Book from "./Book";
import Comment from "./Comment";
import AddComment from "./AddComment";
import Video from "../../../components/JolPlayer";
import Test from "../Test";
import listIcon from "../../../assets/icons/list.png";
import { connect } from "react-redux";
import _ from "lodash";
@ -16,6 +16,7 @@ import { book, publicApi } from "../../../redux/actions";
// import Loader from "../../components/Loader";
function VodTube({
autoPlay,
page,
selectedVideo,
info,
@ -33,28 +34,27 @@ function VodTube({
window.addEventListener("scroll", (e) => {
setTop(scroll.homeScrollHandler(page));
});
localStorage.setItem("scroll-list", "on");
// localStorage.setItem("scroll-list", "on");
getInfo({
bookId: localStorage.getItem("bookId")
? localStorage.getItem("bookId")
: localStorage.getItem("category")?.split(",")[0],
bookId: 8,
});
}, []);
useEffect(() => {
if (allBooks && localStorage.getItem("category")) {
const cat = localStorage.getItem("category")?.split(",");
bookSection({ bookId: cat[0], categoryId: cat[1] });
}
}, [allBooks]);
// useEffect(() => {
// if (allBooks && localStorage.getItem("category")) {
// const cat = localStorage.getItem("category")?.split(",");
// bookSection({ bookId: cat[0], categoryId: cat[1] });
// }
// }, [allBooks]);
const light = theme === "light";
return (
<div
onClick={(e) => e.stopPropagation()}
className={_.join(
[
"fixed flex flex-row rtl pt-20 lg:px-5 xl:px-10 w-full bg-white dark:bg-black bg-opacity-80 transition-opacity duration-500 min-h-screen backdrop-filter backdrop-blur-md",
top > 0 ? "opacity-0" : "opacity-100",
top > 0 ? "opacity-0 z-0" : "opacity-100 z-10",
],
" "
)}
@ -63,10 +63,17 @@ function VodTube({
{/* <Navbar /> */}
<div className="ml-4.5 flex flex-col ml-2" style={{ flex: 8 }}>
<section className="pb-7 flex flex-col">
<Video
fileIds={selectedVideo?.fileIds}
posterId={selectedVideo?.posterId}
/>
<div
className="w-full flex flex-col overflow-y-hidden"
style={{ height: window.innerHeight - 200 }}
>
<Video
fileIds={selectedVideo?.fileIds}
posterId={selectedVideo?.posterId}
autoPlay={autoPlay}
/>
<Test />
</div>
{/* <span className="desktop">درس دوم / بیست و یکم</span> */}
<h1 className="md:hidden sm:hidden xs:hidden mb-5">
{selectedVideo?.name}
@ -89,7 +96,10 @@ function VodTube({
</section>
</div>
<div className="flex flex-col" style={{ flex: 3 }}>
<section className="mb-7 flex flex-col">
<section
className="mb-7 flex flex-col rounded-md overflow-hidden"
style={{ border: "1px solid #70707070" }}
>
<header className="w-full flex justify-between items-center px-2 py-2 bg-gray-100">
<div className="flex flex-col">
<h2 className="m-0">
@ -104,7 +114,10 @@ function VodTube({
ref={videoListTag}
className="pt-2.5 overflow-y-scroll flex flex-col"
id="list"
style={{ minHeight: window.innerHeight / 1.5, maxHeight: window.innerHeight / 1.5}}
style={{
minHeight: window.innerHeight / 1.5,
maxHeight: window.innerHeight / 1.5,
}}
>
{localStorage.getItem("bookId")
? categories?.map((video, i) => (

@ -1,24 +1,34 @@
import React from "react";
import React, { useEffect, useState } from "react";
import Navbar from "../../components/Navbar";
import Page1 from "./Page1";
import Page2 from "./Page2";
import Page3 from "./Page3";
import Page4 from "./Page4";
// import Page3 from "./Page3";
// import Page4 from "./Page4";
import VideoTube from "./VideoTube";
import Dots from "../../components/Dots";
// import Dots from "../../components/Dots";
export default function Home() {
const [autoPlay, setAutoPlay] = useState(false);
useEffect(() => {
window.addEventListener("scroll", () => {
if (window.scrollY > 3 * window.innerHeight) {
setAutoPlay(() => true);
// alert('here');
} else {
setAutoPlay(() => false);
}
});
}, []);
return (
<div
className="flex flex-col bg-white relative w-full rtl"
style={{ height: "700vh"}}
style={{ height: "700vh" }}
>
{/* <Dots page={1} /> */}
<Navbar />
<Page1 page={1} />
<Page2 page={2} />
<VideoTube page={3} />
<Page2 page={2} autoPlay={autoPlay} />
<VideoTube page={3} autoPlay={autoPlay} />
</div>
);
}

@ -6,11 +6,15 @@ module.exports = {
...theme("colors"),
blueC0: "#196EC0",
blueB0 : "#517AB0",
blue90: "#235A90"
blue90: "#235A90",
blueFF : '#E8FCFF'
}),
textColor : (theme) => ({
...theme("colors"),
primary: "#235A90",
blueE8 : '#2E81E8',
green71 : '#067182',
blue52 : '#132F52',
}),
borderColor : (theme) => ({
...theme("colors"),

Loading…
Cancel
Save