Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Introduced turbopack alias for canvas in next.config.mjs. - Updated package.json scripts for development and branding tasks. - Added new dependencies for Tiptap extensions. - Implemented new demo layouts for agenda, contacts, drive, and mail applications. - Enhanced globals.css for improved theming and splash screen animations. - Added OAuth callback handling for drive mounts. - Updated layout components to integrate new demo shells and improve structure.
89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useState } from "react"
|
|
import { useRouter, useSearchParams } from "next/navigation"
|
|
import { Loader2 } from "lucide-react"
|
|
import { MeetHeader } from "@/components/meet/meet-header"
|
|
import { MeetRoomFrame } from "@/components/meet/meet-room-frame"
|
|
import { Button } from "@/components/ui/button"
|
|
import { useMeetConfig, useMeetRoomToken } from "@/lib/api/hooks/use-meet-queries"
|
|
|
|
export function MeetRoomClient({ room }: { room: string }) {
|
|
const router = useRouter()
|
|
const searchParams = useSearchParams()
|
|
const jwt = searchParams.get("jwt") ?? undefined
|
|
const { data: config, isLoading: configLoading } = useMeetConfig()
|
|
const roomToken = useMeetRoomToken()
|
|
const [meetUrl, setMeetUrl] = useState<string | null>(null)
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
useEffect(() => {
|
|
if (!room.trim()) {
|
|
setError("Salle invalide")
|
|
return
|
|
}
|
|
|
|
if (jwt && config?.public_url) {
|
|
const base = config.public_url.replace(/\/$/, "")
|
|
setMeetUrl(`${base}/${encodeURIComponent(room)}?jwt=${encodeURIComponent(jwt)}`)
|
|
return
|
|
}
|
|
|
|
if (jwt) return
|
|
|
|
if (!config?.enabled) return
|
|
|
|
let cancelled = false
|
|
void roomToken
|
|
.mutateAsync(room)
|
|
.then((token) => {
|
|
if (!cancelled) setMeetUrl(token.meet_url)
|
|
})
|
|
.catch(() => {
|
|
if (!cancelled) setError("Impossible de rejoindre la salle")
|
|
})
|
|
|
|
return () => {
|
|
cancelled = true
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- load token once per room
|
|
}, [room, jwt, config?.enabled, config?.public_url])
|
|
|
|
if (configLoading || (!meetUrl && !error && config?.enabled)) {
|
|
return (
|
|
<div className="flex h-dvh flex-col">
|
|
<MeetHeader title={room} />
|
|
<div className="flex flex-1 items-center justify-center text-sm text-muted-foreground">
|
|
<Loader2 className="mr-2 size-4 animate-spin" aria-hidden />
|
|
Connexion à la salle…
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
if (error || !config?.enabled) {
|
|
return (
|
|
<div className="flex h-dvh flex-col">
|
|
<MeetHeader />
|
|
<div className="flex flex-1 flex-col items-center justify-center gap-3 px-6 text-center">
|
|
<p className="text-sm text-muted-foreground">
|
|
{error ?? "UltiMeet n'est pas activé sur cette instance."}
|
|
</p>
|
|
<Button variant="outline" className="rounded-full" onClick={() => router.push("/meet")}>
|
|
Retour au lobby
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
if (!meetUrl) return null
|
|
|
|
return (
|
|
<div className="flex h-dvh flex-col">
|
|
<MeetHeader title={room} />
|
|
<MeetRoomFrame meetUrl={meetUrl} />
|
|
</div>
|
|
)
|
|
}
|