拆分编辑器素材库模型
抽出素材库分组和本地状态变更规则 补充素材库模型单测 更新 TRACKING.md 记录第三十七阶段验证
This commit is contained in:
216
src/components/image-editor/ImageCanvasAssetLibraryModel.ts
Normal file
216
src/components/image-editor/ImageCanvasAssetLibraryModel.ts
Normal file
@@ -0,0 +1,216 @@
|
||||
import type {
|
||||
EditorAsset,
|
||||
EditorAssetFolder,
|
||||
} from './ImageCanvasEditorTypes';
|
||||
|
||||
export type GroupedAssetFolder = EditorAssetFolder & {
|
||||
assets: EditorAsset[];
|
||||
};
|
||||
|
||||
export function groupAssetsByFolder(
|
||||
assetFolders: EditorAssetFolder[],
|
||||
assets: EditorAsset[],
|
||||
): GroupedAssetFolder[] {
|
||||
return assetFolders.map((folder) => ({
|
||||
...folder,
|
||||
assets: assets.filter((asset) => asset.folderId === folder.id),
|
||||
}));
|
||||
}
|
||||
|
||||
export function getSelectableAssets(assets: EditorAsset[]) {
|
||||
return assets.filter((asset) => asset.sourceKind === 'uploaded');
|
||||
}
|
||||
|
||||
export function areAllSelectableAssetsSelected(
|
||||
selectableAssets: EditorAsset[],
|
||||
selectedAssetIds: Set<string>,
|
||||
) {
|
||||
return (
|
||||
selectableAssets.length > 0 &&
|
||||
selectableAssets.every((asset) => selectedAssetIds.has(asset.id))
|
||||
);
|
||||
}
|
||||
|
||||
export function renameAssetById(
|
||||
assets: EditorAsset[],
|
||||
assetId: string,
|
||||
label: string,
|
||||
) {
|
||||
return assets.map((asset) =>
|
||||
asset.id === assetId
|
||||
? {
|
||||
...asset,
|
||||
label,
|
||||
}
|
||||
: asset,
|
||||
);
|
||||
}
|
||||
|
||||
export function toggleAssetFolderCollapsed(
|
||||
assetFolders: EditorAssetFolder[],
|
||||
folderId: string,
|
||||
) {
|
||||
return assetFolders.map((folder) =>
|
||||
folder.id === folderId
|
||||
? {
|
||||
...folder,
|
||||
collapsed: !folder.collapsed,
|
||||
}
|
||||
: folder,
|
||||
);
|
||||
}
|
||||
|
||||
export function createLocalAssetFolder({
|
||||
folderId,
|
||||
label,
|
||||
}: {
|
||||
folderId: string;
|
||||
label: string;
|
||||
}): EditorAssetFolder {
|
||||
return {
|
||||
id: folderId,
|
||||
label,
|
||||
collapsed: false,
|
||||
systemDefault: false,
|
||||
persisted: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function replaceLocalAssetFolder({
|
||||
folders,
|
||||
assets,
|
||||
localFolderId,
|
||||
persistedFolder,
|
||||
}: {
|
||||
folders: EditorAssetFolder[];
|
||||
assets: EditorAsset[];
|
||||
localFolderId: string;
|
||||
persistedFolder: {
|
||||
folderId: string;
|
||||
label: string;
|
||||
collapsed: boolean;
|
||||
systemDefault: boolean;
|
||||
};
|
||||
}) {
|
||||
return {
|
||||
folders: folders.map((folder) =>
|
||||
folder.id === localFolderId
|
||||
? {
|
||||
id: persistedFolder.folderId,
|
||||
label: persistedFolder.label,
|
||||
collapsed: persistedFolder.collapsed,
|
||||
systemDefault: persistedFolder.systemDefault,
|
||||
persisted: true,
|
||||
}
|
||||
: folder,
|
||||
),
|
||||
assets: assets.map((asset) =>
|
||||
asset.folderId === localFolderId
|
||||
? {
|
||||
...asset,
|
||||
folderId: persistedFolder.folderId,
|
||||
}
|
||||
: asset,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
export function removeAssetById(assets: EditorAsset[], assetId: string) {
|
||||
return assets.filter((asset) => asset.id !== assetId);
|
||||
}
|
||||
|
||||
export function renameAssetFolderById(
|
||||
assetFolders: EditorAssetFolder[],
|
||||
folderId: string,
|
||||
label: string,
|
||||
) {
|
||||
return assetFolders.map((folder) =>
|
||||
folder.id === folderId
|
||||
? {
|
||||
...folder,
|
||||
label,
|
||||
}
|
||||
: folder,
|
||||
);
|
||||
}
|
||||
|
||||
export function resolveDefaultAssetFolder(assetFolders: EditorAssetFolder[]) {
|
||||
return (
|
||||
assetFolders.find((folder) => folder.systemDefault) ?? assetFolders[0] ?? null
|
||||
);
|
||||
}
|
||||
|
||||
export function deleteAssetFolderLocally({
|
||||
folders,
|
||||
assets,
|
||||
folderId,
|
||||
defaultFolderId,
|
||||
}: {
|
||||
folders: EditorAssetFolder[];
|
||||
assets: EditorAsset[];
|
||||
folderId: string;
|
||||
defaultFolderId: string;
|
||||
}) {
|
||||
return {
|
||||
folders: folders.filter((folder) => folder.id !== folderId),
|
||||
assets: assets.map((asset) =>
|
||||
asset.folderId === folderId
|
||||
? {
|
||||
...asset,
|
||||
folderId: defaultFolderId,
|
||||
}
|
||||
: asset,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
export function toggleAssetSelection(
|
||||
selectedAssetIds: Set<string>,
|
||||
assetId: string,
|
||||
) {
|
||||
const nextIds = new Set(selectedAssetIds);
|
||||
if (nextIds.has(assetId)) {
|
||||
nextIds.delete(assetId);
|
||||
} else {
|
||||
nextIds.add(assetId);
|
||||
}
|
||||
return nextIds;
|
||||
}
|
||||
|
||||
export function resolveAllAssetSelection({
|
||||
allSelectableAssetsSelected,
|
||||
selectableAssets,
|
||||
}: {
|
||||
allSelectableAssetsSelected: boolean;
|
||||
selectableAssets: EditorAsset[];
|
||||
}) {
|
||||
return allSelectableAssetsSelected
|
||||
? new Set<string>()
|
||||
: new Set(selectableAssets.map((asset) => asset.id));
|
||||
}
|
||||
|
||||
export function removeSelectedAssets(
|
||||
assets: EditorAsset[],
|
||||
selectedAssetIds: Set<string>,
|
||||
) {
|
||||
const deletedAssets = assets.filter((asset) => selectedAssetIds.has(asset.id));
|
||||
return {
|
||||
assets: assets.filter((asset) => !selectedAssetIds.has(asset.id)),
|
||||
deletedAssets,
|
||||
};
|
||||
}
|
||||
|
||||
export function moveAssetToFolderLocally(
|
||||
assets: EditorAsset[],
|
||||
assetId: string,
|
||||
folderId: string,
|
||||
) {
|
||||
return assets.map((asset) =>
|
||||
asset.id === assetId
|
||||
? {
|
||||
...asset,
|
||||
folderId,
|
||||
}
|
||||
: asset,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user