revert: restore app/appType param compatibility and revert segmented-thumb pointer-events change

- Restore backend commands to accept app_type/app/appType with priority app_type
- Frontend invoke() now passes both { app_type, app } again
- Revert CSS change that set pointer-events: none on segmented-thumb
- Keep minor fix: open_config_folder signature uses handle + respects both names

Note: warnings for non_snake_case (appType) are expected for compatibility.
This commit is contained in:
Jason
2025-08-31 18:14:31 +08:00
parent b4ebb7c9e5
commit 06a19519c5
6 changed files with 31 additions and 23 deletions

View File

@@ -455,13 +455,13 @@ pub async fn get_claude_code_config_path() -> Result<String, String> {
/// 兼容两种参数:`app_type`(推荐)或 `app`(字符串) /// 兼容两种参数:`app_type`(推荐)或 `app`(字符串)
#[tauri::command] #[tauri::command]
pub async fn open_config_folder( pub async fn open_config_folder(
app: tauri::AppHandle, handle: tauri::AppHandle,
app_type: Option<AppType>, app_type: Option<AppType>,
app_str: Option<String>, app: Option<String>,
appType: Option<String>, appType: Option<String>,
) -> Result<bool, String> { ) -> Result<bool, String> {
let app_type = app_type let app_type = app_type
.or_else(|| app_str.as_deref().map(|s| s.into())) .or_else(|| app.as_deref().map(|s| s.into()))
.or_else(|| appType.as_deref().map(|s| s.into())) .or_else(|| appType.as_deref().map(|s| s.into()))
.unwrap_or(AppType::Claude); .unwrap_or(AppType::Claude);
@@ -476,7 +476,7 @@ pub async fn open_config_folder(
} }
// 使用 opener 插件打开文件夹 // 使用 opener 插件打开文件夹
app.opener() handle.opener()
.open_path(config_dir.to_string_lossy().to_string(), None::<String>) .open_path(config_dir.to_string_lossy().to_string(), None::<String>)
.map_err(|e| format!("打开文件夹失败: {}", e))?; .map_err(|e| format!("打开文件夹失败: {}", e))?;

View File

@@ -50,7 +50,9 @@
background: var(--seg-thumb); background: var(--seg-thumb);
border-radius: 999px; border-radius: 999px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
transition: transform 220ms ease, width 220ms ease; transition:
transform 220ms ease,
width 220ms ease;
will-change: transform; will-change: transform;
} }

View File

