Search and live history are fixed. Socket tab movement is follow-up work, and the fan count concern needs backend verification. Merge recommendation is yes.
Re-reviewed 6 October 20266 commits7 files1018 additions, 373 deletions
Base 91dd0ed2c5487d0740707e676f79f90e3d432eb7 Head 425977eec0679bc54da19b6756da0dd882b3e2ea Target branch hotfix/release-0.0.23/messages-revamp
Should I merge it now? Yes.
No remaining merge blocker within the agreed scope.
I would merge 425977eec067. The search and live-history repairs passed the focused checks. The user has deferred socket tab movement to a later investigation. The fan count concern depends on a response shape that I have not verified on a live fan account, so it should not block this merge.
This pass reviews the complete one-file update from 5c5c2c0990de to 425977eec067. It adds 121 lines and removes 8. I reran all four reported scenarios and checked the history repair for duplicate IDs, request failure, and conversation changes. I found no new blocker in that update.
GitHub reports the PR open, ready for review, and mergeable with a clean merge state. It lists no status checks and no submitted reviews. This recommendation reflects the agreed scope and the checks recorded below.
Follow-up work
The implementation is unchanged in these areas. Socket tab movement is deferred by the user. The fan count example remains a conditional concern, not a confirmed product defect.
The user has accepted this as follow-up work. It does not block this merge.
The handler first searches the tab named by the socket event. If it cannot find the row there, it searches every loaded tab and updates whichever copy it finds. It never moves that row to the server's tab and does not refresh after finding it in a different tab.
Load a conversation in General.
Deliver an event for that conversation with tab=featured.
The handler finds the General copy and updates it there. Priority still has no copy.
The fixture ended with zero Priority rows and one General row. This matters whenever the server changes membership, such as a conversation moving into Priority. The event's server tab and its counts can disagree with the visible list until another inbox request repairs it.
Handle a tab mismatch explicitly. Remove the stale copy and refresh the relevant tab, or move the row with the server's membership and ordering. Do not reuse the old tab index as the destination.
Verify the fan count response before treating it as a defect
Fans have one combined inbox and no creator tab badges. The component stores tab=all at index 2, then uses that index to subtract read counts from General. This matters to the sidebar total only if the fan API distributes unread counts across multiple categories.
The fixture supplied Featured 3, General 2, and Broadcast 0. Reading a conversation with 3 Featured unread messages left the sidebar at 3 instead of 2. That proves the calculation under those inputs. It does not prove that the live fan API returns those inputs.
If the fan API aggregates all unread messages into General, this case does not apply. I have not verified a live fan response and should not have classified this as a confirmed merge blocker. Check the backend contract during the later investigation.
Search and live history are fixed
Returning to the previous search keeps the list usable
The input handler now emits the search value without cancelling requests or changing loading state. The debounced subscriber starts the request when the value changes. Typing alicex and returning to alice within 500 ms leaves the existing result and cursor intact.
The repeated fixture made one request, left isLoadingChatLogList false, and retained the next-page cursor. The old stuck-loader finding is resolved.
The component records the requested conversation and buffers its live messages while history loads. It merges those messages into the first page, rejects entries belonging to another thread, and skips stable IDs already in the response.
The original race fixture now keeps its live message after an empty history snapshot arrives. Further checks confirmed that a matching stable ID appears once, a live message survives a failed request, switching threads cancels the old request and drops its buffer, and the merge excludes an unrelated conversation.
These checks use the exact updated methods. The deduplication check uses the same stable ID in history and the socket entry. It does not claim to cover every backend ID format.
Several earlier issues are fixed
The current diff deserves a fresh review. I would not block it on these old claims.
Opening a direct-message history page no longer refetches the inbox. The list, search, and loaded pages stay in place.
Broadcast and followers history skip include_validation. Broadcast requests keep from on both pages.
Inbox append and older-history prepend filter IDs already present in their existing lists.
The sidebar inbox GET and the report files are absent from the current PR diff.
The inbox uses infiniteScroll on scrollViewport. Search uses the input event. The current code also writes badge counts onto the field that renders the tabs.
An earlier commit adds a 30-second presence poll for the open direct-message recipient, support for the new socket envelope, and page-based recipient loading in the New Message modal. Those changes expand the review beyond the original cursor-pagination commit.
Checks and limits
I reviewed the complete latest commit and the surrounding history, socket, search, and count methods. The previous pass covered the full seven-file PR at 5c5c2c0990de. This re-review checks the repair at 425977eec067.
I extracted component methods verbatim with the TypeScript parser and ran them with the repository's TypeScript and RxJS packages. Network calls and Angular rendering side effects used stubs. Search used the real RxJS operators and virtual time.
Check on the updated head
Observed result
Return to the previous search inside the debounce window
Fixed. Loader stays false and the next-page cursor remains.
Live message before first history response
Fixed. One live entry remains after the earlier snapshot arrives.
Socket moves a loaded General row to Featured
Row stays in General under the test event. Deferred follow-up.
Fan opens a Featured row from the all list
Fixture shows 3 instead of 2 under split counts. Live fan response shape is unverified.
Same stable message ID in history and live buffer
One entry remains. Buffer clears.
First history request fails after a live message arrives
Live message remains. Loading stops and permissions report failure.
Switch conversations while the first history request is pending
Old request cannot overwrite the new thread. Its buffered entry is excluded.
History merge receives an unrelated conversation
The unrelated entry is excluded.
Ordinary same-tab live preview and unread increment
Preview updates. Row unread and total increase by one.
Cursor containing plus, slash, and equals
URLSearchParams preserves the value through encoding.
git diff --check between the recorded base and updated head
Passed.
GitHub checks and submitted reviews
None listed when fetched for this re-review.
Full Angular builds, main and tenant SSR, signed-in staging flows
Not rerun in this review.
The fixtures establish state changes under the stated inputs. They do not measure how often staging sends each event or snapshot. I did not verify live non-null cursors, payment behavior, hardware recording, presence responses, or recipient pagination end to end.
The PR description reports earlier controlled-response checks, component-method checks, type checking, development compilation, and staging searches. Those are author-reported results. I have not treated them as independent verification of this updated commit.
Later investigation
Confirm when the server changes conversation membership through socket events. Decide whether to move the loaded row or refresh the relevant tab.
Inspect an authenticated fan inbox response. Confirm whether unread counts span multiple categories or aggregate into General before changing the count logic.
These are follow-up questions. The current merge recommendation is yes for 425977eec067.