mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-06-16 13:34:04 +08:00
refactor(claude-desktop): trim duplication in proxy and switch flows
- services/proxy.rs: collapse 10 repeated `OpenCode | OpenClaw | Hermes | ClaudeDesktop` match arms into `_` fallthroughs. - claude_desktop_config.rs: extract a `with_rollback` closure shared by apply_provider_to_paths and restore_official_at_paths. - useProviderActions.ts: replace the triple-nested ternary picking the switch-success toast message with a flat let/if/else block. Net -36 lines. No behavior change; cargo test and pnpm typecheck pass.
This commit is contained in:
@@ -599,6 +599,8 @@ pub fn map_proxy_request_model(mut body: Value, provider: &Provider) -> Result<V
|
||||
}
|
||||
|
||||
pub fn proxy_gateway_base_url_from_db(db: &Database) -> Result<String, AppError> {
|
||||
// get_proxy_config is async-tagged but its body is fully synchronous (rusqlite
|
||||
// under a Mutex), so block_on cannot deadlock the calling thread.
|
||||
let config = futures::executor::block_on(db.get_proxy_config())?;
|
||||
Ok(format!(
|
||||
"{}{}",
|
||||
@@ -617,39 +619,32 @@ fn apply_provider_to_paths(
|
||||
}
|
||||
|
||||
validate_provider(provider)?;
|
||||
let snapshots = snapshot_files(paths)?;
|
||||
|
||||
if let Err(err) = apply_provider_to_paths_inner(db, provider, paths) {
|
||||
if let Err(rollback_err) = restore_snapshots(&snapshots) {
|
||||
log::error!(
|
||||
"Failed to rollback Claude Desktop config after apply error: {rollback_err}"
|
||||
);
|
||||
return Err(AppError::Message(format!(
|
||||
"{err}; rollback failed: {rollback_err}"
|
||||
)));
|
||||
}
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
with_rollback(paths, |paths| apply_provider_to_paths_inner(db, provider, paths))
|
||||
}
|
||||
|
||||
fn restore_official_at_paths(paths: &ClaudeDesktopPaths) -> Result<(), AppError> {
|
||||
with_rollback(paths, restore_official_at_paths_inner)
|
||||
}
|
||||
|
||||
fn with_rollback<F>(paths: &ClaudeDesktopPaths, op: F) -> Result<(), AppError>
|
||||
where
|
||||
F: FnOnce(&ClaudeDesktopPaths) -> Result<(), AppError>,
|
||||
{
|
||||
let snapshots = snapshot_files(paths)?;
|
||||
|
||||
if let Err(err) = restore_official_at_paths_inner(paths) {
|
||||
if let Err(rollback_err) = restore_snapshots(&snapshots) {
|
||||
log::error!(
|
||||
"Failed to rollback Claude Desktop config after restore error: {rollback_err}"
|
||||
);
|
||||
return Err(AppError::Message(format!(
|
||||
"{err}; rollback failed: {rollback_err}"
|
||||
)));
|
||||
}
|
||||
return Err(err);
|
||||
match op(paths) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(err) => match restore_snapshots(&snapshots) {
|
||||
Ok(()) => Err(err),
|
||||
Err(rollback_err) => {
|
||||
log::error!(
|
||||
"Failed to rollback Claude Desktop config after error: {rollback_err}"
|
||||
);
|
||||
Err(AppError::Message(format!(
|
||||
"{err}; rollback failed: {rollback_err}"
|
||||
)))
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn apply_provider_to_paths_inner(
|
||||
|
||||
@@ -466,10 +466,7 @@ impl ProxyService {
|
||||
AppType::Claude => self.read_claude_live()?,
|
||||
AppType::Codex => self.read_codex_live()?,
|
||||
AppType::Gemini => self.read_gemini_live()?,
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes | AppType::ClaudeDesktop => {
|
||||
// These apps don't support proxy features
|
||||
return Err("该应用不支持代理功能".to_string());
|
||||
}
|
||||
_ => return Err("该应用不支持代理功能".to_string()),
|
||||
};
|
||||
|
||||
self.sync_live_config_to_provider(app_type, &live_config)
|
||||
@@ -683,9 +680,7 @@ impl ProxyService {
|
||||
}
|
||||
}
|
||||
}
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes | AppType::ClaudeDesktop => {
|
||||
// These apps don't support proxy features, skip silently
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -864,10 +859,7 @@ impl ProxyService {
|
||||
AppType::Claude => ("claude", self.read_claude_live()?),
|
||||
AppType::Codex => ("codex", self.read_codex_live()?),
|
||||
AppType::Gemini => ("gemini", self.read_gemini_live()?),
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes | AppType::ClaudeDesktop => {
|
||||
// These apps don't support proxy features
|
||||
return Err("该应用不支持代理功能".to_string());
|
||||
}
|
||||
_ => return Err("该应用不支持代理功能".to_string()),
|
||||
};
|
||||
|
||||
let json_str = serde_json::to_string(&config)
|
||||
@@ -1008,10 +1000,7 @@ impl ProxyService {
|
||||
self.write_gemini_live(&live_config)?;
|
||||
log::info!("Gemini Live 配置已接管,代理地址: {proxy_url}");
|
||||
}
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes | AppType::ClaudeDesktop => {
|
||||
// These apps don't support proxy features
|
||||
return Err("该应用不支持代理功能".to_string());
|
||||
}
|
||||
_ => return Err("该应用不支持代理功能".to_string()),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1061,9 +1050,7 @@ impl ProxyService {
|
||||
let _ = self.write_gemini_live(&live_config);
|
||||
}
|
||||
}
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes | AppType::ClaudeDesktop => {
|
||||
// These apps don't support proxy features, skip silently
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1101,9 +1088,7 @@ impl ProxyService {
|
||||
log::info!("Gemini Live 配置已恢复");
|
||||
}
|
||||
}
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes | AppType::ClaudeDesktop => {
|
||||
// These apps don't support proxy features, skip silently
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1192,10 +1177,7 @@ impl ProxyService {
|
||||
AppType::Claude => self.write_claude_live(config),
|
||||
AppType::Codex => self.write_codex_live(config),
|
||||
AppType::Gemini => self.write_gemini_live(config),
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes | AppType::ClaudeDesktop => {
|
||||
// These apps don't support proxy features
|
||||
Err("该应用不支持代理功能".to_string())
|
||||
}
|
||||
_ => Err("该应用不支持代理功能".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1213,10 +1195,7 @@ impl ProxyService {
|
||||
Ok(config) => Self::is_gemini_live_taken_over(&config),
|
||||
Err(_) => false,
|
||||
},
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes | AppType::ClaudeDesktop => {
|
||||
// These apps don't support proxy takeover
|
||||
false
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1256,10 +1235,7 @@ impl ProxyService {
|
||||
AppType::Claude => self.cleanup_claude_takeover_placeholders_in_live(),
|
||||
AppType::Codex => self.cleanup_codex_takeover_placeholders_in_live(),
|
||||
AppType::Gemini => self.cleanup_gemini_takeover_placeholders_in_live(),
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes | AppType::ClaudeDesktop => {
|
||||
// These apps don't support proxy features
|
||||
Ok(())
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1520,9 +1496,7 @@ impl ProxyService {
|
||||
serde_json::to_string(&env_backup)
|
||||
.map_err(|e| format!("序列化 Gemini 配置失败: {e}"))?
|
||||
}
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes | AppType::ClaudeDesktop => {
|
||||
return Err(format!("未知的应用类型: {app_type}"));
|
||||
}
|
||||
_ => return Err(format!("未知的应用类型: {app_type}")),
|
||||
};
|
||||
|
||||
self.db
|
||||
|
||||
@@ -227,26 +227,21 @@ export function useProviderActions(
|
||||
|
||||
// 若已弹过 proxyRequired 警告则不再弹 success
|
||||
if (!proxyRequiredReason) {
|
||||
// OpenCode/OpenClaw: show "added to config" message instead of "switched"
|
||||
const isMultiProviderApp =
|
||||
activeApp === "opencode" || activeApp === "openclaw";
|
||||
const messageKey =
|
||||
activeApp === "claude-desktop"
|
||||
? provider.meta?.claudeDesktopMode === "proxy"
|
||||
? "notifications.claudeDesktopProxyRestartRequired"
|
||||
: "notifications.claudeDesktopRestartRequired"
|
||||
: isMultiProviderApp
|
||||
? "notifications.addToConfigSuccess"
|
||||
: "notifications.switchSuccess";
|
||||
const defaultMessage =
|
||||
activeApp === "claude-desktop"
|
||||
? provider.meta?.claudeDesktopMode === "proxy"
|
||||
? "切换成功,请保持 CC Switch 运行,并重启 Claude Desktop 后生效"
|
||||
: "切换成功,重启 Claude Desktop 后生效"
|
||||
: isMultiProviderApp
|
||||
? "已添加到配置"
|
||||
: "切换成功!";
|
||||
|
||||
let messageKey = "notifications.switchSuccess";
|
||||
let defaultMessage = "切换成功!";
|
||||
if (activeApp === "claude-desktop") {
|
||||
if (provider.meta?.claudeDesktopMode === "proxy") {
|
||||
messageKey = "notifications.claudeDesktopProxyRestartRequired";
|
||||
defaultMessage =
|
||||
"切换成功,请保持 CC Switch 运行,并重启 Claude Desktop 后生效";
|
||||
} else {
|
||||
messageKey = "notifications.claudeDesktopRestartRequired";
|
||||
defaultMessage = "切换成功,重启 Claude Desktop 后生效";
|
||||
}
|
||||
} else if (activeApp === "opencode" || activeApp === "openclaw") {
|
||||
messageKey = "notifications.addToConfigSuccess";
|
||||
defaultMessage = "已添加到配置";
|
||||
}
|
||||
toast.success(t(messageKey, { defaultValue: defaultMessage }), {
|
||||
closeButton: true,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user