signal-desktop/ts/components/NetworkStatus.tsx

122 lines
2.7 KiB
TypeScript
Raw Normal View History

// Copyright 2020-2021 Signal Messenger, LLC
2020-10-30 20:34:04 +00:00
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { LocalizerType } from '../types/Util';
2021-06-09 22:28:54 +00:00
import { SocketStatus } from '../types/SocketStatus';
import { NetworkStateType } from '../state/ducks/network';
const FIVE_SECONDS = 5 * 1000;
export type PropsType = NetworkStateType & {
hasNetworkDialog: boolean;
i18n: LocalizerType;
manualReconnect: () => void;
};
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,
manualReconnect,
}: PropsType): JSX.Element | null => {
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;
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;
}
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>
</div>
);
if (isConnecting) {
return renderDialog({
subtext: i18n('connectingHangOn'),
title: i18n('connecting'),
});
2020-09-12 00:46:52 +00:00
}
if (!isOnline) {
return renderDialog({
renderActionableButton: manualReconnectButton,
subtext: i18n('checkNetworkConnection'),
title: i18n('offline'),
});
}
let subtext = '';
let title = '';
let renderActionableButton;
switch (socketStatus) {
2021-06-09 22:28:54 +00:00
case SocketStatus.CONNECTING:
subtext = i18n('connectingHangOn');
title = i18n('connecting');
break;
2021-06-09 22:28:54 +00:00
case SocketStatus.CLOSED:
case SocketStatus.CLOSING:
default:
renderActionableButton = manualReconnectButton;
title = i18n('disconnected');
subtext = i18n('checkNetworkConnection');
}
return renderDialog({
renderActionableButton,
subtext,
title,
});
};