From 75c1187b54d135323453154209ae6aff9cb817a9 Mon Sep 17 00:00:00 2001 From: thehrz Date: Tue, 20 Aug 2024 19:52:11 +0800 Subject: [PATCH] feat: add ISP check --- src/components/CheckItem.tsx | 23 ++++--- src/components/Checker.tsx | 125 +++++++++++++++++++++++------------ src/types/CheckItem.ts | 5 +- src/types/ISPResponse.ts | 3 + 4 files changed, 105 insertions(+), 51 deletions(-) create mode 100644 src/types/ISPResponse.ts diff --git a/src/components/CheckItem.tsx b/src/components/CheckItem.tsx index 1a6318b..2395710 100644 --- a/src/components/CheckItem.tsx +++ b/src/components/CheckItem.tsx @@ -1,13 +1,10 @@ "use client" import { CheckItemIconState, CheckItemType } from "@/types/CheckItem" import { Icon } from "@iconify/react/dist/iconify.js" -import useSWRImmutable from "swr/immutable" +import { useQuery } from "@tanstack/react-query" type CheckItemProps = CheckItemType -const fetcher = (url: string | URL | Request) => - fetch(url).then((r) => r.json()) - const icon = { ok: ( (url, fetcher) +export default function CheckItem({ + id, + name, + fetcher, + content, +}: CheckItemProps) { + const { data, error, isLoading } = useQuery({ + queryKey: [id], + queryFn: fetcher, + }) return ( <> @@ -41,11 +46,13 @@ export default function CheckItem({ name, url, content }: CheckItemProps) { : isLoading ? icon["loading"] : data != undefined - ? icon[content(data).state] + ? icon[content(data).state ?? "ok"] : null}
- {name} + + {name} + {data != undefined diff --git a/src/components/Checker.tsx b/src/components/Checker.tsx index 0777910..e1b5060 100644 --- a/src/components/Checker.tsx +++ b/src/components/Checker.tsx @@ -1,51 +1,94 @@ "use client" import CheckItem from "./CheckItem" import { CheckItemType } from "@/types/CheckItem" - -const checkList: CheckItemType[] = [ - { - name: "公网 IPv6 地址", - url: "https://6.ipv6test.online/ip/myip", - content: (data) => { - const success = data?.version == 6 - return { - state: success ? "ok" : "error", - text: (success ? `${data?.address}` : "未检测到"), - } - }, - }, - { - name: "公网 IPv4 地址", - url: "https://4.ipv6test.online/ip/myip", - content: (data) => { - const success = data?.version == 4 - return { - state: success ? "ok" : "error", - text: (success ? `${data?.address}` : "未检测到"), - } - }, - }, - { - name: "双协议栈测试", - url: "https://test.ipv6test.online/ip/myip", - content: (data) => { - const isIPv6 = data?.version == 6 - const isIPv4 = data?.version == 4 - - return { - state: isIPv6 ? "ok" : "error", - text: isIPv6 ? "你的网络IPv6访问优先" : isIPv4 ? "你的网络IPv4访问优先" : "未检测到", - } - }, - }, -] +import { useRef } from "react" +import { QueryClient, QueryClientProvider } from "@tanstack/react-query" export default function Checker() { + const IPv4 = useRef("") + const IPv6 = useRef("") + + const checkList: CheckItemType[] = [ + { + id: "IPv6", + name: "公网 IPv6 地址", + fetcher: () => fetch("https://test.ipv6test.online/ip/myip").then((res) => res.json()), + content: (data) => { + const success = data?.version == 6 + if (success && data.address != null) { + IPv6.current = data.address + } + return { + state: success ? "ok" : "error", + text: success ? `${data?.address}` : "未检测到", + } + }, + }, + { + id: "IPv4", + name: "公网 IPv4 地址", + fetcher: () => fetch("https://test.ipv6test.online/ip/myip").then((res) => res.json()), + content: (data) => { + const success = data?.version == 4 + + if (success && data.address != null) { + IPv4.current = data.address + } + + return { + state: success ? "ok" : "error", + text: success ? `${data?.address}` : "未检测到", + } + }, + }, + { + id: "ipv4andipv6", + name: "双协议栈测试", + fetcher: () => fetch("https://test.ipv6test.online/ip/myip").then((res) => res.json()), + content: (data) => { + const isIPv6 = data?.version == 6 + const isIPv4 = data?.version == 4 + + return { + state: isIPv6 ? "ok" : "error", + text: isIPv6 ? "IPv6访问优先" : isIPv4 ? "IPv4访问优先" : "未检测到", + } + }, + }, + { + id: "ISP", + name: "ISP", + fetcher: () => + fetch("https://test.ipv6test.online/ip/isp", { + method: "POST", + body: JSON.stringify({ + address: IPv6.current, + }), + }).then((res) => res.json()), + content: (data) => { + return { + text: data.isp, + } + }, + }, + ] + + const queryClient = new QueryClient(); + + return ( - <> + {checkList.map((item, i) => { - return + return ( + + ) })} - + ) } diff --git a/src/types/CheckItem.ts b/src/types/CheckItem.ts index 9202268..91c05b3 100644 --- a/src/types/CheckItem.ts +++ b/src/types/CheckItem.ts @@ -1,7 +1,8 @@ export interface CheckItemType { + id: string name: string - url: string - content: (data: any) => {state: CheckItemIconState, text: string} + fetcher: () => Promise + content: (data: any) => {state?: CheckItemIconState, text: string} } export type CheckItemIconState = "ok" | "loading" | "info" | "error" diff --git a/src/types/ISPResponse.ts b/src/types/ISPResponse.ts new file mode 100644 index 0000000..25aa645 --- /dev/null +++ b/src/types/ISPResponse.ts @@ -0,0 +1,3 @@ +export default interface ISPResponse { + isp: string +} \ No newline at end of file