动态页的 YouTube 卡补齐两个「看不见」的提示:4K 角标 + 识别绿框 —— 一个是从没取过那路数据
(P11-260),一个是被卡片的背景层盖掉了(P11-261)。
变更
- 4K/8K 画质角标(P11-260):起点是用户报「TV端角标在动态里是不是没显示」→「似乎不显示 4K 角标」。
判读:画质角标只存在于 TVHTML5 的响应里,而项目里只有频道页视频 tab 会额外拉那一路
(getChannelVideos(withQualityBadges=true)→ TV 基页 + 按覆盖续翻);动态的 YouTube 侧走的是
订阅流(每频道 RSS + WEB InnerTube/browse),那条路从不发 TVHTML5,而 WEB 频道页的
metadataRows[].badges[]里 4K 零条(文档 §4.16 实测矩阵)⇒ 动态里的 YouTube 卡只会有 WEB 自带的
会员/直播/首映角标。同一函数也是 TV 首页 YouTube 流与移动端首页/动态的来源,故那几处一样没有;
能看见 4K 的只有频道页视频 tab 与 YouTube 搜索页(WEB/search自带badges[].label)。 - 改法:新增
YoutubeRepository.tvQualityBadgesFor(...),按频道分组复用频道页那套(与频道页
共用缓存,先进过频道页再进动态几乎零请求);动态页在首屏/翻页落地后后台补,拿到
videoId → 文案后原位只改 badge 字段、只补空位(会员/直播等不被顶掉)。两道闸,因为订阅流的
频道数是用户配的(可能几十上百),而原实现是按单频道设计的:①只补 TV 基页、不沿上传列表翻页
⇒ 每频道每轮 ≤1 个请求(同一缓存代内 0 个);②每轮最多 8 个频道 + 起点轮转 ⇒ 请求量恒定,且不会
永远只补前排那几个。 - 不重拉首屏、不丢焦:首屏加载那条
LaunchedEffect的键里没有列表(只有 repository / 登录态 /
子 tab / 频道 id)⇒ 改写列表只触发重组、不重跑取数;补丁不改顺序/条数/bvid ⇒ 网格行 key
(row-$row-<行首项 key>)不变 ⇒ LazyColumn 不重建行,保焦 effect 也因此直接早退。写入前重读当前
列表、只按 videoId 补空位,并按「列表落地代数」丢弃过期结果 —— 防的是竞态覆盖(同 P11-253 那类
列表被截断的事故)。 - YouTube 识别绿框(P11-261):用户报「TV端 youtube动态 好像没有绿边框提示」。根因是画的位置:
绿框原来挂在传给BiliFocusableSurface的 modifier 上,而那个组件会在调用方 modifier 之后再画
一层surfaceColor背景 + 自己的焦点边框色(同一条 2dp 边环);更关键的是两者都画在子内容之下,
卡内不透明封面与半透明信息条会把这类边环整片盖掉(聚焦态 3dp 的 accent 边框更是完全压住)。移动端
之所以看得见,是因为它挂在卡片根 Column 上、周边没有不透明层。改法:绿框改画在内容之上
(drawWithContent在drawContent()之后描边),线宽 2.dp、内缩半个线宽,保证整条线落在卡片边界内。
待验证(真机)
- 动态「视频」子 tab 的 YouTube 卡右上出现 4K 胶囊、卡片带绿色 2dp 边框。
- 日志应有
BiliMT:DynamicFeed: dynamic quality badges applied: matched=… videos=…,且不该出现
feed first-page decision: autoRefresh=true(出现即说明首屏被重拉,焦点会掉);列表条数与焦点位置
也不应变化。
未做
- 首页订阅流没接:TV 首页 YouTube 流、移动端首页/动态仍无 4K 角标(它们与动态共用同一个取数函数,
接上只需在调用处补一行;先等动态这条真机验证过)。超出 TV 基页最新 ~24 条的视频不补角标。