0
Fork 0
mirror of https://github.com/Silent1566/webhtv.git synced 2026-10-18 07:09:16 +00:00

feat(ui): 文件浏览器空态补齐三件套,主动作=重新扫描当前目录

审计 P0 的最后一项空态缺口:两端 FileActivity 此前没有接入 setEmptyContent,空态只显示
布局里的默认单行文案。它一直被挂着的原因是「主动作是导航/产品决策」,我连续几批都记为
卡在决策上、没有代拟。**用户 2026-10-13 裁定:主动作 = 重新扫描。**

决策理由(已写进代码注释与契约):
- 「返回上级」在**根目录没有上级**——点它会退出页面,与按钮文案不符,且不解决「文件刚被
  放进来」的场景;
- 「重新扫描」在**任何**目录都成立,且能反映外部变化(刚用别的应用放进来的文件)——
  这正是本地文件浏览器最需要的能力。

实现:两端 initView 调用新增的 setEmptyContent(),主动作走新增的 rescan(),而 rescan() 复用
update(dir)——它是本页**唯一**的列表填充入口,既重算 list(dir) 又驱动状态机。因此
「扫描后仍为空」会正确地停在空态而不是留白(若接成只刷新适配器就会留白,那正是本仓库
反复出现的那类缺陷)。dir == null 的兜底是必要的:权限回调之前 dir 还是 null,此时点
重新扫描应退回根目录而不是 NPE。

一个容易忽略的细节:list(dir) 在 selectDir 为真时**只返回子目录**,所以「有文件但无子目录」
在选目录模式下也是空态。空态文案因此写成「这个目录下没有可显示的项」而不是「目录是空的」,
避免误导。

- 三语字符串 file_empty_*(简中标题「这里没有内容」、动作「重新扫描」,解释里点明
  「如果是刚放进来的文件,重新扫描即可看到」);
- 两端 FileActivity:setEmptyContent() + rescan(),并补上此前缺失的 R 导入;
- FileBrowserEmptyStateContractTest 4 项:两端三件套与三语齐备;主动作走 update(...) 且
  update 仍驱动状态机;**反例守卫**——rescan() 不得调用 finish()/onBackPressed()/
  getParentFile()(「返回上级」在根目录会退出页面,这是本契约要防的具体错误);
  文案必须表达「这里没有内容」而非「加载失败」(§9.9 把空态与错误态分开)。

验证:契约测试两端 BUILD SUCCESSFUL;leanback assemble BUILD SUCCESSFUL;真机
192.168.50.3:5561 进入空目录 Alarms 后空态三件套完整出现且带 scrim;**主动作的决定性验证**
——往里放一个 rescan-proof.txt 再点「重新扫描」,该文件出现、空态退出、进入 CONTENT 态。
这一次观测同时证明:三件套渲染正确、scrim 生效、主动作真的重新扫描(不是死按钮)、
扫描后状态机正确切换。测试文件已删除、目录恢复为空。

首轮两个 flavor 都 BUILD FAILED,**是编译错误不是断言失败**:两端 FileActivity 此前没有
import com.fongmi.android.tv.R(原本只用 databinding 的 Binding 类)。教训:BUILD FAILED 时
先看有没有测试结果 XML,没有就是编译失败,去跑 compile*UnitTestJavaWithJavac 拿错误。

未验证:手机端未实机点过(改动同构、由共享契约测试覆盖);selectDir 模式与权限被拒分支
未实测;重新扫描不自动监测外部变化(无 FileObserver,刻意的)。
详见 docs/FILE-BROWSER-EMPTY-20261013.md §6.5。

环境限制:本会话无可用 bash,task_guard.sh 无法执行,按同等意图手工暂存/提交/打 tag。
This commit is contained in:
Silent1566 2026-10-13 17:40:20 +08:00
commit 7cc0182c84
7 changed files with 325 additions and 0 deletions