Skip to content

Commit

Permalink
oct-2157: video frame - all viewports
Browse files Browse the repository at this point in the history
  • Loading branch information
jmikolajczyk committed Oct 29, 2024
1 parent aa900d6 commit 6620f3d
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
.constraintsWrapper {
display: flex;
overflow: hidden;
margin-top: 4rem;

@media #{$desktop-up} {
margin-top: 1.2rem;
}
}

.buttonClose {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
.root {
position: relative;
width: 39.2rem;
width: 28rem;
transition: opacity $transition-time-1;
opacity: 0.5;
height: 19.8rem;
height: 14.4rem;

@media #{$desktop-up} {
width: 39.2rem;
height: 19.8rem;
}

.previewVideoOverlay {
cursor: pointer;
Expand All @@ -30,11 +35,26 @@
position: fixed;
top: 50%;
left: 50%;
width: 141.6rem;
height: 68.6rem;
width: 0;
height: 0;
transform: translate(-50%, -50%);
z-index: $z-index-7;

@media #{$tablet-up} {
width: 71.2rem;
height: 34.2rem;
}

@media #{$desktop-up} {
width: 94.6rem;
height: 45.4rem;
}

@media #{$large-desktop-up} {
width: 141.6rem;
height: 68.6rem;
}

.closeButton {
border-radius: $border-radius-10;
display: flex;
Expand Down
121 changes: 83 additions & 38 deletions client/src/components/Home/HomeGridVideoBar/VideoTile/VideoTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { createPortal } from 'react-dom';
import { useTranslation } from 'react-i18next';

import Svg from 'components/ui/Svg';
import useMediaQuery from 'hooks/helpers/useMediaQuery';
import { cross } from 'svg/misc';

import VideoTileProps from './types';
Expand All @@ -15,10 +16,14 @@ const VideoTile: FC<VideoTileProps> = ({ title, url, isDragging }) => {
const { t } = useTranslation('translation', {
keyPrefix: 'components.home.homeGridVideoBar',
});
const ref = useRef(null);
const previewVideoIframeRef = useRef(null);
const ref = useRef<HTMLDivElement>(null);
const videoIframeRef = useRef<HTMLIFrameElement>(null);
const playerRef = useRef<Player>();
const previewVideoIframeRef = useRef<HTMLIFrameElement>(null);
const previewPlayerRef = useRef<Player>();

const isInView = useInView(ref, { amount: 'all' });
const { isMobile, isTablet, isDesktop, isLargeDesktop } = useMediaQuery();

const urlWithOptions = `${url}&dnt=true`;
const previewPlayerSrc = `${urlWithOptions}&muted=true&controls=false&size=640`;
Expand All @@ -27,16 +32,44 @@ const VideoTile: FC<VideoTileProps> = ({ title, url, isDragging }) => {

const [isCloseButtonExpanded, setIsCloseButtonExpanded] = useState(false);

const onFullscreenChangeListener = () => {
// eslint-disable-next-line @typescript-eslint/naming-convention
playerRef.current?.on('fullscreenchange', ({ fullscreen }) => {
if (fullscreen || isLargeDesktop) {
return;
}
playerRef.current?.off('fullscreenchange');
setIsVideoBoxOpen(false);
previewPlayerRef.current?.unload();
});
};

useEffect(() => {
if (!previewVideoIframeRef.current) {
return;
}
const player = new Player(previewVideoIframeRef.current);
previewPlayerRef.current = player;

previewPlayerRef.current = new Player(previewVideoIframeRef.current);
previewPlayerRef.current.getVideoId().then(id => previewPlayerRef.current?.loadVideo(id));
}, []);

useEffect(() => {
if (!videoIframeRef.current) {
return;
}
playerRef.current?.off('fullscreenchange');
if (isMobile) {
playerRef.current?.getFullscreen().then(isFullscreen => {
if (isFullscreen) {
return;
}
playerRef.current?.requestFullscreen();
});
}

onFullscreenChangeListener();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isMobile, isTablet, isDesktop, isLargeDesktop]);

return (
<div ref={ref} className={cx(styles.root, isInView && styles.isInView)}>
<div
Expand Down Expand Up @@ -66,44 +99,56 @@ const VideoTile: FC<VideoTileProps> = ({ title, url, isDragging }) => {
{isVideoBoxOpen &&
createPortal(
<Fragment>
<motion.div
animate={{ opacity: 1 }}
className={cx(styles.videoOverlay, styles.isOpen)}
initial={{ opacity: 0 }}
onClick={() => setIsVideoBoxOpen(false)}
/>
<div className={styles.videoBox}>
{!isMobile && (
<motion.div
className={styles.closeButton}
initial={{ width: '4rem' }}
onClick={() => {
setIsVideoBoxOpen(false);
setIsCloseButtonExpanded(false);
}}
onMouseLeave={() => setIsCloseButtonExpanded(false)}
onMouseOver={() => setIsCloseButtonExpanded(true)}
whileHover={{
width: '14rem',
}}
>
<AnimatePresence>
{isCloseButtonExpanded && (
<motion.div
animate={{ opacity: 1 }}
className={styles.closeButtonText}
exit={{ opacity: 0 }}
initial={{ opacity: 0 }}
>
{t('closeVideoWithArrow')}
</motion.div>
)}
</AnimatePresence>
<Svg img={cross} size={1} />
</motion.div>
animate={{ opacity: 1 }}
className={cx(styles.videoOverlay, styles.isOpen)}
initial={{ opacity: 0 }}
onClick={() => setIsVideoBoxOpen(false)}
/>
)}
<div className={styles.videoBox}>
{!isMobile && (
<motion.div
className={styles.closeButton}
initial={{ width: '4rem' }}
onClick={() => {
setIsVideoBoxOpen(false);
setIsCloseButtonExpanded(false);
}}
onMouseLeave={() => setIsCloseButtonExpanded(false)}
onMouseOver={() => setIsCloseButtonExpanded(true)}
whileHover={{
width: '14rem',
}}
>
<AnimatePresence>
{isCloseButtonExpanded && (
<motion.div
animate={{ opacity: 1 }}
className={styles.closeButtonText}
exit={{ opacity: 0 }}
initial={{ opacity: 0 }}
>
{t('closeVideoWithArrow')}
</motion.div>
)}
</AnimatePresence>
<Svg img={cross} size={1} />
</motion.div>
)}
<iframe
ref={videoIframeRef}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share;"
allowFullScreen
className={styles.video}
onLoad={() => {
playerRef.current = new Player(videoIframeRef.current as HTMLIFrameElement);
if (isMobile) {
playerRef.current.requestFullscreen();
}
onFullscreenChangeListener();
}}
referrerPolicy="strict-origin-when-cross-origin"
src={playerSrc}
title={title}
Expand Down
22 changes: 20 additions & 2 deletions client/src/hooks/helpers/useMediaQuery/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';

import { tabletOnly, desktopOnly, largeDesktopOnly } from 'styles/utils/mediaQueries';
import { phoneOnly, tabletOnly, desktopOnly, largeDesktopOnly } from 'styles/utils/mediaQueries';

import { UseMediaQuery } from './types';

Expand All @@ -16,6 +16,7 @@ function useMediaQuery(): UseMediaQuery {
const [isLargeDesktop, setIsLargeDesktop] = useState<boolean>(getMatches(largeDesktopOnly));
const [isDesktop, setIsDesktop] = useState<boolean>(getMatches(desktopOnly));
const [isTablet, setIsTablet] = useState<boolean>(getMatches(tabletOnly));
const [isMobile, setIsMobile] = useState<boolean>(getMatches(phoneOnly));

function handleChangeLargeDesktop() {
setIsLargeDesktop(getMatches(largeDesktopOnly));
Expand All @@ -29,10 +30,15 @@ function useMediaQuery(): UseMediaQuery {
setIsTablet(getMatches(tabletOnly));
}

function handleChangeMobile() {
setIsMobile(getMatches(phoneOnly));
}

useEffect(() => {
const matchMediaLargeDesktop = window.matchMedia(largeDesktopOnly);
const matchMediaDesktop = window.matchMedia(desktopOnly);
const matchMediaTablet = window.matchMedia(tabletOnly);
const matchMediaMobile = window.matchMedia(phoneOnly);

// Listen matchMedia
if (matchMediaLargeDesktop.addListener) {
Expand All @@ -53,6 +59,12 @@ function useMediaQuery(): UseMediaQuery {
matchMediaTablet.addEventListener('change', handleChangeTablet);
}

if (matchMediaMobile.addListener) {
matchMediaMobile.addListener(handleChangeMobile);
} else {
matchMediaMobile.addEventListener('change', handleChangeMobile);
}

return () => {
if (matchMediaLargeDesktop.removeListener) {
matchMediaLargeDesktop.removeListener(handleChangeLargeDesktop);
Expand All @@ -71,6 +83,12 @@ function useMediaQuery(): UseMediaQuery {
} else {
matchMediaTablet.removeEventListener('change', handleChangeTablet);
}

if (matchMediaMobile.removeListener) {
matchMediaMobile.removeListener(handleChangeMobile);
} else {
matchMediaMobile.removeEventListener('change', handleChangeMobile);
}
};

// eslint-disable-next-line react-hooks/exhaustive-deps
Expand All @@ -79,7 +97,7 @@ function useMediaQuery(): UseMediaQuery {
return {
isDesktop,
isLargeDesktop,
isMobile: !isDesktop && !isTablet && !isLargeDesktop,
isMobile,
isTablet,
};
}
Expand Down

0 comments on commit 6620f3d

Please sign in to comment.