Skip to content

feat(ui): tri-state connection indicator (red/orange/green)#628

Merged
lklimek merged 3 commits into
v1.0-devfrom
feat/tri-state-connection-indicator
Feb 24, 2026
Merged

feat(ui): tri-state connection indicator (red/orange/green)#628
lklimek merged 3 commits into
v1.0-devfrom
feat/tri-state-connection-indicator

Conversation

@lklimek
Copy link
Copy Markdown
Contributor

@lklimek lklimek commented Feb 23, 2026

Issue being fixed or feature implemented

User Story

Imagine you're a Dash Evo Tool user who just connected your wallet. The top-bar circle turns green and says "Connected," but the Networks tab says "Offline." You wonder if something is broken — but actually, your wallet is just syncing blocks. With this change, you'll see an orange circle with "Syncing" status while blocks sync, green "Synced" when everything is ready, and red "Disconnected" only when truly offline. The same terminology appears everywhere, so there's no more confusion.

Details

Closes #333
Closes #62

What was done?

Replaced the binary connected/disconnected connection indicator with a three-state model:

  • Disconnected (Red) — any required subsystem is unavailable
  • Syncing (Orange) — SPV is starting/syncing/stopping, with DAPI available
  • Synced (Green) — fully connected and operational

Changes by file

File Change
src/context/connection_status.rs Added OverallConnectionState enum (#[repr(u8)]), replaced AtomicBool with AtomicU8, renamed overall_connected()overall_state() and refresh_overall()refresh_state()
src/context/wallet_lifecycle.rs Updated 2 call sites to use renamed method
src/ui/components/top_panel.rs Three-color circle (green/orange/red) with differentiated pulsation; restored !status.rpc_online() guard on click-to-launch
src/ui/network_chooser_screen.rs Consistent tri-state labels; SPV syncing spinner uses orange instead of blue

Design decisions

  • RPC mode currently only produces Disconnected or Synced (no syncing state tracked yet) — tooltip has a forward-compat comment for the unreachable Syncing arm
  • SpvStatus::Stopping maps to Syncing (orange) so the "Disconnecting..." spinner remains visible during shutdown
  • Pulsation: normal rate for Synced, slower/subtler for Syncing, none for Disconnected

How has this been tested?

  • cargo clippy --all-features --all-targets -- -D warnings — clean
  • cargo +nightly fmt --all — clean
  • cargo test --all-features --workspace — 42 passed, 0 failed
  • Code reviewed by parallel agents (code-reviewer + rust-developer) — 2 findings fixed before merge

Breaking Changes

None. Internal API renames (overall_connectedoverall_state) are fully contained.

Checklist

  • I have performed a self-review of my own code
  • I have run code review with specialist agents
  • All review findings have been addressed
  • Clippy and fmt pass cleanly
  • All tests pass

Summary by CodeRabbit

  • Improvements
    • Enhanced connection status indicator now displays three distinct states (Disconnected, Syncing, Synced) with color-coded visual feedback and animations to better communicate network synchronization progress.
    • Updated status labels throughout the interface for improved clarity.

🤖 Co-authored by Claudius the Magnificent AI Agent

Replace the binary connected/disconnected indicator with a three-state
model: Disconnected (red), Syncing (orange), and Synced (green). This
provides consistent status terminology between the top-bar circle and
the Networks tab, resolving confusion when Dash Core is connected but
still syncing blocks.

Closes #333
Closes #62

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace get_live_address() (returns Option, max 1) with
get_live_addresses() (returns Vec of all non-banned endpoints)
now that the pinned platform SDK revision supports it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 23, 2026

📝 Walkthrough

Walkthrough

Introduce a three-state OverallConnectionState enum (Disconnected, Syncing, Synced) to replace binary connection status. Refactor ConnectionStatus to use the new state, rename refresh_overall() to refresh_state() with updated logic, and update UI components to display consistent status terminology and visual indicators across connection states.

Changes

Cohort / File(s) Summary
Core Connection State Logic
src/context/connection_status.rs
New three-state OverallConnectionState enum with From conversion. Replaced overall_connected: AtomicBool with overall_state: AtomicU8. Renamed refresh_overall() to refresh_state() with updated logic mapping RPC/SPV modes to Disconnected/Syncing/Synced states. Updated overall_connected() method to overall_state() returning enum. Changed DAPI status calculation from get_live_address() presence to get_live_addresses().len(). Updated tooltip logic and throttling condition to use new state.
State Refresh Call Sites
src/context/wallet_lifecycle.rs
Updated two SPV-related method calls from refresh_overall() to refresh_state() in start_spv() and stop_spv().
UI Status Display Components
src/ui/components/top_panel.rs, src/ui/network_chooser_screen.rs
Replaced boolean connected status with three-state OverallConnectionState. Added state-based color mapping (Synced → green, Syncing → orange, Disconnected → red). Updated pulsation logic: normal for Synced, slower for Syncing, disabled for Disconnected. Updated glow radius and repaint behavior. Changed UI labels from "Connected" to "Synced" for consistency. Applied warning color to SPV syncing state strokes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Poem

🐰 Three states now shine where one did glow,
Disconnected red, orange for the flow,
Green when synced, the truth is clear,
No more confusion, status sincere!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(ui): tri-state connection indicator (red/orange/green)' accurately summarizes the main change: replacing the binary connected/disconnected indicator with a three-state visual system.
Linked Issues check ✅ Passed The PR fully addresses both linked issues: #333 is resolved by implementing consistent tri-state terminology and colors (Disconnected/red, Syncing/orange, Synced/green) across top panel and Networks tab; #62 is resolved by making the indicator reflect combined connectivity (RPC and ZMQ/DAPI) and labeling subsystem states clearly.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to implementing the tri-state connection indicator and aligning terminology/visuals. No extraneous modifications outside the linked issue objectives were introduced.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/tri-state-connection-indicator

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/ui/components/top_panel.rs (1)

114-124: Consider replacing unreachable!() with a safe fallback.

Line 122: The Disconnected arm is correctly unreachable given the if guard on line 115, but unreachable!() will panic if a future refactor alters the guard. A defensive _ => 1.0 would be equally correct and future-proof.

Suggested change
         match overall {
             OverallConnectionState::Synced => 1.0 + 0.2 * (time * 2.0).sin(),
             OverallConnectionState::Syncing => 1.0 + 0.15 * (time * 1.2).sin(),
-            OverallConnectionState::Disconnected => unreachable!(),
+            OverallConnectionState::Disconnected => 1.0,
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ui/components/top_panel.rs` around lines 114 - 124, The match on
OverallConnectionState inside the pulse_scale calculation uses unreachable!()
for the Disconnected arm, which could panic if the surrounding if-guard is later
changed; modify the match in the pulse_scale computation (the match on overall
in the pulse_scale block) to return a safe fallback (e.g., use a wildcard or the
Disconnected arm to return 1.0) instead of calling unreachable!(), so the UI
pulse defaults to 1.0 rather than panicking.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/ui/components/top_panel.rs`:
- Around line 114-124: The match on OverallConnectionState inside the
pulse_scale calculation uses unreachable!() for the Disconnected arm, which
could panic if the surrounding if-guard is later changed; modify the match in
the pulse_scale computation (the match on overall in the pulse_scale block) to
return a safe fallback (e.g., use a wildcard or the Disconnected arm to return
1.0) instead of calling unreachable!(), so the UI pulse defaults to 1.0 rather
than panicking.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d45b3ee and 5dd4031.

📒 Files selected for processing (4)
  • src/context/connection_status.rs
  • src/context/wallet_lifecycle.rs
  • src/ui/components/top_panel.rs
  • src/ui/network_chooser_screen.rs

@thepastaclaw
Copy link
Copy Markdown
Collaborator

Reviewed CodeRabbit feedback. The nitpick about unreachable!() in pulse_scale is addressed in commit 1200b1cf by using a safe fallback (Disconnected => 1.0) to avoid panic risk during future refactors.

@lklimek lklimek merged commit ac5e84c into v1.0-dev Feb 24, 2026
3 checks passed
@lklimek lklimek deleted the feat/tri-state-connection-indicator branch February 24, 2026 08:02
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.

Inconsistent Network Status ("Online" vs "Connected" vs Synced) Lack of network status clarity

2 participants