ai-chatbot/lib/canvas/template-replace-batch.ts

80 lines
2.5 KiB
TypeScript

export const MAX_CANVAS_TEMPLATE_REPLACE_SOURCES = 5;
export type CanvasTemplateReplaceSource = {
id: string;
imageUrl: string;
title: string;
origin: "canvas" | "upload";
sourceNodeId?: string;
};
function normalizeSource(
source: CanvasTemplateReplaceSource | null | undefined
): CanvasTemplateReplaceSource | null {
if (!source) return null;
const imageUrl = String(source.imageUrl || "").trim();
if (!/^https?:\/\//i.test(imageUrl)) return null;
return {
id: String(source.id || imageUrl).trim() || imageUrl,
imageUrl,
title: String(source.title || "替换素材").trim() || "替换素材",
origin: source.origin === "upload" ? "upload" : "canvas",
sourceNodeId: String(source.sourceNodeId || "").trim() || undefined,
};
}
export function normalizeCanvasTemplateReplaceSources(
sources: Array<CanvasTemplateReplaceSource | null | undefined>
): CanvasTemplateReplaceSource[] {
const seenUrls = new Set<string>();
const normalized: CanvasTemplateReplaceSource[] = [];
for (const source of sources) {
const nextSource = normalizeSource(source);
if (!nextSource || seenUrls.has(nextSource.imageUrl)) continue;
seenUrls.add(nextSource.imageUrl);
normalized.push(nextSource);
if (normalized.length >= MAX_CANVAS_TEMPLATE_REPLACE_SOURCES) break;
}
return normalized;
}
export function createCanvasTemplateReplaceSlots(
sources: Array<CanvasTemplateReplaceSource | null | undefined>
): Array<CanvasTemplateReplaceSource | null> {
const slots = normalizeCanvasTemplateReplaceSources(sources);
return Array.from(
{ length: MAX_CANVAS_TEMPLATE_REPLACE_SOURCES },
(_, index) => slots[index] || null
);
}
export function replaceCanvasTemplateSourceSlot(
slots: Array<CanvasTemplateReplaceSource | null>,
slotIndex: number,
source: CanvasTemplateReplaceSource | null
): Array<CanvasTemplateReplaceSource | null> {
const nextSlots = createCanvasTemplateReplaceSlots([]);
slots.slice(0, MAX_CANVAS_TEMPLATE_REPLACE_SOURCES).forEach((item, index) => {
nextSlots[index] = normalizeSource(item);
});
if (slotIndex < 0 || slotIndex >= MAX_CANVAS_TEMPLATE_REPLACE_SOURCES) {
return nextSlots;
}
const normalizedSource = normalizeSource(source);
if (normalizedSource) {
nextSlots.forEach((item, index) => {
if (index !== slotIndex && item?.imageUrl === normalizedSource.imageUrl) {
nextSlots[index] = null;
}
});
}
nextSlots[slotIndex] = normalizedSource;
return nextSlots;
}