Skip to content

Polish initial loading state for task threads#2311

Draft
fercgomes wants to merge 3 commits into
mainfrom
posthog-code/polish-task-loading-state
Draft

Polish initial loading state for task threads#2311
fercgomes wants to merge 3 commits into
mainfrom
posthog-code/polish-task-loading-state

Conversation

@fercgomes
Copy link
Copy Markdown
Contributor

Summary

When opening an existing task with a long thread, the UI used to show a bare 32px spinner with no copy (local sessions), or briefly render just the initial user prompt with no indication more was loading (cloud sessions). Once messages trickled in, there was no signal that the agent was still reconnecting.

Three coordinated changes:

  • Shared InitializingSplash — extracted from CloudInitializingView so cloud and local share one source of truth for the hedgehog + 2s reveal + heading/subtitle layout.
  • LocalInitializingView — replaces the bare local spinner in SessionView with the same polished pattern. Copy keyed on whether we're resuming an existing session ("Loading your conversation…") or spinning up a new one ("Getting things ready…").
  • ConversationLoadingHint — a small pill above the input that surfaces the in-between states: "Reconnecting to your agent…" while local logs have loaded but the agent process is still spawning, and "Loading more messages…" while a cloud run is queued/in_progress and only the initial event has come through. Hidden during active generation since SessionFooter already covers that.

Test plan

  • Cold-launch with several existing tasks that have long threads — clicking one shows the polished splash (or a brief sub-2s spinner) instead of a bare anonymous one, then the thread renders.
  • Kill an in-progress local agent process and reopen the task — messages stay visible and a "Reconnecting…" pill sits above the input until session.status flips to connected.
  • Open a cloud task currently in_progress with only the initial prompt indexed — splash first, then once the prompt arrives the "Loading more messages…" pill is visible until the next event lands.
  • Toggle dark + light mode — splash and pill use Radix tokens, both modes look right.
  • pnpm --filter code typecheck clean; pnpm --filter code test for src/renderer passes (930 tests).

fercgomes added 3 commits May 22, 2026 17:43
When opening an existing task with a long thread, the UI used to show a
bare 32px spinner with no copy (local), or briefly render just the initial
user prompt with no indication more is loading (cloud). Once messages
trickled in, there was no signal that the agent was still reconnecting.

Three coordinated UX changes:

- Extract a shared InitializingSplash (hedgehog + 2s reveal + heading
  + subtitle) so cloud and local share one source of truth.
- New LocalInitializingView replaces the bare local spinner with the
  same polished pattern. Copy is keyed on whether we're resuming an
  existing session ("Loading your conversation…") or spinning up a new
  one ("Getting things ready…").
- New ConversationLoadingHint pill sits above the input and surfaces
  the in-between states: "Reconnecting to your agent…" while local
  logs have loaded but the agent process is still spawning, and
  "Loading more messages…" while a cloud run is queued/in_progress
  and the first event has arrived but more are still being polled.
  Hidden during active generation since SessionFooter already covers
  that.

Generated-By: PostHog Code
Task-Id: 743a524d-7374-453b-91b4-e5ab43342707
"Loading the thread" and "reconnecting to your agent" are different
mechanisms but the same experience from the user's perspective: they're
waiting to see their conversation. The previous splash + pill combo
mentioned both concepts and felt disjointed.

Replace the local initializing splash with a skeleton placeholder of
message bubbles that mirrors the real conversation layout, and drop the
"Reconnecting to your agent…" pill that was conflating the two states.
The cloud queue/sandbox splash stays — that's genuinely different info
(no thread to load yet) and the queue status is meaningful.

- New MessagesSkeleton: two user bubbles + two assistant text-line
  groups, max-width matched to CHAT_CONTENT_MAX_WIDTH, animate-pulse.
- SessionView local isInitializing branch uses MessagesSkeleton.
- Remove ConversationLoadingHint and its usage in ConversationView.
- Revert the isResumingExistingSession plumbing — the skeleton doesn't
  need that distinction.
- Delete LocalInitializingView (replaced by skeleton).

Generated-By: PostHog Code
Task-Id: 743a524d-7374-453b-91b4-e5ab43342707
Previous skeleton lived in SessionView's isInitializing branch as a
full-area replacement for the conversation+input layout, so the
transition from "loading" to "loaded" swapped the entire screen.

Move the skeleton into ConversationView itself, rendered when
items.length === 0 inside the same absolute-positioned slot as the
VirtualizedList. The surrounding chrome (input area, plan bar, footer)
stays mounted the whole time — only the message slot swaps from
skeleton bubbles to real messages. The existing "Connecting to agent…"
overlay in the input area already handles the agent-spawn transition
with its own opacity fade, so no extra indicator needed there.

Cloud sessions still route through CloudInitializingView for the
queued/in-progress no-events case — the queue/sandbox copy carries
real information that the skeleton can't substitute for.

Generated-By: PostHog Code
Task-Id: 743a524d-7374-453b-91b4-e5ab43342707
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant