修复图片编辑复用与元数据回退的小问题
- 修复参考素材标签的空白文本回退显示 - 重构 quick-edit 参数选择逻辑,移除嵌套三元并统一回退 - 抽取生成复用流程的参数回退与缺失素材提示逻辑 - 使用 quick-edit 提交计划中的输出尺寸构建复用时占位符
This commit is contained in:
@@ -148,6 +148,23 @@ function getDialogDefaultPrompt(mode: GenerateDialogState['mode']) {
|
||||
return 'AI 生成图片';
|
||||
}
|
||||
|
||||
function resolveOptionalFieldWithFallback<T extends string>(
|
||||
preferredValue: string | undefined | null,
|
||||
supportedValues: readonly string[],
|
||||
fallbackValues: readonly T[],
|
||||
defaultValue: T,
|
||||
) {
|
||||
const normalizedPreferred = preferredValue?.trim() ?? '';
|
||||
if (supportedValues.includes(normalizedPreferred)) {
|
||||
return normalizedPreferred as T;
|
||||
}
|
||||
return (
|
||||
fallbackValues.find((fallbackValue) =>
|
||||
supportedValues.includes(fallbackValue),
|
||||
) ?? defaultValue
|
||||
);
|
||||
}
|
||||
|
||||
export type ImageGenerationSubmissionPlan =
|
||||
| {
|
||||
kind: 'edit';
|
||||
@@ -306,17 +323,21 @@ export function buildImageGenerationSubmissionPlan({
|
||||
sourceLayer.originalHeight,
|
||||
);
|
||||
const aspectRatio = supportedAspectRatios.includes(dialog.aspectRatio ?? '')
|
||||
? dialog.aspectRatio!
|
||||
: supportedAspectRatios.includes(inferredAspectRatio)
|
||||
? inferredAspectRatio
|
||||
: (dimensionOptions.aspectRatios[0] ?? '1:1');
|
||||
? dialog.aspectRatio!.trim()
|
||||
: resolveOptionalFieldWithFallback(
|
||||
inferredAspectRatio,
|
||||
supportedAspectRatios,
|
||||
dimensionOptions.aspectRatios,
|
||||
'1:1',
|
||||
);
|
||||
const imageSize = supportedImageSizes.includes(dialog.imageSize ?? '')
|
||||
? dialog.imageSize!
|
||||
: supportedImageSizes.includes(inferredImageSize)
|
||||
? inferredImageSize
|
||||
: (dimensionOptions.imageSizes.find((size) => size === '1K') ??
|
||||
dimensionOptions.imageSizes[0] ??
|
||||
'1K');
|
||||
: resolveOptionalFieldWithFallback(
|
||||
inferredImageSize,
|
||||
supportedImageSizes,
|
||||
dimensionOptions.imageSizes,
|
||||
'1K',
|
||||
);
|
||||
const outputSize = resolveEditorImageGenerationPixelSize({
|
||||
model: imageModel,
|
||||
aspectRatio,
|
||||
|
||||
@@ -84,7 +84,7 @@ export function ImageCanvasMetadataModalView({
|
||||
{reference.title}
|
||||
</span>
|
||||
<span>
|
||||
{reference.label ?? '参考素材'}
|
||||
{reference.label?.trim() || '参考素材'}
|
||||
</span>
|
||||
<span className="image-canvas-editor__metadata-reference-id">
|
||||
{formatReferenceType(reference.refType)} ·{' '}
|
||||
|
||||
@@ -257,6 +257,29 @@ const EDITOR_GENERATION_QUEUE_POLL_INTERVAL_MS = 1600;
|
||||
const EDITOR_GENERATION_QUEUE_TIMEOUT_MS = 20 * 60 * 1000;
|
||||
const EDITOR_GENERATION_QUEUE_PROJECT_REFRESH_RETRY_MS = 650;
|
||||
|
||||
function getCanvasCompletionPlaceholderSizeFromPlan({
|
||||
sourceLayer,
|
||||
outputSize,
|
||||
}: {
|
||||
sourceLayer: CanvasLayer;
|
||||
outputSize: string | null | undefined;
|
||||
}) {
|
||||
const match = /^(\d+)x(\d+)$/i.exec(outputSize?.trim() ?? '');
|
||||
if (!match) {
|
||||
return {
|
||||
width: sourceLayer.originalWidth,
|
||||
height: sourceLayer.originalHeight,
|
||||
};
|
||||
}
|
||||
const width = Number(match[1]);
|
||||
const height = Number(match[2]);
|
||||
return {
|
||||
width: Number.isFinite(width) && width > 0 ? width : sourceLayer.originalWidth,
|
||||
height:
|
||||
Number.isFinite(height) && height > 0 ? height : sourceLayer.originalHeight,
|
||||
};
|
||||
}
|
||||
|
||||
type GenerationSubmissionWorkflowOptions = {
|
||||
layers: CanvasLayer[];
|
||||
canvasSize: CanvasSize;
|
||||
@@ -1899,6 +1922,10 @@ export function useImageCanvasGenerationSubmissionWorkflow({
|
||||
projectId,
|
||||
);
|
||||
}
|
||||
const quickEditPlaceholderSize = getCanvasCompletionPlaceholderSizeFromPlan({
|
||||
sourceLayer: submissionPlan.sourceLayer,
|
||||
outputSize: submissionPlan.editInput.size,
|
||||
});
|
||||
const generated = await runEditorGenerationWithWalletRefresh(
|
||||
editEditorImage({
|
||||
prompt: submissionPlan.normalizedPrompt,
|
||||
@@ -1920,12 +1947,10 @@ export function useImageCanvasGenerationSubmissionWorkflow({
|
||||
buildRightSideCanvasCompletionPlaceholder(
|
||||
submissionPlan.sourceLayer,
|
||||
{
|
||||
width: submissionPlan.sourceLayer.originalWidth,
|
||||
height: submissionPlan.sourceLayer.originalHeight,
|
||||
originalWidth:
|
||||
submissionPlan.sourceLayer.originalWidth,
|
||||
originalHeight:
|
||||
submissionPlan.sourceLayer.originalHeight,
|
||||
width: quickEditPlaceholderSize.width,
|
||||
height: quickEditPlaceholderSize.height,
|
||||
originalWidth: quickEditPlaceholderSize.width,
|
||||
originalHeight: quickEditPlaceholderSize.height,
|
||||
},
|
||||
),
|
||||
},
|
||||
|
||||
@@ -115,6 +115,31 @@ import {
|
||||
|
||||
type CanvasSize = { width: number; height: number };
|
||||
|
||||
function getCanvasGenerationRedrawWarning({
|
||||
hasParameterFallbacks,
|
||||
unavailableReferenceCount,
|
||||
isNormalizedGenerationInputs,
|
||||
}: {
|
||||
hasParameterFallbacks: boolean;
|
||||
unavailableReferenceCount: number;
|
||||
isNormalizedGenerationInputs: boolean;
|
||||
}) {
|
||||
const hasUnavailableReferences = unavailableReferenceCount > 0;
|
||||
if (hasParameterFallbacks && hasUnavailableReferences) {
|
||||
return `${CANVAS_GENERATION_PARAMETER_FALLBACK_WARNING} 部分原参考素材不在当前画布或来自面板上传,未恢复,请重新选择。`;
|
||||
}
|
||||
if (hasParameterFallbacks) {
|
||||
return CANVAS_GENERATION_PARAMETER_FALLBACK_WARNING;
|
||||
}
|
||||
if (!isNormalizedGenerationInputs && hasUnavailableReferences) {
|
||||
return '已按旧版数据恢复,部分参数可能使用当前默认值。';
|
||||
}
|
||||
if (hasUnavailableReferences) {
|
||||
return '部分原参考素材不在当前画布或来自面板上传,未恢复,请重新选择。';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
type CropExpandResizeDragState = {
|
||||
pointerId: number;
|
||||
handle: CropExpandResizeHandle;
|
||||
@@ -1345,18 +1370,13 @@ export function useImageCanvasGenerationWorkflow({
|
||||
setQuickEditPanel(null);
|
||||
selectSingleLayer(extractionSource.id);
|
||||
setActiveTool('select');
|
||||
if (hasParameterFallbacks && unavailableReferences.length) {
|
||||
showGenerationWarning(
|
||||
`${CANVAS_GENERATION_PARAMETER_FALLBACK_WARNING} 部分原参考素材不在当前画布或来自面板上传,未恢复,请重新选择。`,
|
||||
);
|
||||
} else if (hasParameterFallbacks) {
|
||||
showGenerationWarning(
|
||||
CANVAS_GENERATION_PARAMETER_FALLBACK_WARNING,
|
||||
);
|
||||
} else if (unavailableReferences.length) {
|
||||
showGenerationWarning(
|
||||
'部分原参考素材不在当前画布或来自面板上传,未恢复,请重新选择。',
|
||||
);
|
||||
const redrawWarning = getCanvasGenerationRedrawWarning({
|
||||
hasParameterFallbacks,
|
||||
unavailableReferenceCount: unavailableReferences.length,
|
||||
isNormalizedGenerationInputs,
|
||||
});
|
||||
if (redrawWarning) {
|
||||
showGenerationWarning(redrawWarning);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1382,22 +1402,13 @@ export function useImageCanvasGenerationWorkflow({
|
||||
setQuickEditPanel(null);
|
||||
selectSingleLayer(null);
|
||||
setActiveTool(getCanvasToolForGenerationMode(sameSourceDraft.mode));
|
||||
if (hasParameterFallbacks && unavailableReferences.length) {
|
||||
showGenerationWarning(
|
||||
`${CANVAS_GENERATION_PARAMETER_FALLBACK_WARNING} 部分原参考素材不在当前画布或来自面板上传,未恢复,请重新选择。`,
|
||||
);
|
||||
} else if (hasParameterFallbacks) {
|
||||
showGenerationWarning(
|
||||
CANVAS_GENERATION_PARAMETER_FALLBACK_WARNING,
|
||||
);
|
||||
} else if (isNormalizedGenerationInputs && unavailableReferences.length) {
|
||||
showGenerationWarning(
|
||||
'部分原参考素材不在当前画布或来自面板上传,未恢复,请重新选择。',
|
||||
);
|
||||
} else if (!isNormalizedGenerationInputs) {
|
||||
showGenerationWarning(
|
||||
'已按旧版数据恢复,部分参数可能使用当前默认值。',
|
||||
);
|
||||
const redrawWarning = getCanvasGenerationRedrawWarning({
|
||||
hasParameterFallbacks,
|
||||
unavailableReferenceCount: unavailableReferences.length,
|
||||
isNormalizedGenerationInputs,
|
||||
});
|
||||
if (redrawWarning) {
|
||||
showGenerationWarning(redrawWarning);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user