80 lines
2.5 KiB
TypeScript
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;
|
|
}
|