import { BaseBoxShapeUtil, TLBaseShape } from "tldraw" import { useEffect, useState } from "react" import { WORKER_URL } from "../routes/Board" export type IVideoChatShape = TLBaseShape< "VideoChat", { w: number h: number roomUrl: string | null userName: string } > export class VideoChatShape extends BaseBoxShapeUtil { static override type = "VideoChat" indicator(_shape: IVideoChatShape) { return null } getDefaultProps(): IVideoChatShape["props"] { return { roomUrl: null, w: 640, h: 480, userName: "", } } async ensureRoomExists(shape: IVideoChatShape) { if (shape.props.roomUrl !== null) { return } const response = await fetch(`${WORKER_URL}/daily/rooms`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ properties: { enable_recording: true, max_participants: 8, }, }), }) const data = await response.json() this.editor.updateShape({ id: shape.id, type: "VideoChat", props: { ...shape.props, roomUrl: (data as any).url, }, }) } component(shape: IVideoChatShape) { const [isInRoom, setIsInRoom] = useState(false) const [error, setError] = useState("") const [isLoading, setIsLoading] = useState(false) useEffect(() => { if (isInRoom && shape.props.roomUrl) { const script = document.createElement("script") script.src = "https://www.daily.co/static/call-machine.js" document.body.appendChild(script) script.onload = () => { // @ts-ignore window.DailyIframe.createFrame({ iframeStyle: { width: "100%", height: "100%", border: "0", borderRadius: "4px", }, showLeaveButton: true, showFullscreenButton: true, }).join({ url: shape.props.roomUrl }) } } }, [isInRoom, shape.props.roomUrl]) return (
{!isInRoom ? ( ) : (
)} {error &&

{error}

}
) } }