Skip to content

fix(tui): standardize a self-animating spinner across probe surfaces (#1312)#1327

Merged
Aaronontheweb merged 2 commits into
netclaw-dev:devfrom
Aaronontheweb:claude-wt-standardize-spinner
Jun 4, 2026
Merged

fix(tui): standardize a self-animating spinner across probe surfaces (#1312)#1327
Aaronontheweb merged 2 commits into
netclaw-dev:devfrom
Aaronontheweb:claude-wt-standardize-spinner

Conversation

@Aaronontheweb

Copy link
Copy Markdown
Collaborator

Closes #1312.

Problem

Probe/validation spinners in the TUI were hand-rolled per surface and had drifted, producing inconsistent — and sometimes broken — animation:

  • ModelManagerPage (model discovery) had no fast tick → the spinner was effectively frozen for the whole probe.
  • ProviderStepView / ProviderManagerPage indexed the glyph on ProbeElapsedSeconds (1 Hz) → the spinner crawled at ~1 fps.
  • SkillFeedsStepView mutated _spinnerTick++ during render.
  • Every surface re-implemented its own SpinnerFrames array, tick source, and redraw subscription — the root of the lazy/frozen probe spinners noted in netclaw model discover/set blocks silently while probing; 10s timeout is tight for busy self-hosted servers #1292, plus a re-entrant-redraw footgun.

What this does

Termina already ships a self-animating SpinnerNode (layout-node model) in the 0.10.2 package Netclaw already references — so this needs no Termina change and no package bump. The work is a Netclaw-side migration onto it.

  • Adds a small shared SpinnerViews helper (Labeled(...) / WithElapsed(...)) that wraps SpinnerNode, standardizing glyph style, color, and indentation. The node owns its own animation timer and propagates invalidation up the layout tree, so views just drop it in — no per-surface tick field and no hand-wired redraw subscription (which structurally removes the re-entrancy footgun).
  • Migrates all five surfaces: SkillFeedsStepView, ProviderStepView, OAuthFlowViews, ModelManagerPage, ProviderManagerPage.
  • Removes the duplicated SpinnerFrames arrays (×5), GetSpinnerFrame, the SpinnerTick reactive properties + their Invalidate subscriptions, the view-local _spinnerTick, and the now-dead EagerProbeElapsedSeconds property + eager-probe redraw timer.
  • Simplifies the probe timers from a 120 ms fast tick to a 1 Hz tick that only drives the cosmetic (Ns) elapsed counter (the glyph self-animates). Elapsed counters are preserved as reactive .AsLayout() siblings.

Net: +112 / −136 lines.

Validation

  • dotnet build (Cli + Tests): 0 warnings / 0 errors
  • dotnet slopwatch analyze: 0 issues
  • Add-FileHeaders.ps1 -Verify: pass
  • 347 TUI unit tests pass
  • Smoke harness: provider-add + provider-rename tapes pass (exercise the manager validation spinner + migrated health glyphs). The init-wizard tape's provider-validation spinner step passes; that tape fails later on a clean-host-only assumption (the External Skills step detecting locally-installed Claude Code) unrelated to this change.

…etclaw-dev#1312)

Replace the five hand-rolled, drifted probe/validation spinners with
Termina's existing self-animating SpinnerNode (already shipped in the
0.10.2 package), via a small shared SpinnerViews helper.

This fixes the frozen ModelManager spinner, the ~1fps crawl on the
provider validation/probe spinners (frame indexed on elapsed seconds),
and the inconsistent cadence across surfaces. The node owns its own
animation timer and propagates invalidation up the layout tree, so views
just drop it in — no per-surface tick field and no hand-wired redraw
subscription, which also removes the re-entrant-redraw footgun.

- Add SpinnerViews with Labeled() and WithElapsed() (reactive "(Ns)"
  counter sibling); standardize on the Dots glyph style and 2-space indent.
- Migrate SkillFeedsStepView, ProviderStepView, OAuthFlowViews,
  ModelManagerPage, and ProviderManagerPage onto it.
- Remove the duplicated SpinnerFrames arrays, GetSpinnerFrame, the
  SpinnerTick reactive properties and their Invalidate subscriptions, the
  view-local _spinnerTick field, and the now-dead EagerProbeElapsedSeconds
  property + eager-probe redraw timer.
- Simplify the probe timers from a 120ms fast tick to a 1Hz tick that only
  drives the cosmetic elapsed counter; the glyph now self-animates.

No Termina change and no package bump required. Elapsed counters are
preserved as reactive siblings.
@Aaronontheweb Aaronontheweb added the tui Terminal UI (Termina) issues label Jun 4, 2026
@Aaronontheweb Aaronontheweb merged commit d1ed40e into netclaw-dev:dev Jun 4, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tui Terminal UI (Termina) issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Standardize a self-animating spinner component for Termina layout-node views

1 participant