From bd8a32360045a0dcd8eb55529daebd1533e055bf Mon Sep 17 00:00:00 2001 From: Jason Date: Sat, 31 Jan 2026 17:16:36 +0800 Subject: [PATCH] feat(opencode): add API key link support for OpenCode provider form Enable API key link feature for OpenCode app, allowing users to access provider websites for key registration directly from the form. --- .../providers/forms/OpenCodeFormFields.tsx | 6 ++++++ .../providers/forms/ProviderForm.tsx | 20 +++++++++++++++++-- .../providers/forms/hooks/useApiKeyLink.ts | 5 +++-- .../forms/hooks/useProviderCategory.ts | 8 +++++++- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/components/providers/forms/OpenCodeFormFields.tsx b/src/components/providers/forms/OpenCodeFormFields.tsx index 49f08e25b..56f7415c2 100644 --- a/src/components/providers/forms/OpenCodeFormFields.tsx +++ b/src/components/providers/forms/OpenCodeFormFields.tsx @@ -139,6 +139,8 @@ interface OpenCodeFormFieldsProps { category?: ProviderCategory; shouldShowApiKeyLink: boolean; websiteUrl: string; + isPartner?: boolean; + partnerPromotionKey?: string; // Base URL baseUrl: string; @@ -161,6 +163,8 @@ export function OpenCodeFormFields({ category, shouldShowApiKeyLink, websiteUrl, + isPartner, + partnerPromotionKey, baseUrl, onBaseUrlChange, models, @@ -376,6 +380,8 @@ export function OpenCodeFormFields({ category={category} shouldShowLink={shouldShowApiKeyLink} websiteUrl={websiteUrl} + isPartner={isPartner} + partnerPromotionKey={partnerPromotionKey} /> {/* Base URL */} diff --git a/src/components/providers/forms/ProviderForm.tsx b/src/components/providers/forms/ProviderForm.tsx index c05dd38b3..ee7f19b02 100644 --- a/src/components/providers/forms/ProviderForm.tsx +++ b/src/components/providers/forms/ProviderForm.tsx @@ -1010,6 +1010,20 @@ export function ProviderForm({ formWebsiteUrl: form.watch("websiteUrl") || "", }); + // 使用 API Key 链接 hook (OpenCode) + const { + shouldShowApiKeyLink: shouldShowOpencodeApiKeyLink, + websiteUrl: opencodeWebsiteUrl, + isPartner: isOpencodePartner, + partnerPromotionKey: opencodePartnerPromotionKey, + } = useApiKeyLink({ + appId: "opencode", + category, + selectedPresetId, + presetEntries, + formWebsiteUrl: form.watch("websiteUrl") || "", + }); + // 使用端点测速候选 hook const speedTestEndpoints = useSpeedTestEndpoints({ appId, @@ -1341,8 +1355,10 @@ export function ProviderForm({ apiKey={opencodeApiKey} onApiKeyChange={handleOpencodeApiKeyChange} category={category} - shouldShowApiKeyLink={false} - websiteUrl="" + shouldShowApiKeyLink={shouldShowOpencodeApiKeyLink} + websiteUrl={opencodeWebsiteUrl} + isPartner={isOpencodePartner} + partnerPromotionKey={opencodePartnerPromotionKey} baseUrl={opencodeBaseUrl} onBaseUrlChange={handleOpencodeBaseUrlChange} models={opencodeModels} diff --git a/src/components/providers/forms/hooks/useApiKeyLink.ts b/src/components/providers/forms/hooks/useApiKeyLink.ts index e02689246..d5e20103c 100644 --- a/src/components/providers/forms/hooks/useApiKeyLink.ts +++ b/src/components/providers/forms/hooks/useApiKeyLink.ts @@ -4,10 +4,11 @@ import type { ProviderCategory } from "@/types"; import type { ProviderPreset } from "@/config/claudeProviderPresets"; import type { CodexProviderPreset } from "@/config/codexProviderPresets"; import type { GeminiProviderPreset } from "@/config/geminiProviderPresets"; +import type { OpenCodeProviderPreset } from "@/config/opencodeProviderPresets"; type PresetEntry = { id: string; - preset: ProviderPreset | CodexProviderPreset | GeminiProviderPreset; + preset: ProviderPreset | CodexProviderPreset | GeminiProviderPreset | OpenCodeProviderPreset; }; interface UseApiKeyLinkProps { @@ -74,7 +75,7 @@ export function useApiKeyLink({ return { shouldShowApiKeyLink: - appId === "claude" || appId === "codex" || appId === "gemini" + appId === "claude" || appId === "codex" || appId === "gemini" || appId === "opencode" ? shouldShowApiKeyLink : false, websiteUrl: getWebsiteUrl, diff --git a/src/components/providers/forms/hooks/useProviderCategory.ts b/src/components/providers/forms/hooks/useProviderCategory.ts index 30808cc41..7760d9bbb 100644 --- a/src/components/providers/forms/hooks/useProviderCategory.ts +++ b/src/components/providers/forms/hooks/useProviderCategory.ts @@ -4,6 +4,7 @@ import type { AppId } from "@/lib/api"; import { providerPresets } from "@/config/claudeProviderPresets"; import { codexProviderPresets } from "@/config/codexProviderPresets"; import { geminiProviderPresets } from "@/config/geminiProviderPresets"; +import { opencodeProviderPresets } from "@/config/opencodeProviderPresets"; interface UseProviderCategoryProps { appId: AppId; @@ -42,7 +43,7 @@ export function useProviderCategory({ if (!selectedPresetId) return; // 从预设 ID 提取索引 - const match = selectedPresetId.match(/^(claude|codex|gemini)-(\d+)$/); + const match = selectedPresetId.match(/^(claude|codex|gemini|opencode)-(\d+)$/); if (!match) return; const [, type, indexStr] = match; @@ -67,6 +68,11 @@ export function useProviderCategory({ if (preset) { setCategory(preset.category || undefined); } + } else if (type === "opencode" && appId === "opencode") { + const preset = opencodeProviderPresets[index]; + if (preset) { + setCategory(preset.category || undefined); + } } }, [appId, selectedPresetId, isEditMode, initialCategory]);