♻️(frontend) starting a bit more structured frontend app

the idea is to use react aria, panda-css, react query and wouter as a
base, in addition to livekit react components

this is still mostly wip but it's usable:

- homepage shows a login link to create a room
- before joining a room you are asked to configure your audio/video/user
name
- note that if you directly go to a a conference url it creates it even
if you are not logged in… very secured!
This commit is contained in:
Emmanuel Pelletier
2024-07-02 20:05:46 +02:00
parent cf11cc3e60
commit e3eb3e240a
48 changed files with 6387 additions and 306 deletions
+81
View File
@@ -0,0 +1,81 @@
import { fetchRoom } from '@/api/fetchRoom'
import { BoxScreen } from '@/layout/BoxScreen'
import { ErrorScreen } from '@/layout/ErrorScreen'
import { ForbiddenScreen } from '@/layout/ForbiddenScreen'
import { LoadingScreen } from '@/layout/LoadingScreen'
import { Screen } from '@/layout/Screen'
import { A } from '@/primitives/A'
import { H1 } from '@/primitives/H'
import { keys } from '@/queries/keys'
import {
LiveKitRoom,
VideoConference,
PreJoin,
LocalUserChoices,
} from '@livekit/components-react'
import { useQuery } from '@tanstack/react-query'
import { useState } from 'react'
import { Link, useLocation, useParams } from 'wouter'
export const Conference = () => {
const { roomId } = useParams()
const [, navigate] = useLocation()
const { status, data } = useQuery({
queryKey: [keys.room, roomId],
queryFn: ({ queryKey }) => fetchRoom(queryKey[1] as string),
})
const [userConfig, setUserConfig] = useState<LocalUserChoices | null>(null)
if (!userConfig) {
return (
<BoxScreen>
<H1>Verify your settings before joining</H1>
<PreJoin
persistUserChoices
onSubmit={(choices) => {
setUserConfig(choices)
}}
/>
<p>
<Link to="/" asChild>
<A size="small">Back to homescreen</A>
</Link>
</p>
</BoxScreen>
)
}
if (status === 'error' || (status === 'success' && !data?.livekit)) {
return <ErrorScreen />
}
if (data?.is_public === false) {
return <ForbiddenScreen />
}
if (data?.livekit?.token) {
return (
<Screen>
<LiveKitRoom
serverUrl={import.meta.env.VITE_LIVEKIT_SERVER_URL}
token={data?.livekit?.token}
connect={true}
audio={{
deviceId: userConfig.audioDeviceId,
}}
video={{
deviceId: userConfig.videoDeviceId,
}}
onDisconnected={() => {
navigate('/')
}}
>
<VideoConference />
</LiveKitRoom>
</Screen>
)
}
return <LoadingScreen />
}