2020-10-30 20:34:04 +00:00
|
|
|
// Copyright 2020 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2020-02-12 21:30:58 +00:00
|
|
|
import React from 'react';
|
|
|
|
|
|
|
|
import { LocalizerType } from '../types/Util';
|
|
|
|
import { NetworkStateType } from '../state/ducks/network';
|
|
|
|
|
2020-03-20 18:01:55 +00:00
|
|
|
const FIVE_SECONDS = 5 * 1000;
|
|
|
|
|
2020-02-12 21:30:58 +00:00
|
|
|
export interface PropsType extends NetworkStateType {
|
|
|
|
hasNetworkDialog: boolean;
|
|
|
|
i18n: LocalizerType;
|
2020-03-20 18:01:55 +00:00
|
|
|
manualReconnect: () => void;
|
2020-02-12 21:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type RenderDialogTypes = {
|
|
|
|
title: string;
|
|
|
|
subtext: string;
|
|
|
|
renderActionableButton?: () => JSX.Element;
|
|
|
|
};
|
|
|
|
|
|
|
|
function renderDialog({
|
|
|
|
title,
|
|
|
|
subtext,
|
|
|
|
renderActionableButton,
|
|
|
|
}: RenderDialogTypes): JSX.Element {
|
|
|
|
return (
|
|
|
|
<div className="module-left-pane-dialog module-left-pane-dialog--warning">
|
|
|
|
<div className="module-left-pane-dialog__message">
|
|
|
|
<h3>{title}</h3>
|
|
|
|
<span>{subtext}</span>
|
|
|
|
</div>
|
|
|
|
{renderActionableButton && renderActionableButton()}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export const NetworkStatus = ({
|
|
|
|
hasNetworkDialog,
|
|
|
|
i18n,
|
|
|
|
isOnline,
|
|
|
|
socketStatus,
|
2020-03-20 18:01:55 +00:00
|
|
|
manualReconnect,
|
2020-02-12 21:30:58 +00:00
|
|
|
}: PropsType): JSX.Element | null => {
|
2020-03-20 18:01:55 +00:00
|
|
|
const [isConnecting, setIsConnecting] = React.useState<boolean>(false);
|
|
|
|
React.useEffect(() => {
|
2020-09-12 00:46:52 +00:00
|
|
|
if (!hasNetworkDialog) {
|
|
|
|
return () => null;
|
|
|
|
}
|
|
|
|
|
|
|
|
let timeout: NodeJS.Timeout;
|
2020-03-20 18:01:55 +00:00
|
|
|
|
|
|
|
if (isConnecting) {
|
|
|
|
timeout = setTimeout(() => {
|
|
|
|
setIsConnecting(false);
|
|
|
|
}, FIVE_SECONDS);
|
|
|
|
}
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
if (timeout) {
|
|
|
|
clearTimeout(timeout);
|
|
|
|
}
|
|
|
|
};
|
2020-09-12 00:46:52 +00:00
|
|
|
}, [hasNetworkDialog, isConnecting, setIsConnecting]);
|
|
|
|
|
|
|
|
if (!hasNetworkDialog) {
|
|
|
|
return null;
|
|
|
|
}
|
2020-03-20 18:01:55 +00:00
|
|
|
|
|
|
|
const reconnect = () => {
|
|
|
|
setIsConnecting(true);
|
|
|
|
manualReconnect();
|
|
|
|
};
|
|
|
|
|
|
|
|
const manualReconnectButton = (): JSX.Element => (
|
|
|
|
<div className="module-left-pane-dialog__actions">
|
2020-09-12 00:46:52 +00:00
|
|
|
<button onClick={reconnect} type="button">
|
|
|
|
{i18n('connect')}
|
|
|
|
</button>
|
2020-03-20 18:01:55 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
|
2020-04-16 19:20:52 +00:00
|
|
|
if (isConnecting) {
|
2020-03-20 18:01:55 +00:00
|
|
|
return renderDialog({
|
|
|
|
subtext: i18n('connectingHangOn'),
|
|
|
|
title: i18n('connecting'),
|
|
|
|
});
|
2020-09-12 00:46:52 +00:00
|
|
|
}
|
|
|
|
if (!isOnline) {
|
2020-03-20 18:01:55 +00:00
|
|
|
return renderDialog({
|
|
|
|
renderActionableButton: manualReconnectButton,
|
|
|
|
subtext: i18n('checkNetworkConnection'),
|
|
|
|
title: i18n('offline'),
|
|
|
|
});
|
2020-02-12 21:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let subtext = '';
|
|
|
|
let title = '';
|
2020-03-20 18:01:55 +00:00
|
|
|
let renderActionableButton;
|
2020-02-12 21:30:58 +00:00
|
|
|
|
|
|
|
switch (socketStatus) {
|
|
|
|
case WebSocket.CONNECTING:
|
|
|
|
subtext = i18n('connectingHangOn');
|
|
|
|
title = i18n('connecting');
|
|
|
|
break;
|
|
|
|
case WebSocket.CLOSED:
|
|
|
|
case WebSocket.CLOSING:
|
|
|
|
default:
|
2020-03-20 18:01:55 +00:00
|
|
|
renderActionableButton = manualReconnectButton;
|
2020-02-12 21:30:58 +00:00
|
|
|
title = i18n('disconnected');
|
|
|
|
subtext = i18n('checkNetworkConnection');
|
|
|
|
}
|
|
|
|
|
|
|
|
return renderDialog({
|
2020-03-20 18:01:55 +00:00
|
|
|
renderActionableButton,
|
2020-02-12 21:30:58 +00:00
|
|
|
subtext,
|
|
|
|
title,
|
|
|
|
});
|
|
|
|
};
|