From e7446481836a157c0299b2a82a7ab5dff0696b32 Mon Sep 17 00:00:00 2001 From: imeepos Date: Tue, 29 Jul 2025 14:33:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=B7=A5=E4=BD=9C=E5=8F=B0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复功能问题: - 修复素材tab无法左右滑动的问题 - 添加自定义滚动条样式,隐藏默认滚动条 - 优化tab布局,支持横向滚动浏览 简化素材卡片设计: - 创建SimpleMaterialCard组件,专用于素材选择 - 改为正方形缩略图,更适合侧边栏2列布局 - 精简信息显示:只保留名称、类型、时长/大小 - 移除繁琐的描述、标签等冗余信息 - 优化选择状态指示器位置和大小 优化布局体验: - 素材选择器改为2列网格布局 - 缩小搜索框和间距,节省空间 - 统一使用紧凑型设计风格 - 改善滚动条样式和交互体验 用户体验提升: - 更直观的素材浏览体验 - 减少视觉干扰,突出核心信息 - 提高操作效率和界面美观度 - 符合专业工具的简洁设计理念 --- .../video-generation/MaterialSelector.tsx | 59 ++++---- .../video-generation/SimpleMaterialCard.tsx | 140 ++++++++++++++++++ apps/desktop/src/pages/VideoGeneration.tsx | 11 +- docs/video-generation-feature.md | 32 ++-- 4 files changed, 190 insertions(+), 52 deletions(-) create mode 100644 apps/desktop/src/components/video-generation/SimpleMaterialCard.tsx diff --git a/apps/desktop/src/components/video-generation/MaterialSelector.tsx b/apps/desktop/src/components/video-generation/MaterialSelector.tsx index 202c491..6693e31 100644 --- a/apps/desktop/src/components/video-generation/MaterialSelector.tsx +++ b/apps/desktop/src/components/video-generation/MaterialSelector.tsx @@ -1,15 +1,14 @@ import React, { useState, useEffect } from 'react'; import { MagnifyingGlassIcon, - PlusIcon, - CheckIcon + PlusIcon } from '@heroicons/react/24/outline'; import { MaterialCategory, MaterialAsset, MaterialSelectorProps } from '../../types/videoGeneration'; -import { MaterialAssetCard } from './MaterialAssetCard'; +import { SimpleMaterialCard } from './SimpleMaterialCard'; /** * 素材选择器组件 @@ -219,60 +218,54 @@ export const MaterialSelector: React.FC = ({ return (
{/* 搜索栏 */} -
+
- + setSearchQuery(e.target.value)} - className="w-full pl-10 pr-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all duration-200 text-sm" + className="w-full pl-8 pr-3 py-1.5 border border-gray-200 rounded text-xs focus:ring-1 focus:ring-primary-500 focus:border-transparent transition-all duration-200" />
- + {/* 选择状态 */} {selectedAssets.length > 0 && ( -
- 已选择 {selectedAssets.length} 个素材 +
+ 已选 {selectedAssets.length} 个 {maxSelection && ` / ${maxSelection}`}
)}
{/* 素材列表 */} -
+
{isLoading ? ( -
-
- 加载中... +
+
+ 加载中...
) : filteredAssets.length === 0 ? (
- -

+ +

{searchQuery.trim() ? '未找到匹配的素材' : '暂无素材'}

) : ( -
+
{filteredAssets.map((asset) => ( -
- - - {/* 选择状态指示器 */} - {isAssetSelected(asset) && ( -
- -
- )} -
+ { + console.log('Preview asset:', asset); + // TODO: 实现预览功能 + }} + /> ))}
)} diff --git a/apps/desktop/src/components/video-generation/SimpleMaterialCard.tsx b/apps/desktop/src/components/video-generation/SimpleMaterialCard.tsx new file mode 100644 index 0000000..e150c1d --- /dev/null +++ b/apps/desktop/src/components/video-generation/SimpleMaterialCard.tsx @@ -0,0 +1,140 @@ +import React from 'react'; +import { + PlayIcon, + MusicalNoteIcon, + DocumentTextIcon, + PhotoIcon, + VideoCameraIcon, + CheckIcon +} from '@heroicons/react/24/outline'; +import { + MaterialAsset, + MaterialCategory, + MATERIAL_CATEGORY_CONFIG +} from '../../types/videoGeneration'; + +interface SimpleMaterialCardProps { + asset: MaterialAsset; + isSelected?: boolean; + onSelect?: (asset: MaterialAsset) => void; + onPreview?: (asset: MaterialAsset) => void; +} + +/** + * 简化版素材卡片组件 + * 只显示核心信息:缩略图、名称、类型 + */ +export const SimpleMaterialCard: React.FC = ({ + asset, + isSelected = false, + onSelect, + onPreview +}) => { + const categoryConfig = MATERIAL_CATEGORY_CONFIG[asset.category]; + + // 获取文件类型图标 + const getTypeIcon = () => { + switch (asset.type) { + case 'image': + return ; + case 'video': + return ; + case 'audio': + return ; + case 'text': + return ; + default: + return ; + } + }; + + return ( +
onSelect?.(asset)} + > + {/* 缩略图区域 */} +
+ {asset.thumbnail_path ? ( + {asset.name} + ) : ( +
+
+ {categoryConfig.icon} +
+
+ )} + + {/* 类型标识 */} +
+
+ {getTypeIcon()} +
+
+ + {/* 播放按钮(视频/音频) */} + {(asset.type === 'video' || asset.type === 'audio') && ( +
+ +
+ )} + + {/* 选择状态指示器 */} + {isSelected && ( +
+ +
+ )} +
+ + {/* 内容区域 */} +
+

+ {asset.name} +

+ + {/* 简化的元数据 */} +
+ + {categoryConfig.label} + + + {/* 时长或大小信息 */} + {asset.metadata?.duration && ( + + {Math.floor(asset.metadata.duration / 60)}:{(asset.metadata.duration % 60).toString().padStart(2, '0')} + + )} + {asset.metadata?.size && !asset.metadata?.duration && ( + + {(asset.metadata.size / 1024 / 1024).toFixed(1)}MB + + )} +
+
+ + {/* 悬停效果 */} +
+
+ ); +}; diff --git a/apps/desktop/src/pages/VideoGeneration.tsx b/apps/desktop/src/pages/VideoGeneration.tsx index 4fe8b63..88e8ed5 100644 --- a/apps/desktop/src/pages/VideoGeneration.tsx +++ b/apps/desktop/src/pages/VideoGeneration.tsx @@ -1,8 +1,6 @@ import React, { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import { - PlayIcon, - CogIcon, SparklesIcon, ArrowRightIcon } from '@heroicons/react/24/outline'; @@ -280,7 +278,8 @@ const VideoGeneration: React.FC = () => {
{/* 素材分类标签 */}
-
+
{Object.values(MaterialCategory).map((category) => { const config = MATERIAL_CATEGORY_CONFIG[category]; const selectedAssets = project.selected_assets[category] || []; @@ -290,15 +289,15 @@ const VideoGeneration: React.FC = () => {