daily-examples/prebuilt-ui/basic-embed/components/Call.js

120 lines
2.9 KiB
JavaScript

import DailyIframe from '@daily-co/daily-js';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { writeText } from 'clipboard-polyfill';
import { Button } from '@dailyjs/shared/components/Button';
import {
Card,
CardBody,
CardHeader,
CardFooter,
} from '@dailyjs/shared/components/Card';
import { ExpiryTimer } from '@dailyjs/shared/components/ExpiryTimer';
import { TextInput } from '@dailyjs/shared/components/Input';
const CALL_OPTIONS = {
showLeaveButton: true,
iframeStyle: {
height: '100%',
width: '100%',
aspectRatio: 16 / 9,
minwidth: '400px',
maxWidth: '920px',
border: '0',
borderRadius: '12px',
},
};
export default function Call({
room,
setRoom,
callFrame,
setCallFrame,
expiry,
}) {
const callRef = useRef(null);
const [isLinkCopied, setIsLinkCopied] = useState(false);
const handleCopyClick = useCallback(() => {
writeText(room);
setIsLinkCopied(true);
setTimeout(() => setIsLinkCopied(false), 5000);
}, [room, isLinkCopied]);
const createAndJoinCall = useCallback(() => {
const newCallFrame = DailyIframe.createFrame(
callRef?.current,
CALL_OPTIONS
);
setCallFrame(newCallFrame);
newCallFrame.join({ url: room });
const leaveCall = () => {
setRoom(null);
setCallFrame(null);
callFrame.destroy();
};
newCallFrame.on('left-meeting', leaveCall);
});
/**
* Initiate Daily iframe creation on component render if it doesn't already exist
*/
useEffect(() => {
if (callFrame) return;
createAndJoinCall();
}, [callFrame, createAndJoinCall]);
return (
<div className="call-container">
{/* Daily iframe container */}
<div ref={callRef} className="call" />
<Card>
<CardHeader>Copy and share the URL to invite others</CardHeader>
<CardBody>
<label htmlFor="copy-url"></label>
<TextInput
type="text"
id="copy-url"
placeholder="Copy this room URL"
value={room}
pattern="^(https:\/\/)?[\w.-]+(\.(daily\.(co)))+[\/\/]+[\w.-]+$"
/>
<Button onClick={handleCopyClick}>
{isLinkCopied ? 'Copied!' : `Copy room URL`}
</Button>
</CardBody>
<CardFooter>{expiry && <ExpiryTimer expiry={expiry} />}</CardFooter>
</Card>
<style jsx>{`
.call-container {
display: flex;
align-items: center;
gap: var(--spacing-md);
}
.call-container :global(.call) {
width: 100%;
}
.call-container :global(.button) {
margin-top: var(--spacing-md);
}
.call-container :global(.card) {
max-width: 300px;
max-height: 300px;
}
@media only screen and (max-width: 750px) {
.call-container {
flex-direction: column;
}
}
`}</style>
</div>
);
}