58 lines
1.5 KiB
JavaScript
58 lines
1.5 KiB
JavaScript
// 3rd party.
|
|
import classnames from 'classnames';
|
|
import React, {useEffect, useState} from 'react';
|
|
// 2nd party.
|
|
import {compose} from '@avocado/core';
|
|
import contempo from 'contempo';
|
|
|
|
const decorate = compose(
|
|
contempo(require('./connection-status.raw.scss').default),
|
|
);
|
|
|
|
const ConnectionStatusComponent = ({socket}) => {
|
|
// Start true even if not really connected to prevent initial "interrupted"
|
|
// state.
|
|
const [isConnected, setIsConnected] = useState(true);
|
|
const [dots, setDots] = useState(0);
|
|
// Juggle connected state.
|
|
useEffect(() => {
|
|
const onConnect = () => {
|
|
setIsConnected(true);
|
|
};
|
|
socket.on('connect', onConnect);
|
|
const onDisconnect = () => {
|
|
setIsConnected(false);
|
|
};
|
|
socket.on('disconnect', onDisconnect);
|
|
return () => {
|
|
socket.off('connect', onConnect);
|
|
socket.off('disconnect', onDisconnect);
|
|
};
|
|
}, []);
|
|
// Make the dots dance.
|
|
useEffect(() => {
|
|
if (isConnected) {
|
|
return;
|
|
}
|
|
const handle = setTimeout(() => {
|
|
setDots((dots + 1) % 39);
|
|
}, 50);
|
|
return () => {
|
|
clearTimeout(handle);
|
|
};
|
|
}, [dots, isConnected]);
|
|
const renderedDots = Array(dots + 1).fill('.').join('');
|
|
return <div className={classnames(
|
|
'connection-status',
|
|
!isConnected ? 'interrupted' : '',
|
|
'unselectable',
|
|
)}>
|
|
<div className="message">
|
|
<p>:[ Connection interrupted ]:</p>
|
|
<p className="dots">{renderedDots}</p>
|
|
</div>
|
|
</div>;
|
|
}
|
|
|
|
export default decorate(ConnectionStatusComponent);
|