diff --git a/docs/plans/2026-10-17-K9.md b/docs/plans/2026-10-17-K9.md new file mode 100644 index 0000000..3f303b1 --- /dev/null +++ b/docs/plans/2026-10-17-K9.md @@ -0,0 +1,70 @@ +# 2026-10-17 K9 首页剧目列表改造(2 列全部剧目) + +## 一、目标与边界 + +首页(发现 tab)移除「继续观看」区块,在分类 chips 下方以懒构建的 2 列网格展示 +当前分类的全部剧目;保留 header、轮播、分类、三态、空态和底部导航。 + +- 客户端分支:`feature/flutter-k9-home-grid`,基线 `develop 99f64ab`。 +- 文档分支:`docs/k9-home-grid`,FruitServer 基线 K9 任务书 `b434f65`。 +- 只改首页(发现页)、三语 l10n、对应 widget 测试与 `docs/plans/`。 +- 不改接口、数据模型、CategoryController 过滤逻辑、轮播、通知、观看记录、 + 收藏、下载或底部导航。 +- 不新增图片、依赖或分页;继续使用 `RemoteImage` 懒加载。 +- 不跑真机,设备侧滚动、布局、分类切换和详情跳转由用户验收。 + +## 二、实现方案 + +1. 删除 `_continueHeader`、`_dramaContent`、`_continueTile`、`_ShowcaseCard` + 与 `_cardsFor`,首页不再构建或保留「继续观看」文案和代码。 +2. 将页面滚动容器改为 `CustomScrollView`,依次放置: + carousel `SliverToBoxAdapter`、分类与标题 `SliverToBoxAdapter`、状态 + `SliverToBoxAdapter` 或剧目 `SliverGrid`、底部留白 `SliverToBoxAdapter`。 +3. 剧目网格使用 `SliverGridDelegateWithFixedCrossAxisCount`: + `crossAxisCount: 2`、`crossAxisSpacing: 12`、`mainAxisSpacing: 16`、 + `childAspectRatio: 2 / 3`;左右由 `SliverPadding` 保持 16。 +4. 卡片封面使用 2:3 比例、14px 圆角、`RemoteImage` 和现有底部深色渐变; + 标题最多 2 行,类型最多 1 行。点击调用现有 + `logic.openCard(..., embedded, onDramaSelected, onAction)`。 +5. 数据直接使用 `CategoryController.visibleDramas`;`For You` 使用其全量 + 去重结果。分类切换后由 ChangeNotifier 驱动 sliver 内容更新。 +6. 保留 `categories.loading` 首载进度、`categories.error` 重试、 + `noCategoryDramas` / `noSearchResults` 空态文案。 +7. l10n 新增 `allDramas`: + `全部剧目` / `All Dramas` / `Semua Drama`,并重新生成 l10n。 + +## 三、影响文件 + +- `ReelShort/lib/pages/discover/discover_view.dart` +- `ReelShort/lib/l10n/app_en.arb` +- `ReelShort/lib/l10n/app_zh.arb` +- `ReelShort/lib/l10n/app_id.arb` +- `ReelShort/lib/l10n/app_localizations*.dart`(生成物) +- `ReelShort/test/discover/home_all_dramas_grid_test.dart`(新增) +- `ReelShort/test/widget_test.dart`(仅更新作废的「继续观看」断言) +- `FruitServer/docs/plans/2026-10-17-K9.md` +- `FruitServer/docs/plans/PROGRESS.md` +- `FruitServer/docs/plans/INBOX.md` + +## 四、测试与门禁 + +1. 先新增 K9 首页 widget 测试并取得红灯。 +2. 实现后验证:无「继续观看」、有「全部剧目」、2 列 sliver、左右/行列间距、 + 2:3 封面、分类切换更新、空态与失败态。 +3. 运行 `dart analyze lib test`、`flutter test`、`flutter build apk --debug`; + 构建前检查无并发 `flutter run/build`。 +4. 完成后 `merge --no-ff` 回客户端 `develop` 并 push;FruitServer 文档同样 + 合并推送。作者与提交者统一为 + `Zhou Weidong <502333560@qq.com>`。 + +## 五、风险与待确认 + +- 既有 `test/widget_test.dart` 有两个壳层用例断言首页出现 + `Continue Watching`。K9 明确要求该文案彻底消失,因此原断言与 + `find.text('Continue Watching'), findsNothing` 不可能同时成立。 + 处理方式:保留两个既有用例及完整导航流程,只把已作废的文案断言更新为 + `All Dramas`,不删除任何测试用例。 +- 首页 feed 可能一次返回较多剧目;必须使用 `SliverGrid` 懒构建,不能嵌套 + `GridView(shrinkWrap: true)`。 +- 2:3 卡片在小屏需要保持标题 2 行和类型 1 行不溢出;测试覆盖 320px 宽度。 +- 不改 `CategoryController` 的数据语义;筛选仍由现有分区 code 决定。 diff --git a/docs/plans/INBOX.md b/docs/plans/INBOX.md index 2800d80..af978a1 100644 --- a/docs/plans/INBOX.md +++ b/docs/plans/INBOX.md @@ -20,7 +20,7 @@ --- -## [待处理] 2026-10-17 | K9 首页剧目列表改造(2 列全部剧目) +## [已处理·待用户验收] 2026-10-17 | K9 首页剧目列表改造(2 列全部剧目) **用户指令(2026-10-17)**:「优化首页,要有全部剧目的列表,一行 2 个,不用显示继续观看的」。 @@ -66,6 +66,32 @@ - 先写 `FruitServer/docs/plans/2026-10-17-K9.md`;每步「叙述 + 命令 + 原始输出 + 解读」追加到 `PROGRESS.md`;完成后停住写回执。 - 提交作者与提交者统一 `Zhou Weidong <502333560@qq.com>`。 +### 五、K9 完成回执(2026-10-17) + +**结论**:首页「继续观看」已移除,分类下方改为 `CustomScrollView + SliverGrid` +的 2 列「全部剧目」列表;分类切换、空态、失败态、全量测试与 APK 构建均完成。 +未改接口、数据模型、轮播、通知或其他页面;未跑真机。 + +- 客户端分支 `feature/flutter-k9-home-grid` 从 `99f64ab` 完成并 + `--no-ff` 合并;功能提交 `cf03178`,合并提交 `2c381be`,已推送 + `99f64ab..2c381be develop`。 +- `discover_view.dart` 从 649 行降到 487 行;新增 + `widgets/home_drama_grid.dart` 167 行。已删除 `_continueHeader`、 + `_dramaContent`、`_continueTile`、`_ShowcaseCard` 与 `_cardsFor`。 +- `SliverGridDelegateWithFixedCrossAxisCount` 为 2 列、列距 12、行距 16; + 左右边距 16;封面 2:3、圆角 14,标题最多 2 行、类型最多 1 行。 +- 新增三语 `allDramas`:`全部剧目` / `All Dramas` / `Semua Drama`。 +- 新增 `test/discover/home_all_dramas_grid_test.dart` 5 个用例,覆盖标题、 + 无继续观看、2 列参数、2:3 封面、分类切换、空态、失败态和 320px 小屏。 +- 既有 `test/widget_test.dart` 的 5 处「Continue Watching」可见文案断言原位 + 更新为「All Dramas」,所有既有用例与导航流程保留,未删除测试用例。 +- `dart analyze lib test` 零告警;`flutter test` 为 + `00:18 +297 ~1: All tests passed!`;`flutter build apk --debug` 成功。 + +用户真机验证步骤与逐步预期、原始输出见 +`docs/plans/PROGRESS.md`「24. K9 首页 2 列全部剧目」。 +设备侧滚动、布局、分类切换和详情跳转验收由用户执行。 + --- ## [已处理·待用户验收] 2026-10-17 | K8 登录页视觉重设计 diff --git a/docs/plans/PROGRESS.md b/docs/plans/PROGRESS.md index f631281..f470e2f 100644 --- a/docs/plans/PROGRESS.md +++ b/docs/plans/PROGRESS.md @@ -2355,3 +2355,183 @@ Running Gradle task 'assembleDebug'... 有一次 light impact。 设备侧截图、日志与最终视觉验收结论由用户执行。 + +--- + +## 2026-10-17 K9 首页 2 列全部剧目 + +### 24.1 范围、分支与计划 + +叙述:按 INBOX K9 条目移除首页「继续观看」,在分类 chips 下方展示当前分类的 +全部剧目。只改发现页、三语 l10n、首页相关测试与 `docs/plans/`;不改接口、 +数据模型、轮播、通知或其他页面。 + +- 客户端:从 `develop 99f64ab` 创建 `feature/flutter-k9-home-grid`。 +- 文档:从 K9 任务书 `b434f65` 创建 `docs/k9-home-grid`。 + +开工前先写并提交计划: + +```text +496d273 docs(plans): 增加 K9 首页剧目网格实施计划 +``` + +### 24.2 先红:首页网格测试 + +叙述:先新增 `test/discover/home_all_dramas_grid_test.dart`,未改实现与既有测试。 + +```text +$ flutter test test/discover/home_all_dramas_grid_test.dart +Expected: no matching candidates + Actual: Found 1 widget with text "Continue Watching" + +Found 0 widgets with key [<'home-drama-card-city-lights-demo'>]: [] + +Found 0 widgets with text "All Dramas": [] + +00:02 +0 -5: Some tests failed. +``` + +解读:继续观看仍存在,「全部剧目」标题、2 列网格和卡片 Key 尚不存在,红灯与 +K9 范围一致。 + +### 24.3 实现与定向绿灯 + +`discover_view.dart` 改为外层 `CustomScrollView`,首页 sliver 顺序为: +轮播、分类与标题、剧目网格、底部留白。网格代码拆到: + +- `lib/pages/discover/widgets/home_drama_grid.dart` + +关键参数: + +```text +crossAxisCount: 2 +mainAxisSpacing: 16 +crossAxisSpacing: 12 +childAspectRatio: 2 / 3 +horizontal padding: 16 +``` + +卡片使用 `RemoteImage`、14px 圆角、底部深色渐变;标题 2 行、类型 1 行。 +点击直接调用现有 `logic.openCard(...)`。分类数据直接使用 +`CategoryController.visibleDramas`。 + +新增三语 `allDramas` 并执行 `flutter gen-l10n`: + +```text +$ rg -n "allDramas" lib/l10n +lib/l10n/app_localizations_en.dart:161: String get allDramas => 'All Dramas'; +lib/l10n/app_zh.arb:58: "allDramas": "全部剧目", +lib/l10n/app_en.arb:58: "allDramas": "All Dramas", +lib/l10n/app_localizations_zh.dart:158: String get allDramas => '全部剧目'; +lib/l10n/app_id.arb:58: "allDramas": "Semua Drama", +lib/l10n/app_localizations_id.dart:161: String get allDramas => 'Semua Drama'; +``` + +定向绿灯: + +```text +$ flutter test test/discover/home_all_dramas_grid_test.dart +00:01 +5: All tests passed! +``` + +覆盖:无继续观看、全部剧目标题、2 列 delegate、左右/行列间距、2:3 封面、 +分类切换、无剧目空态、分类缺失空态、失败重试与 320px 小屏。 + +文件规模: + +```text +487 lib/pages/discover/discover_view.dart +167 lib/pages/discover/widgets/home_drama_grid.dart +245 test/discover/home_all_dramas_grid_test.dart +``` + +解读:改造前 `discover_view.dart` 为 649 行;删除继续观看旧实现并拆分网格后 +降到 500 行以内。首页源码已无 `continueWatching`、`_continueTile`、 +`_ShowcaseCard`、`_cardsFor` 或嵌套 `GridView`。 + +### 24.4 既有壳层断言更新 + +`test/widget_test.dart` 原有 5 处断言首页出现 `Continue Watching`。K9 明确要求 +该文案彻底消失,因此该断言与 `find.text('Continue Watching'), findsNothing` +不可能同时成立。 + +处理:保留全部既有用例、测试名称和导航流程,仅把 5 处已作废的可见文案断言 +原位改为 `All Dramas`;没有删除测试用例。 + +```text +$ flutter test test/widget_test.dart +00:05 +17: All tests passed! +``` + +### 24.5 全量门禁与构建 + +首次静态分析发现新增测试有一个未使用 import: + +```text +warning - test/discover/home_all_dramas_grid_test.dart:10:8 +Unused import: 'package:fruitshorts/core/data/repositories/catalog_repository.dart'. +1 issue found. +``` + +移除后: + +```text +$ dart analyze lib test +Analyzing lib, test... +No issues found! +``` + +```text +$ flutter test +00:18 +297 ~1: All tests passed! +``` + +解读:297 项通过,1 项联调测试因客户端接口服务未启动按设计跳过;输出中的 +`[WatchRecordsController]` 堆栈来自既有故意注入失败的测试。 + +构建前检查: + +```text +$ ps -axo pid=,etime=,args= | rg 'flutter_tools.snapshot (run|build)|xcodebuild|gradlew' +``` + +输出仅有当前检查命令自身,没有并发 Flutter run/build 后执行: + +```text +$ flutter build apk --debug +Running Gradle task 'assembleDebug'... 8.4s +✓ Built build/app/outputs/flutter-apk/app-debug.apk +``` + +### 24.6 Git + +```text +cf03178 feat(flutter): 首页改为两列全部剧目网格 +2c381be merge: 合并 K9 首页全部剧目网格 +99f64ab..2c381be develop -> develop +``` + +功能提交与合并提交 author/committer 均为 +`Zhou Weidong <502333560@qq.com>`。 + +### 24.7 用户真机验证步骤与预期 + +以下设备侧取证由用户执行,Codex 未跑真机。 + +1. 使用最新客户端 `develop` 进入首页「Home/发现」tab。 + 预期:页面不再出现「继续观看」标题或横向卡片。 +2. 向下查看分类 chips。 + 预期:chips 下方显示当前语言对应的「全部剧目」/ `All Dramas` / + `Semua Drama`。 +3. 观察列表布局。 + 预期:一行 2 个剧目,左右各 16,列间距 12、行间距 16;封面为 2:3 圆角。 +4. 向下滚动长列表。 + 预期:继续按 2 列懒加载,滚动中无整页白屏或卡顿。 +5. 依次点击「为你推荐 / 热门 / 最新 / 服务端分类」。 + 预期:网格内容随分类更新;「为你推荐」显示去重后的全部剧目。 +6. 点击任意剧目卡片。 + 预期:沿用原详情流程打开对应剧目。 +7. 在有长标题或空分类数据时检查卡片。 + 预期:标题最多 2 行、类型最多 1 行,不横向溢出;空态和失败重试文案保留。 + +设备侧截图、日志与最终验收结论由用户执行。