@@ -182,16 +182,14 @@ function App() {
<header className="app-header"> <header className="app-header">
<h1>{activeApp === "claude" ? "Claude Code" : "Codex"} </h1> <h1>{activeApp === "claude" ? "Claude Code" : "Codex"} </h1>
<div className="app-tabs"> <div className="app-tabs">
<div <div className="segmented" role="tablist" aria-label="选择应用">
className="segmented"
role="tablist"
aria-label="选择应用"
>
<span <span
className="segmented-thumb" className="segmented-thumb"
style={{ style={{
transform: transform:
activeApp === "claude" ? "translateX(0%)" : "translateX(100%)", activeApp === "claude"
? "translateX(0%)"
: "translateX(100%)",
}} }}
/> />
<button <button

View File

@@ -48,7 +48,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
const [codexConfig, setCodexConfig] = useState(""); const [codexConfig, setCodexConfig] = useState("");
const [codexApiKey, setCodexApiKey] = useState(""); const [codexApiKey, setCodexApiKey] = useState("");
const [selectedCodexPreset, setSelectedCodexPreset] = useState<number | null>( const [selectedCodexPreset, setSelectedCodexPreset] = useState<number | null>(
null null,
); );
// 初始化 Codex 配置 // 初始化 Codex 配置
@@ -151,7 +151,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
}; };
const handleChange = ( const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => { ) => {
const { name, value } = e.target; const { name, value } = e.target;
@@ -188,7 +188,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
// 更新JSON配置 // 更新JSON配置
const updatedConfig = updateCoAuthoredSetting( const updatedConfig = updateCoAuthoredSetting(
formData.settingsConfig, formData.settingsConfig,
checked checked,
); );
setFormData({ setFormData({
...formData, ...formData,
@@ -219,7 +219,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
// Codex: 应用预设 // Codex: 应用预设
const applyCodexPreset = ( const applyCodexPreset = (
preset: (typeof codexProviderPresets)[0], preset: (typeof codexProviderPresets)[0],
index: number index: number,
) => { ) => {
const authString = JSON.stringify(preset.auth || {}, null, 2); const authString = JSON.stringify(preset.auth || {}, null, 2);
setCodexAuth(authString); setCodexAuth(authString);
@@ -244,7 +244,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
const configString = setApiKeyInConfig( const configString = setApiKeyInConfig(
formData.settingsConfig, formData.settingsConfig,
key.trim(), key.trim(),
{ createIfMissing: selectedPreset !== null } { createIfMissing: selectedPreset !== null },
); );
// 更新表单配置 // 更新表单配置
@@ -298,7 +298,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
useEffect(() => { useEffect(() => {
if (initialData) { if (initialData) {
const parsedKey = getApiKeyFromConfig( const parsedKey = getApiKeyFromConfig(
JSON.stringify(initialData.settingsConfig) JSON.stringify(initialData.settingsConfig),
); );
if (parsedKey) setApiKey(parsedKey); if (parsedKey) setApiKey(parsedKey);
} }
@@ -447,7 +447,9 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
: "只需要填这里,下方 auth.json 会自动填充" : "只需要填这里,下方 auth.json 会自动填充"
} }
disabled={isCodexOfficialPreset} disabled={isCodexOfficialPreset}
required={selectedCodexPreset !== null && !isCodexOfficialPreset} required={
selectedCodexPreset !== null && !isCodexOfficialPreset
}
autoComplete="off" autoComplete="off"
style={ style={
isCodexOfficialPreset isCodexOfficialPreset

View File

@@ -16,7 +16,7 @@ export const codexProviderPresets: CodexProviderPreset[] = [
isOfficial: true, isOfficial: true,
// 官方的 key 为null // 官方的 key 为null
auth: { auth: {
"OPENAI_API_KEY": null, OPENAI_API_KEY: null,
}, },
config: ``, config: ``,
}, },
@@ -25,7 +25,7 @@ export const codexProviderPresets: CodexProviderPreset[] = [
websiteUrl: "https://codex.packycode.com/", websiteUrl: "https://codex.packycode.com/",
// PackyCode 一般通过 API Key请将占位符替换为你的实际 key // PackyCode 一般通过 API Key请将占位符替换为你的实际 key
auth: { auth: {
"OPENAI_API_KEY": "sk-your-api-key-here", OPENAI_API_KEY: "sk-your-api-key-here",
}, },
config: `model_provider = "packycode" config: `model_provider = "packycode"
model = "gpt-5" model = "gpt-5"
@@ -38,4 +38,3 @@ wire_api = "responses"
env_key = "packycode"`, env_key = "packycode"`,
}, },
]; ];

View File

@@ -78,7 +78,11 @@ export const tauriAPI = {
app?: AppType, app?: AppType,
): Promise<boolean> => { ): Promise<boolean> => {
try { try {
return await invoke("switch_provider", { id: providerId, app_type: app, app }); return await invoke("switch_provider", {
id: providerId,
app_type: app,
app,
});
} catch (error) { } catch (error) {
console.error("切换供应商失败:", error); console.error("切换供应商失败:", error);
return false; return false;
@@ -90,7 +94,10 @@ export const tauriAPI = {
app?: AppType, app?: AppType,
): Promise<ImportResult> => { ): Promise<ImportResult> => {
try { try {
const success = await invoke<boolean>("import_default_config", { app_type: app, app }); const success = await invoke<boolean>("import_default_config", {
app_type: app,
app,
});
return { return {
success, success,
message: success ? "成功导入默认配置" : "导入失败", message: success ? "成功导入默认配置" : "导入失败",