Feature/nym connect gateway performance (#2815)
* set up ui for gateway performance in nym-connect * reset gateway performance state periodically * remove duplicated imports * set and reset (when necessary) gateway performance * align gateway performance text left
This commit is contained in:
@@ -74,6 +74,7 @@ export const App: React.FC = () => {
|
||||
onConnectClick={handleConnectClick}
|
||||
ipAddress="127.0.0.1"
|
||||
port={1080}
|
||||
gatewayPerformance={context.gatewayPerformance}
|
||||
connectedSince={context.connectedSince}
|
||||
serviceProvider={context.serviceProvider}
|
||||
stats={[
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Box, CircularProgress, Divider, Stack, Tooltip, Typography } from '@mui/material';
|
||||
import { DateTime } from 'luxon';
|
||||
import { ConnectionStatusKind } from '../types';
|
||||
import { ConnectionStatusKind, GatewayPerformance } from '../types';
|
||||
import { ServiceProvider } from '../types/directory';
|
||||
import { ServiceProviderInfo } from './ServiceProviderInfo';
|
||||
|
||||
@@ -58,9 +58,10 @@ const ConnectionStatusContent: React.FC<{
|
||||
|
||||
export const ConnectionStatus: React.FC<{
|
||||
status: ConnectionStatusKind;
|
||||
gatewayPerformance?: GatewayPerformance;
|
||||
connectedSince?: DateTime;
|
||||
serviceProvider?: ServiceProvider;
|
||||
}> = ({ status, serviceProvider }) => {
|
||||
}> = ({ status, serviceProvider, gatewayPerformance }) => {
|
||||
const color =
|
||||
status === ConnectionStatusKind.connected || status === ConnectionStatusKind.disconnecting
|
||||
? '#21D072'
|
||||
@@ -69,7 +70,13 @@ export const ConnectionStatus: React.FC<{
|
||||
return (
|
||||
<>
|
||||
<Box color={color} fontSize={FONT_SIZE} sx={{ mb: 1 }}>
|
||||
<ConnectionStatusContent status={status} />
|
||||
{status === ConnectionStatusKind.connected && gatewayPerformance !== 'Good' ? (
|
||||
<Typography fontWeight={FONT_WEIGHT} fontStyle={FONT_STYLE} textAlign="left" color="primary">
|
||||
Gateway has issues
|
||||
</Typography>
|
||||
) : (
|
||||
<ConnectionStatusContent status={status} />
|
||||
)}
|
||||
</Box>
|
||||
{serviceProvider ? (
|
||||
<Tooltip title={<ServiceProviderInfo serviceProvider={serviceProvider} />}>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import React, { createContext, useCallback, useContext, useEffect, useMemo, useState, useRef } from 'react';
|
||||
import { DateTime } from 'luxon';
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import type { UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { listen } from '@tauri-apps/api/event';
|
||||
import { forage } from '@tauri-apps/tauri-forage';
|
||||
import { ConnectionStatusKind, GatewayPerformance } from '../types';
|
||||
import { ConnectionStatsItem } from '../components/ConnectionStats';
|
||||
import { ServiceProvider, Services } from '../types/directory';
|
||||
import { Error } from 'src/types/error';
|
||||
import { TauriEvent } from 'src/types/event';
|
||||
import { getVersion } from '@tauri-apps/api/app';
|
||||
import { ConnectionStatusKind } from '../types';
|
||||
import { ConnectionStatsItem } from '../components/ConnectionStats';
|
||||
import { ServiceProvider, Services } from '../types/directory';
|
||||
|
||||
const TAURI_EVENT_STATUS_CHANGED = 'app:connection-status-changed';
|
||||
|
||||
@@ -25,7 +25,7 @@ export type TClientContext = {
|
||||
serviceProvider?: ServiceProvider;
|
||||
showHelp: boolean;
|
||||
error?: Error;
|
||||
|
||||
gatewayPerformance: GatewayPerformance;
|
||||
setMode: (mode: ModeType) => void;
|
||||
clearError: () => void;
|
||||
handleShowHelp: () => void;
|
||||
@@ -50,6 +50,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
const [showHelp, setShowHelp] = useState(false);
|
||||
const [error, setError] = useState<Error>();
|
||||
const [appVersion, setAppVersion] = useState<string>();
|
||||
const [gatewayPerformance, setGatewayPerformance] = useState<GatewayPerformance>('Good');
|
||||
|
||||
const getAppVersion = async () => {
|
||||
const version = await getVersion();
|
||||
@@ -93,6 +94,16 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
unlisten.push(result);
|
||||
});
|
||||
|
||||
listen('socks5-status-event', (e: TauriEvent) => {
|
||||
if (e.payload.message.includes('slow')) {
|
||||
setGatewayPerformance('Poor');
|
||||
} else {
|
||||
setGatewayPerformance('Good');
|
||||
}
|
||||
}).then((result) => {
|
||||
unlisten.push(result);
|
||||
});
|
||||
|
||||
return () => {
|
||||
unlisten.forEach((unsubscribe) => unsubscribe());
|
||||
};
|
||||
@@ -110,6 +121,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
const startDisconnecting = useCallback(async () => {
|
||||
try {
|
||||
await invoke('start_disconnecting');
|
||||
setGatewayPerformance('Good');
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
@@ -167,6 +179,20 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
getSpFromStorage();
|
||||
}, []);
|
||||
|
||||
const timerId = useRef<NodeJS.Timeout>();
|
||||
|
||||
useEffect(() => {
|
||||
if (timerId.current) {
|
||||
clearTimeout(timerId.current);
|
||||
}
|
||||
|
||||
if (gatewayPerformance !== 'Good') {
|
||||
timerId.current = setTimeout(() => {
|
||||
setGatewayPerformance('Good');
|
||||
}, 15000);
|
||||
}
|
||||
}, [gatewayPerformance]);
|
||||
|
||||
const contextValue = useMemo(
|
||||
() => ({
|
||||
mode,
|
||||
@@ -187,6 +213,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
setServiceProvider,
|
||||
showHelp,
|
||||
handleShowHelp,
|
||||
gatewayPerformance,
|
||||
}),
|
||||
[
|
||||
appVersion,
|
||||
@@ -200,6 +227,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
connectedSince,
|
||||
services,
|
||||
serviceProvider,
|
||||
gatewayPerformance,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ const mockValues: TClientContext = {
|
||||
services: [],
|
||||
showHelp: false,
|
||||
serviceProvider: { id: '1', description: 'Keybase service provider', gateway: 'abc123', address: '123abc' },
|
||||
gatewayPerformance: 'Good',
|
||||
setMode: () => {},
|
||||
clearError: () => {},
|
||||
handleShowHelp: () => {},
|
||||
|
||||
@@ -4,7 +4,7 @@ import { DateTime } from 'luxon';
|
||||
import { IpAddressAndPortModal } from 'src/components/IpAddressAndPortModal';
|
||||
import { ConnectionTimer } from 'src/components/ConntectionTimer';
|
||||
import { ConnectionStatus } from '../components/ConnectionStatus';
|
||||
import { ConnectionStatusKind } from '../types';
|
||||
import { ConnectionStatusKind, GatewayPerformance } from '../types';
|
||||
import { ConnectionStatsItem } from '../components/ConnectionStats';
|
||||
import { ConnectionButton } from '../components/ConnectionButton';
|
||||
import { IpAddressAndPort } from '../components/IpAddressAndPort';
|
||||
@@ -13,6 +13,7 @@ import { TestAndEarnButtonArea } from '../components/Growth/TestAndEarnButtonAre
|
||||
|
||||
export const ConnectedLayout: React.FC<{
|
||||
status: ConnectionStatusKind;
|
||||
gatewayPerformance: GatewayPerformance;
|
||||
stats: ConnectionStatsItem[];
|
||||
ipAddress: string;
|
||||
port: number;
|
||||
@@ -25,6 +26,7 @@ export const ConnectedLayout: React.FC<{
|
||||
serviceProvider?: ServiceProvider;
|
||||
}> = ({
|
||||
status,
|
||||
gatewayPerformance,
|
||||
showInfoModal,
|
||||
handleCloseInfoModal,
|
||||
ipAddress,
|
||||
@@ -37,8 +39,12 @@ export const ConnectedLayout: React.FC<{
|
||||
}) => (
|
||||
<>
|
||||
<IpAddressAndPortModal show={showInfoModal} onClose={handleCloseInfoModal} ipAddress={ipAddress} port={port} />
|
||||
<Box>
|
||||
<ConnectionStatus status={ConnectionStatusKind.connected} serviceProvider={serviceProvider} />
|
||||
<Box pb={1}>
|
||||
<ConnectionStatus
|
||||
status={ConnectionStatusKind.connected}
|
||||
serviceProvider={serviceProvider}
|
||||
gatewayPerformance={gatewayPerformance}
|
||||
/>
|
||||
</Box>
|
||||
<Divider sx={{ my: 2 }} />
|
||||
<Box sx={{ mb: 3 }}>
|
||||
|
||||
@@ -86,32 +86,33 @@ export const Mock: ComponentStory<typeof AppWindowFrame> = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Box width={width} height={height}>
|
||||
<AppWindowFrame>
|
||||
<ConnectedLayout
|
||||
showInfoModal={false}
|
||||
handleCloseInfoModal={() => undefined}
|
||||
status={context.connectionStatus}
|
||||
busy={busy}
|
||||
onConnectClick={handleConnectClick}
|
||||
ipAddress="127.0.0.1"
|
||||
port={1080}
|
||||
connectedSince={context.connectedSince}
|
||||
serviceProvider={services[0].items[0]}
|
||||
stats={[
|
||||
{
|
||||
label: 'in:',
|
||||
totalBytes: 1024,
|
||||
rateBytesPerSecond: 1024 * 1024 * 1024 + 10,
|
||||
},
|
||||
{
|
||||
label: 'out:',
|
||||
totalBytes: 1024 * 1024 * 1024 * 1024 * 20,
|
||||
rateBytesPerSecond: 1024 * 1024 + 10,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</AppWindowFrame>
|
||||
</Box>
|
||||
<AppWindowFrame>
|
||||
<ConnectedLayout
|
||||
gatewayPerformance="Good"
|
||||
showInfoModal={false}
|
||||
handleCloseInfoModal={() => {
|
||||
return undefined;
|
||||
}}
|
||||
status={context.connectionStatus}
|
||||
busy={busy}
|
||||
onConnectClick={handleConnectClick}
|
||||
ipAddress="127.0.0.1"
|
||||
port={1080}
|
||||
connectedSince={context.connectedSince}
|
||||
serviceProvider={services[0].items[0]}
|
||||
stats={[
|
||||
{
|
||||
label: 'in:',
|
||||
totalBytes: 1024,
|
||||
rateBytesPerSecond: 1024 * 1024 * 1024 + 10,
|
||||
},
|
||||
{
|
||||
label: 'out:',
|
||||
totalBytes: 1024 * 1024 * 1024 * 1024 * 20,
|
||||
rateBytesPerSecond: 1024 * 1024 + 10,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</AppWindowFrame>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@ export const Default: ComponentStory<typeof ConnectedLayout> = () => (
|
||||
<Box p={2} width={242} sx={{ bgcolor: 'nym.background.dark' }}>
|
||||
<ConnectedLayout
|
||||
showInfoModal={false}
|
||||
gatewayPerformance="Good"
|
||||
handleCloseInfoModal={() => {
|
||||
return undefined;
|
||||
}}
|
||||
|
||||
@@ -10,17 +10,17 @@ export default {
|
||||
} as ComponentMeta<typeof ConnectionStatus>;
|
||||
|
||||
export const Disconnected: ComponentStory<typeof ConnectionStatus> = () => (
|
||||
<ConnectionStatus status={ConnectionStatusKind.disconnected} />
|
||||
<ConnectionStatus status={ConnectionStatusKind.disconnected} gatewayPerformance="Good" />
|
||||
);
|
||||
|
||||
export const Connecting: ComponentStory<typeof ConnectionStatus> = () => (
|
||||
<ConnectionStatus status={ConnectionStatusKind.connecting} />
|
||||
<ConnectionStatus status={ConnectionStatusKind.connecting} gatewayPerformance="Good" />
|
||||
);
|
||||
|
||||
export const Connected: ComponentStory<typeof ConnectionStatus> = () => (
|
||||
<ConnectionStatus status={ConnectionStatusKind.connected} connectedSince={DateTime.now()} />
|
||||
<ConnectionStatus status={ConnectionStatusKind.connected} connectedSince={DateTime.now()} gatewayPerformance="Good" />
|
||||
);
|
||||
|
||||
export const Disconnecting: ComponentStory<typeof ConnectionStatus> = () => (
|
||||
<ConnectionStatus status={ConnectionStatusKind.disconnecting} />
|
||||
<ConnectionStatus status={ConnectionStatusKind.disconnecting} gatewayPerformance="Good" />
|
||||
);
|
||||
|
||||
@@ -4,3 +4,5 @@ export enum ConnectionStatusKind {
|
||||
connected = 'connected',
|
||||
connecting = 'connecting',
|
||||
}
|
||||
|
||||
export type GatewayPerformance = 'Good' | 'Poor' | 'VeryPoor';
|
||||
|
||||
Reference in New Issue
Block a user