studynote/src/App.tsx
MikiVL d632e9f6f7 feat(M3): AI 续写/润色/摘要/问答、Hono 代理、模型管理窗口
- 新增 Hono 代理服务(server/index.ts,端口 3001),SSE 流式转发 Claude API
- 新增 src/lib/ai.ts:streamAI() 封装 fetch + ReadableStream + AbortController
- 新增 AI 面板(AiPanel.tsx):流式聊天问答、全文摘要、停止按钮
- 新增模型管理弹窗(ModelSettingsModal.tsx):增删模型、切换激活模型
- 编辑器新增 AI 续写()和面板切换()按钮
- 浮动工具栏新增润色(Wand2)和摘要(FileText)按钮,结果预览 Modal 支持一键替换
- appStore 新增 aiPanelOpen + toggleAiPanel
- vite.config.ts 添加 /api 代理到 localhost:3001
- index.css 添加 .ai-cursor 光标动画

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 00:03:50 +08:00

31 lines
914 B
TypeScript

import { useEffect } from 'react'
import { Sidebar } from './components/sidebar/Sidebar'
import { Editor } from './components/editor/Editor'
import { AiPanel } from './components/ai/AiPanel'
import { useAppStore } from './stores/appStore'
import { seedIfEmpty, deduplicateDB } from './db'
export default function App() {
const { loadAll, theme, focusMode, aiPanelOpen } = useAppStore()
useEffect(() => {
document.documentElement.setAttribute('data-theme', theme)
}, [theme])
useEffect(() => {
seedIfEmpty()
.then(() => deduplicateDB())
.then(() => loadAll())
}, [])
return (
<div className="flex h-screen w-full overflow-hidden" style={{ background: 'var(--bg)' }}>
<div className={`sidebar-panel${focusMode ? ' hidden' : ''}`} style={{ width: 260 }}>
<Sidebar />
</div>
<Editor />
{aiPanelOpen && !focusMode && <AiPanel />}
</div>
)
}