Skip to content

Commit

Permalink
pausing choices video/carousel and feedback now whenn not on screen
Browse files Browse the repository at this point in the history
  • Loading branch information
Resaki1 committed Dec 12, 2023
1 parent 0c74250 commit f2bdaf8
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 109 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@directus/sdk": "^13.0.2",
"@types/react": "^18.2.42",
"@types/react-dom": "^18.2.17",
"@uidotdev/usehooks": "^2.4.1",
"astro": "^4.0.3",
"classnames": "^2.3.2",
"random-avatar-generator": "^2.0.0",
Expand Down
14 changes: 14 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions src/components/ProgressButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type ProgessButtonProps = {
icon: string;
onClick: () => void;
active: boolean;
paused: boolean;
duration: number;
};

Expand All @@ -15,13 +16,14 @@ const ProgressButton = ({
icon,
onClick,
active,
paused,
duration,
}: ProgessButtonProps) => {
return (
<div
className={classNames(
"progress-button",
active && "progress-button--active"
active && "progress-button--active",
)}
>
<Icon name={icon} />
Expand All @@ -33,7 +35,9 @@ const ProgressButton = ({
<div
className="progress-button__progress-bar"
style={{
animation: `progress ${duration}ms linear forwards`,
animation: `progress ${duration}ms linear ${
paused ? "paused" : "running"
} forwards`,
}}
/>
</div>
Expand Down
11 changes: 10 additions & 1 deletion src/components/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import { useRef, useEffect, useMemo } from "react";

type Props = {
className?: string;
handleLoadedMetadata?: (duration: number) => void;
video: string;
paused: boolean;
handleLoadedMetadata?: (duration: number) => void;
};

export default function Video({
className,
video,
paused,
handleLoadedMetadata,
}: Props) {
const videoRef = useRef<HTMLVideoElement>(null);
Expand All @@ -19,6 +21,13 @@ export default function Video({
if (videoRef.current) videoRef.current.defaultMuted = true;
}, []);

useEffect(() => {
if (videoRef.current) {
if (paused) videoRef.current.pause();
else videoRef.current.play();
}
}, [paused]);

const key = useMemo(() => video, [video]);

return (
Expand Down
205 changes: 108 additions & 97 deletions src/components/VideoPlayer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEffect, useState } from "react";
import { useIntersectionObserver } from "@uidotdev/usehooks";
import ProgressButton from "./ProgressButton";
import useMediaQuery from "../hooks/useMediaQuery";
import Video from "./Video";
Expand All @@ -16,10 +17,15 @@ type Props = {
buttonFirstVidLabel: string;
buttonSecondVidLabel: string;
buttonThirdVidLabel: string;
}
}
};
};

const VideoPlayer = (props: Props) => {
const [ref, entry] = useIntersectionObserver({
threshold: 0.75,
rootMargin: "0px",
});

const [position, setPosition] = useState(0);
const theme = useMediaQuery("(prefers-color-scheme: dark)")
? "dark"
Expand All @@ -37,6 +43,7 @@ const VideoPlayer = (props: Props) => {
}, [isMobile]);

useEffect(() => {
if (!entry?.isIntersecting) return;
const interval = setInterval(() => {
setPosition((prevPosition) => {
if (!isMobile ? prevPosition === 8 : prevPosition === 2) {
Expand All @@ -48,106 +55,110 @@ const VideoPlayer = (props: Props) => {
}, duration);

return () => clearInterval(interval);
}, [position, duration, isMobile]);
}, [position, duration, isMobile, entry?.isIntersecting]);

return (
<div className="choices__content">
<div className="choices__buttons">
<ProgressButton
icon="Edit"
onClick={() => setPosition(0)}
active={!isMobile ? position <= 2 : position === 0}
duration={!isMobile ? duration * 3 : duration}
>
{props.textContent.buttonCollab}
</ProgressButton>
<ProgressButton
icon="Vote"
onClick={() => setPosition(3)}
active={!isMobile ? position > 2 && position <= 5 : position === 1}
duration={!isMobile ? duration * 3 : duration}
>
{props.textContent.buttonModerate}
</ProgressButton>
<ProgressButton
icon="Columns"
onClick={() => setPosition(6)}
active={!isMobile ? position > 5 && position <= 8 : position === 2}
duration={!isMobile ? duration * 3 : duration}
>
{props.textContent.buttonCustomize}
</ProgressButton>
</div>
<div className="choices__image-wrapper">
{!isMobile && (
<picture>
<source
srcSet={`/assets/choices/choices_${theme}_${position}.webp`}
type="image/webp"
/>
<img
src={`/assets/choices/choices_${theme}_${position}.png`}
height="290"
width="680"
alt={`${props.textContent.screenshotAlt} ${position + 1}`}
/>
</picture>
)}
</div>
<div className="choices__video-wrapper">
<button
className="choices__video-button choices__video-button--left"
disabled={position === 0}
onClick={() => setPosition(position - 1)}
aria-label={props.textContent.buttonPrevVidLabel}
>
<Icon name="Chevron" />
</button>
{isMobile && (
<Video
className="choices__video"
video={`/assets/choices/videos/choices_${theme}_${position}`}
handleLoadedMetadata={setVideoDuration}
<div className="choices__content" ref={ref}>
<div className="choices__buttons">
<ProgressButton
icon="Edit"
onClick={() => setPosition(0)}
active={!isMobile ? position <= 2 : position === 0}
paused={!entry?.isIntersecting}
duration={!isMobile ? duration * 3 : duration}
>
{props.textContent.buttonCollab}
</ProgressButton>
<ProgressButton
icon="Vote"
onClick={() => setPosition(3)}
active={!isMobile ? position > 2 && position <= 5 : position === 1}
paused={!entry?.isIntersecting}
duration={!isMobile ? duration * 3 : duration}
>
{props.textContent.buttonModerate}
</ProgressButton>
<ProgressButton
icon="Columns"
onClick={() => setPosition(6)}
active={!isMobile ? position > 5 && position <= 8 : position === 2}
paused={!entry?.isIntersecting}
duration={!isMobile ? duration * 3 : duration}
>
{props.textContent.buttonCustomize}
</ProgressButton>
</div>
<div className="choices__image-wrapper">
{!isMobile && (
<picture>
<source
srcSet={`/assets/choices/choices_${theme}_${position}.webp`}
type="image/webp"
/>
)}
<button
className="choices__video-button choices__video-button--right"
disabled={position === 2}
onClick={() => setPosition(position + 1)}
aria-label={props.textContent.buttonNextVidLabel}
>
<Icon name="Chevron" />
</button>
<ul className="choices__video-position-buttons">
<li>
<button
className="choices__video-position-button--0"
disabled={position === 0}
onClick={() => setPosition(0)}
aria-label={props.textContent.buttonFirstVidLabel}
/>
</li>
<img
src={`/assets/choices/choices_${theme}_${position}.png`}
height="290"
width="680"
alt={`${props.textContent.screenshotAlt} ${position + 1}`}
/>
</picture>
)}
</div>
<div className="choices__video-wrapper">
<button
className="choices__video-button choices__video-button--left"
disabled={position === 0}
onClick={() => setPosition(position - 1)}
aria-label={props.textContent.buttonPrevVidLabel}
>
<Icon name="Chevron" />
</button>
{isMobile && (
<Video
className="choices__video"
paused={!entry?.isIntersecting}
video={`/assets/choices/videos/choices_${theme}_${position}`}
handleLoadedMetadata={setVideoDuration}
/>
)}
<button
className="choices__video-button choices__video-button--right"
disabled={position === 2}
onClick={() => setPosition(position + 1)}
aria-label={props.textContent.buttonNextVidLabel}
>
<Icon name="Chevron" />
</button>
<ul className="choices__video-position-buttons">
<li>
<button
className="choices__video-position-button--0"
disabled={position === 0}
onClick={() => setPosition(0)}
aria-label={props.textContent.buttonFirstVidLabel}
/>
</li>

<li>
<button
className="choices__video-position-button--1"
disabled={position === 1}
onClick={() => setPosition(1)}
aria-label={props.textContent.buttonSecondVidLabel}
/>
</li>
<li>
<button
className="choices__video-position-button--2"
disabled={position === 2}
onClick={() => setPosition(2)}
aria-label={props.textContent.buttonThirdVidLabel}
/>
</li>
</ul>
</div>
<li>
<button
className="choices__video-position-button--1"
disabled={position === 1}
onClick={() => setPosition(1)}
aria-label={props.textContent.buttonSecondVidLabel}
/>
</li>
<li>
<button
className="choices__video-position-button--2"
disabled={position === 2}
onClick={() => setPosition(2)}
aria-label={props.textContent.buttonThirdVidLabel}
/>
</li>
</ul>
</div>
</div>
);
}
};

export default VideoPlayer;
5 changes: 2 additions & 3 deletions src/views/Choices/Choices.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ import VideoPlayer from "../../components/VideoPlayer";
import getTranslatedContent from "../../utils/directus";
import "./Choices.scss";
const {lang} = Astro.params;
const { lang } = Astro.params;
const content = await getTranslatedContent("Choices_Section", lang!);
---

<section class="choices">
<h2>{content.header}</h2>
<p>{content.text}</p>
<VideoPlayer client:visible textContent={content} />
<VideoPlayer client:idle textContent={content} />
</section>

10 changes: 5 additions & 5 deletions src/views/Feedback/Feedback.astro
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
import FeedbackCarousel from "./FeedbackCarousel.tsx";
import getTranslatedContent, {getContent} from "../../utils/directus";
import getTranslatedContent, { getContent } from "../../utils/directus";
const {lang} = Astro.params;
const { lang } = Astro.params;
const content = await getTranslatedContent("Feedback_Section", lang!);
const testimonials = await getContent("testimonials") as FeedbackItem[];
const testimonials = (await getContent("testimonials")) as FeedbackItem[];
export type FeedbackItem = {
name: string;
Expand All @@ -16,8 +16,8 @@ export type FeedbackItem = {
---

<section class="feedback">
<h2>{content.header}</h2>
<p>{content.text}</p>
<h2>{content.header}</h2>
<p>{content.text}</p>
<div class="feedback_carousel-container">
<FeedbackCarousel items={testimonials} client:only="react" />
</div>
Expand Down
Loading

0 comments on commit f2bdaf8

Please sign in to comment.