feat(records): 任务详情弹窗排版优化 — 参考素材搬左侧 + tooltip + max-height

用户反馈:右侧太挤,左侧视频下大片空白浪费,参考素材埋在右侧底部要滚才能看。

排版重组 (RecordDetailModal.tsx):
  - 左侧 mediaPanel:视频 + 参考素材(纵向排列)
    - 视频固定 480×270 (16:9 + object-fit contain)
    - 参考素材区紧贴视频下方,有标题"参考素材(N)"
  - 右侧 infoPanel:状态 / 失败原因 / 基本信息 / 提示词
    - prompt 区域宽度从挤压改为可读宽度
    - 不再有参考素材占下方位置
  - 整体不再有"空白左下角"+ "右侧挤死"+"参考要滚"问题

参考素材区限高 (RecordDetailModal.tsx refScrollBox):
  - max-height: 250px + overflow-y: auto
  - Seedance 单任务最多 9 张图(memory: project_seedance_max_refs),
    80px thumb × 5/行 = 1-2 行,250px 兜底有余
  - 极端情况(未来扩 audio/video 参考)走内部滚动,不推视频上去

Tooltip (ReferenceList.tsx):
  - refItem 加 title={label},hover thumb 弹原生 tooltip 显示完整文件名
  - 解决长文件名 "公司年会现场抓拍-高分辨率-竖屏-第3版.jpg" 被省略号截断后看不全的问题
  - 零成本(浏览器原生),无 JS 开销

新增 memory:
  ~/.claude/.../memory/project_seedance_max_refs.md
  - 火山 Seedance API 单任务最多 9 张参考图片
  - 防止以后又按"上百张"做 UI 假设

验证:
  - TS 编译过
  - modal screenshot 4 张更新 (docs/screenshots/v2/modal/)
  - 视频 + 参考素材左侧贴齐,右侧 prompt 区宽松

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
seaislee1209 2026-05-12 15:43:27 +08:00
parent a1c16be1ea
commit 385e1bb49e
2 changed files with 25 additions and 15 deletions

View File

@ -44,14 +44,22 @@ export function RecordDetailModal({ record: r, onClose, showTeam, showCost }: Pr
<button style={closeBtn} onClick={onClose}></button>
</div>
{/* Body — 左视频 / 右信息 双栏 */}
{/* Body — 左:视频+参考素材 / 右:信息+提示词 */}
<div style={body}>
{/* ── 左:视频 ── */}
{/* ── 左:视频 + 参考素材 ── */}
<div style={mediaPanel}>
<MediaArea record={r} />
{refs.length > 0 && (
<>
<div style={sectionTitle}>({refs.length})</div>
<div style={refScrollBox}>
<ReferenceList references={refs} />
</div>
</>
)}
</div>
{/* ── 右:信息(原有内容整体搬过来,排版不动)── */}
{/* ── 右侧:信息 + 提示词 ── */}
<div style={infoPanel}>
{/* Status */}
<div style={{ marginBottom: 16 }}>
@ -72,7 +80,7 @@ export function RecordDetailModal({ record: r, onClose, showTeam, showCost }: Pr
)}
{/* Info Grid */}
<div style={sectionTitle}></div>
<div style={{ ...sectionTitle, marginTop: 0 }}></div>
<div style={infoGrid}>
{r.ark_task_id && <InfoItem label="任务ID" value={r.ark_task_id} />}
{r.username && <InfoItem label="用户" value={r.username} />}
@ -92,14 +100,6 @@ export function RecordDetailModal({ record: r, onClose, showTeam, showCost }: Pr
{/* Prompt */}
<div style={sectionTitle}></div>
<div style={promptBox}>{r.prompt || '(无提示词)'}</div>
{/* References */}
{refs.length > 0 && (
<>
<div style={sectionTitle}>({refs.length})</div>
<ReferenceList references={refs} />
</>
)}
</div>
</div>
</div>
@ -217,13 +217,23 @@ const body: React.CSSProperties = {
minHeight: 0,
};
/* 左侧媒体区 — 固定 480 宽 */
/* 左侧媒体区 — 固定 480 宽,视频 + 参考素材纵向排列 */
const mediaPanel: React.CSSProperties = {
width: 480,
flexShrink: 0,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
alignItems: 'stretch',
minHeight: 0, /* 给内部 flex 让出收缩空间 */
};
/* :max-height + ,
Seedance 9 80px thumb × 5/ = 1-2 ,250px */
const refScrollBox: React.CSSProperties = {
maxHeight: 250,
overflowY: 'auto',
marginTop: 8,
paddingRight: 4,
};
const mediaFrame: React.CSSProperties = {

View File

@ -40,7 +40,7 @@ export function ReferenceList({ references }: Props) {
const hasUrl = fullUrl && !fullUrl.startsWith('asset://');
return (
<div key={i} style={refItem}>
<div key={i} style={refItem} title={label}>
{/* Thumbnail area */}
<div style={thumbWrap}>
{isAudio ? (