修复从好友资料页"发消息"直接进入新P2P会话时名称/在线状态永久缺失的问题

根因比此前提交(ff69e454)修复的isCommType()问题更深一层:即使会话能正确
出现在列表里,openConversation()走的withLaterDesc()增量查询在这条特定
路径(从未经过整页刷新,纯SPA内跳转)下会订阅成功但不返回desc/presence,
topic.public永久为null、在线状态永久为"离线",等待再久也不会自愈——整页
刷新之所以从未复现过这个问题,是因为subscribeMeTopic()自己的全量重新
订阅逻辑无条件覆盖了这个缺口。

改为在topic.public缺失时,用me.getMeta(withOneSub(topic))主动拉取——这
是SDK自己的presence路由内部用于"刚得知这个话题"场景的同一个调用,一次
返回desc+在线状态两者,且me话题的onMetaSub/onSubsUpdated回调早已在登录
时挂好,响应到达后会自动使聊天列表失效重新渲染。

已用全新测试账号对(systester9+systester2)在开发服务器实机验证:通过
真实DOM点击(非navigate()整页刷新)从通讯录进入全新会话,标题栏与侧边栏
立即正确显示对方名称与"在线"状态。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-09-16 18:03:18 +08:00
co-authored by Claude Sonnet 5
parent c455644cca
commit 8431f83ede
@@ -157,6 +157,27 @@ export function ConversationView() {
// the URL to the real name the instant it's known makes every later `getTopic(topicId)` in
// this component resolve the SAME object subscribe() just populated, not a fresh impostor.
if (topic.name !== topicId) navigate(`/messages/${topic.name}`, { replace: true });
// Real, live-confirmed gap on top of the rename issue above: for exactly this brand-new-P2P-
// via-alias case, `openConversation`'s own `withLaterDesc()` (an incremental "only if changed
// since I last knew" fetch) can come back with the subscribe successful but NO desc AND no
// presence at all -- `topic.public` stays permanently `null` and `topic.online` stays falsy
// (confirmed live: still true 10+ seconds later, no amount of waiting fixes either one),
// which is why the header/chat-list fall back to the raw topic id and "离线" forever on THIS
// specific path (reached live via a friend's profile "发消息" button, never through a fresh
// page load -- a full reload's own `subscribeMeTopic()` happens to paper over this by
// fetching every contact's full subscription state unconditionally, which is exactly why this
// was never caught by any test that reloaded the page as part of "opening" a conversation).
// `me.getMeta(withOneSub(topic))` is the same targeted-refresh call the SDK's own presence
// routing (`_routePres`, tinode.dev.js) uses for "just learned about this topic" -- unlike a
// plain desc fetch on the topic itself, this one comes back with BOTH desc AND online status
// in the same `sub` entry (confirmed live capturing the raw frame during an earlier
// investigation), and `TopicMe`'s own `_processMetaSubs` merges both onto this exact topic
// object before notifying -- wireTopicCallbacks already wired `me`'s `onMetaSub`/
// `onSubsUpdated` at login, so the response correctly invalidates the chat list once it lands.
if (!topic.public) {
const me = tinode.getMeTopic();
me.getMeta(me.startMetaQuery().withOneSub(undefined, topic.name).build()).catch(() => {});
}
})
.catch((err) => showError(err, '加载会话失败,请重试'));
return () => {