feat(video): autoplay muted loop for local reels, keep YouTube click-to-play

This commit is contained in:
Vadym Samoilenko 2026-05-11 13:17:09 +01:00
parent 5b84bd9cfa
commit 8ca741bee7

View file

@ -4,7 +4,8 @@
import { useState } from 'react'
import type { Media } from '@/types/globals'
const IMG_POSTER_DEFAULT = '/images/figma/video-preview.webp'
const DEFAULT_MP4 = '/videos/shumiland-reels.mp4'
const DEFAULT_WEBM = '/videos/shumiland-reels.webm'
const IMG_PLAY = '/images/figma/btn-video-play.svg'
function getMediaUrl(img: Media | string | null | undefined): string | null {
@ -25,32 +26,32 @@ interface VideoSectionProps {
}
export function VideoSection({ poster, src }: VideoSectionProps) {
const [playing, setPlaying] = useState(false)
const posterUrl = getMediaUrl(poster) ?? IMG_POSTER_DEFAULT
const [ytPlaying, setYtPlaying] = useState(false)
const posterUrl = getMediaUrl(poster) ?? undefined
const youtubeEmbed = src ? getYouTubeEmbedUrl(src) : null
return (
<section className="relative flex min-h-[400px] w-full items-center justify-center overflow-hidden bg-[#223e0d] md:min-h-[576px] lg:min-h-[960px]">
<img
src={posterUrl}
alt="Відео про Шуміленд"
className="pointer-events-none absolute inset-0 h-full w-full object-cover"
/>
{!playing && (
<button
onClick={() => (src ? setPlaying(true) : undefined)}
className="relative z-10 flex h-[100px] w-[100px] items-center justify-center transition-transform hover:scale-110 focus-visible:ring-4 focus-visible:ring-white/60 focus-visible:outline-none"
aria-label="Дивитися відео"
style={{ cursor: src ? 'pointer' : 'default' }}
>
<img src={IMG_PLAY} alt="" aria-hidden="true" className="h-full w-full" />
</button>
)}
{playing && src && (
<div className="absolute inset-0 z-20 bg-black">
{youtubeEmbed ? (
// If CMS src is a YouTube URL → use click-to-play embed
if (youtubeEmbed) {
return (
<section className="relative flex min-h-[400px] w-full items-center justify-center overflow-hidden bg-[#223e0d] md:min-h-[576px] lg:min-h-[960px]">
{posterUrl && (
<img
src={posterUrl}
alt="Відео про Шуміленд"
className="pointer-events-none absolute inset-0 h-full w-full object-cover"
/>
)}
{!ytPlaying && (
<button
onClick={() => setYtPlaying(true)}
className="relative z-10 flex h-[100px] w-[100px] items-center justify-center transition-transform hover:scale-110 focus-visible:ring-4 focus-visible:ring-white/60 focus-visible:outline-none"
aria-label="Дивитися відео"
>
<img src={IMG_PLAY} alt="" aria-hidden="true" className="h-full w-full" />
</button>
)}
{ytPlaying && (
<div className="absolute inset-0 z-20 bg-black">
<iframe
src={youtubeEmbed}
className="h-full w-full"
@ -58,17 +59,31 @@ export function VideoSection({ poster, src }: VideoSectionProps) {
allowFullScreen
title="Відео про Шуміленд"
/>
) : (
<video
src={src}
className="h-full w-full object-cover"
controls
autoPlay
onEnded={() => setPlaying(false)}
/>
)}
</div>
)}
</section>
)
}
// Default: autoplay local video (square 1:1)
return (
<section className="flex w-full items-center justify-center bg-[#223e0d] py-10 lg:py-16">
<div className="mx-auto w-full max-w-[1200px] px-4">
<div className="flex justify-center">
<video
className="aspect-square w-full max-w-[720px] rounded-[20px] object-cover"
autoPlay
muted
loop
playsInline
preload="metadata"
poster={posterUrl}
>
<source src={DEFAULT_WEBM} type="video/webm" />
<source src={DEFAULT_MP4} type="video/mp4" />
</video>
</div>
)}
</div>
</section>
)
}