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`); +}