feat(canvas): 沉浸专注与短剧流程 - 支持专注模式与流程条并入顶栏体系 (#157)
- 沉浸专注:进入后隐藏顶部栏、Dock、缩放控件、小地图与素材托盘,保留专注胶囊可唤出工具与智能体;小屏默认进入,⇧⌘F 切换,Esc 在无选中与浮层时退出 - 智能体面板改贴边停靠并按顶栏让位,作为沉浸专注的配套依赖 - 短剧流程条并入顶栏:折叠入口移入顶栏按钮组,展开条锚定顶栏下缘,与工作模式开关互斥 - 流程步骤改为里程碑节点与状态轨道,新增 --flow-step-* Design Token Co-authored-by: sikongyue <3155157671@qq.com>
This commit is contained in:
@@ -146,12 +146,10 @@ type CanvasAssistantPanelProps = {
|
||||
onCollapse: () => void;
|
||||
cinematicEntry?: boolean;
|
||||
onCinematicEntryConsumed?: () => void;
|
||||
width: number;
|
||||
onWidthChange: (width: number) => void;
|
||||
focusMode: boolean;
|
||||
resizing?: boolean;
|
||||
};
|
||||
|
||||
export function CanvasAssistantPanel({ nodes, selectedNodeIds, snapshot, projectId, sessions, activeSessionId, onSelectNodeIds, onSessionsChange, onApplyOps, canUndoOps, undoOpsCount, onUndoOps, onPasteImage, agentMode, onAgentModeChange, autoConnectLocal, closing, onCollapse, cinematicEntry = false, onCinematicEntryConsumed, width, onWidthChange, focusMode }: CanvasAssistantPanelProps) {
|
||||
export function CanvasAssistantPanel({ nodes, selectedNodeIds, snapshot, projectId, sessions, activeSessionId, onSelectNodeIds, onSessionsChange, onApplyOps, canUndoOps, undoOpsCount, onUndoOps, onPasteImage, agentMode, onAgentModeChange, autoConnectLocal, closing, onCollapse, cinematicEntry = false, onCinematicEntryConsumed, resizing = false }: CanvasAssistantPanelProps) {
|
||||
const theme = canvasThemes[useThemeStore((state) => state.theme)];
|
||||
const user = useUserStore((state) => state.user);
|
||||
const effectiveConfig = useEffectiveConfig();
|
||||
@@ -166,7 +164,6 @@ export function CanvasAssistantPanel({ nodes, selectedNodeIds, snapshot, project
|
||||
const [isRunning, setIsRunning] = useState(false);
|
||||
const [deleteChatIds, setDeleteChatIds] = useState<string[]>([]);
|
||||
const [onlineLogs, setOnlineLogs] = useState<OnlineAgentLog[]>([]);
|
||||
const [resizing, setResizing] = useState(false);
|
||||
const [removedReferenceIds, setRemovedReferenceIds] = useState<Set<string>>(new Set());
|
||||
const [localSessions, setLocalSessions] = useState<CanvasAssistantSession[]>(() => (sessions.length ? sessions : [createSession()]));
|
||||
const [localActiveSessionId, setLocalActiveSessionId] = useState<string | null>(activeSessionId);
|
||||
@@ -684,22 +681,6 @@ export function CanvasAssistantPanel({ nodes, selectedNodeIds, snapshot, project
|
||||
if (file) onPasteImage(file);
|
||||
};
|
||||
|
||||
const startResize = () => {
|
||||
const move = (event: MouseEvent) => onWidthChange(Math.min(760, Math.max(320, window.innerWidth - event.clientX)));
|
||||
const stop = () => {
|
||||
setResizing(false);
|
||||
document.body.style.cursor = "";
|
||||
document.body.style.userSelect = "";
|
||||
document.removeEventListener("mousemove", move);
|
||||
document.removeEventListener("mouseup", stop);
|
||||
};
|
||||
setResizing(true);
|
||||
document.body.style.cursor = "col-resize";
|
||||
document.body.style.userSelect = "none";
|
||||
document.addEventListener("mousemove", move);
|
||||
document.addEventListener("mouseup", stop);
|
||||
};
|
||||
|
||||
const collapse = () => {
|
||||
onCollapse();
|
||||
};
|
||||
@@ -834,42 +815,20 @@ export function CanvasAssistantPanel({ nodes, selectedNodeIds, snapshot, project
|
||||
</>
|
||||
);
|
||||
|
||||
// 面板顶部偏移:顶部栏高度 + 间距,活动任务面板为 absolute 定位无需额外预留
|
||||
const PANEL_SLOT_TOP_OFFSET = 80;
|
||||
const panelOffsetRight = focusMode ? 0 : 12;
|
||||
const panelOffsetBottom = focusMode ? 0 : 16;
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
className="pointer-events-none absolute z-[var(--z-panel-floating)]"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: closing ? 0 : 1 }}
|
||||
<motion.aside
|
||||
className="pointer-events-auto relative flex h-full w-full flex-col overflow-hidden rounded-[var(--panel-radius)] border"
|
||||
initial={{ x: 48, opacity: 0 }}
|
||||
animate={{ x: closing ? 28 : 0, opacity: closing ? 0 : 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: resizing ? 0 : PANEL_MOTION_SECONDS, ease: [0.22, 1, 0.36, 1] }}
|
||||
style={{
|
||||
top: PANEL_SLOT_TOP_OFFSET,
|
||||
right: panelOffsetRight,
|
||||
bottom: panelOffsetBottom,
|
||||
width: closing ? 0 : width,
|
||||
overflow: "clip",
|
||||
pointerEvents: closing ? "none" : undefined,
|
||||
borderColor: theme.toolbar.border,
|
||||
background: theme.spatial.elevated,
|
||||
color: theme.node.text,
|
||||
boxShadow: `0 24px 72px ${theme.spatial.shadow}`,
|
||||
}}
|
||||
>
|
||||
<motion.aside
|
||||
className="pointer-events-auto relative flex shrink-0 flex-col overflow-hidden rounded-[var(--panel-radius)] border"
|
||||
initial={{ x: 48, opacity: 0 }}
|
||||
animate={{ x: closing ? 28 : 0, opacity: closing ? 0 : 1 }}
|
||||
transition={{ duration: resizing ? 0 : PANEL_MOTION_SECONDS, ease: [0.22, 1, 0.36, 1] }}
|
||||
style={{
|
||||
width,
|
||||
height: "100%",
|
||||
borderColor: theme.toolbar.border,
|
||||
background: theme.spatial.elevated,
|
||||
color: theme.node.text,
|
||||
boxShadow: focusMode ? "none" : `0 24px 72px ${theme.spatial.shadow}`,
|
||||
}}
|
||||
>
|
||||
<button type="button" className="absolute inset-y-0 left-0 z-[var(--node-z-overlay)] w-4 -translate-x-1/2 cursor-col-resize" onMouseDown={startResize} aria-label="调整右侧面板宽度" />
|
||||
<AgentPanelChrome
|
||||
theme={theme}
|
||||
mode={agentMode}
|
||||
@@ -896,8 +855,7 @@ export function CanvasAssistantPanel({ nodes, selectedNodeIds, snapshot, project
|
||||
) : (
|
||||
onlineContent
|
||||
)}
|
||||
</motion.aside>
|
||||
</motion.div>
|
||||
</motion.aside>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user