From c2fe02cf068214a4f2782b6ce520161fa0990eb7 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Thu, 27 Aug 2026 15:47:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=E6=A8=A1=E6=9D=BF=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E6=9D=A1=E5=AE=BD=E5=BA=A6=E7=BC=A9=E7=9F=AD?= =?UTF-8?q?=E8=87=B31/3=EF=BC=8C=E7=B4=A0=E6=9D=90=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E7=82=B9=E5=87=BB=E6=92=AD=E6=94=BE=E4=BA=A4?= =?UTF-8?q?=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - generate.css: xx-choice-thumb 宽度从 100% 改为 33%(max-width 80px),居中显示 - ManualMaterialList.tsx: 重构为独立 MaterialCard 组件 - 移除 hover 自动播放逻辑 - 默认显示视频封面/缩略图(非黑色) - 点击播放按钮开始播放,播放时隐藏按钮 - 播放中点击视频区域可暂停并恢复按钮 - 卡片内嵌播放,无弹窗 --- .../material/ManualMaterialList.tsx | 431 +++++++++--------- apps/web/src/pages/generate/generate.css | 4 +- 2 files changed, 231 insertions(+), 204 deletions(-) diff --git a/apps/web/src/pages/generate/components/material/ManualMaterialList.tsx b/apps/web/src/pages/generate/components/material/ManualMaterialList.tsx index dbee4a1b0..240f4cffd 100644 --- a/apps/web/src/pages/generate/components/material/ManualMaterialList.tsx +++ b/apps/web/src/pages/generate/components/material/ManualMaterialList.tsx @@ -1,7 +1,8 @@ /** * 手动选择素材列表 — 竖屏 9:16 卡片网格 + * 交互:默认显示封面,点击播放按钮播放,播放中隐藏按钮,点击视频区域暂停 */ -import React, { useRef, useCallback } from "react" +import React, { useRef, useState, useCallback } from "react" import { Typography } from "antd" import type { AssetItem } from "@/api/assets" @@ -22,37 +23,230 @@ const fmtDuration = (seconds?: number): string => { return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}` } +/** 单个素材卡片 */ +const MaterialCard: React.FC<{ + asset: AssetItem + checked: boolean + onToggle: () => void +}> = ({ asset, checked, onToggle }) => { + const videoRef = useRef(null) + const [isPlaying, setIsPlaying] = useState(false) + const isVideo = asset.mime_type?.startsWith("video/") ?? false + const thumbSrc = asset.thumbnail_url || undefined + + const handlePlayToggle = useCallback( + (e: React.MouseEvent) => { + e.stopPropagation() + const video = videoRef.current + if (!video || !isVideo) return + + if (isPlaying) { + video.pause() + setIsPlaying(false) + } else { + video.play().catch(() => {}) + setIsPlaying(true) + } + }, + [isPlaying, isVideo], + ) + + const handleVideoEnded = useCallback(() => { + setIsPlaying(false) + }, []) + + const handleCardClick = useCallback(() => { + // 如果视频正在播放,点击卡片空白区域暂停视频 + if (isPlaying) { + const video = videoRef.current + if (video) { + video.pause() + setIsPlaying(false) + } + return + } + onToggle() + }, [isPlaying, onToggle]) + + return ( +
+ {/* 视频元素 */} + {isVideo && asset.file_url ? ( +