added recording and streaming
This commit is contained in:
parent
7923cc7856
commit
7723d0c86c
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
|
import HeaderCapsule from '@dailyjs/shared/components/HeaderCapsule';
|
||||||
import { useParticipants } from '@dailyjs/shared/contexts/ParticipantsProvider';
|
import { useParticipants } from '@dailyjs/shared/contexts/ParticipantsProvider';
|
||||||
import { useUIState } from '@dailyjs/shared/contexts/UIStateProvider';
|
import { useUIState } from '@dailyjs/shared/contexts/UIStateProvider';
|
||||||
|
|
||||||
|
|
@ -10,17 +11,18 @@ export const Header = () => {
|
||||||
() => (
|
() => (
|
||||||
<header className="room-header">
|
<header className="room-header">
|
||||||
<img src="assets/daily-logo.svg" alt="Daily" className="logo" />
|
<img src="assets/daily-logo.svg" alt="Daily" className="logo" />
|
||||||
<div className="capsule">Basic call demo</div>
|
|
||||||
<div className="capsule">
|
<HeaderCapsule>Basic call demo</HeaderCapsule>
|
||||||
|
<HeaderCapsule>
|
||||||
{`${participantCount} ${
|
{`${participantCount} ${
|
||||||
participantCount === 1 ? 'participant' : 'participants'
|
participantCount === 1 ? 'participant' : 'participants'
|
||||||
}`}
|
}`}
|
||||||
</div>
|
</HeaderCapsule>
|
||||||
{customCapsule && (
|
{customCapsule && (
|
||||||
<div className={`capsule ${customCapsule.variant}`}>
|
<HeaderCapsule variant={customCapsule.variant}>
|
||||||
{customCapsule.variant === 'recording' && <span />}
|
{customCapsule.variant === 'recording' && <span />}
|
||||||
{customCapsule.label}
|
{customCapsule.label}
|
||||||
</div>
|
</HeaderCapsule>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<style jsx>{`
|
<style jsx>{`
|
||||||
|
|
@ -37,44 +39,6 @@ export const Header = () => {
|
||||||
.logo {
|
.logo {
|
||||||
margin-right: var(--spacing-xs);
|
margin-right: var(--spacing-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.capsule.recording {
|
|
||||||
background: var(--secondary-default);
|
|
||||||
}
|
|
||||||
|
|
||||||
.capsule.recording span {
|
|
||||||
display: block;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
background: white;
|
|
||||||
border-radius: 12px;
|
|
||||||
animation: capsulePulse 2s infinite linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes capsulePulse {
|
|
||||||
0% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`}</style>
|
`}</style>
|
||||||
</header>
|
</header>
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
|
|
||||||
import { VideoGrid } from '../VideoGrid';
|
import { VideoGrid } from '../VideoGrid';
|
||||||
import { Header } from './Header';
|
import { Header } from './Header';
|
||||||
import RoomContainer from './RoomContainer';
|
import { RoomContainer } from './RoomContainer';
|
||||||
|
|
||||||
export const Room = () => (
|
export const Room = () => (
|
||||||
<RoomContainer>
|
<RoomContainer>
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,7 @@ import PropTypes from 'prop-types';
|
||||||
import WaitingRoom from '../WaitingRoom';
|
import WaitingRoom from '../WaitingRoom';
|
||||||
|
|
||||||
export const RoomContainer = ({ children }) => {
|
export const RoomContainer = ({ children }) => {
|
||||||
const { localParticipant } = useParticipants();
|
const { isOwner } = useParticipants();
|
||||||
const isOwner = !!localParticipant?.isOwner;
|
|
||||||
|
|
||||||
useJoinSound();
|
useJoinSound();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ export default async function handler(req, res) {
|
||||||
exp: Math.round(Date.now() / 1000) + (expiryMinutes || 5) * 60, // expire in x minutes
|
exp: Math.round(Date.now() / 1000) + (expiryMinutes || 5) * 60, // expire in x minutes
|
||||||
eject_at_room_exp: true,
|
eject_at_room_exp: true,
|
||||||
enable_knocking: privacy !== 'public',
|
enable_knocking: privacy !== 'public',
|
||||||
|
enable_recording: 'local',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,8 @@ export const FlyingEmojisOverlay = () => {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
left: 24px;
|
left: 0px;
|
||||||
right: 24px;
|
right: 0px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import React from 'react';
|
||||||
|
|
||||||
import App from '@dailyjs/basic-call/components/App';
|
import App from '@dailyjs/basic-call/components/App';
|
||||||
import FlyingEmojiOverlay from '@dailyjs/flying-emojis/components/FlyingEmojis';
|
import FlyingEmojiOverlay from '@dailyjs/flying-emojis/components/FlyingEmojis';
|
||||||
|
import { LiveStreamingProvider } from '@dailyjs/live-streaming/contexts/LiveStreamingProvider';
|
||||||
|
import { RecordingProvider } from '@dailyjs/recording/contexts/RecordingProvider';
|
||||||
import { ChatProvider } from '@dailyjs/text-chat/contexts/ChatProvider';
|
import { ChatProvider } from '@dailyjs/text-chat/contexts/ChatProvider';
|
||||||
import Room from '../Room';
|
import Room from '../Room';
|
||||||
|
|
||||||
|
|
@ -10,16 +12,18 @@ import Room from '../Room';
|
||||||
* as the layout logic changes considerably for the basic demo
|
* as the layout logic changes considerably for the basic demo
|
||||||
*/
|
*/
|
||||||
export const LiveFitnessApp = () => (
|
export const LiveFitnessApp = () => (
|
||||||
<>
|
<ChatProvider>
|
||||||
<ChatProvider>
|
<LiveStreamingProvider>
|
||||||
<FlyingEmojiOverlay />
|
<RecordingProvider>
|
||||||
<App
|
<FlyingEmojiOverlay />
|
||||||
customComponentForState={{
|
<App
|
||||||
room: () => <Room />,
|
customComponentForState={{
|
||||||
}}
|
room: () => <Room />,
|
||||||
/>
|
}}
|
||||||
</ChatProvider>
|
/>
|
||||||
</>
|
</RecordingProvider>
|
||||||
|
</LiveStreamingProvider>
|
||||||
|
</ChatProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default LiveFitnessApp;
|
export default LiveFitnessApp;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import Button from '@dailyjs/shared/components/Button';
|
||||||
|
import HeaderCapsule from '@dailyjs/shared/components/HeaderCapsule';
|
||||||
|
import { useParticipants } from '@dailyjs/shared/contexts/ParticipantsProvider';
|
||||||
|
|
||||||
|
export const Header = () => {
|
||||||
|
const { participantCount } = useParticipants();
|
||||||
|
|
||||||
|
return useMemo(
|
||||||
|
() => (
|
||||||
|
<header className="room-header">
|
||||||
|
<img src="assets/daily-logo.svg" alt="Daily" className="logo" />
|
||||||
|
|
||||||
|
<HeaderCapsule variant="button">
|
||||||
|
{`${participantCount} ${
|
||||||
|
participantCount === 1 ? 'participant' : 'participants'
|
||||||
|
}`}
|
||||||
|
<Button size="tiny" variant="outline-dark">
|
||||||
|
Invite
|
||||||
|
</Button>
|
||||||
|
</HeaderCapsule>
|
||||||
|
|
||||||
|
<style jsx>{`
|
||||||
|
.room-header {
|
||||||
|
display: flex;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
column-gap: var(--spacing-xxs);
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: var(--spacing-sm);
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
margin-right: var(--spacing-xs);
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</header>
|
||||||
|
),
|
||||||
|
[participantCount]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Header;
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import RoomContainer from '@dailyjs/basic-call/components/Room/RoomContainer';
|
import { RoomContainer } from '@dailyjs/basic-call/components/Room/RoomContainer';
|
||||||
|
import { Header } from './Header';
|
||||||
|
|
||||||
export const Room = () => (
|
export const Room = () => (
|
||||||
<RoomContainer>
|
<RoomContainer>
|
||||||
|
<Header />
|
||||||
<main>Hello</main>
|
<main>Hello</main>
|
||||||
</RoomContainer>
|
</RoomContainer>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,30 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import FlyingEmojiTrayButton from '@dailyjs/flying-emojis/components/Tray';
|
import FlyingEmojiTrayButton from '@dailyjs/flying-emojis/components/Tray';
|
||||||
|
import LiveStreamingButton from '@dailyjs/live-streaming/components/Tray';
|
||||||
|
import RecordingButton from '@dailyjs/recording/components/Tray';
|
||||||
|
import { useParticipants } from '@dailyjs/shared/contexts/ParticipantsProvider';
|
||||||
import ChatTrayButton from '@dailyjs/text-chat/components/Tray';
|
import ChatTrayButton from '@dailyjs/text-chat/components/Tray';
|
||||||
|
|
||||||
export const Tray = () => (
|
export const Tray = () => {
|
||||||
<>
|
const { isOwner } = useParticipants();
|
||||||
<FlyingEmojiTrayButton />
|
|
||||||
<ChatTrayButton />
|
if (isOwner) {
|
||||||
</>
|
return (
|
||||||
);
|
<>
|
||||||
|
<FlyingEmojiTrayButton />
|
||||||
|
<ChatTrayButton />
|
||||||
|
<LiveStreamingButton />
|
||||||
|
<RecordingButton />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FlyingEmojiTrayButton />
|
||||||
|
<ChatTrayButton />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default Tray;
|
export default Tray;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ const withTM = require('next-transpile-modules')([
|
||||||
'@dailyjs/basic-call',
|
'@dailyjs/basic-call',
|
||||||
'@dailyjs/flying-emojis',
|
'@dailyjs/flying-emojis',
|
||||||
'@dailyjs/text-chat',
|
'@dailyjs/text-chat',
|
||||||
|
'@dailyjs/live-streaming',
|
||||||
|
'@dailyjs/recording',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const packageJson = require('./package.json');
|
const packageJson = require('./package.json');
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
"@dailyjs/basic-call": "*",
|
"@dailyjs/basic-call": "*",
|
||||||
"@dailyjs/flying-emojis": "*",
|
"@dailyjs/flying-emojis": "*",
|
||||||
"@dailyjs/text-chat": "*",
|
"@dailyjs/text-chat": "*",
|
||||||
|
"@dailyjs/live-streaming": "*",
|
||||||
|
"@dailyjs/recording": "*",
|
||||||
"next": "^11.0.0",
|
"next": "^11.0.0",
|
||||||
"pluralize": "^8.0.0",
|
"pluralize": "^8.0.0",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ export default function Room({
|
||||||
domain,
|
domain,
|
||||||
customTrayComponent,
|
customTrayComponent,
|
||||||
asides,
|
asides,
|
||||||
|
modals,
|
||||||
}) {
|
}) {
|
||||||
const [token, setToken] = useState();
|
const [token, setToken] = useState();
|
||||||
const [tokenError, setTokenError] = useState();
|
const [tokenError, setTokenError] = useState();
|
||||||
|
|
@ -78,7 +79,11 @@ export default function Room({
|
||||||
* Main call UI
|
* Main call UI
|
||||||
*/
|
*/
|
||||||
return (
|
return (
|
||||||
<UIStateProvider customTrayComponent={customTrayComponent} asides={asides}>
|
<UIStateProvider
|
||||||
|
customTrayComponent={customTrayComponent}
|
||||||
|
asides={asides}
|
||||||
|
modals={modals}
|
||||||
|
>
|
||||||
<CallProvider domain={domain} room={room} token={token}>
|
<CallProvider domain={domain} room={room} token={token}>
|
||||||
<ParticipantsProvider>
|
<ParticipantsProvider>
|
||||||
<TracksProvider>
|
<TracksProvider>
|
||||||
|
|
@ -100,6 +105,7 @@ Room.propTypes = {
|
||||||
instructor: PropTypes.bool,
|
instructor: PropTypes.bool,
|
||||||
customTrayComponent: PropTypes.node,
|
customTrayComponent: PropTypes.node,
|
||||||
asides: PropTypes.arrayOf(PropTypes.func),
|
asides: PropTypes.arrayOf(PropTypes.func),
|
||||||
|
modals: PropTypes.arrayOf(PropTypes.func),
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function getServerSideProps(context) {
|
export async function getServerSideProps(context) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import App from '@dailyjs/basic-call/pages/_app';
|
import App from '@dailyjs/basic-call/pages/_app';
|
||||||
|
import LiveStreamingModal from '@dailyjs/live-streaming/components/LiveStreamingModal';
|
||||||
|
import RecordingModal from '@dailyjs/recording/components/RecordingModal';
|
||||||
import ChatAside from '@dailyjs/text-chat/components/ChatAside';
|
import ChatAside from '@dailyjs/text-chat/components/ChatAside';
|
||||||
import Tray from '../components/Tray';
|
import Tray from '../components/Tray';
|
||||||
|
|
||||||
App.customTrayComponent = <Tray />;
|
App.customTrayComponent = <Tray />;
|
||||||
App.asides = [ChatAside];
|
App.asides = [ChatAside];
|
||||||
|
App.modals = [LiveStreamingModal, RecordingModal];
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
// Note: I am here because next-transpile-modules requires a mainfile
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
// Note: I am here because next-transpile-modules requires a mainfile
|
||||||
|
|
@ -195,7 +195,7 @@ export const Button = forwardRef(
|
||||||
}
|
}
|
||||||
|
|
||||||
.button.tiny {
|
.button.tiny {
|
||||||
height: 32px;
|
height: 28px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
border-radius: var(--radius-xs);
|
border-radius: var(--radius-xs);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|
@ -320,6 +320,22 @@ export const Button = forwardRef(
|
||||||
box-shadow: 0 0 0px 3px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 0 0px 3px rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button.outline-dark {
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--blue-light);
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.outline-dark:hover,
|
||||||
|
.button.outline-dark:focus,
|
||||||
|
.button.outline-dark:active {
|
||||||
|
border: 1px solid var(--primary-default);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.button.outline-dark:focus {
|
||||||
|
box-shadow: 0 0 0px 3px ${hexa(theme.primary.default, 0.35)};
|
||||||
|
}
|
||||||
|
|
||||||
.button.muted {
|
.button.muted {
|
||||||
color: var(--red-default);
|
color: var(--red-default);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,19 @@ export const ExpiryTimer = ({ expiry }) => {
|
||||||
}
|
}
|
||||||
const i = setInterval(() => {
|
const i = setInterval(() => {
|
||||||
const timeLeft = Math.round((expiry - Date.now()) / 1000);
|
const timeLeft = Math.round((expiry - Date.now()) / 1000);
|
||||||
|
if (timeLeft < 0) {
|
||||||
|
return setSecs(null);
|
||||||
|
}
|
||||||
setSecs(`${Math.floor(timeLeft / 60)}:${`0${timeLeft % 60}`.slice(-2)}`);
|
setSecs(`${Math.floor(timeLeft / 60)}:${`0${timeLeft % 60}`.slice(-2)}`);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
return () => clearInterval(i);
|
return () => clearInterval(i);
|
||||||
}, [expiry]);
|
}, [expiry]);
|
||||||
|
|
||||||
|
if (!secs) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="countdown">
|
<div className="countdown">
|
||||||
{secs}
|
{secs}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
export const HeaderCapsule = ({ children, variant }) => {
|
||||||
|
const cx = classNames('capsule', variant);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cx}>
|
||||||
|
{children}
|
||||||
|
<style jsx>{`
|
||||||
|
.capsule {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--spacing-xxs);
|
||||||
|
background-color: var(--blue-dark);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
padding: var(--spacing-xxxxs) var(--spacing-xxs);
|
||||||
|
min-height: 40px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 1;
|
||||||
|
font-weight: var(--weight-medium);
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.capsule.button {
|
||||||
|
padding-right: var(--spacing-xxxxs);
|
||||||
|
}
|
||||||
|
|
||||||
|
.capsule.recording {
|
||||||
|
background: var(--secondary-default);
|
||||||
|
}
|
||||||
|
|
||||||
|
.capsule.recording span {
|
||||||
|
display: block;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
animation: capsulePulse 2s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes capsulePulse {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
HeaderCapsule.propTypes = {
|
||||||
|
children: PropTypes.node,
|
||||||
|
variant: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default HeaderCapsule;
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export { HeaderCapsule as default } from './HeaderCapsule';
|
||||||
|
|
@ -75,7 +75,10 @@ export const ParticipantsProvider = ({ children }) => {
|
||||||
[allParticipants]
|
[allParticipants]
|
||||||
);
|
);
|
||||||
|
|
||||||
const isOwner = useMemo(() => localParticipant?.isOwner, [localParticipant]);
|
const isOwner = useMemo(
|
||||||
|
() => !!localParticipant?.isOwner,
|
||||||
|
[localParticipant]
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The participant who should be rendered prominently right now
|
* The participant who should be rendered prominently right now
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ export const UIStateProvider = ({
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const closeModal = useCallback((modalName) => {
|
const closeModal = useCallback((modalName) => {
|
||||||
|
if (!modalName) {
|
||||||
|
setActiveModals({});
|
||||||
|
}
|
||||||
|
|
||||||
setActiveModals((prevState) => ({
|
setActiveModals((prevState) => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
[modalName]: false,
|
[modalName]: false,
|
||||||
|
|
@ -34,6 +38,10 @@ export const UIStateProvider = ({
|
||||||
setShowAside((p) => (p === newAside ? null : newAside));
|
setShowAside((p) => (p === newAside ? null : newAside));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const closeAside = useCallback(() => {
|
||||||
|
setShowAside(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UIStateContext.Provider
|
<UIStateContext.Provider
|
||||||
value={{
|
value={{
|
||||||
|
|
@ -42,6 +50,7 @@ export const UIStateProvider = ({
|
||||||
customTrayComponent,
|
customTrayComponent,
|
||||||
openModal,
|
openModal,
|
||||||
closeModal,
|
closeModal,
|
||||||
|
closeAside,
|
||||||
currentModals,
|
currentModals,
|
||||||
toggleAside,
|
toggleAside,
|
||||||
showAside,
|
showAside,
|
||||||
|
|
@ -57,7 +66,6 @@ export const UIStateProvider = ({
|
||||||
|
|
||||||
UIStateProvider.propTypes = {
|
UIStateProvider.propTypes = {
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
demoMode: PropTypes.bool,
|
|
||||||
asides: PropTypes.arrayOf(PropTypes.func),
|
asides: PropTypes.arrayOf(PropTypes.func),
|
||||||
modals: PropTypes.arrayOf(PropTypes.func),
|
modals: PropTypes.arrayOf(PropTypes.func),
|
||||||
customTrayComponent: PropTypes.node,
|
customTrayComponent: PropTypes.node,
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import {
|
||||||
} from '@dailyjs/shared/contexts/useCallMachine';
|
} from '@dailyjs/shared/contexts/useCallMachine';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import HairCheck from '../components/HairCheck';
|
import HairCheck from '../components/HairCheck';
|
||||||
|
import { useUIState } from '../contexts/UIStateProvider';
|
||||||
|
|
||||||
export const useCallUI = ({
|
export const useCallUI = ({
|
||||||
state,
|
state,
|
||||||
|
|
@ -25,6 +26,7 @@ export const useCallUI = ({
|
||||||
notFoundRedirect = 'not-found',
|
notFoundRedirect = 'not-found',
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const { closeAside, closeModal } = useUIState();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(`%c🔀 App state changed: ${state}`, `color: gray;`);
|
console.log(`%c🔀 App state changed: ${state}`, `color: gray;`);
|
||||||
|
|
@ -36,6 +38,10 @@ export const useCallUI = ({
|
||||||
return <Loader />;
|
return <Loader />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure we hide any active asides or modals when the state changes
|
||||||
|
closeAside();
|
||||||
|
closeModal();
|
||||||
|
|
||||||
// Update the UI based on the state of our call
|
// Update the UI based on the state of our call
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case CALL_STATE_NOT_FOUND:
|
case CALL_STATE_NOT_FOUND:
|
||||||
|
|
@ -80,7 +86,7 @@ export const useCallUI = ({
|
||||||
return callEnded ? (
|
return callEnded ? (
|
||||||
callEnded()
|
callEnded()
|
||||||
) : (
|
) : (
|
||||||
<MessageCard onBack={() => window.location.reload()}>
|
<MessageCard>
|
||||||
You have left the call. We hope you had fun!
|
You have left the call. We hope you had fun!
|
||||||
</MessageCard>
|
</MessageCard>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue