5d3178f15d
* refactor(guest-wait): turn guest wait page into a React component * Fix rendering when the meeting is ended * refactor(guest-wait): Backend portion for migration of `guest-wait` to Graphql * Add message timeout * Remove static guest wait page --------- Co-authored-by: Gustavo Trott <gustavo@trott.com.br>
200 lines
5.0 KiB
TypeScript
200 lines
5.0 KiB
TypeScript
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;
|