// ============================================================ // CanvasPage — 无限画布页面 // // 两栏 flex 布局(Assets 阶段为单栏): // 左侧:ShotList(镜头单选列表) // 右侧:CanvasViewport(主画布) // 顶部:CanvasToolbar // 底部:状态栏 // ============================================================ import { useTheme } from '@/components/providers/ThemeProvider'; import { useCanvasStore } from './store/useCanvasStore'; import { useDirectoryScan } from './hooks/useDirectoryScan'; import { CanvasToolbar } from './toolbar/CanvasToolbar'; import { CanvasViewport } from './core/CanvasViewport'; import { ShotList } from './navigation/ShotList'; /** 中心区域占位提示 */ function Placeholder({ icon, title, hint, isDark, }: { icon: string; title: string; hint: string; isDark: boolean; }) { return (
{icon}
{title}
{hint}
); } export function CanvasPage() { const { isDark } = useTheme(); const workspaceRoot = useCanvasStore((s) => s.workspaceRoot); const selectedProject = useCanvasStore((s) => s.selectedProject); const selectedEpisode = useCanvasStore((s) => s.selectedEpisode); const selectedShot = useCanvasStore((s) => s.selectedShot); const items = useCanvasStore((s) => s.items); const isScanning = useCanvasStore((s) => s.isScanning); const currentStage = useCanvasStore((s) => s.currentStage); // 启动目录扫描监听 useDirectoryScan(); const isAssets = currentStage === 'Assets'; /** 根据当前选中状态决定主视图内容 */ const renderMainContent = () => { if (!workspaceRoot) { return ( ); } if (!selectedProject) { return ( ); } if (isScanning) { return (
🔍
正在扫描文件…
); } if (!isAssets && !selectedEpisode) { return ( ); } if (!isAssets && !selectedShot) { return ( ); } if (items.length === 0) { return ( ); } return ; }; return (
{/* 顶部工具栏 */} {/* 中心区域:两栏布局 */}
{/* 左侧镜头列表(Assets 阶段隐藏) */} {/* 右侧主内容 */}
{renderMainContent()}
{/* 底部状态栏 */}
离线模式 · 本地文件系统 | {isScanning ? '扫描中…' : workspaceRoot ? `项目:${selectedProject || '(未选)'} · 阶段:${currentStage} · ${items.length} 个文件` : '准备就绪'} {selectedEpisode && ( <> | 集数:{selectedEpisode} )} {selectedShot && ( <> | 镜头:{selectedShot} )} Phase 1
); }