45 lines
1.3 KiB
TypeScript
45 lines
1.3 KiB
TypeScript
import { useEffect, useState } from 'react'
|
|
import { Video } from './Video'
|
|
import { start } from './lib/start'
|
|
|
|
import { ArrowPathIcon } from '@heroicons/react/24/solid'
|
|
|
|
function App() {
|
|
const [mediaStreams, setMediaStreams] = useState<MediaStream[]>([])
|
|
const [focusedIndex, setFocusedIndex] = useState<number>(-1)
|
|
|
|
useEffect(() => {
|
|
start().then((streams) => {
|
|
setMediaStreams(streams)
|
|
})
|
|
}, [])
|
|
|
|
const handleClick = (index: number) => (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
|
if (focusedIndex === index) {
|
|
setFocusedIndex(-1)
|
|
} else {
|
|
setFocusedIndex(index)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<div className='grid grid-cols-3 bg-slate-900 aspect-video'>
|
|
{mediaStreams.map((stream, index) => (
|
|
<div key={`medistream-${index}`} className={`relative ${focusedIndex === index ? 'z-50' : ''}`}>
|
|
<Video mediaStream={stream} index={index} focused={focusedIndex === index} onClick={handleClick(index)} />
|
|
</div>
|
|
))}
|
|
</div>
|
|
<button
|
|
className={'absolute bg-white p-2 shadow-xl top-3 right-3 rounded-lg'}
|
|
onClick={() => window.location.reload()}
|
|
>
|
|
<ArrowPathIcon className='h-6 w-6 text-black' />
|
|
</button>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default App
|