index.tsx raw

   1  import { cn } from '@/lib/utils'
   2  import { useUserPreferences } from '@/providers/UserPreferencesProvider'
   3  import mediaManager from '@/services/media-manager.service'
   4  import { useEffect, useRef, useState } from 'react'
   5  import ExternalLink from '../ExternalLink'
   6  
   7  export default function VideoPlayer({ src, className }: { src: string; className?: string }) {
   8    const { muteMedia, updateMuteMedia } = useUserPreferences()
   9    const [error, setError] = useState(false)
  10    const videoRef = useRef<HTMLVideoElement>(null)
  11  
  12    useEffect(() => {
  13      if (!videoRef.current) return
  14  
  15      const video = videoRef.current
  16  
  17      const handleVolumeChange = () => {
  18        updateMuteMedia(video.muted)
  19      }
  20  
  21      video.addEventListener('volumechange', handleVolumeChange)
  22  
  23      return () => {
  24        video.removeEventListener('volumechange', handleVolumeChange)
  25      }
  26    }, [])
  27  
  28    useEffect(() => {
  29      const video = videoRef.current
  30      if (!video || video.muted === muteMedia) return
  31  
  32      if (muteMedia) {
  33        video.muted = true
  34      } else {
  35        video.muted = false
  36      }
  37    }, [muteMedia])
  38  
  39    if (error) {
  40      return <ExternalLink url={src} />
  41    }
  42  
  43    return (
  44      <div>
  45        <video
  46          ref={videoRef}
  47          controls
  48          playsInline
  49          className={cn('rounded-xl max-h-[80vh] sm:max-h-[60vh] border', className)}
  50          src={src}
  51          onClick={(e) => e.stopPropagation()}
  52          onPlay={(event) => {
  53            mediaManager.play(event.currentTarget)
  54          }}
  55          muted={muteMedia}
  56          onError={() => setError(true)}
  57        />
  58      </div>
  59    )
  60  }
  61