From a6acb15a007fcaef2aa4aaa6fbfbc2ca7651422b Mon Sep 17 00:00:00 2001 From: MystiPanda Date: Sun, 14 Jan 2024 18:35:10 +0800 Subject: [PATCH] refactor: Use Tauri Http API --- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 4 ++ src/hooks/use-clash.ts | 4 +- src/pages/_layout.tsx | 4 +- src/services/api.ts | 108 ++++++++++++++++++++------------------ 5 files changed, 67 insertions(+), 55 deletions(-) diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 178bc75c..21d8a013 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -39,7 +39,7 @@ window-shadows = { version = "0.2" } tokio = { version = "1", features = ["full"] } serde = { version = "1.0", features = ["derive"] } reqwest = { version = "0.11", features = ["json", "rustls-tls"] } -tauri = { version = "1.5", features = [ "notification-all", "icon-png", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all"] } +tauri = { version = "1.5", features = [ "http-all", "notification-all", "icon-png", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all"] } tauri-plugin-websocket = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } [target.'cfg(windows)'.dependencies] diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 79e2fb79..41b81610 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -54,6 +54,10 @@ }, "notification": { "all": true + }, + "http": { + "all": true, + "scope": ["http://**", "https://**"] } }, "windows": [], diff --git a/src/hooks/use-clash.ts b/src/hooks/use-clash.ts index 9804c5fc..1bd9318a 100644 --- a/src/hooks/use-clash.ts +++ b/src/hooks/use-clash.ts @@ -1,7 +1,7 @@ import useSWR, { mutate } from "swr"; import { useLockFn } from "ahooks"; import { - getAxios, + refreshClashInfo, getClashConfig, getVersion, updateConfigs, @@ -72,7 +72,7 @@ export const useClashInfo = () => { mutateInfo(); mutate("getClashConfig"); // 刷新接口 - getAxios(true); + await refreshClashInfo(); }; return { diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx index f49b6a16..e3cb8a36 100644 --- a/src/pages/_layout.tsx +++ b/src/pages/_layout.tsx @@ -10,7 +10,7 @@ import { alpha, List, Paper, ThemeProvider } from "@mui/material"; import { listen } from "@tauri-apps/api/event"; import { appWindow } from "@tauri-apps/api/window"; import { routers } from "./_routers"; -import { getAxios } from "@/services/api"; +import { refreshClashInfo } from "@/services/api"; import { useVerge } from "@/hooks/use-verge"; import LogoSvg from "@/assets/image/logo.svg?react"; import { BaseErrorBoundary, Notice } from "@/components/base"; @@ -50,7 +50,7 @@ const Layout = () => { listen("verge://refresh-clash-config", async () => { // the clash info may be updated - await getAxios(true); + await refreshClashInfo(); mutate("getProxies"); mutate("getVersion"); mutate("getClashConfig"); diff --git a/src/services/api.ts b/src/services/api.ts index f9b0cba2..1941d4d2 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -1,22 +1,30 @@ -import axios, { AxiosInstance } from "axios"; import { getClashInfo } from "./cmds"; +import { + fetch as tauriFetch, + HttpVerb, + Body, + Response, +} from "@tauri-apps/api/http"; +let clashInfo: IClashInfo | null; -let axiosIns: AxiosInstance = null!; - -/// initialize some information -/// enable force update axiosIns -export const getAxios = async (force: boolean = false) => { - if (axiosIns && !force) return axiosIns; +export const refreshClashInfo = async () => { + clashInfo = await getClashInfo(); + return clashInfo; +}; +export const fetch = async ( + path: string, + method: HttpVerb, + body?: any +): Promise> => { let server = ""; let secret = ""; try { - const info = await getClashInfo(); + const info = clashInfo ?? (await refreshClashInfo()); if (info?.server) { server = info.server; - // compatible width `external-controller` if (server.startsWith(":")) server = `127.0.0.1${server}`; else if (/^\d+$/.test(server)) server = `127.0.0.1:${server}`; @@ -24,19 +32,18 @@ export const getAxios = async (force: boolean = false) => { if (info?.secret) secret = info?.secret; } catch {} - axiosIns = axios.create({ - baseURL: `http://${server}`, + return tauriFetch(`http://${server}${path}`, { + method, headers: secret ? { Authorization: `Bearer ${secret}` } : {}, timeout: 15000, + body: body ? Body.json(body) : undefined, }); - axiosIns.interceptors.response.use((r) => r.data); - return axiosIns; }; /// Get Version export const getVersion = async () => { - const instance = await getAxios(); - return instance.get("/version") as Promise<{ + const res = await fetch("/version", "GET"); + return res.data as Promise<{ premium: boolean; meta?: boolean; version: string; @@ -45,33 +52,32 @@ export const getVersion = async () => { /// Get current base configs export const getClashConfig = async () => { - const instance = await getAxios(); - return instance.get("/configs") as Promise; + const res = await fetch("/configs", "GET"); + return res.data as Promise; }; /// Update current configs export const updateConfigs = async (config: Partial) => { - const instance = await getAxios(); - return instance.patch("/configs", config); + const res = await fetch("/configs", "PATCH", config); + return res; }; /// Update geo data export const updateGeoData = async () => { - const instance = await getAxios(); - return instance.post("/configs/geo"); + const res = await fetch("/configs/geo", "POST"); + return res; }; /// Upgrade clash core export const upgradeCore = async () => { - const instance = await getAxios(); - return instance.post("/upgrade"); + const res = await fetch("/upgrade", "POST"); + return res; }; /// Get current rules export const getRules = async () => { - const instance = await getAxios(); - const response = await instance.get("/rules"); - return response?.rules as IRuleItem[]; + const res = await fetch("/rules", "GET"); + return res?.data?.rules as IRuleItem[]; }; /// Get Proxy delay @@ -80,25 +86,26 @@ export const getProxyDelay = async (name: string, url?: string) => { timeout: 10000, url: url || "http://1.1.1.1", }; - const instance = await getAxios(); - const result = await instance.get( + const result = await fetch( `/proxies/${encodeURIComponent(name)}/delay`, + "GET", { params } ); - return result as any as { delay: number }; + return result.data as any as { delay: number }; }; /// Update the Proxy Choose export const updateProxy = async (group: string, proxy: string) => { - const instance = await getAxios(); - return instance.put(`/proxies/${encodeURIComponent(group)}`, { name: proxy }); + const res = await fetch(`/proxies/${encodeURIComponent(group)}`, "PUT", { + name: proxy, + }); + return res; }; // get proxy export const getProxiesInner = async () => { - const instance = await getAxios(); - const response = await instance.get("/proxies"); - return (response?.proxies || {}) as Record; + const res = await fetch("/proxies", "GET"); + return (res?.data?.proxies || {}) as Record; }; /// Get the Proxy information @@ -167,10 +174,8 @@ export const getProxies = async () => { // get proxy providers export const getProviders = async () => { - const instance = await getAxios(); - const response = await instance.get("/providers/proxies"); - - const providers = (response.providers || {}) as Record; + const res = await fetch("/providers/proxies", "GET"); + const providers = (res.data.providers || {}) as Record; return Object.fromEntries( Object.entries(providers).filter(([key, item]) => { @@ -182,31 +187,34 @@ export const getProviders = async () => { // proxy providers health check export const providerHealthCheck = async (name: string) => { - const instance = await getAxios(); - return instance.get( - `/providers/proxies/${encodeURIComponent(name)}/healthcheck` + const res = await fetch( + `/providers/proxies/${encodeURIComponent(name)}/healthcheck`, + "GET" ); + return res; }; export const providerUpdate = async (name: string) => { - const instance = await getAxios(); - return instance.put(`/providers/proxies/${encodeURIComponent(name)}`); + const res = await fetch( + `/providers/proxies/${encodeURIComponent(name)}`, + "PUT" + ); + return res; }; export const getConnections = async () => { - const instance = await getAxios(); - const result = await instance.get("/connections"); - return result as any as IConnections; + const res = await fetch("/connections", "GET"); + return res.data as any as IConnections; }; // Close specific connection export const deleteConnection = async (id: string) => { - const instance = await getAxios(); - await instance.delete(`/connections/${encodeURIComponent(id)}`); + const res = await fetch(`/connections/${encodeURIComponent(id)}`, "DELETE"); + return res; }; // Close all connections export const closeAllConnections = async () => { - const instance = await getAxios(); - await instance.delete(`/connections`); + const res = await fetch("/connections", "DELETE"); + return res; };