Merge branch 'video-overlay' into 'develop'

video-overlay

See merge request witapp/aura-webapp!209
This commit is contained in:
Daniil Chemerkin 2024-06-29 15:34:24 +00:00
commit 1d37835694
7 changed files with 198 additions and 5 deletions

View File

@ -5,6 +5,8 @@ import Loader from "@/components/Loader";
import PlayButton from "../../../../ui/PlayButton";
import metricService, { EGoals } from "@/services/metric/metricService";
import PlayPauseButton from "../../../../ui/PlayPauseButton";
import VideoOverlay from "../../../../ui/VideoOverlay";
import PlayPauseButtonV2 from "../../../../ui/PlayPauseButtonV2";
interface IPersonalVideoProps {
gender: string;
@ -17,6 +19,7 @@ const PersonalVideo = React.memo<IPersonalVideoProps>(
const [isPlaying, setIsPlaying] = useState(false);
const [isStarted, setIsStarted] = useState(false);
const [isError, setIsError] = useState(false);
const [isOverlayShow, setIsOverlayShow] = useState(false);
const onError = (error: unknown) => {
if (!error) return;
@ -33,14 +36,27 @@ const PersonalVideo = React.memo<IPersonalVideoProps>(
metricService.reachGoal(EGoals.ROSE_VIDEO_PLAY_END);
};
const handlePlayPause = () => {
const handlePlayPause = (
event: React.MouseEvent<HTMLElement | SVGSVGElement>
) => {
event.preventDefault();
event.stopPropagation();
setIsPlaying((prev) => !prev);
if (isPlaying) metricService.reachGoal(EGoals.ROSE_VIDEO_PLAY_USER_PLAY);
if (!isPlaying) metricService.reachGoal(EGoals.ROSE_VIDEO_PLAY_USER_STOP);
};
return (
<div className={`${styles.container} ${classNameContainer}`}>
<div
className={`${styles.container} ${classNameContainer}`}
onClick={() => setIsOverlayShow(true)}
>
<VideoOverlay isShow={isOverlayShow} setIsShow={setIsOverlayShow}>
<PlayPauseButtonV2
state={isPlaying ? "pause" : "play"}
onClick={(event) => handlePlayPause(event)}
/>
</VideoOverlay>
{!isPlaying && !isError && !isStarted && (
<Loader className={styles.loader} />
)}
@ -48,7 +64,9 @@ const PersonalVideo = React.memo<IPersonalVideoProps>(
<PlayButton
backgroundFill={gender === "male" ? "#85B6FF" : "#D1ACF2"}
className={styles["play-button"]}
onClick={() => {
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
setIsError(false);
setIsPlaying(true);
}}
@ -72,10 +90,10 @@ const PersonalVideo = React.memo<IPersonalVideoProps>(
aspectRatio: "16 / 9",
}}
/>
{!isError && isStarted && (
{!isError && isStarted && !isOverlayShow && (
<PlayPauseButton
state={isPlaying ? "pause" : "play"}
onClick={handlePlayPause}
onClick={(event) => handlePlayPause(event)}
className={styles["play-pause-button"]}
/>
)}

View File

@ -144,6 +144,13 @@ function TrialPaymentPage() {
classNameContainer={styles["personal-video"]}
/>
)}
{/* {!!videoUrl.length && ( */}
<PersonalVideo
gender={gender}
url="https://aura-node.s3.eu-west-2.amazonaws.com/videos/combined/66775660bce86c6a989b3b4f.mp4"
classNameContainer={styles["personal-video"]}
/>
{/* )} */}
{singleOrWithPartner === "partner" && (
<WithPartnerInformation
zodiacSign={zodiacSign}

View File

@ -15,6 +15,7 @@ function PlayPauseButton({
viewBox="0 0 71 50"
fill="none"
xmlns="http://www.w3.org/2000/svg"
onClick={() => null}
{...props}
>
<g filter="url(#filter0_b_201_4)">

View File

@ -0,0 +1,56 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import styles from "./styles.module.scss";
interface IPlayPauseButtonV2Props {
state?: "play" | "pause";
}
function PlayPauseButtonV2({
state,
...props
}: IPlayPauseButtonV2Props &
DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) {
return (
<div className={styles.container} {...props}>
{state === "pause" ? (
<svg
width="24"
height="32"
viewBox="0 0 24 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
x="0.0281982"
width="7.04226"
height="32"
rx="3.52113"
fill="#D9D9D9"
/>
<rect
x="16.9297"
width="7.04226"
height="32"
rx="3.52113"
fill="#D9D9D9"
/>
</svg>
) : (
<svg
width="30"
height="35"
viewBox="0 0 30 35"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3.18651 34.141C1.85318 34.9108 0.186514 33.9485 0.186514 32.4089L0.186518 2.96408C0.186518 1.42448 1.85318 0.46223 3.18652 1.23203L28.6865 15.9545C30.0198 16.7243 30.0198 18.6488 28.6865 19.4186L3.18651 34.141Z"
fill="#D9D9D9"
/>
</svg>
)}
</div>
);
}
export default PlayPauseButtonV2;

View File

@ -0,0 +1,65 @@
import { useEffect, useRef, useState } from "react";
import styles from "./styles.module.scss";
interface IVideoOverlayProps {
isShow: boolean;
setIsShow: React.Dispatch<React.SetStateAction<boolean>>;
animationDuration?: number;
children?: React.ReactNode;
}
function VideoOverlay({
isShow,
setIsShow,
animationDuration = 5000,
children,
}: IVideoOverlayProps) {
const timeoutRef = useRef<NodeJS.Timeout>();
const [animationDurationLocal, setAnimationDurationLocal] =
useState(animationDuration);
const click = () => {
if (timeoutRef.current) clearTimeout(timeoutRef.current);
setAnimationDurationLocal((prev) => prev + animationDuration);
timeoutRef.current = setTimeout(() => {
setIsShow(false);
}, animationDuration);
};
useEffect(() => {
if (!isShow) return;
console.log("start ");
timeoutRef.current = setTimeout(() => {
setIsShow(false);
}, animationDuration);
return () => {
if (timeoutRef.current) clearTimeout(timeoutRef.current);
};
}, [animationDuration, isShow, setIsShow]);
return (
<>
{isShow && (
<div
className={styles.overlay}
style={{
animationDelay: `0s, ${animationDurationLocal - 500}ms`,
}}
onClick={click}
>
<div
className={styles.content}
style={{
animationDelay: `0s, ${animationDurationLocal - 500}ms`,
}}
>
{children}
</div>
</div>
)}
</>
);
}
export default VideoOverlay;

View File

@ -0,0 +1,46 @@
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
animation-fill-mode: forwards;
animation-name: appearance, disappearing;
animation-duration: 0.5s;
}
@keyframes appearance {
to {
background-color: rgba(0, 0, 0, 0.27);
}
}
@keyframes disappearing {
to {
background-color: rgba(0, 0, 0, 0);
}
}
.content {
opacity: 0;
animation-fill-mode: forwards;
animation-name: appearance-content, disappearing-content;
animation-duration: 0.5s;
}
@keyframes appearance-content {
to {
opacity: 1;
}
}
@keyframes disappearing-content {
to {
opacity: 0;
}
}