Files
omniai-web/src/features/canvas/useCanvasDerivedState.ts
T

75 lines
2.2 KiB
TypeScript
Raw Normal View History

2026-06-05 18:01:48 +08:00
import { useCallback, useMemo } from "react";
import type { ServerAssetItem } from "../../api/assetClient";
import type {
CanvasImageNode,
CanvasNodeKind,
CanvasNodePackage,
CanvasTextNode,
CanvasVideoNode,
} from "./canvasTypes";
import { getCanvasSelectionKey } from "./canvasUtils";
export function useCanvasAssetSummary(serverAssets: ServerAssetItem[]) {
return useMemo(() => {
const canvasAssets: ServerAssetItem[] = [];
const assetCountsByCategory = new Map<string, number>();
for (const asset of serverAssets) {
if (asset.imageUrl) {
canvasAssets.push(asset);
}
assetCountsByCategory.set(asset.type, (assetCountsByCategory.get(asset.type) ?? 0) + 1);
}
return { canvasAssets, assetCountsByCategory };
}, [serverAssets]);
}
export function useCanvasVisibleNodes({
textNodes,
imageNodes,
videoNodes,
nodePackages,
}: {
textNodes: CanvasTextNode[];
imageNodes: CanvasImageNode[];
videoNodes: CanvasVideoNode[];
nodePackages: CanvasNodePackage[];
}) {
const collapsedPackageNodeKeys = useMemo(
() => new Set(
nodePackages.flatMap((nodePackage) =>
nodePackage.collapsed ? nodePackage.nodeIds.map((node) => getCanvasSelectionKey(node)) : []
)
),
[nodePackages],
);
const isNodeCollapsedInPackage = useCallback(
(kind: CanvasNodeKind, id: string) =>
collapsedPackageNodeKeys.has(getCanvasSelectionKey({ kind, id })),
[collapsedPackageNodeKeys],
);
const visibleTextNodes = useMemo(
() => textNodes.filter((textNode) => !collapsedPackageNodeKeys.has(getCanvasSelectionKey({ kind: "text", id: textNode.id }))),
[collapsedPackageNodeKeys, textNodes],
);
const visibleImageNodes = useMemo(
() => imageNodes.filter((imageNode) => !collapsedPackageNodeKeys.has(getCanvasSelectionKey({ kind: "image", id: imageNode.id }))),
[collapsedPackageNodeKeys, imageNodes],
);
const visibleVideoNodes = useMemo(
() => videoNodes.filter((videoNode) => !collapsedPackageNodeKeys.has(getCanvasSelectionKey({ kind: "video", id: videoNode.id }))),
[collapsedPackageNodeKeys, videoNodes],
);
return {
collapsedPackageNodeKeys,
isNodeCollapsedInPackage,
visibleTextNodes,
visibleImageNodes,
visibleVideoNodes,
};
}