Componentize-ing, styling tweaks, README updates, typos
This commit is contained in:
parent
770f95bd7c
commit
b235b9a211
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
## How the demo works
|
## How the demo works
|
||||||
|
|
||||||
This demo embeds [Daily Prebuilt](https://www.daily.co/prebuilt), a ready-to-use video chat interface, into a Next.js site. It makes use of [Next API routes](https://nextjs.org/docs/api-routes/introduction) to create a Daily room server-side.
|
This demo embeds [Daily Prebuilt](https://www.daily.co/prebuilt), a ready-to-use video chat interface, into a Next.js site. It makes use of [Next API routes](https://nextjs.org/docs/api-routes/introduction) to create Daily rooms server-side.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
|
|
@ -15,7 +15,8 @@ You can also paste an existing Daily room into the input. The room URL should be
|
||||||
# Running locally
|
# Running locally
|
||||||
1. Copy .env.example and change it to an .env.local with your own DAILY_API_KEY and DAILY_DOMAIN
|
1. Copy .env.example and change it to an .env.local with your own DAILY_API_KEY and DAILY_DOMAIN
|
||||||
2. `cd basic-embed`
|
2. `cd basic-embed`
|
||||||
3. yarn dev
|
3. yarn
|
||||||
|
4. yarn workspace @prebuilt-ui/basic-embed dev
|
||||||
|
|
||||||
Or...
|
Or...
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Well } from '@dailyjs/shared/components/Well';
|
||||||
|
import { Button } from '@dailyjs/shared/components/Button';
|
||||||
|
|
||||||
|
export function CreateRoom({ isConfigured, isValidRoom, setRoom, setExpiry }) {
|
||||||
|
const [isError, setIsError] = useState(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a request to create a Daily room server-side via Next API routes, then set the returned url in local state to trigger Daily iframe creation in <Call />
|
||||||
|
*/
|
||||||
|
const createRoom = async () => {
|
||||||
|
try {
|
||||||
|
const res = await fetch('/api/room', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const resJson = await res.json();
|
||||||
|
setExpiry(resJson.config?.exp);
|
||||||
|
setRoom(resJson.url);
|
||||||
|
} catch (e) {
|
||||||
|
setIsError(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{!isConfigured && (
|
||||||
|
<Well variant="error">
|
||||||
|
You must configure env variables to create rooms (see README
|
||||||
|
instructions).
|
||||||
|
</Well>
|
||||||
|
)}
|
||||||
|
{isError && (
|
||||||
|
<Well variant="error">Error creating the room. Please try again.</Well>
|
||||||
|
)}
|
||||||
|
<Button onClick={createRoom} disabled={isValidRoom}>
|
||||||
|
Create room and start
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
export const Header = () => (
|
|
||||||
<header className="header">
|
|
||||||
<div className="row">
|
|
||||||
<img src="daily-logo.svg" alt="Daily" className="logo" />
|
|
||||||
<div className="capsule">Prebuilt demo</div>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<div className="capsule">
|
|
||||||
<a href="https://docs.daily.co/docs/">API docs</a>
|
|
||||||
</div>
|
|
||||||
<span className="divider"></span>
|
|
||||||
<a href="https://github.com/daily-demos/examples/tree/main/prebuilt-ui/basic-embed">
|
|
||||||
<img src="github-logo.png" alt="Ocotocat" className="logo octocat" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<style jsx>{`
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
padding: var(--spacing-sm);
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
justify-content: space-between;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
margin-right: var(--spacing-xs);
|
|
||||||
}
|
|
||||||
|
|
||||||
.octocat {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
margin-left: var(--spacing-xxs);
|
|
||||||
}
|
|
||||||
|
|
||||||
.capsule {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: var(--spacing-xxxs);
|
|
||||||
background-color: var(--blue-dark);
|
|
||||||
border-radius: var(--radius-sm);
|
|
||||||
padding: var(--spacing-xxs) var(--spacing-xs);
|
|
||||||
box-sizing: border-box;
|
|
||||||
line-height: 1;
|
|
||||||
font-weight: var(--weight-medium);
|
|
||||||
user-select: none;
|
|
||||||
margin-right: var(--spacing-xxs);
|
|
||||||
color: var(--text-reverse);
|
|
||||||
}
|
|
||||||
|
|
||||||
.capsule a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: var(--text-reverse);
|
|
||||||
}
|
|
||||||
|
|
||||||
.divider {
|
|
||||||
background: var(--gray-light);
|
|
||||||
margin: 0 var(--spacing-xxs);
|
|
||||||
height: 32px;
|
|
||||||
width: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 750px) {
|
|
||||||
.header {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
</header>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default Header;
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
import React, { useCallback, useRef, useState } from 'react';
|
||||||
|
import { Button } from '@dailyjs/shared/components/Button';
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardBody,
|
||||||
|
CardFooter,
|
||||||
|
CardHeader,
|
||||||
|
} from '@dailyjs/shared/components/Card';
|
||||||
|
import { CreateRoom } from '../components/CreateRoom';
|
||||||
|
import { Field } from '@dailyjs/shared/components/Field';
|
||||||
|
import { TextInput } from '@dailyjs/shared/components/Input';
|
||||||
|
|
||||||
|
export default function Home({ setRoom, setExpiry, isConfigured }) {
|
||||||
|
const roomRef = useRef(null);
|
||||||
|
const [isValidRoom, setIsValidRoom] = useState(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the room is valid, setIsValidRoom and enable the join button
|
||||||
|
*/
|
||||||
|
const checkValidity = useCallback(
|
||||||
|
(e) => {
|
||||||
|
if (e?.target?.checkValidity()) {
|
||||||
|
setIsValidRoom(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[isValidRoom]
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the roomUrl in local state to trigger Daily iframe creation in <Call />
|
||||||
|
*/
|
||||||
|
const joinCall = useCallback(() => {
|
||||||
|
const roomUrl = roomRef?.current?.value;
|
||||||
|
setRoom(roomUrl);
|
||||||
|
}, [roomRef]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
Start demo with a new unique room, or paste in your own room URL
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<CreateRoom
|
||||||
|
isConfigured={isConfigured}
|
||||||
|
isValidRoom={isValidRoom}
|
||||||
|
setRoom={setRoom}
|
||||||
|
setExpiry={setExpiry}
|
||||||
|
/>
|
||||||
|
<Field label="Or enter room to join">
|
||||||
|
<TextInput
|
||||||
|
ref={roomRef}
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter room URL..."
|
||||||
|
pattern="^(https:\/\/)?[\w.-]+(\.(daily\.(co)))+[\/\/]+[\w.-]+$"
|
||||||
|
onChange={checkValidity}
|
||||||
|
/>
|
||||||
|
</Field>
|
||||||
|
<CardFooter>
|
||||||
|
<Button onClick={joinCall} disabled={!isValidRoom}>
|
||||||
|
Join room
|
||||||
|
</Button>
|
||||||
|
</CardFooter>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,254 +0,0 @@
|
||||||
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 { Header } from '../components/Header';
|
|
||||||
|
|
||||||
export default function PrebuiltCall(props) {
|
|
||||||
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 (
|
|
||||||
<Card>
|
|
||||||
<CardHeader>
|
|
||||||
Start demo with a new unique room, or paste in your own room URL.
|
|
||||||
</CardHeader>
|
|
||||||
<CardBody>
|
|
||||||
{!props.configured && (
|
|
||||||
<Well variant="error">
|
|
||||||
You must configure env variables to create rooms (see README
|
|
||||||
instructions).
|
|
||||||
</Well>
|
|
||||||
)}
|
|
||||||
{isError && (
|
|
||||||
<Well variant="error">
|
|
||||||
Error creating the room. Please try again.
|
|
||||||
</Well>
|
|
||||||
)}
|
|
||||||
<Button onClick={() => createRoom()} disabled={roomValidity}>
|
|
||||||
Create room and start
|
|
||||||
</Button>
|
|
||||||
<Field label="Or enter room to join" className="roomField">
|
|
||||||
<TextInput
|
|
||||||
ref={roomURLRef}
|
|
||||||
type="text"
|
|
||||||
placeholder="Enter room URL..."
|
|
||||||
pattern="^(https:\/\/)?[\w.-]+(\.(daily\.(co)))+[\/\/]+[\w.-]+$"
|
|
||||||
onChange={handleRoomInput}
|
|
||||||
/>
|
|
||||||
</Field>
|
|
||||||
<CardFooter>
|
|
||||||
<Button
|
|
||||||
onClick={() => submitJoinRoom()}
|
|
||||||
disabled={!roomValidity}
|
|
||||||
>
|
|
||||||
Join room
|
|
||||||
</Button>
|
|
||||||
</CardFooter>
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
case 'call':
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div ref={iframeRef} className="call" />
|
|
||||||
<Card>
|
|
||||||
<CardHeader>Copy and share the URL to invite others.</CardHeader>
|
|
||||||
<CardBody>
|
|
||||||
<label for="copy-url"></label>
|
|
||||||
<TextInput
|
|
||||||
type="text"
|
|
||||||
class="url-input"
|
|
||||||
id="copy-url"
|
|
||||||
placeholder="Copy this room URL"
|
|
||||||
value={roomURL}
|
|
||||||
pattern="^(https:\/\/)?[\w.-]+(\.(daily\.(co)))+[\/\/]+[\w.-]+$"
|
|
||||||
/>
|
|
||||||
<Button onClick={handleCopyClick}>
|
|
||||||
{linkCopied ? 'Copied!' : `Copy room URL`}
|
|
||||||
</Button>
|
|
||||||
{exp && (
|
|
||||||
<h3>
|
|
||||||
This room expires in:{' '}
|
|
||||||
<span className="countdown">{secs}</span>
|
|
||||||
</h3>
|
|
||||||
)}
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [demoState, roomValidity, roomURLRef, exp, secs]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="container">
|
|
||||||
<Header />
|
|
||||||
{content}
|
|
||||||
<style jsx>{`
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-around;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container :global(.call) {
|
|
||||||
height: 70%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container :global(.countdown) {
|
|
||||||
padding: 4px 0;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: var(--weight-medium);
|
|
||||||
border-radius: 0 0 0 var(--radius-sm);
|
|
||||||
color: var(--blue-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.field) {
|
|
||||||
margin-top: var(--spacing-sm);
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.card) {
|
|
||||||
margin: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 750px) {
|
|
||||||
.container {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -3,8 +3,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default async function handler(req, res) {
|
export default async function handler(req, res) {
|
||||||
const { roomExp } = req.body.properties;
|
|
||||||
|
|
||||||
if (req.method === 'POST') {
|
if (req.method === 'POST') {
|
||||||
const options = {
|
const options = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
@ -19,7 +17,7 @@ export default async function handler(req, res) {
|
||||||
enable_network_ui: true,
|
enable_network_ui: true,
|
||||||
enable_screenshare: true,
|
enable_screenshare: true,
|
||||||
enable_chat: true,
|
enable_chat: true,
|
||||||
exp: roomExp,
|
exp: Math.round(Date.now() / 1000) + 5 * 60,
|
||||||
eject_at_room_exp: true,
|
eject_at_room_exp: true,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,64 @@
|
||||||
import PrebuiltCall from '../components/PrebuiltCall';
|
// import PrebuiltCall from '../components/PrebuiltCall';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import Call from '../components/Call';
|
||||||
|
import Home from '../components/Home';
|
||||||
|
import Header from '@dailyjs/shared/components/Header';
|
||||||
import getDemoProps from '@dailyjs/shared/lib/demoProps';
|
import getDemoProps from '@dailyjs/shared/lib/demoProps';
|
||||||
|
|
||||||
export default function Index({ isConfigured = false }) {
|
export default function Index({ isConfigured = false }) {
|
||||||
|
const [room, setRoom] = useState(null);
|
||||||
|
const [expiry, setExpiry] = useState(null);
|
||||||
|
const [callFrame, setCallFrame] = useState(null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="index-container">
|
||||||
<PrebuiltCall configured={isConfigured} />
|
<Header
|
||||||
|
demoTitle={'Daily Prebuilt demo'}
|
||||||
|
repoLink={
|
||||||
|
'https://github.com/daily-demos/examples/tree/main/prebuilt-ui/basic-embed'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<main>
|
||||||
|
{room ? (
|
||||||
|
<Call
|
||||||
|
room={room}
|
||||||
|
expiry={expiry}
|
||||||
|
setRoom={setRoom}
|
||||||
|
setCallFrame={setCallFrame}
|
||||||
|
callFrame={callFrame}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Home
|
||||||
|
setRoom={setRoom}
|
||||||
|
setExpiry={setExpiry}
|
||||||
|
isConfigured={isConfigured}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</main>
|
||||||
<style jsx>{`
|
<style jsx>{`
|
||||||
display: flex;
|
.index-container {
|
||||||
align-items: center;
|
display: flex;
|
||||||
justify-content: center;
|
flex-direction: column;
|
||||||
height: 100vh;
|
min-height: 100vh;
|
||||||
|
overflow: auto;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 2rem;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.field) {
|
||||||
|
margin-top: var(--spacing-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.card) {
|
||||||
|
margin: 8px;
|
||||||
|
}
|
||||||
`}</style>
|
`}</style>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue