Enhance canvas connection validation and image resolution handling
- Introduced new functions for validating canvas connections, ensuring proper source and target node types. - Updated edge and node mutation logic to enforce connection policies and improve error handling. - Enhanced image resolution handling by integrating a new image source resolution function for better URL retrieval. - Refactored existing validation logic to streamline connection checks and improve maintainability.
This commit is contained in:
87
lib/canvas-connection-policy.ts
Normal file
87
lib/canvas-connection-policy.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { isAdjustmentNodeType } from "@/lib/canvas-node-types";
|
||||
|
||||
export const CANVAS_NODE_DND_MIME = "application/lemonspace-node-type";
|
||||
|
||||
const ADJUSTMENT_ALLOWED_SOURCE_TYPES = new Set<string>([
|
||||
"image",
|
||||
"asset",
|
||||
"ai-image",
|
||||
"curves",
|
||||
"color-adjust",
|
||||
"light-adjust",
|
||||
"detail-adjust",
|
||||
]);
|
||||
|
||||
const RENDER_ALLOWED_SOURCE_TYPES = new Set<string>([
|
||||
"image",
|
||||
"asset",
|
||||
"ai-image",
|
||||
"curves",
|
||||
"color-adjust",
|
||||
"light-adjust",
|
||||
"detail-adjust",
|
||||
]);
|
||||
|
||||
const ADJUSTMENT_DISALLOWED_TARGET_TYPES = new Set<string>(["prompt", "ai-image"]);
|
||||
|
||||
export type CanvasConnectionValidationReason =
|
||||
| "incomplete"
|
||||
| "self-loop"
|
||||
| "unknown-node"
|
||||
| "adjustment-source-invalid"
|
||||
| "adjustment-incoming-limit"
|
||||
| "adjustment-target-forbidden"
|
||||
| "render-source-invalid";
|
||||
|
||||
export function validateCanvasConnectionPolicy(args: {
|
||||
sourceType: string;
|
||||
targetType: string;
|
||||
targetIncomingCount: number;
|
||||
}): CanvasConnectionValidationReason | null {
|
||||
const { sourceType, targetType, targetIncomingCount } = args;
|
||||
|
||||
if (isAdjustmentNodeType(targetType)) {
|
||||
if (!ADJUSTMENT_ALLOWED_SOURCE_TYPES.has(sourceType)) {
|
||||
return "adjustment-source-invalid";
|
||||
}
|
||||
if (targetIncomingCount >= 1) {
|
||||
return "adjustment-incoming-limit";
|
||||
}
|
||||
}
|
||||
|
||||
if (targetType === "render" && !RENDER_ALLOWED_SOURCE_TYPES.has(sourceType)) {
|
||||
return "render-source-invalid";
|
||||
}
|
||||
|
||||
if (
|
||||
isAdjustmentNodeType(sourceType) &&
|
||||
ADJUSTMENT_DISALLOWED_TARGET_TYPES.has(targetType)
|
||||
) {
|
||||
return "adjustment-target-forbidden";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getCanvasConnectionValidationMessage(
|
||||
reason: CanvasConnectionValidationReason,
|
||||
): string {
|
||||
switch (reason) {
|
||||
case "incomplete":
|
||||
return "Unvollstaendige Verbindung.";
|
||||
case "self-loop":
|
||||
return "Node kann nicht mit sich selbst verbunden werden.";
|
||||
case "unknown-node":
|
||||
return "Verbindung enthaelt unbekannte Nodes.";
|
||||
case "adjustment-source-invalid":
|
||||
return "Adjustment-Nodes akzeptieren nur Bild-, Asset-, KI-Bild- oder Adjustment-Input.";
|
||||
case "adjustment-incoming-limit":
|
||||
return "Adjustment-Nodes erlauben genau eine eingehende Verbindung.";
|
||||
case "adjustment-target-forbidden":
|
||||
return "Adjustment-Ausgaben koennen nicht an Prompt- oder KI-Bild-Nodes angeschlossen werden.";
|
||||
case "render-source-invalid":
|
||||
return "Render akzeptiert nur Bild-, Asset-, KI-Bild- oder Adjustment-Input.";
|
||||
default:
|
||||
return "Verbindung ist fuer diese Node-Typen nicht erlaubt.";
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,10 @@
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { toast, type ToastDurationOverrides } from './toast';
|
||||
import type { CanvasNodeDeleteBlockReason } from './toast';
|
||||
import {
|
||||
getCanvasConnectionValidationMessage,
|
||||
type CanvasConnectionValidationReason,
|
||||
} from '@/lib/canvas-connection-policy';
|
||||
|
||||
const DURATION = {
|
||||
success: 4000,
|
||||
@@ -77,6 +81,13 @@ export const msg = {
|
||||
desc: `${why.desc} ${suffix}`,
|
||||
};
|
||||
},
|
||||
connectionRejected: (
|
||||
_t: ToastTranslations,
|
||||
reason: CanvasConnectionValidationReason,
|
||||
) => ({
|
||||
title: 'Verbindung abgelehnt',
|
||||
desc: getCanvasConnectionValidationMessage(reason),
|
||||
}),
|
||||
},
|
||||
ai: {
|
||||
generating: (t: ToastTranslations) => ({ title: t('ai.generating') }),
|
||||
@@ -205,3 +216,12 @@ export const msg = {
|
||||
deleteFailed: (t: ToastTranslations) => ({ title: t('dashboard.deleteFailed') }),
|
||||
},
|
||||
} as const;
|
||||
|
||||
export function showCanvasConnectionRejectedToast(
|
||||
t: ToastTranslations,
|
||||
reason: CanvasConnectionValidationReason,
|
||||
duration?: ToastDurationOverrides,
|
||||
): void {
|
||||
const payload = msg.canvas.connectionRejected(t, reason);
|
||||
toast.warning(payload.title, payload.desc, duration ?? { duration: DURATION.warning });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user