75 lines
2.0 KiB
TypeScript
75 lines
2.0 KiB
TypeScript
import { isCanvasImageReadyForAi } from "@/lib/canvas/local-upload-state";
|
|
import type { CanvasNode } from "@/types/canvas";
|
|
|
|
export type LayoutReplaceSource = {
|
|
id: string;
|
|
imageUrl: string;
|
|
kind: "canvas" | "upload";
|
|
nodeId?: string;
|
|
title: string;
|
|
};
|
|
|
|
function resolveCanvasImageUrl(node: CanvasNode) {
|
|
const data = (node.data || {}) as Record<string, any>;
|
|
return String(
|
|
data.src ||
|
|
data.previewImage ||
|
|
data.imageUrl ||
|
|
data.renderArtifacts?.screenshotUrl ||
|
|
""
|
|
).trim();
|
|
}
|
|
|
|
export function getLayoutReplaceSourceIdentity(source: LayoutReplaceSource) {
|
|
if (source.kind === "canvas" && source.nodeId) {
|
|
return `canvas:${source.nodeId}`;
|
|
}
|
|
return `${source.kind}:${source.imageUrl}`;
|
|
}
|
|
|
|
export function getReadyCanvasLayoutReplaceSource(
|
|
node: CanvasNode
|
|
): LayoutReplaceSource | null {
|
|
if (!isCanvasImageReadyForAi(node)) return null;
|
|
const data = (node.data || {}) as Record<string, any>;
|
|
const imageUrl = resolveCanvasImageUrl(node);
|
|
return {
|
|
id: `canvas:${node.id}`,
|
|
imageUrl,
|
|
kind: "canvas",
|
|
nodeId: node.id,
|
|
title: String(data.title || "画布图片").trim() || "画布图片",
|
|
};
|
|
}
|
|
|
|
export function mergeUniqueLayoutReplaceSources(
|
|
current: LayoutReplaceSource[],
|
|
incoming: LayoutReplaceSource[],
|
|
maxCount: number
|
|
) {
|
|
const next = [...current];
|
|
const identities = new Set(next.map(getLayoutReplaceSourceIdentity));
|
|
for (const source of incoming) {
|
|
const identity = getLayoutReplaceSourceIdentity(source);
|
|
if (next.length >= maxCount) break;
|
|
if (identities.has(identity)) continue;
|
|
identities.add(identity);
|
|
next.push(source);
|
|
}
|
|
return next;
|
|
}
|
|
|
|
export function getAvailableCanvasLayoutReplaceSources(
|
|
canvasSources: LayoutReplaceSource[],
|
|
currentSources: LayoutReplaceSource[]
|
|
) {
|
|
const existingIdentities = new Set(
|
|
currentSources.map(getLayoutReplaceSourceIdentity)
|
|
);
|
|
return canvasSources.filter(
|
|
(source) =>
|
|
Boolean(source.nodeId) &&
|
|
!existingIdentities.has(getLayoutReplaceSourceIdentity(source))
|
|
);
|
|
}
|