import { BaseBoxShapeUtil, TLBaseShape } from "tldraw"; import { useEffect, useState } from "react"; import { WORKER_URL } from '../components/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}

}
); } }