import DailyIframe from '@daily-co/daily-js'; import React, { useCallback, useEffect, useMemo, useRef, useState, } from 'react'; import { writeText } from 'clipboard-polyfill'; import { Button } from '@dailyjs/shared/components/Button'; import { Card, CardBody, CardFooter, CardHeader, } from '@dailyjs/shared/components/Card'; import Field from '@dailyjs/shared/components/Field'; import { TextInput } from '@dailyjs/shared/components/Input'; import { Well } from '@dailyjs/shared/components/Well'; import getDemoProps from '@dailyjs/shared/lib/demoProps'; import { Header } from '../components/Header'; export default function PrebuiltCall() { const [demoState, setDemoState] = useState('home'); const [isError, setIsError] = useState(false); const [roomURL, setRoomURL] = useState(''); const [exp, setExp] = useState(); const [secs, setSecs] = useState(); const [roomValidity, setRoomValidity] = useState(false); const roomURLRef = useRef(null); const iframeRef = useRef(null); const callFrame = useRef(null); const [linkCopied, setLinkCopied] = useState(false); // Updates the time left that displays in the UI useEffect(() => { if (!exp) { return false; } const i = setInterval(() => { const timeLeft = Math.floor((new Date(exp * 1000) - Date.now()) / 1000); setSecs(`${Math.floor(timeLeft / 60)}:${`0${timeLeft % 60}`.slice(-2)}`); }, 1000); return () => clearInterval(i); }, [exp]); // Listens for a "call" demo state, and creates then joins a callFrame as soon as that happens useEffect(() => { if (!iframeRef?.current || demoState !== 'call') { return; } try { callFrame.current = DailyIframe.createFrame(iframeRef.current, { showLeaveButton: true, iframeStyle: { height: '100%', width: '100%', aspectRatio: 16 / 9, minwidth: '400px', maxWidth: '920px', border: '0', borderRadius: '12px', }, }); callFrame.current.join({ url: roomURL, }); } catch (e) { setDemoState('home'); setIsError(true); return; } const handleLeftMeeting = () => { setDemoState('home'); setRoomValidity(false); callFrame.current.destroy(); }; callFrame.current.on('left-meeting', handleLeftMeeting); }, [demoState, iframeRef, roomURL]); const createRoom = useCallback( async (e) => { if (!roomURLRef?.current.value) { const roomExp = Math.round(Date.now() / 1000) + 60 * 5; try { const res = await fetch('/api/room', { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ properties: { roomExp, }, }), }); const roomJson = await res.json(); const { url } = roomJson; setRoomURL(url); setDemoState('call'); setExp(roomExp); setIsError(false); } catch (e) { setDemoState('home'); setIsError(true); } } }, [roomURL, exp] ); // Updates state if a room is provided const handleRoomInput = useCallback( (e) => { setRoomURL(e?.target?.value); if (e?.target?.checkValidity()) { setRoomValidity(true); console.log(roomValidity); } }, [roomValidity] ); const submitJoinRoom = useCallback(() => { setDemoState('call'); }); const handleCopyClick = useCallback(() => { console.log('click'); writeText(roomURL); setLinkCopied(true); setTimeout(() => setLinkCopied(false), 5000); }, [roomURL, linkCopied]); const content = useMemo(() => { switch (demoState) { case 'home': return ( Start demo with a new unique room, or paste in your own room URL. {isError && ( Error creating the room. Please try again. )} ); case 'call': return ( <>
Copy and share the URL to invite others. {exp && (

This room expires in:{' '} {secs}

)}
); } }, [demoState, roomValidity, roomURLRef, exp, secs]); return (
{content}
); } export async function getStaticProps() { const defaultProps = getDemoProps(); return { props: defaultProps, }; }