Skip to content

bridge: keep a pin outside the loaded page reachable without a message store - #10

Open
std-external wants to merge 1 commit into
std-microblock:mainfrom
std-external:fix/pinned-dialog-page-window
Open

std-external wants to merge 1 commit into
std-microblock:mainfrom
std-external:fix/pinned-dialog-page-window

Conversation

@std-external

@std-external std-external commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

背景

置顶会话被从 getDialogs 的分页流里剔除,而剔除发生在上游页取回之后:页会短于请求条数。Telegram Android 恰好把「返回条数 ≠ 请求条数」当作「服务端已经到底」(MessagesController.java:13732/13759 的 dialogs.size() != count → serverDialogsEndReached;DialogsActivity.java:7832-7847 只在标志清空时请求下一页),于是只加载到第一页。

这个主问题已经由 main 上的 bb4eb9c("bridge: keep dialog pages full when pinned dialogs leave the stream")修掉了,比本分支先落地。本 PR 因此重写成只补它没有覆盖的那一小块。

本 PR 改什么

置顶会话离开分页流的前提是客户端能从别处拿到它:首屏前置返回,或者由 getPinnedDialogs 单独拉取。但 DialogRpc 的 store 是可选参数,没有消息库时两条路都断了:

  • _pinnedDialogs 只能从加载页或 store.readDialogs 里拿会话,storeless 时加载页之外的置顶会话取不到 ⇒ 不会出现在首屏前置里;
  • getPinnedDialogs 走同一条路径 ⇒ 也返回空;
  • 而它仍然被从分页流里剔除 ⇒ 该会话在任何一页、任何一次 getPinnedDialogs 里都看不到。

修法:没有消息库时只让本次响应已经前置返回过的置顶会话离开分页流,其余留在流里;有消息库时行为完全不变。(现有接线 packages/bridge/src/index.ts 恒传 MessageStore,所以这是稳健性缺口,不是线上 bug。)

复现与验证

新增 e2e:keeps a pinned dialog outside the loaded page reachable without a message store(storeless 构造、30 个会话、置顶第 26 个):

  • 修前:两页合计只返回 29 个会话,置顶的那个不在任何一页里,getPinnedDialogs 返回空(实测 expected [ ... ] to have a length of 30 but got 29);
  • 修后:30 个会话不重不漏,置顶会话仍在流里可见。

命令与结果:

  • vitest run --config vitest.mtproto-e2e.config.mts packages/bridge/src/dialog-folders.e2e.test.ts --maxWorkers=1 → 14 passed(含 main 上已有的 keeps every dialog page full when pinned dialogs are pulled out of the stream 与 Android 归档页用例)
  • vitest run packages/bridge/src → 798 passed;唯一失败是 voice/voice-worker-client.test.ts(spawn cargo ENOENT,本机没有 Rust 工具链,与本次改动无关)
  • tsc --project tsconfig.test.json → 0 错误

附:主问题在 main 上已修复的独立验证

把原先那条「每一页都必须满」的断言(exclude_pinned、limit 5、用上一条会话当锚点、30 个会话里置顶前两个)拿去跑当前 main:第一页正好 5 条、每页都满、不重不漏 —— 通过。即 bb4eb9c 的修法确实堵住了 Android 那条路径。

来源:crossgram 聊天群里 @MicroBlock 报告 Android 置顶后只能加载一部分会话,要求修掉。

…e store

置顶会话从分页流里剔除的前提是客户端能从别处拿到它:首屏前置返回,或由
getPinnedDialogs 单独拉取。没有消息库(DialogRpc 的 store 可选)时两条路都
断了,位于加载页之外的置顶会话会被从每一页里删掉,getPinnedDialogs 也返回
空,等于该会话在客户端彻底消失。

无消息库时只让本次响应已经前置返回过的置顶会话离开分页流,其余留在流里;
有消息库(现有接线)的行为不变。
@std-external
std-external force-pushed the fix/pinned-dialog-page-window branch from 49e03f5 to ae66011 Compare October 15, 2026 05:21
@std-external std-external changed the title bridge: keep a dialog page at the requested limit when its dialogs are pinned bridge: keep a pin outside the loaded page reachable without a message store Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant