// ============================================================
// 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 (
);
}
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
);
}