diff --git a/src/components/connection/connection-item.tsx b/src/components/connection/connection-item.tsx
index 419233c..088ef55 100644
--- a/src/components/connection/connection-item.tsx
+++ b/src/components/connection/connection-item.tsx
@@ -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 { 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 {
value: ApiType.ConnectionsItem;
@@ -7,7 +23,34 @@ interface Props {
const ConnectionItem = (props: Props) => {
const { value } = props;
- return
{value.metadata.host || value.metadata.destinationIP}
;
+ const onDelete = useLockFn(async () => deleteConnection(value.id));
+
+ return (
+
+
+
+ }
+ >
+
+
+ {value.metadata.network}
+
+ {value.metadata.type}
+ {value.chains.length > 0 && (
+ {value.chains[value.chains.length - 1]}
+ )}
+ {dayjs(value.start).fromNow()}
+
+ }
+ />
+
+ );
};
export default ConnectionItem;
diff --git a/src/locales/en.json b/src/locales/en.json
index aba0ea1..fc27bef 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -17,6 +17,7 @@
"Profile URL": "Profile URL",
"Import": "Import",
"New": "New",
+ "Close All": "Close All",
"Settings": "Settings",
"Clash Setting": "Clash Setting",
diff --git a/src/locales/zh.json b/src/locales/zh.json
index a51b132..737a03d 100644
--- a/src/locales/zh.json
+++ b/src/locales/zh.json
@@ -17,6 +17,7 @@
"Profile URL": "配置文件链接",
"Import": "导入",
"New": "新建",
+ "Close All": "关闭全部",
"Settings": "设置",
"Clash Setting": "Clash 设置",
diff --git a/src/pages/connections.tsx b/src/pages/connections.tsx
index 16ec936..0c4e866 100644
--- a/src/pages/connections.tsx
+++ b/src/pages/connections.tsx
@@ -1,9 +1,10 @@
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 { useTranslation } from "react-i18next";
import { ApiType } from "../services/types";
-import { getInfomation } from "../services/api";
+import { closeAllConnections, getInfomation } from "../services/api";
import BasePage from "../components/base/base-page";
import ConnectionItem from "../components/connection/connection-item";
@@ -29,10 +30,26 @@ const ConnectionsPage = () => {
return () => ws?.close();
}, []);
+ const onCloseAll = useLockFn(closeAllConnections);
+
return (
-
+
+ {t("Close All")}
+
+ }
+ >
}
/>
diff --git a/src/services/api.ts b/src/services/api.ts
index 192a8a8..8a73c4d 100644
--- a/src/services/api.ts
+++ b/src/services/api.ts
@@ -141,3 +141,15 @@ export async function getProviders() {
const response = await instance.get("/providers/proxies");
return response.providers as any;
}
+
+// Close specific connection
+export async function deleteConnection(id: string) {
+ const instance = await getAxios();
+ await instance.delete(`/connections/${encodeURIComponent(id)}`);
+}
+
+// Close all connections
+export async function closeAllConnections() {
+ const instance = await getAxios();
+ await instance.delete(`/connections`);
+}