feat: 标题样式面板迁移到Step5 + CSS实时预览 + 修复封面错误展示 #1408

Closed
xiaoxia wants to merge 1 commits from feat/title-style-panel-to-step5 into develop
Owner

改动内容

1. Step4 — 删除样式面板

  • 从 Step4TitleSettings.tsx 中删除 <TitleStylePanel> 的 import 和渲染
  • Step4 仅保留:标题文字输入(AutoComplete)+ AI 标题生成(AiTitleGenerator)+ AI 自动选择切换

2. Step5 — 接收样式面板

  • 在 Step5GeneratePreview.tsx 中引入 <TitleStylePanel> 组件
  • 接收 titleSettings + 所有样式回调作为 props(从父组件 GeneratePage 传入)
  • 样式面板放在预览控制区的上方,用户能一边看预览一边调样式

3. PreviewVideoPanel — 添加 CSS 标题实时预览层

  • 在预览视频 <video> 元素上方叠加 CSS 标题层
  • 仅在预览视频已生成(status === "ready")时显示
  • 标题层根据当前 titleSettings 实时渲染:
    • 标题文字(titleSettings.title)
    • 位置(position → CSS top/middle/bottom 定位,与 ASS alignment 8/5/2 对齐)
    • 字体(font → font-family)
    • 字号(size → 百分比缩放,cap 36)
    • 粗体/斜体(bold/italic → font-weight/font-style)
    • 描边(stroke → -webkit-text-stroke)
    • 阴影(shadow → text-shadow)
    • 颜色(color)

4. 渲染一致性

  • CSS 预览层使用与后端 ass_subtitle_builder.py 完全一致的参数:
    • TITLE_MARGIN_TOP = 60, TITLE_MARGIN_BOTTOM = 60, TITLE_MARGIN_SIDE = 40
    • 默认视频高度 720px,所有位置用百分比换算
    • position → ASS alignment 映射:top→8, center→5, bottom→2
  • 用户看到的 CSS 预览效果 = 后端 FFmpeg 渲染出的预览视频效果

5. 封面生成 400 错误展示

  • 修复封面生成失败时双重 toast 问题
  • API 拦截器已弹出后端具体错误信息时,hook 不再重复弹出
  • 后端 400 消息("请先生成预览视频,再生成封面" 等)由拦截器统一展示

修改的文件

  • GeneratePage.tsx — 调用 useTitleStyleUpdaters 获取样式回调,传递给 Step5 和 PreviewVideoPanel
  • GenerateStepContent.tsx — 新增样式回调 props,传递给 Step5
  • Step4TitleSettings.tsx — 删除 TitleStylePanel
  • Step5GeneratePreview.tsx — 添加 TitleStylePanel
  • PreviewVideoPanel.tsx — 添加 TitleOverlay CSS 层
  • useStep6Cover.ts — 修复双重 toast(检查 __msgShown)
