refactor: 清理 Electron 遗留代码并优化项目结构

- 删除 Electron 主进程代码 (src/main/)
- 删除构建产物文件夹 (build/, dist/, release/)
- 清理 package.json 中的 Electron 依赖和脚本
- 删除 TypeScript 配置中的 Electron 相关文件
- 优化前端代码结构至 Tauri 标准结构 (src/renderer → src/)
- 删除移动端图标和不必要文件
- 更新文档说明技术栈变更为 Tauri
This commit is contained in:
farion1231
2025-08-23 21:13:25 +08:00
parent 29581b85d9
commit 12fa80e002
63 changed files with 16 additions and 922 deletions

244
src/App.tsx Normal file
View File

@@ -0,0 +1,244 @@
import { useState, useEffect, useRef } from "react";
import { Provider } from "../shared/types";
import ProviderList from "./components/ProviderList";
import AddProviderModal from "./components/AddProviderModal";
import EditProviderModal from "./components/EditProviderModal";
import { ConfirmDialog } from "./components/ConfirmDialog";
import "./App.css";
function App() {
const [providers, setProviders] = useState<Record<string, Provider>>({});
const [currentProviderId, setCurrentProviderId] = useState<string>("");
const [isAddModalOpen, setIsAddModalOpen] = useState(false);
const [configPath, setConfigPath] = useState<string>("");
const [editingProviderId, setEditingProviderId] = useState<string | null>(
null
);
const [notification, setNotification] = useState<{
message: string;
type: "success" | "error";
} | null>(null);
const [isNotificationVisible, setIsNotificationVisible] = useState(false);
const [confirmDialog, setConfirmDialog] = useState<{
isOpen: boolean;
title: string;
message: string;
onConfirm: () => void;
} | null>(null);
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
// 设置通知的辅助函数
const showNotification = (
message: string,
type: "success" | "error",
duration = 3000
) => {
// 清除之前的定时器
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
// 立即显示通知
setNotification({ message, type });
setIsNotificationVisible(true);
// 设置淡出定时器
timeoutRef.current = setTimeout(() => {
setIsNotificationVisible(false);
// 等待淡出动画完成后清除通知
setTimeout(() => {
setNotification(null);
timeoutRef.current = null;
}, 300); // 与CSS动画时间匹配
}, duration);
};
// 加载供应商列表
useEffect(() => {
loadProviders();
loadConfigPath();
}, []);
// 清理定时器
useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);
const loadProviders = async () => {
const loadedProviders = await window.electronAPI.getProviders();
const currentId = await window.electronAPI.getCurrentProvider();
setProviders(loadedProviders);
setCurrentProviderId(currentId);
// 如果供应商列表为空,尝试自动导入现有配置为"default"供应商
if (Object.keys(loadedProviders).length === 0) {
await handleAutoImportDefault();
}
};
const loadConfigPath = async () => {
const path = await window.electronAPI.getClaudeCodeConfigPath();
setConfigPath(path);
};
// 生成唯一ID
const generateId = () => {
return crypto.randomUUID();
};
const handleAddProvider = async (provider: Omit<Provider, "id">) => {
const newProvider: Provider = {
...provider,
id: generateId(),
};
await window.electronAPI.addProvider(newProvider);
await loadProviders();
setIsAddModalOpen(false);
};
const handleEditProvider = async (provider: Provider) => {
try {
await window.electronAPI.updateProvider(provider);
await loadProviders();
setEditingProviderId(null);
// 显示编辑成功提示
showNotification("供应商配置已保存", "success", 2000);
} catch (error) {
console.error("更新供应商失败:", error);
setEditingProviderId(null);
showNotification("保存失败,请重试", "error");
}
};
const handleDeleteProvider = async (id: string) => {
const provider = providers[id];
setConfirmDialog({
isOpen: true,
title: "删除供应商",
message: `确定要删除供应商 "${provider?.name}" 吗?此操作无法撤销。`,
onConfirm: async () => {
await window.electronAPI.deleteProvider(id);
await loadProviders();
setConfirmDialog(null);
showNotification("供应商删除成功", "success");
},
});
};
const handleSwitchProvider = async (id: string) => {
const success = await window.electronAPI.switchProvider(id);
if (success) {
setCurrentProviderId(id);
// 显示重启提示
showNotification(
"切换成功!请重启 Claude Code 终端以生效",
"success",
2000
);
} else {
showNotification("切换失败,请检查配置", "error");
}
};
// 自动导入现有配置为"default"供应商
const handleAutoImportDefault = async () => {
try {
const result = await window.electronAPI.importCurrentConfigAsDefault()
if (result.success) {
await loadProviders()
showNotification("已自动导入现有配置为 default 供应商", "success", 3000)
}
// 如果导入失败(比如没有现有配置),静默处理,不显示错误
} catch (error) {
console.error('自动导入默认配置失败:', error)
// 静默处理,不影响用户体验
}
}
const handleOpenConfigFolder = async () => {
await window.electronAPI.openConfigFolder();
};
return (
<div className="app">
<header className="app-header">
<h1>Claude Code </h1>
<div className="header-actions">
<button className="add-btn" onClick={() => setIsAddModalOpen(true)}>
</button>
</div>
</header>
<main className="app-main">
<div className="provider-section">
{/* 浮动通知组件 */}
{notification && (
<div
className={`notification-floating ${
notification.type === "error"
? "notification-error"
: "notification-success"
} ${isNotificationVisible ? "fade-in" : "fade-out"}`}
>
{notification.message}
</div>
)}
<ProviderList
providers={providers}
currentProviderId={currentProviderId}
onSwitch={handleSwitchProvider}
onDelete={handleDeleteProvider}
onEdit={setEditingProviderId}
/>
</div>
{configPath && (
<div className="config-path">
<span>: {configPath}</span>
<button
className="browse-btn"
onClick={handleOpenConfigFolder}
title="打开配置文件夹"
>
</button>
</div>
)}
</main>
{isAddModalOpen && (
<AddProviderModal
onAdd={handleAddProvider}
onClose={() => setIsAddModalOpen(false)}
/>
)}
{editingProviderId && providers[editingProviderId] && (
<EditProviderModal
provider={providers[editingProviderId]}
onSave={handleEditProvider}
onClose={() => setEditingProviderId(null)}
/>
)}
{confirmDialog && (
<ConfirmDialog
isOpen={confirmDialog.isOpen}
title={confirmDialog.title}
message={confirmDialog.message}
onConfirm={confirmDialog.onConfirm}
onCancel={() => setConfirmDialog(null)}
/>
)}
</div>
);
}
export default App;