humus-old/client/ui/connection-status.js
2019-04-20 21:36:05 -05:00

82 lines
1.9 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(`
.connection-status {
display: none;
}
.connection-status.interrupted {
background-color: rgba(0, 0, 0, .75);
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
position: relative;
}
.connection-status.interrupted .message {
color: white;
font-family: monospace;
font-size: 0.7em;
text-align: center;
text-transform: uppercase;
}
.connection-status.interrupted .message .dots {
color: rgb(150, 150, 150);
font-size: 0.5em;
}
`),
);
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);