Skip to content

Commit 8cdc682

Browse files
authored
Merge pull request #63 from teacoder-team/dev
perf(player): fast iframe lesson player
2 parents eb69c1b + c6051f4 commit 8cdc682

1 file changed

Lines changed: 46 additions & 23 deletions

File tree

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,60 @@
11
'use client'
22

3-
import dynamic from 'next/dynamic'
4-
import { useRef, useState } from 'react'
5-
6-
import { type KinescopePlayer } from '../shared/player'
3+
import { useEffect, useRef, useState } from 'react'
74

85
interface LessonPlayerProps {
96
videoId: string
107
}
118

12-
const Player = dynamic(
13-
() => import('../shared/player').then(mod => mod.Player),
14-
{
15-
ssr: false
16-
}
17-
)
18-
199
export function LessonPlayer({ videoId }: LessonPlayerProps) {
20-
const playerRef = useRef<KinescopePlayer | null>(null)
21-
const [isLoading, setIsLoading] = useState(true)
10+
const embedUrl = `https://kinescope.io/embed/${videoId}`
11+
12+
const [isInView, setIsInView] = useState(false)
13+
const [iframeLoaded, setIframeLoaded] = useState(false)
14+
const containerRef = useRef<HTMLDivElement>(null)
2215

23-
function handlePlayerReady() {
24-
setIsLoading(false)
25-
}
16+
useEffect(() => {
17+
if (!containerRef.current) return
18+
19+
const observer = new IntersectionObserver(
20+
entries => {
21+
entries.forEach(entry => {
22+
if (entry.isIntersecting) {
23+
setIsInView(true)
24+
observer.disconnect()
25+
}
26+
})
27+
},
28+
{ threshold: 0.3 }
29+
)
30+
31+
observer.observe(containerRef.current)
32+
return () => observer.disconnect()
33+
}, [])
2634

2735
return (
28-
<div className='relative mx-auto aspect-video w-full max-w-5xl overflow-hidden rounded-lg'>
29-
{isLoading && <p className='absolute'>Загрузка...</p>}
30-
<Player
31-
forwardRef={playerRef}
32-
videoId={videoId}
33-
onReady={handlePlayerReady}
34-
/>
36+
<div
37+
ref={containerRef}
38+
className='relative mx-auto aspect-video w-full max-w-5xl overflow-hidden rounded-lg bg-muted'
39+
>
40+
{!iframeLoaded && (
41+
<div className='absolute inset-0 flex flex-col items-center justify-center bg-muted'>
42+
<div className='z-10 text-base text-muted-foreground'>
43+
Загрузка видео…
44+
</div>
45+
</div>
46+
)}
47+
48+
{isInView && (
49+
<iframe
50+
className='h-full w-full'
51+
src={embedUrl}
52+
allow='fullscreen; picture-in-picture; encrypted-media'
53+
allowFullScreen
54+
frameBorder='0'
55+
onLoad={() => setIframeLoaded(true)}
56+
/>
57+
)}
3558
</div>
3659
)
3760
}

0 commit comments

Comments
 (0)