mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-25 13:45:03 +08:00
fix(usage): only auto-poll Copilot/ChatGPT quota for current provider
CopilotQuotaFooter and CodexOauthQuotaFooter called their hooks with a hardcoded `enabled: true` plus an unconditional 5-minute refetch and refetchOnWindowFocus, so non-current reverse-proxy cards kept polling in violation of the project's "only the active provider auto-queries on cooldown" rule. With multiple Copilot or ChatGPT accounts bound to different cards, every card kept hitting its own usage endpoint. Adopt the same pattern as useUsageQuery: keep `enabled` independent of isCurrent so first-fetch and manual refresh still work, but gate refetchInterval / refetchIntervalInBackground / refetchOnWindowFocus on a new `autoQuery` option, and thread `isCurrent` from ProviderCard through the footers into the hooks.
This commit is contained in:
@@ -6,6 +6,8 @@ import { SubscriptionQuotaView } from "@/components/SubscriptionQuotaFooter";
|
||||
interface CodexOauthQuotaFooterProps {
|
||||
meta?: ProviderMeta;
|
||||
inline?: boolean;
|
||||
/** 是否为当前激活的供应商 */
|
||||
isCurrent?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -17,12 +19,13 @@ interface CodexOauthQuotaFooterProps {
|
||||
const CodexOauthQuotaFooter: React.FC<CodexOauthQuotaFooterProps> = ({
|
||||
meta,
|
||||
inline = false,
|
||||
isCurrent = false,
|
||||
}) => {
|
||||
const {
|
||||
data: quota,
|
||||
isFetching: loading,
|
||||
refetch,
|
||||
} = useCodexOauthQuota(meta, true);
|
||||
} = useCodexOauthQuota(meta, { enabled: true, autoQuery: isCurrent });
|
||||
|
||||
return (
|
||||
<SubscriptionQuotaView
|
||||
|
||||
@@ -13,6 +13,8 @@ import {
|
||||
interface CopilotQuotaFooterProps {
|
||||
meta?: ProviderMeta;
|
||||
inline?: boolean;
|
||||
/** 是否为当前激活的供应商 */
|
||||
isCurrent?: boolean;
|
||||
}
|
||||
|
||||
/** 格式化相对时间 */
|
||||
@@ -33,6 +35,7 @@ function formatRelativeTime(
|
||||
const CopilotQuotaFooter: React.FC<CopilotQuotaFooterProps> = ({
|
||||
meta,
|
||||
inline = false,
|
||||
isCurrent = false,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const accountId = resolveManagedAccountId(
|
||||
@@ -44,7 +47,7 @@ const CopilotQuotaFooter: React.FC<CopilotQuotaFooterProps> = ({
|
||||
data: quota,
|
||||
isFetching: loading,
|
||||
refetch,
|
||||
} = useCopilotQuota(accountId, true);
|
||||
} = useCopilotQuota(accountId, { enabled: true, autoQuery: isCurrent });
|
||||
|
||||
const [now, setNow] = React.useState(Date.now());
|
||||
React.useEffect(() => {
|
||||
|
||||
@@ -357,9 +357,17 @@ export function ProviderCard({
|
||||
<div className="ml-auto">
|
||||
<div className="flex items-center gap-1">
|
||||
{isCopilot ? (
|
||||
<CopilotQuotaFooter meta={provider.meta} inline={true} />
|
||||
<CopilotQuotaFooter
|
||||
meta={provider.meta}
|
||||
inline={true}
|
||||
isCurrent={isCurrent}
|
||||
/>
|
||||
) : isCodexOauth ? (
|
||||
<CodexOauthQuotaFooter meta={provider.meta} inline={true} />
|
||||
<CodexOauthQuotaFooter
|
||||
meta={provider.meta}
|
||||
inline={true}
|
||||
isCurrent={isCurrent}
|
||||
/>
|
||||
) : isOfficial ? (
|
||||
<SubscriptionQuotaFooter appId={appId} inline={true} />
|
||||
) : hasMultiplePlans ? (
|
||||
|
||||
@@ -13,7 +13,17 @@ export interface CopilotQuota {
|
||||
queriedAt: number | null;
|
||||
}
|
||||
|
||||
export function useCopilotQuota(accountId: string | null, enabled: boolean) {
|
||||
export interface UseCopilotQuotaOptions {
|
||||
enabled?: boolean;
|
||||
/** 是否启用自动轮询(5 分钟)与窗口 focus 重取 */
|
||||
autoQuery?: boolean;
|
||||
}
|
||||
|
||||
export function useCopilotQuota(
|
||||
accountId: string | null,
|
||||
options: UseCopilotQuotaOptions = {},
|
||||
) {
|
||||
const { enabled = true, autoQuery = false } = options;
|
||||
return useQuery<CopilotQuota>({
|
||||
queryKey: ["copilot", "quota", accountId ?? "default"],
|
||||
queryFn: async (): Promise<CopilotQuota> => {
|
||||
@@ -44,8 +54,9 @@ export function useCopilotQuota(accountId: string | null, enabled: boolean) {
|
||||
};
|
||||
},
|
||||
enabled,
|
||||
refetchInterval: REFETCH_INTERVAL,
|
||||
refetchOnWindowFocus: true,
|
||||
refetchInterval: autoQuery ? REFETCH_INTERVAL : false,
|
||||
refetchIntervalInBackground: autoQuery,
|
||||
refetchOnWindowFocus: autoQuery,
|
||||
staleTime: REFETCH_INTERVAL,
|
||||
retry: 1,
|
||||
});
|
||||
|
||||
@@ -19,6 +19,12 @@ export function useSubscriptionQuota(appId: AppId, enabled: boolean) {
|
||||
});
|
||||
}
|
||||
|
||||
export interface UseCodexOauthQuotaOptions {
|
||||
enabled?: boolean;
|
||||
/** 是否启用自动轮询(5 分钟)与窗口 focus 重取 */
|
||||
autoQuery?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Codex OAuth (ChatGPT Plus/Pro 反代) 订阅额度查询 hook
|
||||
*
|
||||
@@ -30,15 +36,17 @@ export function useSubscriptionQuota(appId: AppId, enabled: boolean) {
|
||||
*/
|
||||
export function useCodexOauthQuota(
|
||||
meta: ProviderMeta | undefined,
|
||||
enabled: boolean,
|
||||
options: UseCodexOauthQuotaOptions = {},
|
||||
) {
|
||||
const { enabled = true, autoQuery = false } = options;
|
||||
const accountId = resolveManagedAccountId(meta, PROVIDER_TYPES.CODEX_OAUTH);
|
||||
return useQuery({
|
||||
queryKey: ["codex_oauth", "quota", accountId ?? "default"],
|
||||
queryFn: () => subscriptionApi.getCodexOauthQuota(accountId),
|
||||
enabled,
|
||||
refetchInterval: REFETCH_INTERVAL,
|
||||
refetchOnWindowFocus: true,
|
||||
refetchInterval: autoQuery ? REFETCH_INTERVAL : false,
|
||||
refetchIntervalInBackground: autoQuery,
|
||||
refetchOnWindowFocus: autoQuery,
|
||||
staleTime: REFETCH_INTERVAL,
|
||||
retry: 1,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user