fix(chat): new-chat stale selection + blank thread header entering created conversations - #29452
Merged
Conversation
…eader Two bugs entering a conversation via new chat: - The team-building store is a per-namespace singleton that outlives the modal, and finishedTeamBuilding preserved teamSoFar while the blur cancel doesn't fire on modal removal, so reopening new chat showed the previous selection. Finish now clears the selection for every namespace except teams (whose add-members error path re-opens the builder with the chips intact), and the screen resets stale non-teams selections on mount. - The pendingWaiting -> real conversation switch is a setParams on the same screen, so the native header measured an empty title and iOS never re-measures it. BadgeHeaderUpdater (which force-reconfigures the bar once title content arrives) lived inside the conversation-keyed provider and remounted on the switch, seeing the title as already present and never firing. It now lives outside the keyed subtree, and the header title arms ensureConversationMetaLoaded itself so it can self-heal a conversation whose meta never loaded.
navigateAppend's replace degrades to setParams for the same route name, which keeps the native screen alive; its header title was measured while pendingWaiting rendered it empty and iOS never re-measures an initially-empty title subview, so the header stayed blank even after the one-shot setOptions reconfigure fired (verified via instrumentation: JS title rendered and laid out at 105pt wide, bar still blank). Replacing with a fresh screen measures the title with content already present. Includes temporary [HDR] console instrumentation to verify on device; strip before merging.
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes two regressions in the new-chat flow: (1) stale user/team selection persisting across re-opening the team builder, and (2) an intermittently blank iOS conversation header when transitioning from pendingWaiting to the real conversation.
Changes:
- Reset team-building state for non-
teamsnamespaces both onfinishedTeamBuildingand on builder mount to prevent stale selection leakage. - Force a true React Navigation
StackActions.replacewhen transitioningpendingWaiting → real conversationto ensure iOS re-measures the header title. - Make the header more resilient by keeping
BadgeHeaderUpdateralive across same-screen conversation swaps and having the header armensureConversationMetaLoadeddirectly.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| shared/team-building/page.tsx | Resets non-teams team-builder state on mount to avoid stale chips across modal re-opens. |
| shared/stores/tests/team-building.test.ts | Adds coverage verifying finishedTeamBuilding clears selection/error for chat namespace while preserving teams behavior. |
| shared/stores/team-building.tsx | Updates finishedTeamBuilding to clear selection outside teams, keeping teams selection preservation intact. |
| shared/constants/router.tsx | Uses StackActions.replace for pendingWaiting → real conversation to avoid header blanking caused by setParams. |
| shared/chat/conversation/header-area/index.tsx | Ensures conversation meta is loaded from the header to self-heal missing title data. |
| shared/chat/conversation/container.tsx | Moves BadgeHeaderUpdater outside the conversation-keyed provider so its “title was empty” tracking survives param-based swaps. |
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.
Problem
Two bugs in the new-chat flow:
Root causes / fixes
Stale selection — the team-building store is a per-namespace singleton that outlives the modal.
finishedTeamBuildingdeliberately preservedteamSoFar, and the blur-listener cleanup (CancelOnBlur) doesn't fire when the modal is removed, so the selection leaked into the next session.finishedTeamBuildingnow clears the selection for every namespace exceptteams(whose add-members error path re-opens the builder and relies on the chips being intact; everyonCompletehandler receives a copied set, so nothing else reads the store after finish).Blank header — the pendingWaiting → real-conversation switch went through
navigateAppend's replace, which degrades tosetParamsfor the same route name. That keeps the native screen alive, and its header title was measured while pendingWaiting rendered it empty — iOS never re-measures an initially-empty title subview. Instrumentation confirmed the JS side was fully healthy (title rendered and laid out at 105pt) and the existing one-shotsetOptionsreconfigure fired, yet the bar stayed blank.navigateToThreadnow dispatches a realStackActions.replacefor this case, so the fresh screen measures the title with its content already present.BadgeHeaderUpdatermoved outside the conversation-keyed provider so its title-was-empty tracking survives same-screen conversation swaps.ensureConversationMetaLoadeditself, so the header self-heals for any conversation whose meta never loaded.Tests
yarn lint,yarn tsc,yarn jest stores/tests/team-building.test.tsall green.