Skip to content

fix(swift-ios): reopened threads no longer show stale history after swipe back - #11491

Open
mackinleysmith wants to merge 1 commit into
pingdotgg:t3code/rebuild-mobile-app-swiftfrom
mackinleysmith:t3code/fix-ios-thread-stale-on-open
Open

fix(swift-ios): reopened threads no longer show stale history after swipe back#11491
mackinleysmith wants to merge 1 commit into
pingdotgg:t3code/rebuild-mobile-app-swiftfrom
mackinleysmith:t3code/fix-ios-thread-stale-on-open

Conversation

@mackinleysmith

Copy link
Copy Markdown
Contributor

What Changed

On compact width, the swipe-back gesture now only collapses the split view column. It no longer clears the thread selection. This is the same thing the system back button does, so the thread view is re-shown rather than destroyed and recreated. One line in WorkspaceView.swift plus a comment explaining why.

Why

Reopening a thread after leaving it with swipe back showed the cached transcript and never caught up. No pill, no updates, until the user backed out and reopened. It was most visible after a background trip because new content had arrived in the meantime.

Instrumenting the simulator build showed the sequence:

  1. Swipe back cleared selectedThreadID, destroying the thread view while the split view was still finishing its interactive pop.
  2. The next open of that thread got onAppear followed by a spurious onDisappear while still on screen.
  3. That disappear ran releaseThread, which cancelled the load before it subscribed to the socket or armed the HTTP fallback.
  4. The model treated the cancellation as benign and kept the cached detail, with sync state nil, so nothing was shown.

Leaving with the nav-bar back button keeps the selection and re-shows the same view, and every reopen on that path was fresh. Making the swipe path do the same removes the trigger.

Lifecycle log, before (the reopen is instance 3D1EF3):

[repro-view] task start instance=3D1EF3
[repro-view] onAppear instance=3D1EF3
[repro-view] onDisappear instance=3D1EF3
[repro] releaseThread active=<thread> seq=nil wasSync=false
[repro-view] task end instance=3D1EF3 cancelled=true

After, same flow:

[repro-view] task start instance=F8494C
[repro-view] onAppear instance=F8494C
[repro] loadThread cached seq=90502 warm=false
[repro] subscribe after=90502
[repro] item event thread.message-sent seq=90503
[repro] item event thread.activity-appended seq=90507
[repro] item synchronized active=90507
[repro] markDetailSynchronized

Verification

  • Reproduced on iPhone 17 Pro simulator against a disposable local server: open thread, swipe back, push a message over HTTP, reopen. Stale every time on the base commit, both with and without a background trip in between.
  • Same flows on this branch show the new message and reach synchronized. Also verified the swipe, background, foreground, reopen variant.
  • Debug build compiles clean. Native test suite not run locally; nothing in it references the changed callback.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (no visual change; behavior only, logs above)
  • I included a video for animation/interaction changes (not applicable)

Model: Claude Fable 5.1. Harness: Claude Code inside T3 Code.

…wipe back

Leaving a thread with the swipe-back gesture cleared the selection, which
destroyed the thread view while the split view was still finishing its
interactive pop. The next open of that thread received onAppear followed by a
spurious onDisappear, and releaseThread cancelled the load before it could
subscribe or arm the HTTP fallback. The view then showed the cached transcript
with no sync indicator until the user backed out and reopened.

Collapse the compact column on swipe back and keep the selection, which is
what the system back button already does. The view is re-shown instead of
recreated, its task re-runs, and the cached resume replays new events.

Model: Claude Fable 5.1. Harness: Claude Code inside T3 Code.
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Sep 13, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 8595f01

Macroscope's review found this PR approvable — This is a small one-file fix that changes only compact swipe-back navigation, preserving the selected thread so its loading and cache lifecycle is not interrupted. Existing close and navigation flows remain unchanged, with no schema, configuration, deployment, or static-analysis impact.

You can add or adjust custom eligibility rules. Learn more.

@mackinleysmith

Copy link
Copy Markdown
Contributor Author

Release Smoke failure is inherited from the base branch, not this change.

The job fails in vp install --lockfile-only with ERR_PNPM_UNUSED_PATCH for expo-audio@57.0.4. apps/mobile/package.json on t3code/rebuild-mobile-app-swift still declares "expo-audio": "~57.0.4", and expo-audio 57.0.5 was published after this branch's last green CI run on Sep 8, so the lockfile-only resolve now picks 57.0.5 and the patch keyed to 57.0.4 goes unused.

main fixed this in #11426 (pin to 57.0.4), which the Swift branch has not picked up yet. Merging main into the branch, or cherry-picking 18d8cbf, clears it for every PR against this base. Kept out of this PR to stay single-concern. Happy to open that as a separate one-line PR if useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant