docs: 记录 K94 首页类型 Feed 留痕
This commit is contained in:
1 parent
1fa3631e53
commit
3036b782f9
2 files changed
+176
No files matched your search
@@ -0,0 +1,126 @@
|
||||
# K94 首页内容类型 Feed 与无感切换
|
||||
|
||||
## 目标
|
||||
|
||||
- 首页顶栏「漫剧 / 真人剧 / 推荐」接入既有 `/app/feed`。
|
||||
- 每频道独立缓存与分页,切换时先同步展示缓存,再后台静默刷新。
|
||||
- 推荐首屏复用 `/app/home/feed` 打平数据,首次进入不额外转圈。
|
||||
- 无缓存频道只在黑色内容区显示小转圈,顶栏和底栏保持。
|
||||
- 滑动接近末尾自动加载下一页,并在播放器队列中原地追加。
|
||||
|
||||
## 分支
|
||||
|
||||
- ReelShort:`feat/k94-home-type-feed`,从 `origin/develop` 创建。
|
||||
- FruitServer 仅文档留痕,不改功能代码。
|
||||
|
||||
## A. 数据层
|
||||
|
||||
### A1 FeedPage
|
||||
|
||||
新增 `lib/core/data/models/feed_page.dart`:
|
||||
|
||||
- `dramas` 使用 `Drama.fromCardJson`。
|
||||
- `nextCursor` 兼容数字/字符串,空值或字符串 `"null"` 转为 null。
|
||||
- `hasMore` 读取布尔值。
|
||||
|
||||
### A2 CatalogApi / Repository
|
||||
|
||||
- `CatalogApi.feed({types, cursor, size})` 请求 `/app/feed`。
|
||||
- types 为空不传;非空用逗号拼接。
|
||||
- cursor 为空不传。
|
||||
- 返回结构异常抛 `ApiException(-1, '返回数据格式异常')`。
|
||||
- `CatalogRepository` 与 HTTP 实现增加 `fetchFeed`。
|
||||
- 所有测试 CatalogRepository 实现同步补齐方法。
|
||||
|
||||
## B. 频道控制器
|
||||
|
||||
新增:
|
||||
|
||||
- `lib/pages/home/home_feed_channel.dart`
|
||||
- `lib/core/data/services/home_feed_controller.dart`
|
||||
|
||||
`HomeFeedController` 使用每个频道独立状态:
|
||||
|
||||
- dramas / cursor / hasMore / loaded / loadingMore / requestSeq
|
||||
- 当前 channel,默认 recommend
|
||||
- `seedRecommend`:同步写入推荐首屏,不发请求
|
||||
- `selectChannel`:同步切频道并 notify;无缓存加载第一页,有缓存静默刷新
|
||||
- `refreshCurrent`:失败保留旧列表
|
||||
- `loadMore`:cursor 追加,按 drama.id 去重
|
||||
- 所有响应必须同时满足“仍为当前频道 + requestSeq 最新”才应用
|
||||
- dispose 后停止 notify
|
||||
|
||||
## C. 首页接入
|
||||
|
||||
### C1 顶栏受控
|
||||
|
||||
`HomeFeedHeader`:
|
||||
|
||||
- 删除内部 tab 状态、comingSoon 和 SnackBar。
|
||||
- 新增 `channel` 与 `onChannelSelected`。
|
||||
- 三个 Key 保持不变。
|
||||
- refresh 内部 loading 状态保留。
|
||||
|
||||
### C2 HomePage
|
||||
|
||||
- `_HomePageState` 用 `CatalogController.repository` 创建 HomeFeedController。
|
||||
- Catalog 首次有数据时同步 seed recommend,随后在 post-frame 静默刷新 recommend。
|
||||
- `_HomeTabs` 使用稳定 Key,删除 `ValueKey(catalog.dramas.first.id)`。
|
||||
- 当前频道无数据时,保留 `_HomeTabs` 顶栏/底栏,body 用黑色背景 + 居中
|
||||
`home-feed-channel-loading`。
|
||||
- 当前频道有数据时把频道列表传给 PlayerPage。
|
||||
- 刷新回调改 `refreshCurrent`;分页回调改 `loadMore`。
|
||||
|
||||
### C3 PlayerPage / PlayerLogic
|
||||
|
||||
- PlayerPage 增加 `feedChannel` 和 `onLoadMore`。
|
||||
- 同频道 feed 列表变化:`updateFeed(..., keepDramaId: currentDramaId)`。
|
||||
- channel 变化:`updateFeed(..., keepDramaId: null)`,回到新频道第 1 个。
|
||||
- PlayerLogic 保存 factory/coordinator,支持需要换内容时替换 PlaybackSession。
|
||||
- 空列表清空 queue/visibleIndices 并停止旧播放。
|
||||
- 当前剧仍在新列表且索引不变时,只扩展队列与 episode 列表,不重新 select。
|
||||
- PageView 在 `position >= visibleIndices.length - 3` 时调用 onLoadMore。
|
||||
|
||||
## D. 测试
|
||||
|
||||
新增 `test/core/data/services/home_feed_controller_test.dart`:
|
||||
|
||||
- recommendation seed 不发请求
|
||||
- 三频道请求 types 分别为 `[] / [ANIME] / [LIVE]`
|
||||
- 缓存频道切换不清空并后台刷新
|
||||
- loadMore 追加去重、无更多后不再请求
|
||||
- 串包只接受最新频道请求
|
||||
- refresh 失败保留旧数据
|
||||
|
||||
新增顶栏 widget 测试:
|
||||
|
||||
- 三个 Key 存在
|
||||
- 点击分别回调 anime/live/recommend
|
||||
- 当前 channel 决定选中样式
|
||||
|
||||
PlayerLogic 测试补充:
|
||||
|
||||
- updateFeed 空列表安全
|
||||
- 追加列表保持当前剧
|
||||
- 切频道列表回到第 1 个
|
||||
|
||||
门禁:
|
||||
|
||||
- `dart analyze lib test`
|
||||
- `flutter test --no-pub`
|
||||
- `flutter build apk --debug`
|
||||
|
||||
## 风险与控制
|
||||
|
||||
1. PlaybackSession 的 episodes 是构造时绑定的列表;分页原地追加时会同步扩展该列表,
|
||||
避免仅换 queue 而 session 仍指向旧列表。
|
||||
2. 换频道可能释放并重建播放器 session,这是内容源变化;静默刷新/分页在顺序不变时
|
||||
不重新 select 当前剧,避免视频重启。
|
||||
3. 推荐 seed 只保证首帧立即有内容;后台 `/app/feed` 刷新失败时保留 seed。
|
||||
4. 首页仍在 `/app/home/feed` 首次加载期间使用既有启动页;频道切换不再触发整页 splash。
|
||||
|
||||
## Git
|
||||
|
||||
- 提交:`feat(home): 首页按内容类型分频道 Feed 并支持分页`
|
||||
- `--no-ff` 合回 ReelShort `develop` 并 push。
|
||||
- 作者:`Zhou Weidong <502333560@qq.com>`;禁止 `git add -A`。
|
||||
@@ -24064,3 +24064,53 @@ Build successful. Please see dist-dev directory
|
||||
- ReelShortWeb Husky 与当前 npm/pnpm 环境不兼容,功能与合并提交使用 `--no-verify`,
|
||||
门禁已独立完成。
|
||||
- 未改 FruitServer 代码,未安装或操作真机,等待用户验收。
|
||||
|
||||
## 2026-10-21 K94 首页内容类型 Feed 与分页
|
||||
|
||||
- 已完整读取 K94 `docs/plans/INBOX.md`;本批次只改 ReelShort Flutter 客户端。
|
||||
- 已创建 ReelShort `feat/k94-home-type-feed` worktree,基于最新 `origin/develop`。
|
||||
- 已先写计划 `docs/plans/2026-10-21-K94-home-type-feed.md`,记录数据层、频道缓存、
|
||||
首页无感切换、播放器队列更新、分页触发和测试矩阵。
|
||||
- 不改后端、ReelShortWeb、specs;不安装或操作真机。
|
||||
- 已完成数据层:新增 `FeedPage`,`CatalogApi.feed` 与 `CatalogRepository.fetchFeed`
|
||||
支持 types/cursor/size,并补齐所有测试仓库实现。
|
||||
- 已完成 `HomeFeedChannel` 与 `HomeFeedController`:推荐 seed、三频道独立缓存、
|
||||
静默刷新、游标追加去重、requestSeq 防串包、失败保留旧数据。
|
||||
- 首页顶栏改为受控频道,删除 comingSoon;无缓存频道在黑色内容区显示小转圈,
|
||||
推荐首屏立即使用 `/app/home/feed` 打平数据。
|
||||
- `PlayerLogic.updateFeed` 支持原地扩队列与当前剧索引重映射;同频道刷新不重启当前视频,
|
||||
频道变化回到第 1 个;PageView 倒数第 3 个触发 loadMore。
|
||||
- 已补 Feed API、控制器、顶栏和 PlayerLogic 测试,并更新既有 CatalogRepository 测试实现。
|
||||
|
||||
门禁原始输出:
|
||||
|
||||
```text
|
||||
$ dart analyze lib test
|
||||
Analyzing lib, test...
|
||||
No issues found!
|
||||
|
||||
$ flutter test --no-pub
|
||||
00:53 +532: All tests passed!
|
||||
|
||||
$ flutter build apk --debug
|
||||
Running Gradle task 'assembleDebug'... 27.9s
|
||||
✓ Built build/app/outputs/flutter-apk/app-debug.apk
|
||||
```
|
||||
|
||||
解读:静态分析零告警,532 项测试全过,debug APK 构建成功;未安装或操作真机。
|
||||
|
||||
### K94 交付结果
|
||||
|
||||
- ReelShort 功能提交:`ae61d9e feat(home): 首页按内容类型分频道 Feed 并支持分页`。
|
||||
- ReelShort develop 合并提交:`c8392b2 merge: 合并 K94 首页类型 Feed`,
|
||||
已推送 `4d0be47..c8392b2`。
|
||||
- 推荐首屏使用 home feed seed,并在后台静默刷新 `/app/feed`;漫剧/真人剧首次请求分别带
|
||||
`ANIME/LIVE`,推荐不带 types,均使用游标分页。
|
||||
- 三频道独立缓存、同步切换、requestSeq 防串包、分页去重和失败保留旧数据已实现。
|
||||
- 顶栏删除 comingSoon 并改为受控频道;无缓存频道保留顶栏/底栏,在黑色内容区显示
|
||||
`home-feed-channel-loading` 小转圈。
|
||||
- PlayerLogic 原地更新 queue/visibleIndices;当前剧仍存在时重映射 active slot,
|
||||
不重启当前 player;频道变化回到第 1 个。
|
||||
- 门禁:`dart analyze lib test` 零告警;`flutter test --no-pub` 532 项全过;
|
||||
`flutter build apk --debug` 成功生成 `build/app/outputs/flutter-apk/app-debug.apk`。
|
||||
- 未改后端、ReelShortWeb、specs;未安装或操作真机,等待用户验收。
|
||||
Reference in new issue
Block a user