import type { VimeoEmbedItem as TVimeoEmbedItem } from '@cntrl-site/sdk'; import { getLayoutStyles } from '@cntrl-site/sdk'; import type { FC } from 'react'; import type { ItemProps } from '../Item'; import Player from '@vimeo/player'; import { useEffect, useId, useMemo, useState } from 'react'; import JSXStyle from 'styled-jsx/style'; import { useItemAngle } from '../useItemAngle'; import { useCntrlContext } from '../../../provider/useCntrlContext'; import { useRegisterResize } from '../../../common/useRegisterResize'; import { getStyleFromItemStateAndParams } from '../../../utils/getStyleFromItemStateAndParams'; import { useEmbedVideoItem } from './useEmbedVideoItem'; import { LinkWrapper } from '../LinkWrapper'; import { useLayoutContext } from '../../useLayoutContext'; import { useItemGeometry } from '../../../ItemGeometry/useItemGeometry'; export const VimeoEmbedItem: FC> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => { const reactId = useId(); const id = `${reactId}-vimeo-${item.id}`; const { layouts } = useCntrlContext(); const { radius: itemRadius, blur: itemBlur, opacity: itemOpacity } = useEmbedVideoItem(item, sectionId); const layoutId = useLayoutContext(); const [iframeRef, setIframeRef] = useState(null); const vimeoPlayer = useMemo(() => iframeRef ? new Player(iframeRef) : undefined, [iframeRef]); const itemAngle = useItemAngle(item, sectionId); const { url } = item.commonParams; const layoutParams = layoutId ? item.layoutParams[layoutId] : null; const [ref, setRef] = useState(null); const [imgRef, setImgRef] = useState(null); const [isCoverVisible, setIsCoverVisible] = useState(item.commonParams.coverUrl !== null); const layoutValues: Record[] = [item.area, item.layoutParams]; const wrapperStateParams = interactionCtrl?.getState(['angle', 'blur', 'opacity']); const frameStateParams = interactionCtrl?.getState(['radius']); const angle = getStyleFromItemStateAndParams(wrapperStateParams?.styles?.angle, itemAngle); const blur = getStyleFromItemStateAndParams(wrapperStateParams?.styles?.blur, itemBlur); const opacity = getStyleFromItemStateAndParams(wrapperStateParams?.styles?.opacity, itemOpacity); const radius = getStyleFromItemStateAndParams(frameStateParams?.styles?.radius, itemRadius); useRegisterResize(ref, onResize); useItemGeometry(item.id, ref); const validUrl = useMemo(() => { if (!layoutParams) return url; const validURL = new URL(url); validURL.searchParams.append('controls', String(layoutParams.controls)); validURL.searchParams.append('autoplay', String(layoutParams.play === 'auto')); validURL.searchParams.append('muted', String(layoutParams.muted)); validURL.searchParams.append('loop', String(layoutParams.loop)); validURL.searchParams.append('pip', String(layoutParams.pictureInPicture)); validURL.searchParams.append('title', '0'); validURL.searchParams.append('byline', '0'); validURL.searchParams.append('portrait', '0'); validURL.searchParams.append('autopause', 'false'); return validURL.href; }, [url, layoutParams]); useEffect(() => { if (!vimeoPlayer || !imgRef || !layoutParams) return; if (layoutParams.play === 'on-click') { setIsCoverVisible(true); } if (layoutParams.play === 'auto') { setIsCoverVisible(false); } vimeoPlayer.on('pause', (e) => { if (e.seconds === 0) { setIsCoverVisible(true); } }); vimeoPlayer.on('ended', () => { setIsCoverVisible(true); }); }, [vimeoPlayer, imgRef, layoutParams]); const handleClick = async () => { if (!vimeoPlayer) return; const isPaused = await vimeoPlayer.getPaused(); if (isPaused) { vimeoPlayer.play(); setIsCoverVisible(false); } else { vimeoPlayer.pause(); } }; const onCoverClick = () => { if (!vimeoPlayer || !imgRef) return; vimeoPlayer!.play(); setIsCoverVisible(false); }; const isInteractive = opacity !== 0; useEffect(() => { onVisibilityChange?.(isInteractive); if (!isInteractive && vimeoPlayer) { vimeoPlayer.pause(); } }, [isInteractive, onVisibilityChange, vimeoPlayer]); useEffect(() => { if (!vimeoPlayer || !interactionCtrl) return; interactionCtrl.setActionReceiver((type) => { switch (type) { case 'play': vimeoPlayer.play(); break; case 'pause': vimeoPlayer.pause(); break; } }); }, [interactionCtrl, vimeoPlayer]); return (
{ if (!vimeoPlayer || !layoutParams || layoutParams.play !== 'on-hover' || isCoverVisible) return; vimeoPlayer.play(); }} onMouseLeave={() => { if (!vimeoPlayer || !layoutParams || layoutParams.play !== 'on-hover') return; vimeoPlayer.pause(); }} > {item.commonParams.coverUrl && ( onCoverClick() } : {})} {...(layoutParams?.play === 'on-hover' ? { onMouseEnter: () => { if (!vimeoPlayer || !layoutParams || layoutParams.play !== 'on-hover') return; setIsCoverVisible(false); vimeoPlayer.play(); } } : {})} src={item.commonParams.coverUrl ?? ''} style={{ display: isCoverVisible ? 'block' : 'none', cursor: 'pointer', position: 'absolute', objectFit: 'cover', height: '100%', width: '100%', top: '0', left: '0' }} alt="Cover img" /> )} {/* ↓ This is necessary to track clicks on an iframe. */} {layoutParams && (!layoutParams.controls && (layoutParams.play === 'on-click' || layoutParams.play === 'auto')) && (
)}