Files
CC-Switch/src/components/providers/forms/GeminiFormFields.tsx
T
Dex Miller 99c910e58e fix(provider): persist endpoint auto-select state (#611)
- Add endpointAutoSelect field to ProviderMeta for persistence
- Lift autoSelect state from EndpointSpeedTest to ProviderForm
- Save auto-select preference when provider is saved
- Restore preference when editing existing provider

Fixes https://github.com/farion1231/cc-switch/issues/589
2026-01-12 16:26:17 +08:00

157 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useTranslation } from "react-i18next";
import { FormLabel } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Info } from "lucide-react";
import EndpointSpeedTest from "./EndpointSpeedTest";
import { ApiKeySection, EndpointField } from "./shared";
import type { ProviderCategory } from "@/types";
interface EndpointCandidate {
url: string;
}
interface GeminiFormFieldsProps {
providerId?: string;
// API Key
shouldShowApiKey: boolean;
apiKey: string;
onApiKeyChange: (key: string) => void;
category?: ProviderCategory;
shouldShowApiKeyLink: boolean;
websiteUrl: string;
isPartner?: boolean;
partnerPromotionKey?: string;
// Base URL
shouldShowSpeedTest: boolean;
baseUrl: string;
onBaseUrlChange: (url: string) => void;
isEndpointModalOpen: boolean;
onEndpointModalToggle: (open: boolean) => void;
onCustomEndpointsChange: (endpoints: string[]) => void;
autoSelect: boolean;
onAutoSelectChange: (checked: boolean) => void;
// Model
shouldShowModelField: boolean;
model: string;
onModelChange: (value: string) => void;
// Speed Test Endpoints
speedTestEndpoints: EndpointCandidate[];
}
export function GeminiFormFields({
providerId,
shouldShowApiKey,
apiKey,
onApiKeyChange,
category,
shouldShowApiKeyLink,
websiteUrl,
isPartner,
partnerPromotionKey,
shouldShowSpeedTest,
baseUrl,
onBaseUrlChange,
isEndpointModalOpen,
onEndpointModalToggle,
onCustomEndpointsChange,
autoSelect,
onAutoSelectChange,
shouldShowModelField,
model,
onModelChange,
speedTestEndpoints,
}: GeminiFormFieldsProps) {
const { t } = useTranslation();
// 检测是否为 Google 官方(使用 OAuth
const isGoogleOfficial =
partnerPromotionKey?.toLowerCase() === "google-official";
return (
<>
{/* Google OAuth 提示 */}
{isGoogleOfficial && (
<div className="rounded-lg border border-blue-200 bg-blue-50 p-4 dark:border-blue-800 dark:bg-blue-950">
<div className="flex gap-3">
<Info className="h-5 w-5 flex-shrink-0 text-blue-600 dark:text-blue-400" />
<div className="space-y-1">
<p className="text-sm font-medium text-blue-900 dark:text-blue-100">
{t("provider.form.gemini.oauthTitle", {
defaultValue: "OAuth 认证模式",
})}
</p>
<p className="text-sm text-blue-700 dark:text-blue-300">
{t("provider.form.gemini.oauthHint", {
defaultValue:
"Google 官方使用 OAuth 个人认证,无需填写 API Key。首次使用时会自动打开浏览器进行登录。",
})}
</p>
</div>
</div>
</div>
)}
{/* API Key 输入框 */}
{shouldShowApiKey && !isGoogleOfficial && (
<ApiKeySection
value={apiKey}
onChange={onApiKeyChange}
category={category}
shouldShowLink={shouldShowApiKeyLink}
websiteUrl={websiteUrl}
isPartner={isPartner}
partnerPromotionKey={partnerPromotionKey}
/>
)}
{/* Base URL 输入框(统一使用与 Codex 相同的样式与交互) */}
{shouldShowSpeedTest && (
<EndpointField
id="baseUrl"
label={t("providerForm.apiEndpoint", { defaultValue: "API 端点" })}
value={baseUrl}
onChange={onBaseUrlChange}
placeholder={t("providerForm.apiEndpointPlaceholder", {
defaultValue: "https://your-api-endpoint.com/",
})}
onManageClick={() => onEndpointModalToggle(true)}
/>
)}
{/* Model 输入框 */}
{shouldShowModelField && (
<div>
<FormLabel htmlFor="gemini-model">
{t("provider.form.gemini.model", { defaultValue: "模型" })}
</FormLabel>
<Input
id="gemini-model"
value={model}
onChange={(e) => onModelChange(e.target.value)}
placeholder="gemini-3-pro-preview"
/>
</div>
)}
{/* 端点测速弹窗 */}
{shouldShowSpeedTest && isEndpointModalOpen && (
<EndpointSpeedTest
appId="gemini"
providerId={providerId}
value={baseUrl}
onChange={onBaseUrlChange}
initialEndpoints={speedTestEndpoints}
visible={isEndpointModalOpen}
onClose={() => onEndpointModalToggle(false)}
autoSelect={autoSelect}
onAutoSelectChange={onAutoSelectChange}
onCustomEndpointsChange={onCustomEndpointsChange}
/>
)}
</>
);
}