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