Skip to content

Preserve the thread shell while detail loads - #4830

Merged
juliusmarminge merged 3 commits into
mainfrom
t3code/fix-thread-loading-shell
Jul 29, 2026
Merged

Preserve the thread shell while detail loads#4830
juliusmarminge merged 3 commits into
mainfrom
t3code/fix-thread-loading-shell

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Jul 29, 2026

Copy link
Copy Markdown
Member

What Changed

  • Added a static loading shell that preserves project and thread metadata while the thread detail snapshot loads.
  • Updated the thread route to render the loading shell during the loading state instead of briefly rendering an empty view.
  • Added coverage for metadata rendering, generic loading behavior, accessibility state, and static placeholders.

Why

Opening a thread could temporarily lose the chat layout while its detail snapshot was loading. This keeps the surrounding chat chrome visible, reduces visual disruption, and avoids continuously repainting loading animations.

UI Changes

The thread route now shows a stable header, message placeholders, and composer shell while content loads. Before/after screenshots are not included.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Low Risk
UI and loading-state gating only; no auth, persistence, or send-path protocol changes beyond blocking send until detail loads.

Overview
Preserves the chat layout while thread detail is still loading by rendering ChatView when the route is in a shell-only loading state, instead of showing a blank view until the detail snapshot arrives.

The route computes threadSyncPhase (loading / syncing / none) from shell vs detail presence and environment thread status, passes it into ChatView, and shows a static ThreadSyncStatusPill (“Loading messages…” / “Syncing messages…”). While detail is loading, buildLoadingThreadFromShell supplies an activeServerThread with empty messages so metadata and chrome stay visible; the timeline hides the empty placeholder, onSend is blocked, and the composer gets sendDisabledReason (“Messages loading”) wired through ComposerPrimaryActions (disabled state + aria-label).

shouldWriteThreadErrorToCurrentServerThread now keys off activeServerThread so local errors still attach during the shell-derived loading phase. Tests cover shell→thread mapping, sync phase resolution, the status pill, and updated error-write behavior.

Reviewed by Cursor Bugbot for commit 145f427. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Preserve the thread shell while detail loads in ChatView

  • Mounts ChatView earlier when only a ThreadShell is available, using a new buildLoadingThreadFromShell util to construct a minimal Thread with empty message/plan/activity collections.
  • Adds resolveThreadSyncPhase and threadSyncLabel in threadSync.ts to derive 'loading' or 'syncing' states from shell/detail presence and thread status.
  • Renders a new ThreadSyncStatusPill component during loading/syncing phases and hides the empty thread placeholder.
  • Disables the composer send button with a 'Messages loading' reason (surfaced via aria-label) while thread detail is loading.

Macroscope summarized 145f427.

- Render a stable loading shell with available project and thread metadata
- Add coverage for populated and generic loading states
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eccef79e-87b2-410e-887a-ac92151bfaba

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 29, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Jul 29, 2026
@macroscopeapp

macroscopeapp Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new loading state behavior for thread shells and has an unresolved review comment identifying a potential bug where errors during the loading window may be written to the wrong error store, causing error banners to not display correctly.

You can customize Macroscope's approvability policy. Learn more.

- Keep thread metadata visible during message loading
- Show sync status and disable composer until details are ready
@macroscopeapp
macroscopeapp Bot dismissed their stale review July 29, 2026 11:36

Dismissing prior approval to re-evaluate 7dd91b5

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is ON, but a cloud agent failed to start.

Reviewed by Cursor Bugbot for commit 7dd91b5. Configure here.

const activeThread = activeServerThread ?? localDraftThread;
const threadError = isServerThread
? (localServerError ?? serverThread?.session?.lastError ?? null)
? (localServerError ?? activeServerThread?.session?.lastError ?? null)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loading errors use draft store

Medium Severity

While thread detail is loading, activeServerThread/isServerThread can be satisfied by loadingServerThread, but setThreadError still only writes server errors when serverThread is non-null. Failures during that window go to the draft error map, while threadError reads localServerErrorsByThreadKey, so error banners may not appear on the server thread route.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7dd91b5. Configure here.

- Treat the loading thread shell as the active server thread
- Preserve error state across thread promotion and add focused coverage
@juliusmarminge
juliusmarminge merged commit 3137c2b into main Jul 29, 2026
16 checks passed
@juliusmarminge
juliusmarminge deleted the t3code/fix-thread-loading-shell branch July 29, 2026 11:54
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Jul 29, 2026
## What's Changed
* Simplify files panel header by @juliusmarminge in pingdotgg/t3code#4828
* build(desktop): reduce installed app size by ~300MB by @wukko in pingdotgg/t3code#4824
* Update model version from claude-opus-4-8 to claude-opus-5 by @juliusmarminge in pingdotgg/t3code#4832
* Preserve the thread shell while detail loads by @juliusmarminge in pingdotgg/t3code#4830
* Reduce idle work and disk churn with native resource diagnostics by @juliusmarminge in pingdotgg/t3code#2679

## New Contributors
* @wukko made their first contribution in pingdotgg/t3code#4824

**Full Changelog**: pingdotgg/t3code@v0.0.31-nightly.20260729.944...v0.0.31-nightly.20260729.946

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.31-nightly.20260729.946
H-Ekana added a commit to H-Ekana/v3code that referenced this pull request Jul 29, 2026
Brings in 20 upstream commits including native resource diagnostics (pingdotgg#2679),
event-driven Git ref invalidation (pingdotgg#4727), 300MB installer size reduction
(pingdotgg#4824), thread-shell preservation while detail loads (pingdotgg#4830), HTTP
compression, and the v0.0.30 release prep.

Merge resolutions of note:
- vcs.ts / ProcessDiagnostics / EventNdjsonLogger: upstream superseded our
  polling-interval, WMI, and log-batching fixes with better implementations
- build-desktop-artifact: kept fork artifact naming + bundled Codex plugin
  extraResource on top of upstream's size optimizations
- ChatView/ChatComposer: both feature sets kept (send-morph/reveal/hydration
  + thread-shell loading, sendDisabledReason, ThreadSyncStatusPill)
- RpcAuthorization: added fork-only shell.revealPath scope
- AGENTS.md: kept fork operational rules, took upstream's product sections
- ProjectionPipeline: expiry timestamps via DateTime.nowUnsafe (wall clock)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ohbentos pushed a commit to ohbentos/t3code that referenced this pull request Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 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