diff --git a/src/views/contact-management-view.jsx b/src/views/contact-management-view.jsx index 6285f29b..e82fb1fa 100644 --- a/src/views/contact-management-view.jsx +++ b/src/views/contact-management-view.jsx @@ -406,7 +406,7 @@ function Verification({uid, onToast}) { ; } -function Profile({uid, friend, onTopicSelected, onToast}) { +function Profile({uid, friend, onTopicSelected, onCreateTopic, onToast}) { const [profile, setProfile] = React.useState(() => (uid ? readCachedData('profile-seed:' + uid) : null)); // A failed fetch with no seed to fall back on previously left this stuck on "加载中…" forever -- // tracked separately from `profile` itself (which legitimately stays null while genuinely still @@ -478,7 +478,17 @@ function Profile({uid, friend, onTopicSelected, onToast}) { // Real native Tinode p2p topic name (from my side) is just the peer's own user_id ("usrXXXX") -- // NOT `profile.topic` (a separate "p2pXXXX" identifier the custom REST layer uses internally, // which Tinode.topicType() doesn't recognize, so selecting it left the message pane blank). - const openChat = () => onTopicSelected(uid); + // + // Must go through onCreateTopic (tinode-web.jsx's handleStartTopicRequest), not the plain + // onTopicSelected -- confirmed live: a freshly-accepted friend with zero prior message history has + // no locally cached p2p topic yet, and onTopicSelected (handleTopicSelected) only *selects* a topic, + // it never sends the native {sub} request that actually creates/joins it. messages-view.jsx's own + // isWriter stays stuck at its default `false` (no ACS ever arrives because nothing subscribed), + // permanently showing "消息已禁用" with no compose box and no way to send the first message -- + // 100% reproducible for every real "just became friends, say hi" case, not an edge case. + // handleStartTopicRequest already guards the case this topic *does* have history (isTopicCached), + // delegating straight to handleTopicSelected then, so this is safe to call unconditionally. + const openChat = () => (onCreateTopic || onTopicSelected)(uid); return