mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
8fe5c1041a
* feat: add Universal Provider feature - Add Universal Provider data structures and type definitions - Implement backend CRUD operations and sync functionality - Add frontend UI components (UniversalProviderPanel, Card, FormModal) - Add NewAPI icon and preset configuration - Support cross-app (Claude/Codex/Gemini) configuration sync - Add website URL field for providers - Implement real-time refresh via event notifications - Add i18n support (Chinese/English/Japanese) * feat: integrate universal provider presets into add provider dialog - Add universal provider presets (NewAPI, Custom Gateway) to preset selector - Show universal presets with Layers icon badge in preset selector - Open UniversalProviderFormModal when universal preset is clicked - Pass initialPreset to auto-fill form when opened from add dialog - Add i18n keys for addSuccess/addFailed messages - Keep separate universal provider panel for management * refactor: move universal provider management to add dialog - Remove Layers button from main navigation header - Add 'Manage' button next to universal provider presets - Open UniversalProviderPanel from within add provider dialog - Add i18n keys for 'manage' in all locales * style: display universal provider presets on separate line - Move universal provider section to a new row with border separator - Add label '统一供应商:' to clarify the section * style: unify universal provider label style with preset label - Use FormLabel component for consistent styling - Add background to 'Manage' button matching preset buttons - Update icon size and button padding for consistency * feat: add sync functionality and JSON preview for Universal Provider * fix: add missing in_failover_queue field to Provider structs After rebasing to main, the Provider struct gained a new `in_failover_queue` field. This fix adds the missing field to the three to_*_provider() methods in UniversalProvider. * refactor: redesign AddProviderDialog with tab-based layout - Add tabs to separate app-specific providers and universal providers - Move "Add Universal Provider" button from panel header to footer - Remove unused handleAdd callback and clean up imports - Update emptyHint i18n text to reference the footer button * fix: append /v1 suffix to Codex base_url in Universal Provider Codex uses OpenAI-compatible API which requires the /v1 endpoint suffix. The Universal Provider now automatically appends /v1 to base_url when generating Codex provider config if not already present. - Handle trailing slashes to avoid double slashes - Apply fix to both backend (to_codex_provider) and frontend preview * feat: auto-sync universal provider to apps on creation Previously, users had to manually click sync after adding a universal provider. Now it automatically syncs to Claude/Codex/Gemini on creation, providing a smoother user experience. --------- Co-authored-by: Jason <farion1231@gmail.com>
110 lines
2.9 KiB
TypeScript
110 lines
2.9 KiB
TypeScript
import { invoke } from "@tauri-apps/api/core";
|
||
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
|
||
import type {
|
||
Provider,
|
||
UniversalProvider,
|
||
UniversalProvidersMap,
|
||
} from "@/types";
|
||
import type { AppId } from "./types";
|
||
|
||
export interface ProviderSortUpdate {
|
||
id: string;
|
||
sortIndex: number;
|
||
}
|
||
|
||
export interface ProviderSwitchEvent {
|
||
appType: AppId;
|
||
providerId: string;
|
||
}
|
||
|
||
export const providersApi = {
|
||
async getAll(appId: AppId): Promise<Record<string, Provider>> {
|
||
return await invoke("get_providers", { app: appId });
|
||
},
|
||
|
||
async getCurrent(appId: AppId): Promise<string> {
|
||
return await invoke("get_current_provider", { app: appId });
|
||
},
|
||
|
||
async add(provider: Provider, appId: AppId): Promise<boolean> {
|
||
return await invoke("add_provider", { provider, app: appId });
|
||
},
|
||
|
||
async update(provider: Provider, appId: AppId): Promise<boolean> {
|
||
return await invoke("update_provider", { provider, app: appId });
|
||
},
|
||
|
||
async delete(id: string, appId: AppId): Promise<boolean> {
|
||
return await invoke("delete_provider", { id, app: appId });
|
||
},
|
||
|
||
async switch(id: string, appId: AppId): Promise<boolean> {
|
||
return await invoke("switch_provider", { id, app: appId });
|
||
},
|
||
|
||
async importDefault(appId: AppId): Promise<boolean> {
|
||
return await invoke("import_default_config", { app: appId });
|
||
},
|
||
|
||
async updateTrayMenu(): Promise<boolean> {
|
||
return await invoke("update_tray_menu");
|
||
},
|
||
|
||
async updateSortOrder(
|
||
updates: ProviderSortUpdate[],
|
||
appId: AppId,
|
||
): Promise<boolean> {
|
||
return await invoke("update_providers_sort_order", { updates, app: appId });
|
||
},
|
||
|
||
async onSwitched(
|
||
handler: (event: ProviderSwitchEvent) => void,
|
||
): Promise<UnlistenFn> {
|
||
return await listen("provider-switched", (event) => {
|
||
const payload = event.payload as ProviderSwitchEvent;
|
||
handler(payload);
|
||
});
|
||
},
|
||
};
|
||
|
||
// ============================================================================
|
||
// 统一供应商(Universal Provider)API
|
||
// ============================================================================
|
||
|
||
export const universalProvidersApi = {
|
||
/**
|
||
* 获取所有统一供应商
|
||
*/
|
||
async getAll(): Promise<UniversalProvidersMap> {
|
||
return await invoke("get_universal_providers");
|
||
},
|
||
|
||
/**
|
||
* 获取单个统一供应商
|
||
*/
|
||
async get(id: string): Promise<UniversalProvider | null> {
|
||
return await invoke("get_universal_provider", { id });
|
||
},
|
||
|
||
/**
|
||
* 添加或更新统一供应商
|
||
*/
|
||
async upsert(provider: UniversalProvider): Promise<boolean> {
|
||
return await invoke("upsert_universal_provider", { provider });
|
||
},
|
||
|
||
/**
|
||
* 删除统一供应商
|
||
*/
|
||
async delete(id: string): Promise<boolean> {
|
||
return await invoke("delete_universal_provider", { id });
|
||
},
|
||
|
||
/**
|
||
* 手动同步统一供应商到各应用
|
||
*/
|
||
async sync(id: string): Promise<boolean> {
|
||
return await invoke("sync_universal_provider", { id });
|
||
},
|
||
};
|