daily-examples/dailyjs/basic-call/pages/index.js

158 lines
4.4 KiB
JavaScript

import React, { useState, useCallback } from 'react';
import { CallProvider } from '@dailyjs/shared/contexts/CallProvider';
import { MediaDeviceProvider } from '@dailyjs/shared/contexts/MediaDeviceProvider';
import { ParticipantsProvider } from '@dailyjs/shared/contexts/ParticipantsProvider';
import { TracksProvider } from '@dailyjs/shared/contexts/TracksProvider';
import { UIStateProvider } from '@dailyjs/shared/contexts/UIStateProvider';
import { WaitingRoomProvider } from '@dailyjs/shared/contexts/WaitingRoomProvider';
import getDemoProps from '@dailyjs/shared/lib/demoProps';
import PropTypes from 'prop-types';
import App from '../components/App';
import { CreatingRoom } from '../components/CreatingRoom';
import { Intro, NotConfigured } from '../components/Intro';
/**
* Index page
* ---
* - Checks configuration variables are set in local env
* - Optionally obtain a meeting token from Daily REST API (./pages/api/token)
* - Set call owner status
* - Finally, renders the main application loop
*/
export default function Index({
domain,
isConfigured = false,
predefinedRoom = '',
forceFetchToken = false,
forceOwner = false,
subscribeToTracksAutomatically = true,
demoMode = false,
asides,
modals,
customTrayComponent,
customAppComponent,
}) {
const [roomName, setRoomName] = useState(predefinedRoom);
const [fetchingToken, setFetchingToken] = useState(false);
const [token, setToken] = useState();
const [tokenError, setTokenError] = useState();
const getMeetingToken = useCallback(async (room, isOwner = false) => {
if (!room) {
return false;
}
setFetchingToken(true);
// Fetch token from serverside method (provided by Next)
const res = await fetch('/api/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ roomName: room, isOwner }),
});
const resJson = await res.json();
if (!resJson?.token) {
setTokenError(resJson?.error || true);
setFetchingToken(false);
return false;
}
console.log(`🪙 Token received`);
setFetchingToken(false);
setToken(resJson.token);
// Setting room name will change ready state
setRoomName(room);
return true;
}, []);
const isReady = !!(isConfigured && roomName);
if (!isReady) {
return (
<main>
{(() => {
if (!isConfigured) return <NotConfigured />;
if (demoMode) return <CreatingRoom onCreated={getMeetingToken} />;
return (
<Intro
forceFetchToken={forceFetchToken}
forceOwner={forceOwner}
title={process.env.PROJECT_TITLE}
room={roomName}
error={tokenError}
fetching={fetchingToken}
domain={domain}
onJoin={(room, isOwner, fetchToken) =>
fetchToken ? getMeetingToken(room, isOwner) : setRoomName(room)
}
/>
);
})()}
<style jsx>{`
height: 100vh;
display: grid;
grid-template-columns: 640px;
align-items: center;
justify-content: center;
`}</style>
</main>
);
}
/**
* Main call UI
*/
return (
<UIStateProvider
asides={asides}
modals={modals}
customTrayComponent={customTrayComponent}
>
<CallProvider
domain={domain}
room={roomName}
token={token}
subscribeToTracksAutomatically={subscribeToTracksAutomatically}
>
<ParticipantsProvider>
<TracksProvider>
<MediaDeviceProvider>
<WaitingRoomProvider>
{customAppComponent || <App />}
</WaitingRoomProvider>
</MediaDeviceProvider>
</TracksProvider>
</ParticipantsProvider>
</CallProvider>
</UIStateProvider>
);
}
Index.propTypes = {
isConfigured: PropTypes.bool.isRequired,
predefinedRoom: PropTypes.string,
domain: PropTypes.string,
asides: PropTypes.arrayOf(PropTypes.func),
modals: PropTypes.arrayOf(PropTypes.func),
customTrayComponent: PropTypes.node,
customAppComponent: PropTypes.node,
forceFetchToken: PropTypes.bool,
forceOwner: PropTypes.bool,
subscribeToTracksAutomatically: PropTypes.bool,
demoMode: PropTypes.bool,
};
export async function getStaticProps() {
const defaultProps = getDemoProps();
return {
props: defaultProps,
};
}