## 改动内容 ### 1. Step4 — 删除样式面板 - 从 Step4TitleSettings.tsx 中删除 `<TitleStylePanel>` 的 import 和渲染 - Step4 仅保留:标题文字输入(AutoComplete)+ AI 标题生成(AiTitleGenerator)+ AI 自动选择切换 ### 2. Step5 — 接收样式面板 - 在 Step5GeneratePreview.tsx 中引入 `<TitleStylePanel>` 组件 - 接收 titleSettings + 所有样式回调作为 props(从父组件 GeneratePage 传入) - 样式面板放在预览控制区的上方,用户能一边看预览一边调样式 ### 3. PreviewVideoPanel — 添加 CSS 标题实时预览层 - 在预览视频 `<video>` 元素上方叠加 CSS 标题层 - 仅在预览视频已生成(status === "ready")时显示 - 标题层根据当前 titleSettings 实时渲染: - 标题文字(titleSettings.title) - 位置(position → CSS top/middle/bottom 定位,与 ASS alignment 8/5/2 对齐) - 字体(font → font-family) - 字号(size → 百分比缩放,cap 36) - 粗体/斜体(bold/italic → font-weight/font-style) - 描边(stroke → -webkit-text-stroke) - 阴影(shadow → text-shadow) - 颜色(color) ### 4. 渲染一致性 - CSS 预览层使用与后端 `ass_subtitle_builder.py` 完全一致的参数: - `TITLE_MARGIN_TOP = 60`, `TITLE_MARGIN_BOTTOM = 60`, `TITLE_MARGIN_SIDE = 40` - 默认视频高度 720px,所有位置用百分比换算 - position → ASS alignment 映射:top→8, center→5, bottom→2 - 用户看到的 CSS 预览效果 = 后端 FFmpeg 渲染出的预览视频效果 ### 5. 封面生成 400 错误展示 - 修复封面生成失败时双重 toast 问题 - API 拦截器已弹出后端具体错误信息时,hook 不再重复弹出 - 后端 400 消息("请先生成预览视频,再生成封面" 等)由拦截器统一展示 ## 修改的文件 - `GeneratePage.tsx` — 调用 useTitleStyleUpdaters 获取样式回调,传递给 Step5 和 PreviewVideoPanel - `GenerateStepContent.tsx` — 新增样式回调 props,传递给 Step5 - `Step4TitleSettings.tsx` — 删除 TitleStylePanel - `Step5GeneratePreview.tsx` — 添加 TitleStylePanel - `PreviewVideoPanel.tsx` — 添加 TitleOverlay CSS 层 - `useStep6Cover.ts` — 修复双重 toast(检查 __msgShown)
xiaoxia added the feature label 2026-08-17 20:12:47 +08:00
xiaoxia added 1 commit 2026-08-17 20:12:47 +08:00
feat: 标题样式面板迁移到Step5 + CSS实时预览 + 修复封面错误展示
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Failing after 1s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 43s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m43s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m12s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m5s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m6s
AI Code Review / AI Code Review (pull_request) Failing after 2m7s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m21s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 2m15s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m39s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 6m4s
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 7s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 14s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 24s
f561136afa
- Step4 删除 TitleStylePanel,仅保留标题输入 + AI 生成
- Step5 接收 TitleStylePanel,用户可实时调整标题样式
- PreviewVideoPanel 添加 CSS 标题覆盖层,与 FFmpeg ASS 坐标对齐
- 渲染参数(位置/字体/字号/粗体/斜体/描边/阴影/颜色)与后端完全一致
- 修复封面生成 400 错误双重 toast(检查 __msgShown 避免重复弹出)
- useTitleStyleUpdaters 提升到 GeneratePage,Step5 和 PreviewVideoPanel 共用
Collaborator

【阻塞级判定】

  • 是否存在阻塞级问题:是
  • 阻塞级问题数量:3 个

📊 审查概览

  • 整体评价:需修改
  • 建议级问题数量:1 个

🔴 阻塞级问题(必须修复)

  1. [PreviewVideoPanel.tsx: buildTitleStyle函数] 标题字号被硬编码截断导致预览不一致

    • 问题类型:逻辑bug
    • 问题描述:代码中 const fontSizePercent = (Math.min(settings.size, 36) / ASS_VIDEO_HEIGHT) * 100 使用了 Math.min(settings.size, 36) 强制将字号上限限制为 36。如果用户在后端配置或通过其他途径设置了大于 36 的字号(例如 48 或 60),前端 CSS 预览将显示为 36 的效果,但最终生成的视频会使用真实的大字号,导致“所见即所得”失效。
    • 修改建议:移除 Math.min 限制,直接使用 settings.size 计算百分比,确保预览与生成结果一致。
  2. [PreviewVideoPanel.tsx: buildTitleStyle函数] 描边宽度未随字号缩放

    • 问题类型:逻辑bug
    • 问题描述:代码中 base.WebkitTextStroke = "1px #000000" 将描边宽度硬编码为 1px。由于字号是响应式的(使用容器高度的百分比),在不同屏幕尺寸或视频比例下,字体的实际像素大小会变化。固定的 1px 描边会导致在大字号下描边过细(视觉不一致),而在小字号下描边过粗,无法匹配后端 FFmpeg 渲染效果(FFmpeg 的描边通常随字号缩放)。
    • 修改建议:使用相对单位(如 em,例如 0.05em)或基于容器高度的百分比来设置描边宽度,使其随字号同步缩放。
  3. [PreviewVideoPanel.tsx: buildTitleStyle函数] 阴影偏移与模糊未随字号缩放

    • 问题类型:逻辑bug
    • 问题描述:代码中 base.textShadow = "2px 2px 4px rgba(0,0,0,0.8)" 将阴影参数硬编码为像素值。与描边问题类似,固定的像素值无法适配响应式的字号大小。当预览容器变大时,字号变大但阴影保持不变,导致视觉层级感丢失或与生成视频效果不符。
    • 修改建议:将阴影参数改为相对单位(如 em),确保阴影效果与字号大小成正比。

💡 改进建议(不阻塞合并)

  1. [PreviewVideoPanel.tsx: getPositionStyle函数] 增加坐标系假设说明
    • 具体内容:代码中 sidePercent 计算基于 1280 宽度,这隐含假设了后端 ASS 字幕的 PlayResX 为 1280。建议在注释中明确这一假设,以便后续维护者理解该计算逻辑的边界条件。

