bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/join-handler/guest-wait/component.tsx

200 lines
5.0 KiB
TypeScript
Raw Normal View History

import React, {
useCallback,
useContext,
useEffect,
useRef,
useState,
} from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { LoadingContext } from '../../common/loading-screen/loading-screen-HOC/component';
import Styled from './styles';
const REDIRECT_TIMEOUT = 15000;
export const GUEST_STATUSES = {
ALLOW: 'ALLOW',
DENY: 'DENY',
WAIT: 'WAIT',
};
const intlMessages = defineMessages({
windowTitle: {
id: 'app.guest.windowTitle',
description: 'tab title',
},
guestWait: {
id: 'app.guest.guestWait',
description: '',
},
noSessionToken: {
id: 'app.guest.noSessionToken',
description: '',
},
guestInvalid: {
id: 'app.guest.guestInvalid',
description: '',
},
allow: {
id: 'app.guest.allow',
description: '',
},
deny: {
id: 'app.guest.guestDeny',
description: '',
},
firstPosition: {
id: 'app.guest.firstPositionInWaitingQueue',
description: '',
},
position: {
id: 'app.guest.positionInWaitingQueue',
description: '',
},
calculating: {
id: 'app.guest.calculating',
description: '',
},
});
function getSearchParam(name: string) {
const params = new URLSearchParams(window.location.search);
if (params && params.has(name)) {
const param = params.get(name);
return param;
}
return null;
}
interface GuestWaitProps {
guestStatus: string | null;
guestLobbyMessage: string | null;
positionInWaitingQueue: number | null;
logoutUrl: string;
}
const GuestWait: React.FC<GuestWaitProps> = (props) => {
const {
guestLobbyMessage,
guestStatus,
logoutUrl,
positionInWaitingQueue,
} = props;
const intl = useIntl();
const [animate, setAnimate] = useState(true);
const [message, setMessage] = useState(intl.formatMessage(intlMessages.guestWait));
const [positionMessage, setPositionMessage] = useState(intl.formatMessage(intlMessages.calculating));
const lobbyMessageRef = useRef('');
const positionInWaitingQueueRef = useRef('');
const loadingContextInfo = useContext(LoadingContext);
const updateLobbyMessage = useCallback((message: string | null) => {
if (!message) {
setMessage(intl.formatMessage(intlMessages.guestWait));
return;
}
if (message !== lobbyMessageRef.current) {
lobbyMessageRef.current = message;
if (lobbyMessageRef.current.length !== 0) {
setMessage(lobbyMessageRef.current);
} else {
setMessage(intl.formatMessage(intlMessages.guestWait));
}
}
}, [intl]);
const updatePositionInWaitingQueue = useCallback((newPositionInWaitingQueue: number) => {
if (positionInWaitingQueueRef.current !== newPositionInWaitingQueue.toString()) {
positionInWaitingQueueRef.current = newPositionInWaitingQueue.toString();
if (positionInWaitingQueueRef.current === '1') {
setPositionMessage(intl.formatMessage(intlMessages.firstPosition));
} else {
setPositionMessage(intl.formatMessage(intlMessages.position) + positionInWaitingQueueRef.current);
}
}
}, [intl]);
useEffect(() => {
document.title = intl.formatMessage(intlMessages.windowTitle);
}, []);
useEffect(() => {
const sessionToken = getSearchParam('sessionToken');
if (loadingContextInfo.isLoading) {
loadingContextInfo.setLoading(false, '');
}
if (!sessionToken) {
setAnimate(false);
setMessage(intl.formatMessage(intlMessages.noSessionToken));
return;
}
if (!guestStatus) {
setAnimate(false);
setPositionMessage('');
setMessage(intl.formatMessage(intlMessages.guestInvalid));
return;
}
if (guestStatus === GUEST_STATUSES.ALLOW) {
setPositionMessage('');
updateLobbyMessage(intl.formatMessage(intlMessages.allow));
setAnimate(false);
return;
}
if (guestStatus === GUEST_STATUSES.DENY) {
setAnimate(false);
setPositionMessage('');
setMessage(intl.formatMessage(intlMessages.deny));
setTimeout(() => {
window.location.assign(logoutUrl);
}, REDIRECT_TIMEOUT);
return;
}
// WAIT
updateLobbyMessage(guestLobbyMessage || '');
if (positionInWaitingQueue) {
updatePositionInWaitingQueue(positionInWaitingQueue);
}
}, [
guestLobbyMessage,
guestStatus,
logoutUrl,
positionInWaitingQueue,
intl,
updateLobbyMessage,
updatePositionInWaitingQueue,
]);
return (
<Styled.Container>
<Styled.Content id="content">
<Styled.Heading as="h2">3/5</Styled.Heading>
<Styled.Heading id="heading">{intl.formatMessage(intlMessages.windowTitle)}</Styled.Heading>
{animate && (
<Styled.Spinner>
<Styled.Bounce1 />
<Styled.Bounce2 />
<Styled.Bounce />
</Styled.Spinner>
)}
<p aria-live="polite" data-test="guestMessage">
{message}
</p>
<Styled.Position id="positionInWaitingQueue">
<p aria-live="polite">{positionMessage}</p>
</Styled.Position>
</Styled.Content>
</Styled.Container>
);
};
export default GuestWait;