mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-28 07:14:40 +08:00
Compare commits
2 Commits
9d81a13c58
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c57a962109 | ||
|
|
36926df26c |
@@ -10,14 +10,13 @@ import { useLockFn } from "ahooks";
|
||||
import { useCallback, useEffect, useMemo, useReducer } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router";
|
||||
import useSWR from "swr";
|
||||
|
||||
import { useServiceInstaller } from "@/hooks/use-service-installer";
|
||||
import { useSystemState } from "@/hooks/use-system-state";
|
||||
import { useUpdate } from "@/hooks/use-update";
|
||||
import { useVerge } from "@/hooks/use-verge";
|
||||
import { getSystemInfo } from "@/services/cmds";
|
||||
import { showNotice } from "@/services/notice-service";
|
||||
import { checkUpdateSafe as checkUpdate } from "@/services/update";
|
||||
import { version as appVersion } from "@root/package.json";
|
||||
|
||||
import { EnhancedCard } from "./enhanced-card";
|
||||
@@ -52,6 +51,18 @@ export const SystemInfoCard = () => {
|
||||
const { isAdminMode, isSidecarMode } = useSystemState();
|
||||
const { installServiceAndRestartCore } = useServiceInstaller();
|
||||
|
||||
// 自动检查更新逻辑
|
||||
const { checkUpdate: triggerCheckUpdate } = useUpdate(true, {
|
||||
onSuccess: () => {
|
||||
const now = Date.now();
|
||||
localStorage.setItem("last_check_update", now.toString());
|
||||
dispatchSystemState({
|
||||
type: "set-last-check-update",
|
||||
payload: new Date(now).toLocaleString(),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// 系统信息状态
|
||||
const [systemState, dispatchSystemState] = useReducer(systemStateReducer, {
|
||||
osInfo: "",
|
||||
@@ -109,7 +120,7 @@ export const SystemInfoCard = () => {
|
||||
|
||||
timeoutId = window.setTimeout(() => {
|
||||
if (verge?.auto_check_update) {
|
||||
checkUpdate().catch(console.error);
|
||||
triggerCheckUpdate().catch(console.error);
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
@@ -118,26 +129,7 @@ export const SystemInfoCard = () => {
|
||||
window.clearTimeout(timeoutId);
|
||||
}
|
||||
};
|
||||
}, [verge?.auto_check_update, dispatchSystemState]);
|
||||
|
||||
// 自动检查更新逻辑
|
||||
useSWR(
|
||||
verge?.auto_check_update ? "checkUpdate" : null,
|
||||
async () => {
|
||||
const now = Date.now();
|
||||
localStorage.setItem("last_check_update", now.toString());
|
||||
dispatchSystemState({
|
||||
type: "set-last-check-update",
|
||||
payload: new Date(now).toLocaleString(),
|
||||
});
|
||||
return await checkUpdate();
|
||||
},
|
||||
{
|
||||
revalidateOnFocus: false,
|
||||
refreshInterval: 24 * 60 * 60 * 1000, // 每天检查一次
|
||||
dedupingInterval: 60 * 60 * 1000, // 1小时内不重复检查
|
||||
},
|
||||
);
|
||||
}, [verge?.auto_check_update, dispatchSystemState, triggerCheckUpdate]);
|
||||
|
||||
// 导航到设置页面
|
||||
const goToSettings = useCallback(() => {
|
||||
@@ -164,7 +156,7 @@ export const SystemInfoCard = () => {
|
||||
// 检查更新
|
||||
const onCheckUpdate = useLockFn(async () => {
|
||||
try {
|
||||
const info = await checkUpdate();
|
||||
const info = await triggerCheckUpdate();
|
||||
if (!info?.available) {
|
||||
showNotice.success(
|
||||
"settings.components.verge.advanced.notifications.latestVersion",
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { Button } from "@mui/material";
|
||||
import { useRef } from "react";
|
||||
import useSWR from "swr";
|
||||
|
||||
import { DialogRef } from "@/components/base";
|
||||
import { useVerge } from "@/hooks/use-verge";
|
||||
import { checkUpdateSafe } from "@/services/update";
|
||||
import { useUpdate } from "@/hooks/use-update";
|
||||
|
||||
import { UpdateViewer } from "../setting/mods/update-viewer";
|
||||
|
||||
@@ -14,20 +12,9 @@ interface Props {
|
||||
|
||||
export const UpdateButton = (props: Props) => {
|
||||
const { className } = props;
|
||||
const { verge } = useVerge();
|
||||
const { auto_check_update } = verge || {};
|
||||
|
||||
const viewerRef = useRef<DialogRef>(null);
|
||||
|
||||
const { data: updateInfo } = useSWR(
|
||||
auto_check_update || auto_check_update === null ? "checkUpdate" : null,
|
||||
checkUpdateSafe,
|
||||
{
|
||||
errorRetryCount: 2,
|
||||
revalidateIfStale: false,
|
||||
focusThrottleInterval: 36e5, // 1 hour
|
||||
},
|
||||
);
|
||||
const { updateInfo } = useUpdate();
|
||||
|
||||
if (!updateInfo?.available) return null;
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { useEffect, useMemo } from "react";
|
||||
import useSWR from "swr";
|
||||
|
||||
import { useRuntimeConfig } from "@/hooks/use-clash";
|
||||
import { useVerge } from "@/hooks/use-verge";
|
||||
import { useAppData } from "@/providers/app-data-context";
|
||||
import { getRuntimeConfig } from "@/services/cmds";
|
||||
import delayManager from "@/services/delay";
|
||||
import { debugLog } from "@/utils/debug";
|
||||
|
||||
@@ -107,14 +106,7 @@ export const useRenderList = (
|
||||
const latencyTimeout = verge?.default_latency_timeout;
|
||||
|
||||
// 获取运行时配置用于链式代理模式
|
||||
const { data: runtimeConfig } = useSWR(
|
||||
isChainMode ? "getRuntimeConfig" : null,
|
||||
getRuntimeConfig,
|
||||
{
|
||||
revalidateOnFocus: false,
|
||||
revalidateIfStale: true,
|
||||
},
|
||||
);
|
||||
const { data: runtimeConfig } = useRuntimeConfig(!!isChainMode);
|
||||
|
||||
// 计算列数
|
||||
const col = useMemo(
|
||||
|
||||
@@ -4,10 +4,9 @@ import { writeText } from "@tauri-apps/plugin-clipboard-manager";
|
||||
import type { Ref } from "react";
|
||||
import { useImperativeHandle, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import useSWR from "swr";
|
||||
|
||||
import { BaseDialog, DialogRef } from "@/components/base";
|
||||
import { getNetworkInterfacesInfo } from "@/services/cmds";
|
||||
import { useNetworkInterfaces } from "@/hooks/use-network";
|
||||
import { showNotice } from "@/services/notice-service";
|
||||
|
||||
export function NetworkInterfaceViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
@@ -22,13 +21,7 @@ export function NetworkInterfaceViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
close: () => setOpen(false),
|
||||
}));
|
||||
|
||||
const { data: networkInterfaces } = useSWR(
|
||||
"clash-verge-rev-internal://network-interfaces",
|
||||
getNetworkInterfacesInfo,
|
||||
{
|
||||
fallbackData: [], // default data before fetch
|
||||
},
|
||||
);
|
||||
const { networkInterfaces } = useNetworkInterfaces();
|
||||
|
||||
return (
|
||||
<BaseDialog
|
||||
|
||||
@@ -8,13 +8,12 @@ import { useImperativeHandle, useMemo, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import rehypeRaw from "rehype-raw";
|
||||
import useSWR from "swr";
|
||||
|
||||
import { BaseDialog, DialogRef } from "@/components/base";
|
||||
import { useUpdate } from "@/hooks/use-update";
|
||||
import { portableFlag } from "@/pages/_layout";
|
||||
import { showNotice } from "@/services/notice-service";
|
||||
import { useSetUpdateState, useUpdateState } from "@/services/states";
|
||||
import { checkUpdateSafe as checkUpdate } from "@/services/update";
|
||||
|
||||
export function UpdateViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
const { t } = useTranslation();
|
||||
@@ -23,11 +22,7 @@ export function UpdateViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
const updateState = useUpdateState();
|
||||
const setUpdateState = useSetUpdateState();
|
||||
|
||||
const { data: updateInfo } = useSWR("checkUpdate", checkUpdate, {
|
||||
errorRetryCount: 2,
|
||||
revalidateIfStale: false,
|
||||
focusThrottleInterval: 36e5, // 1 hour
|
||||
});
|
||||
const { updateInfo } = useUpdate();
|
||||
|
||||
const [downloaded, setDownloaded] = useState(0);
|
||||
const [total, setTotal] = useState(0);
|
||||
|
||||
@@ -51,11 +51,12 @@ const validatePorts = (patch: ClashInfoPatch) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const useRuntimeConfig = (shouldFetch: boolean = true) => {
|
||||
return useSWR(shouldFetch ? "getRuntimeConfig" : null, getRuntimeConfig);
|
||||
};
|
||||
|
||||
export const useClash = () => {
|
||||
const { data: clash, mutate: mutateClash } = useSWR(
|
||||
"getRuntimeConfig",
|
||||
getRuntimeConfig,
|
||||
);
|
||||
const { data: clash, mutate: mutateClash } = useRuntimeConfig();
|
||||
|
||||
const { data: versionData, mutate: mutateVersion } = useSWR(
|
||||
"getVersion",
|
||||
|
||||
22
src/hooks/use-network.ts
Normal file
22
src/hooks/use-network.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import useSWR from "swr";
|
||||
|
||||
import { getNetworkInterfacesInfo } from "@/services/cmds";
|
||||
|
||||
export const useNetworkInterfaces = () => {
|
||||
const { data, error, isLoading, mutate } = useSWR(
|
||||
"getNetworkInterfacesInfo",
|
||||
getNetworkInterfacesInfo,
|
||||
{
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
fallbackData: [],
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
networkInterfaces: data || [],
|
||||
loading: isLoading,
|
||||
error,
|
||||
mutate,
|
||||
};
|
||||
};
|
||||
46
src/hooks/use-update.ts
Normal file
46
src/hooks/use-update.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import useSWR, { SWRConfiguration } from "swr";
|
||||
|
||||
import { checkUpdateSafe } from "@/services/update";
|
||||
|
||||
import { useVerge } from "./use-verge";
|
||||
|
||||
export interface UpdateInfo {
|
||||
version: string;
|
||||
body: string;
|
||||
date: string;
|
||||
available: boolean;
|
||||
downloadAndInstall: (onEvent?: any) => Promise<void>;
|
||||
}
|
||||
|
||||
export const useUpdate = (
|
||||
enabled: boolean = true,
|
||||
options?: SWRConfiguration,
|
||||
) => {
|
||||
const { verge } = useVerge();
|
||||
const { auto_check_update } = verge || {};
|
||||
|
||||
// Determine if we should check for updates
|
||||
// If enabled is explicitly false, don't check
|
||||
// Otherwise, respect the auto_check_update setting (or default to true if null/undefined for manual triggers)
|
||||
const shouldCheck = enabled && auto_check_update !== false;
|
||||
|
||||
const {
|
||||
data: updateInfo,
|
||||
mutate: checkUpdate,
|
||||
isValidating,
|
||||
} = useSWR(shouldCheck ? "checkUpdate" : null, checkUpdateSafe, {
|
||||
errorRetryCount: 2,
|
||||
revalidateIfStale: false,
|
||||
revalidateOnFocus: false,
|
||||
focusThrottleInterval: 36e5, // 1 hour
|
||||
refreshInterval: 24 * 60 * 60 * 1000, // 24 hours
|
||||
dedupingInterval: 60 * 60 * 1000, // 1 hour
|
||||
...options,
|
||||
});
|
||||
|
||||
return {
|
||||
updateInfo,
|
||||
checkUpdate,
|
||||
loading: isValidating,
|
||||
};
|
||||
};
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
getRunningMode,
|
||||
getSystemProxy,
|
||||
} from "@/services/cmds";
|
||||
import { SWR_DEFAULTS, SWR_MIHOMO, SWR_REALTIME } from "@/services/config";
|
||||
import { SWR_DEFAULTS, SWR_MIHOMO } from "@/services/config";
|
||||
|
||||
import { AppDataContext, AppDataContextType } from "./app-data-context";
|
||||
|
||||
@@ -30,14 +30,7 @@ export const AppDataProvider = ({
|
||||
const { data: proxiesData, mutate: refreshProxy } = useSWR(
|
||||
"getProxies",
|
||||
calcuProxies,
|
||||
{
|
||||
...SWR_REALTIME,
|
||||
onError: (_) => {
|
||||
// FIXME when we intially start the app, and core is starting,
|
||||
// there will be error thrown by getProxies API.
|
||||
// We should handle this case properly later.
|
||||
},
|
||||
},
|
||||
SWR_MIHOMO,
|
||||
);
|
||||
|
||||
const { data: clashConfig, mutate: refreshClashConfig } = useSWR(
|
||||
|
||||
@@ -16,12 +16,6 @@ export const SWR_DEFAULTS = {
|
||||
dedupingInterval: 5000,
|
||||
} as const;
|
||||
|
||||
export const SWR_REALTIME = {
|
||||
...SWR_DEFAULTS,
|
||||
refreshInterval: 8000,
|
||||
dedupingInterval: 3000,
|
||||
} as const;
|
||||
|
||||
export const SWR_SLOW_POLL = {
|
||||
...SWR_DEFAULTS,
|
||||
refreshInterval: 60000,
|
||||
@@ -29,4 +23,6 @@ export const SWR_SLOW_POLL = {
|
||||
|
||||
export const SWR_MIHOMO = {
|
||||
...SWR_NOT_SMART,
|
||||
errorRetryInterval: 500,
|
||||
errorRetryCount: 15,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user