/
ConnectionStatusBar.tsx
82 lines (66 loc) · 2.35 KB
/
ConnectionStatusBar.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { Icon } from '@rocket.chat/fuselage';
import { useConnectionStatus, useTranslation } from '@rocket.chat/ui-contexts';
import type { MouseEventHandler } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import './ConnectionStatusBar.styles.css';
// TODO: frontend chapter day - fix unknown translation keys
const getReconnectCountdown = (retryTime: number): number => {
const timeDiff = retryTime - Date.now();
return (timeDiff > 0 && Math.round(timeDiff / 1000)) || 0;
};
const useReconnectCountdown = (
retryTime: number | undefined,
status: 'connected' | 'connecting' | 'failed' | 'waiting' | 'offline',
): number => {
const reconnectionTimerRef = useRef<ReturnType<typeof setInterval>>();
const [reconnectCountdown, setReconnectCountdown] = useState(() => (retryTime ? getReconnectCountdown(retryTime) : 0));
useEffect(() => {
if (status === 'waiting') {
if (reconnectionTimerRef.current) {
return;
}
reconnectionTimerRef.current = setInterval(() => {
retryTime && setReconnectCountdown(getReconnectCountdown(retryTime));
}, 500);
return;
}
reconnectionTimerRef.current && clearInterval(reconnectionTimerRef.current);
reconnectionTimerRef.current = undefined;
}, [retryTime, status]);
useEffect(
() => (): void => {
reconnectionTimerRef.current && clearInterval(reconnectionTimerRef.current);
},
[],
);
return reconnectCountdown;
};
function ConnectionStatusBar() {
const { connected, retryTime, status, reconnect } = useConnectionStatus();
const reconnectCountdown = useReconnectCountdown(retryTime, status);
const t = useTranslation();
if (connected) {
return null;
}
const handleRetryClick: MouseEventHandler<HTMLAnchorElement> = (event) => {
event.preventDefault();
reconnect?.();
};
return (
<div className='ConnectionStatusBar' role='alert'>
<strong>
<Icon name='warning' /> {t('meteor_status' as Parameters<typeof t>[0], { context: status })}
</strong>
{status === 'waiting' && <> {t('meteor_status_reconnect_in', { count: reconnectCountdown })}</>}
{['waiting', 'offline'].includes(status) && (
<>
{' '}
<a className='ConnectionStatusBar__retry-link' href='#' onClick={handleRetryClick}>
{t('meteor_status_try_now' as Parameters<typeof t>[0], { context: status })}
</a>
</>
)}
</div>
);
}
export default ConnectionStatusBar;