From 0e534925049b02ceb9b3dfdfe07c80ed79e5a48c Mon Sep 17 00:00:00 2001 From: ronalduQualabs Date: Wed, 29 Jan 2025 13:48:56 -0300 Subject: [PATCH] Add Suspense in Background Video and suppressHydrationWarning --- src/components/players/background-player.tsx | 200 +++++++++---------- 1 file changed, 97 insertions(+), 103 deletions(-) diff --git a/src/components/players/background-player.tsx b/src/components/players/background-player.tsx index 3ec0f54..9c8e79e 100644 --- a/src/components/players/background-player.tsx +++ b/src/components/players/background-player.tsx @@ -1,6 +1,6 @@ 'use client'; -import { forwardRef, Children, isValidElement, useState } from 'react'; +import { forwardRef, Children, isValidElement, useState, Suspense } from 'react'; import Media from './media/index.js'; import { getPlaybackId, getPosterURLFromPlaybackId } from '../../providers/mux/transformer.js'; import { svgBlurImage } from '../utils.js'; @@ -8,80 +8,71 @@ import { svgBlurImage } from '../utils.js'; import type { PlayerProps } from '../types.js'; import type { MediaProps } from './media/index.js'; -const BackgroundPlayer = forwardRef & PlayerProps>((allProps, forwardedRef) => { - let { - style, - className, - children, - asset, - poster, - blurDataURL, - onPlaying, - onLoadStart, - ...rest - } = allProps; - - const slottedPoster = Children.toArray(children).find((child) => { - return typeof child === 'object' && 'type' in child && (child.props as any).slot === 'poster'; - }); - - // If there's a slotted poster image (e.g. next/image) remove the default player poster and blurDataURL. - if (isValidElement(slottedPoster)) { - poster = ''; - blurDataURL = undefined; - } +const BackgroundPlayer = forwardRef & PlayerProps>( + (allProps, forwardedRef) => { + let { style, className, children, asset, poster, blurDataURL, onPlaying, onLoadStart, ...rest } = allProps; - const props = rest as MediaProps & { thumbnailTime?: number }; - const imgStyleProps: React.CSSProperties = {}; - const playbackId = asset ? getPlaybackId(asset) : undefined; - - let isCustomPoster = true; - let srcSet: string | undefined; - - if (playbackId && asset?.status === 'ready') { - props.src = undefined; - props.playbackId = playbackId; - - if (poster) { - isCustomPoster = poster !== getPosterURLFromPlaybackId(playbackId, props); - - if (!isCustomPoster) { - // If it's not a custom poster URL, optimize with a srcset. - srcSet = - `${getPosterURLFromPlaybackId(playbackId, { ...props, width: 480 })} 480w,` + - `${getPosterURLFromPlaybackId(playbackId, { ...props, width: 640 })} 640w,` + - `${getPosterURLFromPlaybackId(playbackId, { ...props, width: 960 })} 960w,` + - `${getPosterURLFromPlaybackId(playbackId, { ...props, width: 1280 })} 1280w,` + - `${getPosterURLFromPlaybackId(playbackId, { ...props, width: 1600 })} 1600w,` + - `${getPosterURLFromPlaybackId(playbackId, { ...props })} 1920w`; - } + const slottedPoster = Children.toArray(children).find((child) => { + return typeof child === 'object' && 'type' in child && (child.props as any).slot === 'poster'; + }); + + // If there's a slotted poster image (e.g. next/image) remove the default player poster and blurDataURL. + if (isValidElement(slottedPoster)) { + poster = ''; + blurDataURL = undefined; } - } - if (blurDataURL) { - const showGeneratedBlur = !isCustomPoster && blurDataURL === asset?.blurDataURL; - const showCustomBlur = isCustomPoster && blurDataURL !== asset?.blurDataURL; - - if (showGeneratedBlur || showCustomBlur) { - imgStyleProps.width = '100%'; - imgStyleProps.height = '100%'; - imgStyleProps.color = 'transparent'; - imgStyleProps.backgroundSize = 'cover'; - imgStyleProps.backgroundPosition = 'center'; - imgStyleProps.backgroundRepeat = 'no-repeat'; - imgStyleProps.backgroundImage = `url('data:image/svg+xml;charset=utf-8,${svgBlurImage(blurDataURL)}')`; + const props = rest as MediaProps & { thumbnailTime?: number }; + const imgStyleProps: React.CSSProperties = {}; + const playbackId = asset ? getPlaybackId(asset) : undefined; + + let isCustomPoster = true; + let srcSet: string | undefined; + + if (playbackId && asset?.status === 'ready') { + props.src = undefined; + props.playbackId = playbackId; + + if (poster) { + isCustomPoster = poster !== getPosterURLFromPlaybackId(playbackId, props); + + if (!isCustomPoster) { + // If it's not a custom poster URL, optimize with a srcset. + srcSet = + `${getPosterURLFromPlaybackId(playbackId, { ...props, width: 480 })} 480w,` + + `${getPosterURLFromPlaybackId(playbackId, { ...props, width: 640 })} 640w,` + + `${getPosterURLFromPlaybackId(playbackId, { ...props, width: 960 })} 960w,` + + `${getPosterURLFromPlaybackId(playbackId, { ...props, width: 1280 })} 1280w,` + + `${getPosterURLFromPlaybackId(playbackId, { ...props, width: 1600 })} 1600w,` + + `${getPosterURLFromPlaybackId(playbackId, { ...props })} 1920w`; + } + } } - } - // Remove props that are not supported by MuxVideo. - delete props.thumbnailTime; + if (blurDataURL) { + const showGeneratedBlur = !isCustomPoster && blurDataURL === asset?.blurDataURL; + const showCustomBlur = isCustomPoster && blurDataURL !== asset?.blurDataURL; + + if (showGeneratedBlur || showCustomBlur) { + imgStyleProps.width = '100%'; + imgStyleProps.height = '100%'; + imgStyleProps.color = 'transparent'; + imgStyleProps.backgroundSize = 'cover'; + imgStyleProps.backgroundPosition = 'center'; + imgStyleProps.backgroundRepeat = 'no-repeat'; + imgStyleProps.backgroundImage = `url('data:image/svg+xml;charset=utf-8,${svgBlurImage(blurDataURL)}')`; + } + } - const [posterHidden, setPosterHidden] = useState(false); + // Remove props that are not supported by MuxVideo. + delete props.thumbnailTime; + const [posterHidden, setPosterHidden] = useState(false); - return ( - <> - -
- { - onPlaying?.(event as any); - setPosterHidden(true); - }} - onLoadStart={(event) => { - onLoadStart?.(event as any); - setPosterHidden(false); - }} - muted={true} - autoPlay={true} - loop={true} - playsInline={true} - {...props} - /> - {poster && ( - - )} -
{children}
-
- - ); -}); + } +
+ { + onPlaying?.(event as any); + setPosterHidden(true); + }} + onLoadStart={(event) => { + onLoadStart?.(event as any); + setPosterHidden(false); + }} + muted={true} + autoPlay={true} + loop={true} + playsInline={true} + {...props} + /> + {poster && ( + + )} +
{children}
+
+ + + ); + } +); export default BackgroundPlayer;