良好实践

  • PreviewVideoPanel.tsx 中使用 useMemo 缓存样式计算对象,避免每次渲染都重新创建对象,有利于性能。
  • useStep6Cover.ts 中增加了对 __msgShown 的检查,有效防止了拦截器已处理错误时的重复 Toast 提示,改善了用户体验。
  • 组件拆分清晰,TitleOverlay 独立封装,职责单一。

格式检查通过 | 逻辑审查需修改 | ⚠️ 建议关注性能


🤖 由 AI 代码审查机器人自动生成 | 2026-08-17 12:14:54 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:是 - 阻塞级问题数量:3 个 ### 📊 审查概览 - 整体评价:需修改 - 建议级问题数量:1 个 ### 🔴 阻塞级问题(必须修复) 1. **[PreviewVideoPanel.tsx: buildTitleStyle函数] 标题字号被硬编码截断导致预览不一致** - 问题类型:逻辑bug - 问题描述:代码中 `const fontSizePercent = (Math.min(settings.size, 36) / ASS_VIDEO_HEIGHT) * 100` 使用了 `Math.min(settings.size, 36)` 强制将字号上限限制为 36。如果用户在后端配置或通过其他途径设置了大于 36 的字号(例如 48 或 60),前端 CSS 预览将显示为 36 的效果,但最终生成的视频会使用真实的大字号,导致“所见即所得”失效。 - 修改建议:移除 `Math.min` 限制,直接使用 `settings.size` 计算百分比,确保预览与生成结果一致。 2. **[PreviewVideoPanel.tsx: buildTitleStyle函数] 描边宽度未随字号缩放** - 问题类型:逻辑bug - 问题描述:代码中 `base.WebkitTextStroke = "1px #000000"` 将描边宽度硬编码为 `1px`。由于字号是响应式的(使用容器高度的百分比),在不同屏幕尺寸或视频比例下,字体的实际像素大小会变化。固定的 `1px` 描边会导致在大字号下描边过细(视觉不一致),而在小字号下描边过粗,无法匹配后端 FFmpeg 渲染效果(FFmpeg 的描边通常随字号缩放)。 - 修改建议:使用相对单位(如 `em`,例如 `0.05em`)或基于容器高度的百分比来设置描边宽度,使其随字号同步缩放。 3. **[PreviewVideoPanel.tsx: buildTitleStyle函数] 阴影偏移与模糊未随字号缩放** - 问题类型:逻辑bug - 问题描述:代码中 `base.textShadow = "2px 2px 4px rgba(0,0,0,0.8)"` 将阴影参数硬编码为像素值。与描边问题类似,固定的像素值无法适配响应式的字号大小。当预览容器变大时,字号变大但阴影保持不变,导致视觉层级感丢失或与生成视频效果不符。 - 修改建议:将阴影参数改为相对单位(如 `em`),确保阴影效果与字号大小成正比。 ### 💡 改进建议(不阻塞合并) 1. **[PreviewVideoPanel.tsx: getPositionStyle函数] 增加坐标系假设说明** - 具体内容:代码中 `sidePercent` 计算基于 `1280` 宽度,这隐含假设了后端 ASS 字幕的 `PlayResX` 为 1280。建议在注释中明确这一假设,以便后续维护者理解该计算逻辑的边界条件。 ### ✅ 良好实践 - `PreviewVideoPanel.tsx` 中使用 `useMemo` 缓存样式计算对象,避免每次渲染都重新创建对象,有利于性能。 - `useStep6Cover.ts` 中增加了对 `__msgShown` 的检查,有效防止了拦截器已处理错误时的重复 Toast 提示,改善了用户体验。 - 组件拆分清晰,`TitleOverlay` 独立封装,职责单一。 --- ✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-08-17 12:14:54 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->

🚀 预览环境已部署

项目 详情
PR号 #1408
预览链接 https://pr-1408.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1408 | | 预览链接 | [https://pr-1408.preview.xiaoxiajianji.com](https://pr-1408.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
auto-approve-bot approved these changes 2026-08-17 20:20:34 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot approved these changes 2026-08-17 20:20:34 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
xiaoxia closed this pull request 2026-08-17 20:28:40 +08:00

🗑️ 预览环境已清理

PR #1408 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1408 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Some checks are pending
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Failing after 1s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 43s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m43s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m12s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m5s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m6s
AI Code Review / AI Code Review (pull_request) Failing after 2m7s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m21s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 2m15s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m39s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 6m4s
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 7s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 14s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 24s

Pull request closed

Sign in to join this conversation.