feat(assets): 素材库与画布 - 新增可交互通用文件夹

This commit is contained in:
echoD886 committed 2026-08-20 15:16:45 +08:00
1 parent 9ee71d4650
commit 935108edca
35 files changed
+2010 -155

No files matched your search

@@ -3,11 +3,12 @@ import { App } from "antd";
import copyToClipboard from "copy-to-clipboard";
import { nanoid } from "nanoid";
import { FRAME_HEADER_HEIGHT, getFrameChildIds, getFrameChildren, isFrameNode } from "@/lib/canvas/canvas-frame";
import { NODE_DEFAULT_SIZE } from "@/constant/canvas";
import { FOLDER_COLLAPSED_HEIGHT, FOLDER_COLLAPSED_WIDTH, FRAME_HEADER_HEIGHT, getFrameChildIds, getFrameChildren, isFrameNode } from "@/lib/canvas/canvas-frame";
import { alignCanvasNodes, layoutCanvasFlow, layoutCanvasNodes, nextCanvasVersionLabel, type CanvasAlignmentMode } from "@/lib/canvas/canvas-layout";
import { createCanvasNode, removeCanvasNodes } from "@/lib/canvas/canvas-project-domain";
import { isolateCopiedNodeMetadata } from "@/lib/canvas/canvas-node-copy";
import { CanvasNodeType, type CanvasConnection, type CanvasNodeData, type ContextMenuState, type Position } from "@/types/canvas";
import { CanvasNodeType, type CanvasConnection, type CanvasFolderStyle, type CanvasNodeData, type ContextMenuState, type Position } from "@/types/canvas";
import { cloneCanvasDrawing } from "@/lib/canvas/canvas-drawing-storage";
import { isDrawingEngineAvailable, type CanvasDrawingEngine } from "@/lib/canvas/canvas-drawing-engine";
import { useUserStore } from "@/stores/use-user-store";
@@ -132,6 +133,28 @@ export function useCanvasNodeOperations({
if (type !== CanvasNodeType.Text && type !== CanvasNodeType.Script && type !== CanvasNodeType.Audio && type !== CanvasNodeType.Frame && type !== CanvasNodeType.Drawing) setDialogNodeId(node.id);
}, [commitNodes, defaultDrawingEngine, getCanvasCenter, message, nodesRef, selectNodes, setDialogNodeId, tldrawLicenseKey]);
const createFolder = useCallback((position?: Position, linked?: { id: string; projectId: string; title: string; style: CanvasFolderStyle; createdAt: string }) => {
const folder = createCanvasNode(CanvasNodeType.Frame, position || getCanvasCenter(), {
frame: {
collapsed: true,
expandedWidth: NODE_DEFAULT_SIZE[CanvasNodeType.Frame].width,
expandedHeight: NODE_DEFAULT_SIZE[CanvasNodeType.Frame].height,
},
folder: {
style: linked?.style || "glass",
createdAt: linked?.createdAt || new Date().toISOString(),
assetFolderId: linked?.id,
projectId: linked?.projectId,
},
});
folder.title = linked?.title || "我的文件";
folder.width = FOLDER_COLLAPSED_WIDTH;
folder.height = FOLDER_COLLAPSED_HEIGHT;
commitNodes([...nodesRef.current, folder]);
selectNodes(new Set([folder.id]));
message.success(linked ? "素材文件夹已放到画布,打开可浏览其中内容" : "文件夹已创建,可拖入任意非容器节点");
}, [commitNodes, getCanvasCenter, message, nodesRef, selectNodes]);
const arrangeSelectedNodes = useCallback((mode: "row" | "column" | "grid" | "flow") => {
const selected = nodesRef.current.filter((node) => selectedNodeIdsRef.current.has(node.id) && !node.metadata?.locked && !isFrameNode(node));
if (selected.length < 2) return;
@@ -464,6 +487,7 @@ export function useCanvasNodeOperations({
arrangeSelectedNodes,
copyNodesToClipboard,
copySelectedNodes,
createFolder,
createNode,
createReferenceGroup,
createStoryboardGroup,