From 5c36ae066bf70b0cd366ef6a7ad43d78c1a03aae Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 7 Jun 2026 17:10:40 +0800 Subject: [PATCH] fix(providers): only block explicit official providers under proxy takeover MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The proxy-takeover block previously fell back to the isOfficial heuristic (empty base_url / missing key) when category was absent. That misjudged custom providers whose endpoint lives in meta or whose fields are simply unfilled: their switch button got disabled, making users think the config was broken. That extra UI block was also "virtual" — the executor in useProviderActions only ever honored category === "official", so the front end blocked more than the backend would enforce. Gate the block solely on explicit category === "official", matching the executor and unifying both verdicts on a single source of truth. Also rework the blocked-state UI: - drop the red "blocked" badge for a plain disabled Enable button - move title/cursor onto a wrapper span (disabled buttons set pointer-events:none, so an on-button title/cursor never fired) - replace the account-ban warning tooltip with a lighter hint (provider.blockedByProxyHint), four locales kept in sync --- src/components/providers/ProviderActions.tsx | 64 +++++++++++++------- src/components/providers/ProviderCard.tsx | 10 ++- src/i18n/locales/en.json | 2 +- src/i18n/locales/ja.json | 2 +- src/i18n/locales/zh-TW.json | 2 +- src/i18n/locales/zh.json | 2 +- 6 files changed, 56 insertions(+), 26 deletions(-) diff --git a/src/components/providers/ProviderActions.tsx b/src/components/providers/ProviderActions.tsx index 30dfe3d90..4e9911450 100644 --- a/src/components/providers/ProviderActions.tsx +++ b/src/components/providers/ProviderActions.tsx @@ -7,7 +7,6 @@ import { Minus, Play, Plus, - ShieldAlert, Terminal, TestTube2, Trash2, @@ -45,6 +44,18 @@ interface ProviderActionsProps { onSetAsDefault?: () => void; } +// 主按钮的呈现状态。title 用于 disabled 态向用户解释为何不可点击; +// 因 Button 基类带 disabled:pointer-events-none,title 必须挂在外层非禁用 +// 的 wrapper 上才会在 hover 时显示(见下方 包裹)。 +interface MainButtonState { + disabled: boolean; + variant: "default" | "secondary"; + className: string; + icon: JSX.Element; + text: string; + title?: string; +} + export function ProviderActions({ appId, isCurrent, @@ -108,7 +119,7 @@ export function ProviderActions({ } }; - const getMainButtonState = () => { + const getMainButtonState = (): MainButtonState => { if (isOmo) { if (isCurrent) { return { @@ -174,16 +185,6 @@ export function ProviderActions({ }; } - if (isOfficialBlockedByProxy) { - return { - disabled: true, - variant: "secondary" as const, - className: "opacity-40 cursor-not-allowed", - icon: , - text: t("provider.blockedByProxy", { defaultValue: "已拦截" }), - }; - } - if (isCurrent) { return { disabled: true, @@ -195,6 +196,17 @@ export function ProviderActions({ }; } + if (isOfficialBlockedByProxy) { + return { + disabled: true, + variant: "default" as const, + className: "", + icon: , + text: t("provider.enable"), + title: t("provider.blockedByProxyHint"), + }; + } + return { disabled: false, variant: "default" as const, @@ -247,16 +259,26 @@ export function ProviderActions({ ); })()} - + +