Repository navigation
feat: 首页推荐/热点分页、话题榜与话题页、进吧签到状态、可导出诊断日志 - #84
Open
IamNewHands wants to merge 11 commits into
Open
IamNewHands wants to merge 11 commits into
IamNewHands wants to merge 11 commits into
Conversation
改用 /c/f/forum/forumGuide 一次取回关注贴吧列表里的 level_id 与 is_sign,在磁贴上显示 Lv.N 与已签角标。 状态请求与原关注列表并行发出,失败时只缺少装饰信息, 不影响吧列表本身。
首页顶部分页:推荐复用原有个性化流,热点读取 /c/f/forum/hotThreadList (cmd=309661) 的 protobuf 端点,显示吧内热帖与子分页。 新增 TiebaHotAPI、HotFeed 与 HotThreadsView;热点响应按实测的线格式解码, 并用逐字段用例固定下来(论坛 id 的变长整数、手写标题字节都由 fixture 覆盖)。 新源文件与生成的 proto 产物注册进 Xcode 工程,条目顺序与 UUID 与 XcodeGen 的输出一致。顺带修掉 FollowedForumStatusTests 里一处非 Equatable 比较。
真机上无法从外部区分两个症状:首页分页显示与官方客户端不一致的帖子,以及 关注贴吧磁贴从不显示等级或签到状态。两处都被吞掉了——ForumHubView 用 try? 丢弃状态错误,followedForumGuide 是唯一从未观察过字段名的调用。 - 新增 AppLog(有界内存日志)与设置页的导出入口,记录未公开端点的真实响应: forumGuide 的原始 body 骨架、逐页 error_code、行数与等级直方图;推荐/热点 流是否已登录、子分页名与前几行的来源吧;ForumHubView 不再丢弃状态错误。 - 每条消息在写入时即抹掉 BDUSS、STOKEN、tbs 等凭据,导出文件可直接发送。 - 两个 protobuf 信息流的 Cookie 头带上已登录凭据:只发 ka=open 会把请求标记 为匿名,这很可能就是推荐流是通用排序而非官方客户端的关注吧混排的原因。 - 注册新源文件到 Xcode 工程,并修掉 AppLog 的两处编译错误与一处 range 长度读取。
诊断日志证实两处线格式假设错误。 进吧等级:/c/f/forum/forumGuide 的响应是扁平结构,like_forum 与 like_forum_has_more 和 error_code 同级,没有 data 包装层,原 DTO 按嵌套 data 解码后每次都读到 nil,再被 guard 抛成「服务器返回了空数据」。改为顶层 解码(与 aiotieba、tieba-lite-harmony 同一端点同一参数集一致),并把 DataDTO 折叠进 DTO;第 1 页无条目时补一条 ERROR,以区分「0 关注」与 「字段名不符」。 热点:默认请求此前发空 tab_code,服务端只回 4 条残缺列表;官方实现用 tab_code=all,现在空码一律改写为 HotTab.allCode。服务端 hot_thread_tab_info 只含分类子标签,mapper 固定补一个「全部」入口排在最前(服务端已给 all 则 不重复),标签栏初始选中即全部。 诊断:DiagnosticJSON 上限 6 → 40,顶层键列表不再被 …N more 截断;热点日志 改打服务端子标签 name(code) 与原始/保留条数。 测试:扁平指南 DTO(含多余展示键)、缺 like_forum 视为空、空 tab_code → all、 mapper 补全部且不重复、skeleton 不再截断字段列表。
真机反馈:一键签到只有转圈,看不出进行到哪、还剩多少;而且对今天已签到的吧也照样发 一次请求,关注列表长了就很慢。三个改动: - 签到前先读一次关注吧 guide(forumGuide 的 is_sign),今天已签到的吧直接计入 今天已签过并跳过请求。关注 100 个吧、其中 90 个已签时,写请求从 100 次降到 10 次。 - guide 读不到时不清空任何吧(重复签到只是无操作的 no-op),并往诊断日志记一条 error, 避免读状态失败被当成全都签过了。 - 新增 ForumSignProgress(已完成/总数/当前吧名)并发布:进吧签到区显示 3/120 计数、 正在签到:xx吧 一行、以及取消按钮;结束后清空,结果仍由既有 alert 汇报。设置页说明 文案同步改为今天已签到的贴吧会直接跳过。 Fixture 新增 .signAlreadyDone 场景驱动 guide 返回签到态;补 3 个测试(跳过已签到、 进度发布并在结束后清空、进度文案)。build number 59 到 60。
热点「全部」要按真实热度合并四个分类,并把话题榜渲染到页面顶部,两者都用到现在 被当作未知字段丢掉的字段: - HotThreadListResponseData 增加 topic_list = 1(RecomTopicList:topic_id=1 / topic_name=2 / discuss_num=4),即官方热点页顶部那块热议话题。 - ThreadInfo 增加 optional hot_num = 182:热点响应每条都带它,且每个分类列表 本身已按它降序,合并后的「全部」用它排序。 - scripts/generate-ios-protos.sh 的产物清单与 .proto 同步更新;Swift 生成产物 一并提交(nameMap 字节码无法从现有样例可靠反推,不能手写)。
热点「全部」:服务端没有「全部」分类码(空码、all、0 返回同一份 4 条默认 列表),只能客户端拼:默认列表 + 四个分类列表的并集,按服务端下发的 hot_num(182) 降序,同热度按回复数、再按 id 兜底,重复 tid 保留热度更高的一份; 四个分类并发拉取,任一失败只记 AppLog 并继续用其余分类。话题榜(topic_list) 渲染在热点页顶部:排名 + 话题名 + 讨论数,前三名用官方红/橙/黄。 话题页:新端点 GET /mo/q/newtopic/topicDetail(JSON),匿名探针实测后按游标 翻页(只给 pn/offset 会返回 no=300000 param invalid,必须带上一页最后一条的 feed_id)。新增 TopicDetailView(话题头部 + 帖子流 + 下拉刷新 + 触底加载), 从热点页热议话题进入;HomeNavigationRoute 增加 .topic 路由。v1 限制:media 点击直接进帖子,该接口不返回视频信息。 顺带修复:切标签取消旧请求时 URLError.cancelled 曾被当成分类拉取失败记 ERROR 并合并出残缺列表,现在取消按取消处理。 测试:话题 JSON 解码(字符串/数字混用)、行映射与缺字段、游标、空列表; 话题 wire 解码、话题过滤与顺序、讨论数文案、合并去重/热度排序/同热度兜底。
一键签到时所有吧都已签到,整轮没有任何写请求,但协调器仍然先解析写令牌。 那一步是一次登录握手,本次日志里它独自耗时 20.2s:用户看到的是「无需签到」, 却要盯着转圈等 20 秒才显示完成。现在待签列表为空时直接跳过令牌解析,并记一条 说明跳过原因的日志;有待签贴吧时行为不变。 同时给写令牌解析加慢速分步日志:客户端登录与网页兜底各自超过 3s 才记一条 WARN (成功的跳记、失败记原因),下一次日志就能指出这 20 秒花在哪一跳,而不是只有一个 总数。正常几百毫秒的解析不产生任何日志,点赞收藏不会刷屏。 夹具新增 signAllDone 场景与写令牌解析计数,新增两个单测:无待签贴吧时解析次数 必须为 0;有待签贴吧时整轮只解析一次(而不是每个吧一次)。 构建号 64 → 65。
…tely 设置 → 诊断 新增「记录诊断日志」开关,默认开启。关闭后 AppLog.record 直接返回, 一条都不再记录(不是隐藏),已记录的内容保留,仍可查看、导出或清空。 开关存在 UserDefaults(dev.infinityf4p.tiebapure.diagnostics.logging-enabled), 未设置过时为开启。AppLog.isEnabled 是不需要 await 的静态读取,所以昂贵的调用点 可以先问再构造:进吧等级那行要把 39KB 响应整份走一遍 DiagnosticJSON.skeleton, 现在关闭时直接跳过,而不是构造完再丢掉。设置页 footer 与诊断日志页的空态文案都 跟着开关变化,避免「已关闭却提示回首页刷新一次」这种误导。 补两个单测:关闭时 record 与 recordError 一条都不记、重新开启立即恢复;未设置过时 默认开启、关闭状态能跨实例读到。构建号 65 → 66。
… long-press refreshes Split Home reselect into discernible intents driven by gesture recognizers on the tab bar: single tap collapses detail/search to the feed root, double tap additionally scrolls to top (no refresh), long press refreshes. HomeView now observes three tokens (returnToRoot/scrollToTop/refresh) instead of one. Update HomeNavigationTests and home-tab UI tests to the new gestures.
推荐 和 热点 是首页仅有的两个分页,所以在任一页面上左右滑动都切到另一页: 在推荐上右滑进入热点,在热点上左滑回到推荐。HomeFeedSwipePolicy 只把足够长、 且明显偏水平的拖动当作翻页;手势只挂在滚动内容上,热点子分页的横向标签栏 仍由它自己的横向滚动处理,不会被抢走拖动。分段控件保留,是无障碍和可发现 的主要切换方式。 两个分页改为常驻视图树,切换只改可见性:热点保留已加载列表与滚动位置,不再 每次右滑都重新请求;隐藏分页移出命中测试与无障碍树。HotFeedLoadPolicy 门控 「首次激活才加载」。首页 tab 手势对可见分页生效,与推荐一致:单击返回列表根、 双击回到顶部、长按刷新;HomeFeedGestureTargetPolicy 只把 token 投给当前分页, 避免后台分页被滚动或被偷偷重新请求。HotThreadsView 增加顶部滚动锚点,回顶复用 与推荐相同的无动画 transaction,避免 iOS 26 上懒加载布局在动画中反复更新。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
本 PR 把 fork 上最近几天的四个功能域整理后提交上游,共 11 个 commit。
1. 首页「推荐 / 热点」分页(
feat(home))/c/f/forum/hotThreadList(cmd=309661)的 protobuf 端点。all/0返回同一份 4 条默认列表),所以「全部」= 默认列表 + 四个分类并发拉取的并集,按服务端下发的hot_num(182)降序,同热度按回复数、再按 id 兜底,重复 tid 保留热度更高的一份;任一分类失败只记日志并用其余分类。topic_list)渲染在热点页顶部:排名 + 话题名 + 讨论数,前三名用官方红 / 橙 / 黄。HomeFeedSwipePolicy只把足够长且明显偏水平的拖动当作翻页,子分页的横向标签栏不受影响)。2. 话题页(
feat(topic))GET /mo/q/newtopic/topicDetail(JSON)。按游标翻页:只给pn/offset会返回no=300000 param invalid,必须带上一页最后一条的feed_id。TopicDetailView(话题头部 + 帖子流 + 下拉刷新 + 触底加载),从热点页的热议话题点入。3. 进吧签到(
feat(forumhub)/fix(sign))signForum每次都走refreshedClientTBS,它会先发一次/c/s/login才回退到已存 tbs,于是每个吧都多一次登录握手(40 个待签 = 40 次登录 + 40 次签到);现在取不到令牌时才回退到逐吧解析。4. 可导出的应用内诊断日志(
feat(diagnostics)/feat(settings))AppLog(有界内存日志)与设置页的导出入口,记录未公开端点的真实响应:forumGuide的原始 body 骨架、逐页error_code、行数与等级直方图;推荐 / 热点流是否已登录、子分页名与前几行的来源吧;ForumHubView不再用try?丢弃状态错误。ka=open会把请求标记为匿名)。5. 协议修正与生成产物(
fix(api)/build(protos))/c/f/forum/forumGuide的响应是扁平结构:like_forum与like_forum_has_more和error_code同级,不存在 data 包装层。原 DTO 按嵌套 data 解码,于是每次成功响应都读到 nil,再被 guard 抛成「服务器返回了空数据,请稍后重试」。改为顶层解码,并把DataDTO折叠进 DTO;第 1 页无条目时补一条 ERROR,以区分「0 关注」与「字段名不符」。tab_code,服务端只回 4 条残缺列表;官方实现用tab_code=all,现在空码一律改写为HotTab.allCode。服务端hot_thread_tab_info只含分类子标签,mapper 固定补一个「全部」入口排在最前(服务端已给 all 则不重复)。HotThreadListResponseData.topic_list = 1(RecomTopicList)与ThreadInfo.hot_num = 182此前被当作未知字段丢掉,现在补上声明并同步生成产物。URLError.cancelled曾被当成分类拉取失败记 ERROR 并合并出残缺列表,现在取消按取消处理。说明
.github/workflows/*一行未动,project.yml与上游逐字节相同(构建号仍是上游的 58)。TiebaPure.xcodeproj,条目顺序与 UUID 与 XcodeGen 的输出一致。HotThreadListTests、TopicThreadsTests、AppLogTests、FollowedForumStatusTests,以及热点 / 话题线格式、合并排序、签到状态、扁平指南 DTO 等用例。.github/workflows/ci.yml(本 PR 未改动它)跑通:单元测试全量 + 13 项 UI 冒烟 + iPad 布局 + Release 构建与 bundled notices 校验 —— https://github.com/IamNewHands/TiebaPure-iOS/actions/runs/37020874404