mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-02 18:41:35 +08:00
Merge remote-tracking branch 'origin/main' into feat/auto-failover-switch
# Conflicts: # src/App.tsx
This commit is contained in:
+89
-75
@@ -310,79 +310,93 @@ function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderContent = () => {
|
const renderContent = () => {
|
||||||
switch (currentView) {
|
const content = (() => {
|
||||||
case "settings":
|
switch (currentView) {
|
||||||
return (
|
case "settings":
|
||||||
<SettingsPage
|
return (
|
||||||
open={true}
|
<SettingsPage
|
||||||
onOpenChange={() => setCurrentView("providers")}
|
open={true}
|
||||||
onImportSuccess={handleImportSuccess}
|
onOpenChange={() => setCurrentView("providers")}
|
||||||
/>
|
onImportSuccess={handleImportSuccess}
|
||||||
);
|
/>
|
||||||
case "prompts":
|
);
|
||||||
return (
|
case "prompts":
|
||||||
<PromptPanel
|
return (
|
||||||
ref={promptPanelRef}
|
<PromptPanel
|
||||||
open={true}
|
ref={promptPanelRef}
|
||||||
onOpenChange={() => setCurrentView("providers")}
|
open={true}
|
||||||
appId={activeApp}
|
onOpenChange={() => setCurrentView("providers")}
|
||||||
/>
|
appId={activeApp}
|
||||||
);
|
/>
|
||||||
case "skills":
|
);
|
||||||
return (
|
case "skills":
|
||||||
<SkillsPage
|
return (
|
||||||
ref={skillsPageRef}
|
<SkillsPage
|
||||||
onClose={() => setCurrentView("providers")}
|
ref={skillsPageRef}
|
||||||
initialApp={activeApp}
|
onClose={() => setCurrentView("providers")}
|
||||||
/>
|
initialApp={activeApp}
|
||||||
);
|
/>
|
||||||
case "mcp":
|
);
|
||||||
return (
|
case "mcp":
|
||||||
<UnifiedMcpPanel
|
return (
|
||||||
ref={mcpPanelRef}
|
<UnifiedMcpPanel
|
||||||
onOpenChange={() => setCurrentView("providers")}
|
ref={mcpPanelRef}
|
||||||
/>
|
onOpenChange={() => setCurrentView("providers")}
|
||||||
);
|
/>
|
||||||
case "agents":
|
);
|
||||||
return <AgentsPanel onOpenChange={() => setCurrentView("providers")} />;
|
case "agents":
|
||||||
default:
|
return <AgentsPanel onOpenChange={() => setCurrentView("providers")} />;
|
||||||
return (
|
default:
|
||||||
<div className="mx-auto max-w-[56rem] px-5 flex flex-col h-[calc(100vh-8rem)] overflow-hidden">
|
return (
|
||||||
{/* 独立滚动容器 - 解决 Linux/Ubuntu 下 DndContext 与滚轮事件冲突 */}
|
<div className="mx-auto max-w-[56rem] px-5 flex flex-col h-[calc(100vh-8rem)] overflow-hidden">
|
||||||
<div className="flex-1 px-1 pb-12 overflow-x-hidden overflow-y-auto">
|
{/* 独立滚动容器 - 解决 Linux/Ubuntu 下 DndContext 与滚轮事件冲突 */}
|
||||||
<AnimatePresence mode="wait">
|
<div className="flex-1 overflow-y-auto overflow-x-hidden pb-12 px-1">
|
||||||
<motion.div
|
<AnimatePresence mode="wait">
|
||||||
key={activeApp}
|
<motion.div
|
||||||
initial={{ opacity: 0 }}
|
key={activeApp}
|
||||||
animate={{ opacity: 1 }}
|
initial={{ opacity: 0 }}
|
||||||
exit={{ opacity: 0 }}
|
animate={{ opacity: 1 }}
|
||||||
transition={{ duration: 0.15 }}
|
exit={{ opacity: 0 }}
|
||||||
className="space-y-4"
|
transition={{ duration: 0.15 }}
|
||||||
>
|
className="space-y-4"
|
||||||
<ProviderList
|
>
|
||||||
providers={providers}
|
<ProviderList
|
||||||
currentProviderId={currentProviderId}
|
providers={providers}
|
||||||
appId={activeApp}
|
currentProviderId={currentProviderId}
|
||||||
isLoading={isLoading}
|
appId={activeApp}
|
||||||
isProxyRunning={isProxyRunning}
|
isLoading={isLoading}
|
||||||
isProxyTakeover={
|
isProxyRunning={isProxyRunning}
|
||||||
isProxyRunning && isCurrentAppTakeoverActive
|
isProxyTakeover={isProxyRunning && isCurrentAppTakeoverActive}
|
||||||
}
|
activeProviderId={activeProviderId}
|
||||||
activeProviderId={activeProviderId}
|
onSwitch={switchProvider}
|
||||||
onSwitch={switchProvider}
|
onEdit={setEditingProvider}
|
||||||
onEdit={setEditingProvider}
|
onDelete={setConfirmDelete}
|
||||||
onDelete={setConfirmDelete}
|
onDuplicate={handleDuplicateProvider}
|
||||||
onDuplicate={handleDuplicateProvider}
|
onConfigureUsage={setUsageProvider}
|
||||||
onConfigureUsage={setUsageProvider}
|
onOpenWebsite={handleOpenWebsite}
|
||||||
onOpenWebsite={handleOpenWebsite}
|
onCreate={() => setIsAddOpen(true)}
|
||||||
onCreate={() => setIsAddOpen(true)}
|
/>
|
||||||
/>
|
</motion.div>
|
||||||
</motion.div>
|
</AnimatePresence>
|
||||||
</AnimatePresence>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
}
|
||||||
}
|
})();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AnimatePresence mode="wait">
|
||||||
|
<motion.div
|
||||||
|
key={currentView}
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
transition={{ duration: 0.2 }}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</motion.div>
|
||||||
|
</AnimatePresence>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -494,14 +508,14 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className="flex items-center gap-2"
|
className="flex items-center gap-2 min-h-[40px]"
|
||||||
style={{ WebkitAppRegion: "no-drag" } as any}
|
style={{ WebkitAppRegion: "no-drag" } as any}
|
||||||
>
|
>
|
||||||
{currentView === "prompts" && (
|
{currentView === "prompts" && (
|
||||||
<Button
|
<Button
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => promptPanelRef.current?.openAdd()}
|
onClick={() => promptPanelRef.current?.openAdd()}
|
||||||
className={addActionButtonClass}
|
className={`ml-auto ${addActionButtonClass}`}
|
||||||
title={t("prompts.add")}
|
title={t("prompts.add")}
|
||||||
>
|
>
|
||||||
<Plus className="w-5 h-5" />
|
<Plus className="w-5 h-5" />
|
||||||
@@ -511,7 +525,7 @@ function App() {
|
|||||||
<Button
|
<Button
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => mcpPanelRef.current?.openAdd()}
|
onClick={() => mcpPanelRef.current?.openAdd()}
|
||||||
className={addActionButtonClass}
|
className={`ml-auto ${addActionButtonClass}`}
|
||||||
title={t("mcp.unifiedPanel.addServer")}
|
title={t("mcp.unifiedPanel.addServer")}
|
||||||
>
|
>
|
||||||
<Plus className="w-5 h-5" />
|
<Plus className="w-5 h-5" />
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { createPortal } from "react-dom";
|
import { createPortal } from "react-dom";
|
||||||
|
import { motion } from "framer-motion";
|
||||||
import { ArrowLeft } from "lucide-react";
|
import { ArrowLeft } from "lucide-react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
@@ -35,7 +36,10 @@ export const FullScreenPanel: React.FC<FullScreenPanelProps> = ({
|
|||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
return createPortal(
|
return createPortal(
|
||||||
<div
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.2 }}
|
||||||
className="fixed inset-0 z-[60] flex flex-col"
|
className="fixed inset-0 z-[60] flex flex-col"
|
||||||
style={{ backgroundColor: "hsl(var(--background))" }}
|
style={{ backgroundColor: "hsl(var(--background))" }}
|
||||||
>
|
>
|
||||||
@@ -71,7 +75,7 @@ export const FullScreenPanel: React.FC<FullScreenPanelProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>,
|
</motion.div>,
|
||||||
document.body,
|
document.body,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user