Skip to content

Commit

Permalink
refactor(gui): Simplify NetworkStatusWidget (#298)
Browse files Browse the repository at this point in the history
  • Loading branch information
zccz14 authored Dec 1, 2023
1 parent ae71a8a commit 9950c1c
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 140 deletions.
11 changes: 10 additions & 1 deletion ui/web/public/locales/en/HostList.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
"add_dedicated_host": "Add dedicated host",
"add_host": "New",
"add_to_list": "Add to host list",
"config": "Config",
"connect": "connect",
"dedicated_hosts": "Dedicated host list",
"disconnect": "Disconnect",
"download_rate": "Download",
"edit_host": "Edit host",
"host_label": "Host label",
"host_label_default": "unnamed host",
Expand All @@ -12,7 +15,13 @@
"host_url_note": "Please ask your hosting administrator",
"link_copied": "Link copied",
"new_shared_host": "Create shared host",
"No_Host": "No Host",
"not_configured": "Not Configured",
"offline": "Offline",
"online": "Online",
"shared_hosts": "Shared hosting list",
"status": "Status",
"terminal_id": "Terminal ID",
"terminal_id_note": "A flag to distinguish it from other terminals in the same host. It cannot be repeated in the same host."
"terminal_id_note": "A flag to distinguish it from other terminals in the same host. It cannot be repeated in the same host.",
"upload_rate": "Upload"
}
14 changes: 0 additions & 14 deletions ui/web/public/locales/en/NetworkStatusWidget.json

This file was deleted.

11 changes: 10 additions & 1 deletion ui/web/public/locales/zh-Hans/HostList.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
"add_dedicated_host": "添加专用主机",
"add_host": "新增",
"add_to_list": "添加到主机列表",
"config": "配置",
"connect": "连接",
"dedicated_hosts": "专用主机列表",
"disconnect": "断开",
"download_rate": "下行速率",
"edit_host": "编辑主机",
"host_label": "主机标签",
"host_label_default": "未命名主机",
Expand All @@ -12,7 +15,13 @@
"host_url_note": "请询问您的主机管理员",
"link_copied": "已复制链接",
"new_shared_host": "创建共享型主机",
"No_Host": "无主机模式",
"not_configured": "未配置",
"offline": "离线",
"online": "在线",
"shared_hosts": "共享型主机列表",
"status": "连接状态",
"terminal_id": "终端ID",
"terminal_id_note": "同一主机中与其他终端区分的标志,同一主机内不能重复"
"terminal_id_note": "同一主机中与其他终端区分的标志,同一主机内不能重复",
"upload_rate": "上行速率"
}
14 changes: 0 additions & 14 deletions ui/web/public/locales/zh-Hans/NetworkStatusWidget.json

This file was deleted.

2 changes: 1 addition & 1 deletion ui/web/src/modules/Agent/CloudAgentList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { executeCommand, registerCommand } from '../CommandCenter';
import { resolveVersion } from '../Extensions';
import { registerPage } from '../Pages';
import { supabase } from '../SupaBase';
import { secretURL } from '../Terminals/NetworkStatusWidget';
import { secretURL } from '../Workbench/HostList';
import { currentHostConfig$ } from '../Workbench/model';
import { agentConf$ } from './AgentConfForm';
import { bundleCode } from './utils';
Expand Down
118 changes: 11 additions & 107 deletions ui/web/src/modules/Terminals/NetworkStatusWidget.tsx
Original file line number Diff line number Diff line change
@@ -1,117 +1,21 @@
import { IconDesktop, IconSignal, IconUnlink, IconWrench } from '@douyinfe/semi-icons';
import { Button, Card, Descriptions, Popover, Space, Typography } from '@douyinfe/semi-ui';
import { useObservable, useObservableState } from 'observable-hooks';
import { Button } from '@douyinfe/semi-ui';
import { CloseWifi, Wifi } from '@icon-park/react';
import { useObservableState } from 'observable-hooks';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { bufferTime, combineLatest, map, of, switchMap } from 'rxjs';
import { executeCommand } from '../CommandCenter';
import { terminal$ } from '../Terminals';
import { currentHostConfig$ } from '../Workbench/model';

export const secretURL = (url: string) => {
try {
const theUrl = new URL(url);
theUrl.searchParams.set('host_token', '******');
return theUrl.toString();
} catch (e) {
return url;
}
};

export const NetworkStatusWidget = React.memo(() => {
const { t } = useTranslation(['NetworkStatusWidget', 'translation']);
const config = useObservableState(currentHostConfig$);

const network$ = useObservable(() =>
terminal$.pipe(
switchMap((terminal) =>
terminal
? combineLatest([
terminal._conn.output$.pipe(
bufferTime(2000),
map((buffer) => ((JSON.stringify(buffer).length / 2e3) * 8).toFixed(1)),
),
terminal._conn.input$.pipe(
bufferTime(2000),
map((buffer) => ((JSON.stringify(buffer).length / 2e3) * 8).toFixed(1)),
),
])
: of(['0.0', '0.0']),
),
),
);

const network = useObservableState(network$, ['0.0', '0.0'] as [string, string]);
return (
<Space>
<Popover
content={
<Card style={{ minWidth: 200 }}>
<Descriptions
data={[
//
{
key: t('host_label'),
value: <Typography.Text>{config?.name ?? t('not_configured')}</Typography.Text>,
},
{
key: t('host_url'),
value: (
<Typography.Text copyable={{ content: config?.host_url ?? t('not_configured') }}>
{secretURL(config?.host_url ?? t('not_configured'))}
</Typography.Text>
),
},
{
key: t('terminal_id'),
value: (
<Typography.Text copyable>{config?.terminal_id ?? t('not_configured')}</Typography.Text>
),
},
{
key: t('upload_rate'),
value: `${network[0]} kbps`,
},
{
key: t('download_rate'),
value: `${network[1]} kbps`,
},
{
key: t('status'),
value: <Typography.Text>{+network[1] > 0 ? t('online') : t('offline')}</Typography.Text>,
},
]}
></Descriptions>
<Space>
<Button
icon={<IconWrench />}
onClick={() => {
executeCommand('Page.open', { type: 'HostList' });
}}
>
{t('config')}
</Button>
<Button
icon={<IconUnlink />}
disabled={!currentHostConfig$.value}
onClick={() => {
currentHostConfig$.next(null);
}}
>
{t('disconnect')}
</Button>
</Space>
</Card>
}
>
<Typography.Text
icon={
config ? <IconSignal style={{ color: +network[1] > 0 ? 'green' : 'red' }} /> : <IconDesktop />
}
>
{config ? `${config.name} / ${config.terminal_id}` : t('No_Host')}
</Typography.Text>
</Popover>
</Space>
<Button
type="tertiary"
theme="borderless"
icon={config ? <Wifi size={20} /> : <CloseWifi size={20} />}
onClick={() => {
executeCommand('HostList');
}}
></Button>
);
});
2 changes: 1 addition & 1 deletion ui/web/src/modules/Workbench/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const HomePage = React.memo(() => {
},
}}
>
Connect Hosts...
Connect Host...
</Typography.Text>
<Typography.Text
icon={<SmartOptimization theme="outline" size="16" />}
Expand Down
84 changes: 83 additions & 1 deletion ui/web/src/modules/Workbench/HostList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import {
IconLink,
IconPlus,
IconShareStroked,
IconUnlink,
} from '@douyinfe/semi-icons';
import {
Button,
ButtonGroup,
Card,
Descriptions,
List,
Modal,
Expand All @@ -25,13 +27,14 @@ import { t } from 'i18next';
import { JSONSchema7 } from 'json-schema';
import { useObservableState } from 'observable-hooks';
import { useTranslation } from 'react-i18next';
import { bufferTime, combineLatest, map, of, shareReplay, switchMap } from 'rxjs';
import { executeCommand } from '../CommandCenter';
import { fs } from '../FileSystem/api';
import Form from '../Form';
import { shareHosts$ } from '../Host/model';
import { registerPage } from '../Pages';
import { authState$ } from '../SupaBase';
import { secretURL } from '../Terminals/NetworkStatusWidget';
import { terminal$ } from '../Terminals';
import { IHostConfigItem, currentHostConfig$, hostConfigList$ } from './model';

const configSchema = (): JSONSchema7 => ({
Expand All @@ -53,17 +56,57 @@ const configSchema = (): JSONSchema7 => ({
},
});

export const secretURL = (url: string) => {
try {
const theUrl = new URL(url);
theUrl.searchParams.set('host_token', '******');
return theUrl.toString();
} catch (e) {
return url;
}
};

export const network$ = terminal$.pipe(
switchMap((terminal) =>
terminal
? combineLatest([
terminal._conn.output$.pipe(
bufferTime(2000),
map((buffer) => ((JSON.stringify(buffer).length / 2e3) * 8).toFixed(1)),
),
terminal._conn.input$.pipe(
bufferTime(2000),
map((buffer) => ((JSON.stringify(buffer).length / 2e3) * 8).toFixed(1)),
),
])
: of(['0.0', '0.0']),
),
shareReplay(1),
);

registerPage('HostList', () => {
const configs = useObservableState(hostConfigList$, []) || [];
const { t } = useTranslation('HostList');
const auth = useObservableState(authState$);
const HOST_CONFIG = '/hosts.json';
const config = useObservableState(currentHostConfig$);

const network = useObservableState(network$, ['0.0', '0.0'] as [string, string]);

const sharedHosts = useObservableState(shareHosts$, []);

return (
<Space vertical align="start">
<Space>
<Button
icon={<IconUnlink />}
disabled={!currentHostConfig$.value}
onClick={() => {
currentHostConfig$.next(null);
}}
>
{t('disconnect')}
</Button>
<Button
icon={<IconPlus />}
onClick={async () => {
Expand Down Expand Up @@ -110,6 +153,45 @@ registerPage('HostList', () => {
{t('common:view_source')}
</Button>
</Space>

{config && (
<Card style={{ minWidth: 200 }}>
<Descriptions
data={[
//
{
key: t('host_label'),
value: <Typography.Text>{config.name}</Typography.Text>,
},
{
key: t('host_url'),
value: (
<Typography.Text copyable={{ content: config.host_url }}>
{secretURL(config.host_url)}
</Typography.Text>
),
},
{
key: t('terminal_id'),
value: <Typography.Text copyable>{config.terminal_id}</Typography.Text>,
},
{
key: t('upload_rate'),
value: `${network[0]} kbps`,
},
{
key: t('download_rate'),
value: `${network[1]} kbps`,
},
{
key: t('status'),
value: <Typography.Text>{+network[1] > 0 ? t('online') : t('offline')}</Typography.Text>,
},
]}
></Descriptions>
</Card>
)}

{auth && (
<>
<Typography.Title heading={5}>{t('shared_hosts')}</Typography.Title>
Expand Down

0 comments on commit 9950c1c

Please sign in to comment.