bcff8f1957
Project CI / Native shell tests (push) Successful in 13m23s
Project CI / Repository checks (push) Successful in 1m12s
Project CI / Frontend tests (push) Successful in 2m55s
Project CI / Backend tests (push) Successful in 4m0s
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
读边界的内联媒体脱敏在每层对象上无差别删除 null 值,把 SFX 自动时长 metadata 里 合法的 requestedDurationSeconds: null 一并删掉;客户端据此判定整份 soundEffect 非法, 音频信息页的「生成输入」退化成空,Task 也被截成 0 这类误导值。手动指定时长的音效不受 影响,图片路径的 generationInputs 没有可为 null 的字段,所以只有部分 SFX 可见。 - sanitize_editor_payload_media_value 改为返回「是否被抹除」,只删除本次抹掉的内联 媒体,调用方原有的显式 null 保留;脱敏强度不变,内联媒体与保留字段仍连键消失 - SFX 自动时长的 requestedDurationSeconds 接受显式 null 与整个键缺失两种同义形态 - 音频信息页 Task 按图层 assetKind 判定,不再随 soundEffect 元数据缺失降级成截断值 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/153 Co-authored-by: Linghong <ink29535@proton.me> Co-committed-by: Linghong <ink29535@proton.me>
130 lines
5.5 KiB
TypeScript
130 lines
5.5 KiB
TypeScript
import { EDITOR_SOUND_EFFECT_MODEL } from '../../../packages/shared/src/contracts/editorAudio';
|
|
import { UnifiedModal } from '../common/UnifiedModal';
|
|
import type { CanvasLayer } from './ImageCanvasEditorTypes';
|
|
import { formatTaskIdForDisplay } from './ImageCanvasExportModel';
|
|
import {
|
|
formatEditorGenerationInputFieldValue,
|
|
formatLayerImageType,
|
|
getEditorLayerModelDisplayName,
|
|
isEditorUserVisibleGenerationInputField,
|
|
} from './ImageCanvasGenerationModel';
|
|
|
|
export type ImageCanvasMetadataModalViewProps = {
|
|
layer: CanvasLayer | null;
|
|
onClose: () => void;
|
|
};
|
|
|
|
function formatReferenceType(refType: 'project-resource' | 'asset') {
|
|
return refType === 'project-resource' ? '项目资源' : '素材';
|
|
}
|
|
|
|
export function ImageCanvasMetadataModalView({
|
|
layer,
|
|
onClose,
|
|
}: ImageCanvasMetadataModalViewProps) {
|
|
const visibleGenerationInputFields =
|
|
layer?.generationInputs?.fields.filter(
|
|
isEditorUserVisibleGenerationInputField,
|
|
) ?? [];
|
|
const generationInputReferences = layer?.generationInputs?.references ?? [];
|
|
const mediaLabel =
|
|
layer?.mediaType === 'audio'
|
|
? '音频'
|
|
: layer?.mediaType === 'video'
|
|
? '视频'
|
|
: layer?.mediaType === 'image-sequence'
|
|
? '序列帧'
|
|
: '图片';
|
|
|
|
// TODO: Remove this override after full dark style support.
|
|
return (
|
|
<UnifiedModal
|
|
open={Boolean(layer)}
|
|
title={`${mediaLabel}信息`}
|
|
size="sm"
|
|
portalTheme="light"
|
|
closeLabel={`关闭${mediaLabel}信息`}
|
|
onClose={onClose}
|
|
panelClassName="image-canvas-editor__metadata-dialog"
|
|
bodyClassName="image-canvas-editor__metadata-body"
|
|
>
|
|
{layer ? (
|
|
<dl className="image-canvas-editor__metadata-grid">
|
|
<dt>{mediaLabel}类型</dt>
|
|
<dd>{formatLayerImageType(layer)}</dd>
|
|
<dt>生成输入</dt>
|
|
<dd className="image-canvas-editor__metadata-inputs">
|
|
{visibleGenerationInputFields.length ||
|
|
generationInputReferences.length ? (
|
|
<>
|
|
{visibleGenerationInputFields.map((field) => (
|
|
<div
|
|
key={`${field.title}-${field.value}`}
|
|
className="image-canvas-editor__metadata-input-field"
|
|
>
|
|
<span className="image-canvas-editor__metadata-input-title">
|
|
{field.title}
|
|
</span>
|
|
<span>{formatEditorGenerationInputFieldValue(field)}</span>
|
|
</div>
|
|
))}
|
|
{generationInputReferences.length ? (
|
|
<div className="image-canvas-editor__metadata-reference-list">
|
|
{generationInputReferences.map((reference) => (
|
|
<div
|
|
key={`${reference.title}-${reference.label ?? ''}-${reference.refType}-${reference.refId}`}
|
|
className="image-canvas-editor__metadata-reference-card"
|
|
>
|
|
<span className="image-canvas-editor__metadata-reference-copy">
|
|
<span className="image-canvas-editor__metadata-input-title">
|
|
{reference.title}
|
|
</span>
|
|
<span>{reference.label?.trim() || '参考素材'}</span>
|
|
<span className="image-canvas-editor__metadata-reference-id">
|
|
{formatReferenceType(reference.refType)} ·{' '}
|
|
{reference.refId}
|
|
</span>
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : null}
|
|
</>
|
|
) : (
|
|
'-'
|
|
)}
|
|
</dd>
|
|
<dt>Model</dt>
|
|
<dd>{getEditorLayerModelDisplayName(layer.model)}</dd>
|
|
{layer.mediaType !== 'audio' ? (
|
|
<>
|
|
<dt>Resolution</dt>
|
|
<dd>
|
|
{layer.originalWidth} x {layer.originalHeight} px
|
|
</dd>
|
|
</>
|
|
) : null}
|
|
<dt>Task</dt>
|
|
<dd>
|
|
{/* 中文注释:音效的 taskId 是 operation id 形态,`formatTaskIdForDisplay` 的
|
|
「取最后一段数字」会把它截成 `0`、`1234` 这类误导值。判据要回答的是「这个
|
|
taskId 由谁生成」,而不是「这个图层被归成哪一类」,所以落在 model 上:它是
|
|
资源行权威字段(registered 图层的 serializeLayer 不回写它),改「素材标签」
|
|
不影响它,水合时 resolveHydratedLayerModel 也优先取资源行的值;后端
|
|
canonicalize_editor_sound_effect_model 只接受 eleven_text_to_sound_v2 一个取值。
|
|
用 assetKind / resourceAssetKind 判都踩过坑:前者是 assetKindOverride ??
|
|
resourceAssetKind,用户改一次标签就翻转;后者在 legacy 布局(快照没有
|
|
assetKindOverride 键,旧 assetKind 被当成 override)和资源行查不到时都是 null。
|
|
soundEffect 那一支只是补充——它和生成 action 一样长在 generationInputs 上,
|
|
元数据整块缺失时会一并消失,而那正是这里要兜住的场景。 */}
|
|
{layer.model === EDITOR_SOUND_EFFECT_MODEL ||
|
|
layer.generationInputs?.soundEffect?.schemaVersion === 2
|
|
? layer.taskId || '-'
|
|
: formatTaskIdForDisplay(layer.taskId)}
|
|
</dd>
|
|
</dl>
|
|
) : null}
|
|
</UnifiedModal>
|
|
);
|
|
}
|