feat(assets): 素材选择器 - 支持按媒体类型筛选并覆盖远程项目资产
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -50,6 +50,7 @@ export function AssetPickerModal({ open, multiple = true, onInsert, onClose }: P
|
||||
category: normalizeAssetCategory(asset.category),
|
||||
archived: asset.status === "archived",
|
||||
kindLabel: asset.kind === "image" ? "图片" : asset.kind === "video" ? "视频" : asset.kind === "audio" ? "音频" : "文本",
|
||||
mediaKind: asset.kind,
|
||||
asset,
|
||||
searchText: (asset.tags || []).join(" "),
|
||||
})),
|
||||
@@ -62,6 +63,7 @@ export function AssetPickerModal({ open, multiple = true, onInsert, onClose }: P
|
||||
<AssetLibraryPickerModal
|
||||
remoteLibrary
|
||||
open={open}
|
||||
mediaKinds={["image", "video", "audio", "text"]}
|
||||
items={items}
|
||||
categoryLabels={{ ...categoryLabels, ...externalAssetSources.categoryLabels }}
|
||||
folders={externalAssetSources.folders}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useMemo } from "react";
|
||||
|
||||
import { AssetLibraryPickerModal, type AssetLibraryPickerItem } from "@/components/assets/asset-library-picker-modal";
|
||||
import { AssetLibraryPickerModal, type AssetLibraryPickerItem, type AssetPickerMediaKind } from "@/components/assets/asset-library-picker-modal";
|
||||
import { useExternalAssetSources } from "@/hooks/use-external-asset-sources";
|
||||
import { externalAssetToInsertPayload, type InsertAssetPayload } from "@/components/canvas/asset-picker-modal";
|
||||
import { compileCharacterReferencePrompt } from "@/lib/canvas/canvas-character-reference";
|
||||
@@ -55,12 +55,15 @@ export function CanvasProjectAssetModal({
|
||||
character?.character?.representations.find((representation) => representation.role === "primary") ||
|
||||
character?.character?.representations.find((representation) => representation.role === "front");
|
||||
const remoteResourceId = resourceIdFromStorageKey(project?.storageKey);
|
||||
// 项目资产可能只有服务端记录、没有本地素材,媒体类型要显式声明,筛选才能覆盖它们。
|
||||
const mediaKind = character ? undefined : pickerMediaKind(media?.kind || project?.mediaType);
|
||||
return {
|
||||
id: item.id,
|
||||
title: character?.title || project?.title || media?.title || "未命名资产",
|
||||
category: item.category,
|
||||
folderId: item.folderId,
|
||||
kindLabel: character ? "角色卡" : (media?.kind || project?.mediaType) === "video" ? "视频" : (media?.kind || project?.mediaType) === "audio" ? "音频" : (media?.kind || project?.mediaType) === "text" ? "文本" : "图片",
|
||||
kindLabel: character ? "角色卡" : mediaKind === "video" ? "视频" : mediaKind === "audio" ? "音频" : mediaKind === "text" ? "文本" : "图片",
|
||||
mediaKind,
|
||||
asset: media,
|
||||
imageUrl: coverRepresentation ? resourceFileUrl(coverRepresentation.resourceId) : project?.mediaType === "image" && remoteResourceId ? resourceFileUrl(remoteResourceId) : undefined,
|
||||
imageStorageKey: coverRepresentation ? `resource:${coverRepresentation.resourceId}` : undefined,
|
||||
@@ -77,6 +80,7 @@ export function CanvasProjectAssetModal({
|
||||
<AssetLibraryPickerModal
|
||||
remoteLibrary={!detail}
|
||||
open={open}
|
||||
mediaKinds={["image", "video", "audio", "text"]}
|
||||
items={pickerItems}
|
||||
categoryLabels={{ ...categoryLabels, ...externalAssetSources.categoryLabels }}
|
||||
initialCategory={initialCategory}
|
||||
@@ -117,6 +121,10 @@ export function CanvasProjectAssetModal({
|
||||
);
|
||||
}
|
||||
|
||||
function pickerMediaKind(value?: string): AssetPickerMediaKind {
|
||||
return value === "video" || value === "audio" || value === "text" ? value : "image";
|
||||
}
|
||||
|
||||
function toInsertPayload(item: ProjectPickerItem): InsertAssetPayload {
|
||||
if (item.character?.character) {
|
||||
return projectCharacterToInsertPayload(item.character);
|
||||
|
||||
Reference in New Issue
Block a user