Files
CC-Switch/src/hooks/useStreamCheck.ts
T

79 lines
2.2 KiB
TypeScript

import { useState, useCallback } from "react";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import {
streamCheckProvider,
type StreamCheckResult,
} from "@/lib/api/model-test";
import type { AppId } from "@/lib/api";
export function useStreamCheck(appId: AppId) {
const { t } = useTranslation();
const [checkingIds, setCheckingIds] = useState<Set<string>>(new Set());
const checkProvider = useCallback(
async (
providerId: string,
providerName: string,
): Promise<StreamCheckResult | null> => {
setCheckingIds((prev) => new Set(prev).add(providerId));
try {
const result = await streamCheckProvider(appId, providerId);
if (result.status === "operational") {
toast.success(
t("streamCheck.operational", {
name: providerName,
time: result.responseTimeMs,
defaultValue: `${providerName} 运行正常 (${result.responseTimeMs}ms)`,
}),
{ closeButton: true },
);
} else if (result.status === "degraded") {
toast.warning(
t("streamCheck.degraded", {
name: providerName,
time: result.responseTimeMs,
defaultValue: `${providerName} 响应较慢 (${result.responseTimeMs}ms)`,
}),
);
} else {
toast.error(
t("streamCheck.failed", {
name: providerName,
error: result.message,
defaultValue: `${providerName} 检查失败: ${result.message}`,
}),
);
}
return result;
} catch (e) {
toast.error(
t("streamCheck.error", {
name: providerName,
error: String(e),
defaultValue: `${providerName} 检查出错: ${String(e)}`,
}),
);
return null;
} finally {
setCheckingIds((prev) => {
const next = new Set(prev);
next.delete(providerId);
return next;
});
}
},
[appId, t],
);
const isChecking = useCallback(
(providerId: string) => checkingIds.has(providerId),
[checkingIds],
);
return { checkProvider, isChecking };
}