Add FunClip timeline handoff source

This commit is contained in:
2026-07-07 09:39:54 +08:00
parent 13f44a4bbc
commit 38bba0828c
2 changed files with 45 additions and 7 deletions

View File

@@ -9780,6 +9780,37 @@ function FunClipEditingPage({
| 'clip'
| 'published';
const timelineHandoffSource = useMemo<ClipSource | null>(() => {
const asset = timelineHandoff?.asset;
const url = publishableAssetMediaUrl(asset);
if (!asset || (asset.type !== 'video' && asset.type !== 'audio') || !url) {
return null;
}
return {
id: `handoff-${asset.assetId || asset.id || 'media'}`,
assetId: asset.assetId || asset.id,
name: asset.name || '数字人成片',
type: asset.type,
source: 'asset-center',
section: 'work',
tags: Array.from(
new Set<AssetCenterSourceTag>([
...(asset.sourceTags || []),
'ai',
'clip',
])
),
provider: asset.provider || '数字人',
url,
thumbnailUrl: publishableAssetThumbnailUrl(asset),
localPath: asset.localPath,
durationMs: asset.durationMs,
width: asset.width,
height: asset.height,
createdAt: asset.createdAt || timelineHandoff.createdAt || Date.now(),
};
}, [timelineHandoff]);
const sourceOptions = useMemo<ClipSource[]>(() => {
const materialSources = assets
.filter((asset) => asset.type === 'video' || asset.type === 'audio')
@@ -9830,7 +9861,11 @@ function FunClipEditingPage({
};
});
const seen = new Set<string>();
return [...finishedSources, ...materialSources]
return [
...(timelineHandoffSource ? [timelineHandoffSource] : []),
...finishedSources,
...materialSources,
]
.filter((item) => {
const key = item.assetId || item.localPath || item.url || item.id;
if (seen.has(key)) {
@@ -9840,7 +9875,7 @@ function FunClipEditingPage({
return true;
})
.sort((a, b) => b.createdAt - a.createdAt);
}, [assets, finishedAssets]);
}, [assets, finishedAssets, timelineHandoffSource]);
const clipPresets: Array<{
id: ClipPresetId;

View File

@@ -76,9 +76,7 @@ const ModelDescFallback: React.FC<{ model: ModelConfig }> = React.memo(
({ model }) => {
const meta = useModelMeta(model.sourceProfileId, model.id);
if (!meta?.description) return null;
return (
<div className="model-selector__item-desc">{meta.description}</div>
);
return <div className="model-selector__item-desc">{meta.description}</div>;
}
);
@@ -209,7 +207,9 @@ export const ModelSelector: React.FC<ModelSelectorProps> = React.memo(
selectedModel,
selectedModelRef
);
setActiveVendor(selectedIsSelectable ? currentModel?.vendor || null : null);
setActiveVendor(
selectedIsSelectable ? currentModel?.vendor || null : null
);
} else {
setSearchQuery('');
}
@@ -298,7 +298,10 @@ export const ModelSelector: React.FC<ModelSelectorProps> = React.memo(
const alignedLeft = rect.left;
const nextLeft = Math.min(
Math.max(viewportGutter, alignedLeft),
Math.max(viewportGutter, windowWidth - preferredWidth - viewportGutter)
Math.max(
viewportGutter,
windowWidth - preferredWidth - viewportGutter
)
);
setPortalPosition({