b123a36aae
后端修复: - main.go: 恢复 /api/v1/chat 路由中丢失的 handleChat 调用 (空响应回归) - orchestrator.go: splitChatByLines 改为双换行分割, 避免单换行误拆 - chat_handler.go: multi_message 增加 !hasReview 守卫, 消息延迟 200→800ms - thinker.go: RecordUserMessage 追踪活跃会话ID, 推送主动消息到正确会话 - thinker.go: 增强思考提示词 — 禁止在用户休息/离开时发送主动消息 前端修复: - useWebSocket.ts: stream_segments 不再创建消息气泡, 消除重复回复 - MessageBubble.tsx: 动作消息居左对齐无头像, 时间戳移至气泡外侧 hover 显示 - ChatInput.tsx: 昔涟输入提示移至输入框上方, 波点动画效果 - MessageList/TypingIndicator/ChatContainer: 清理冗余 isTyping 传递 - MemoryPanel.tsx: 新增记忆面板组件 文档重整: - docs/debug/ → docs/debug_log/ 重命名统一 - 新增 debug_log/README.md 索引 - .gitignore: 新增 android/ 排除规则 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
import { useState } from 'react';
|
|
import { Sidebar } from './Sidebar';
|
|
import { Header } from './Header';
|
|
import { SearchModal } from './SearchModal';
|
|
import { MemoryPanel } from './MemoryPanel';
|
|
import { useAuth } from '@/hooks/useAuth';
|
|
|
|
interface AppLayoutProps {
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
export function AppLayout({ children }: AppLayoutProps) {
|
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
const [searchOpen, setSearchOpen] = useState(false);
|
|
const [memoryOpen, setMemoryOpen] = useState(false);
|
|
const { isLoggedIn } = useAuth();
|
|
|
|
return (
|
|
<div className="flex h-screen bg-[#FFFAF5] dark:bg-[#1a1a2e]">
|
|
{/* 侧边栏 */}
|
|
{isLoggedIn && (
|
|
<>
|
|
{/* 移动端遮罩 */}
|
|
{sidebarOpen && (
|
|
<div
|
|
className="fixed inset-0 bg-black/30 z-20 lg:hidden"
|
|
onClick={() => setSidebarOpen(false)}
|
|
/>
|
|
)}
|
|
<div
|
|
className={`
|
|
fixed lg:static inset-y-0 left-0 z-30 w-64 transform transition-transform duration-300 ease-in-out
|
|
${sidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'}
|
|
`}
|
|
>
|
|
<Sidebar onClose={() => setSidebarOpen(false)} onMemoryClick={() => setMemoryOpen(true)} />
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
{/* 主内容区 */}
|
|
<div className="flex-1 flex flex-col min-w-0">
|
|
{isLoggedIn && (
|
|
<Header
|
|
onMenuClick={() => setSidebarOpen(!sidebarOpen)}
|
|
onSearchClick={() => setSearchOpen(true)}
|
|
/>
|
|
)}
|
|
<main className="flex-1 min-h-0 overflow-hidden">{children}</main>
|
|
</div>
|
|
|
|
{/* 搜索弹窗 */}
|
|
<SearchModal isOpen={searchOpen} onClose={() => setSearchOpen(false)} />
|
|
{/* 记忆管理弹窗 */}
|
|
<MemoryPanel isOpen={memoryOpen} onClose={() => setMemoryOpen(false)} />
|
|
</div>
|
|
);
|
|
}
|