Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start autoplay when video is in view #2839

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

juliawegmayr
Copy link
Contributor

@juliawegmayr juliawegmayr commented Nov 27, 2024

Description

Videos that are set to autoplay should only start if the user scrolls to the Video. If he scrolls away, the video should pause. Implementation for: DamVideoBlock, YoutubeVideoBlock and VimeoVideoBlock.

Screenshots/screencasts

DamVideoBlock:

Screen.Recording.2024-11-27.at.13.32.10.mov

YoutubeVideoBlock:

Screen.Recording.2024-11-27.at.13.34.19.mov

VimeoVideoBlock:

Screen.Recording.2024-11-27.at.13.35.36.mov

Changeset

  • I have verified if my change requires a changeset

Related tasks and documents

(https://vivid-planet.atlassian.net/browse/COM-1313)

@juliawegmayr juliawegmayr self-assigned this Nov 27, 2024
@juliawegmayr juliawegmayr force-pushed the start-autoplay-when-video-is-in-view branch from 58f2db7 to 9688201 Compare November 27, 2024 11:01
@juliawegmayr juliawegmayr force-pushed the start-autoplay-when-video-is-in-view branch from 9688201 to 13a48c7 Compare November 27, 2024 12:21
@juliawegmayr juliawegmayr marked this pull request as ready for review November 27, 2024 12:49
@auto-assign auto-assign bot requested a review from johnnyomair November 27, 2024 12:49
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These functions should be in the respective blocks. There's no need for a separate file IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed here: 42b53fb

@@ -0,0 +1,20 @@
import { RefObject, useEffect, useState } from "react";

export const useIsElementVisible = (ref: RefObject<HTMLDivElement>) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming: useIsElementInViewport would probably be better. An element can still be hidden using display: none.

BTW, nice implementation using IntersectionObserver 👏🏼

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you :)

Naming changed here: 0ebb7d3

@johnnyomair johnnyomair force-pushed the start-autoplay-when-video-is-in-view branch from a48e93d to 108a218 Compare November 28, 2024 13:39
@@ -21,6 +22,20 @@ const parseYoutubeIdentifier = (value: string): string | undefined => {
return youtubeId ?? undefined;
};

const pauseYoutubeVideo = () => {
const iframe = document.getElementsByTagName("iframe")[0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if there are multiple iframe tags?

use a ref instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!
Changed here: b880c4c

Copy link
Collaborator

@johnnyomair johnnyomair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also use Refs for the iframes

@juliawegmayr
Copy link
Contributor Author

@johnnyomair
While testing I realized, that videos on full-screens weren't starting/stopping. That's why I changed the value of threshold in the IntersectionObserver: 26b70cb

johnnyomair
johnnyomair previously approved these changes Dec 5, 2024
Comment on lines 59 to 61
useEffect(() => {
inView && autoplay ? playYoutubeVideo() : pauseYoutubeVideo();
}, [autoplay, inView]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useIsElementInViewport has a local state and re-renders the Video Block once it gets into view. But you don't have to re-render, as you only call the JS api inside the iframe.

You could argue that performance doesn't matter here, it's only re-rendered once - but I'd argue that it makes the code more complicated than it has to be.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would you design useIsElementInViewport to remove the state and effect? Something like this?

useIsElementInViewport(ref, (inView) => {
  if(autoplay) {
    if(inView) {
      playYouTubeVideo();
    } else {
      pauseYouTubeVideo();
    }
  }
});

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it better like this?
23411e5

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it better like this?

yes, much simpler - isn't it?


const inView = useIsElementInViewport(inViewRef);

inView && autoplay ? playDamVideo(videoRef) : pauseDamVideo(videoRef);
Copy link
Member

@thomasdax98 thomasdax98 Dec 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be in a useEffect

nvm since the state in useIsElementInViewport only changes if the element get in view, not triggering unnecessary rerenders

@@ -33,6 +46,13 @@ export const DamVideoBlock = withPreview(
const [showPreviewImage, setShowPreviewImage] = useState(true);
const hasPreviewImage = Boolean(previewImage && previewImage.damFile);

const inViewRef = useRef<HTMLDivElement>(null);
Copy link
Member

@thomasdax98 thomasdax98 Dec 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need the extra inViewRef? Wouldn't it be possible to use the videoRef directly to check if it's in view?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already tried that, but using only one ref is not possible, as controlling the videos does not work in that case.

Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)
D Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants