feat: connections page simply support

This commit is contained in:
GyDi 2022-03-18 14:43:22 +08:00 committed by GitHub
parent 7074bbc405
commit 5b886fe6be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 4 deletions

View File

@ -1,4 +1,20 @@
import dayjs from "dayjs";
import { useLockFn } from "ahooks";
import { styled, Box, ListItem, IconButton, ListItemText } from "@mui/material";
import { CloseRounded } from "@mui/icons-material";
import { ApiType } from "../../services/types"; import { ApiType } from "../../services/types";
import { deleteConnection } from "../../services/api";
const Tag = styled(Box)(({ theme }) => ({
display: "inline-block",
fontSize: "12px",
padding: "0 4px",
lineHeight: 1.375,
border: "1px solid #ccc",
borderRadius: 4,
marginRight: "0.1em",
transform: "scale(0.92)",
}));
interface Props { interface Props {
value: ApiType.ConnectionsItem; value: ApiType.ConnectionsItem;
@ -7,7 +23,34 @@ interface Props {
const ConnectionItem = (props: Props) => { const ConnectionItem = (props: Props) => {
const { value } = props; const { value } = props;
return <div>{value.metadata.host || value.metadata.destinationIP}</div>; const onDelete = useLockFn(async () => deleteConnection(value.id));
return (
<ListItem
dense
secondaryAction={
<IconButton edge="end" onClick={onDelete}>
<CloseRounded />
</IconButton>
}
>
<ListItemText
primary={value.metadata.host || value.metadata.destinationIP}
secondary={
<Box>
<Tag sx={{ textTransform: "uppercase", color: "success" }}>
{value.metadata.network}
</Tag>
<Tag>{value.metadata.type}</Tag>
{value.chains.length > 0 && (
<Tag>{value.chains[value.chains.length - 1]}</Tag>
)}
<Tag>{dayjs(value.start).fromNow()}</Tag>
</Box>
}
/>
</ListItem>
);
}; };
export default ConnectionItem; export default ConnectionItem;

View File

@ -17,6 +17,7 @@
"Profile URL": "Profile URL", "Profile URL": "Profile URL",
"Import": "Import", "Import": "Import",
"New": "New", "New": "New",
"Close All": "Close All",
"Settings": "Settings", "Settings": "Settings",
"Clash Setting": "Clash Setting", "Clash Setting": "Clash Setting",

View File

@ -17,6 +17,7 @@
"Profile URL": "配置文件链接", "Profile URL": "配置文件链接",
"Import": "导入", "Import": "导入",
"New": "新建", "New": "新建",
"Close All": "关闭全部",
"Settings": "设置", "Settings": "设置",
"Clash Setting": "Clash 设置", "Clash Setting": "Clash 设置",

View File

@ -1,9 +1,10 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Paper } from "@mui/material"; import { useLockFn } from "ahooks";
import { Button, Paper } from "@mui/material";
import { Virtuoso } from "react-virtuoso"; import { Virtuoso } from "react-virtuoso";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { ApiType } from "../services/types"; import { ApiType } from "../services/types";
import { getInfomation } from "../services/api"; import { closeAllConnections, getInfomation } from "../services/api";
import BasePage from "../components/base/base-page"; import BasePage from "../components/base/base-page";
import ConnectionItem from "../components/connection/connection-item"; import ConnectionItem from "../components/connection/connection-item";
@ -29,10 +30,26 @@ const ConnectionsPage = () => {
return () => ws?.close(); return () => ws?.close();
}, []); }, []);
const onCloseAll = useLockFn(closeAllConnections);
return ( return (
<BasePage title={t("Connections")} contentStyle={{ height: "100%" }}> <BasePage
title={t("Connections")}
contentStyle={{ height: "100%" }}
header={
<Button
size="small"
sx={{ mt: 1 }}
variant="contained"
onClick={onCloseAll}
>
{t("Close All")}
</Button>
}
>
<Paper sx={{ boxShadow: 2, height: "100%" }}> <Paper sx={{ boxShadow: 2, height: "100%" }}>
<Virtuoso <Virtuoso
initialTopMostItemIndex={999}
data={conn.connections} data={conn.connections}
itemContent={(index, item) => <ConnectionItem value={item} />} itemContent={(index, item) => <ConnectionItem value={item} />}
/> />

View File

@ -141,3 +141,15 @@ export async function getProviders() {
const response = await instance.get<any, any>("/providers/proxies"); const response = await instance.get<any, any>("/providers/proxies");
return response.providers as any; return response.providers as any;
} }
// Close specific connection
export async function deleteConnection(id: string) {
const instance = await getAxios();
await instance.delete<any, any>(`/connections/${encodeURIComponent(id)}`);
}
// Close all connections
export async function closeAllConnections() {
const instance = await getAxios();
await instance.delete<any, any>(`/connections`);
}