crypto-com / crypto-com/cdcx-cli

TUI: persist last-session UI state (active tab, selected instrument, sort, filters, depth preset, etc.)

Open
#32 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
25
Forks
9
PR merge metrics
No merged PRs in 30d

Description

## Summary
The TUI currently forgets all in-session UI state on quit. Every relaunch drops you on Market tab / default sort / BTC_USDT selected / depth 50 / category Spot, regardless of where you were when you quit. For power users who live in the TUI across many short sessions, this is friction.

Add a best-effort state-restore layer that remembers the last session's UI state and restores it on launch.

## What to persist

**Navigation**
- Active tab (Market / Portfolio / Orders / History / Watchlist / Positions).
- Selected instrument on Market / Watchlist / Positions (falls back gracefully if the instrument is no longer available).

**Market tab**
- Category filter (Spot / Perpetual / Futures / ...).
- Sort field + direction (Volume / Change / Price / Name, asc/desc).
- Search query? — probably NOT; search feels ephemeral. Up for debate.
- View mode: Table / Detail / Chart / Compare? — probably NOT; rehydrating straight into a Compare view is jarring. Up for debate.
- Timeframe (1m / 5m / ... / 1D).
- **Book depth preset** (10 / 50 / 150) — from #26.
- Heatmap on/off.
- Volume unit (USD / Notional).
- Split-view state (table + chart).

**Help overlay**
- Last shortcuts page viewed? — probably NOT; #30 explicitly resets to page 1 every open, and that's the right UX. This one is low-value.

**Orders / History / Portfolio**
- Sort field + direction on any tab that has sortable columns.
- History pagination position? — probably NOT; data moves forward between sessions, so \"resume on page 3\" is stale.

**Compare view**
- List of pinned instruments (if view_mode is persisted).

## Where to persist

`~/.config/cdcx/tui.toml` — same file #23 (watchlist) and settings already round-trip. One new top-level `[session]` table:

```toml
[session]
active_tab = \"market\"
selected_instrument = \"ETH_USDT\"
volume_unit = \"usd\"
split_view = false

[session.market]
category = \"PERPETUAL_SWAP\"
sort_field = \"volume\"
sort_asc = false
timeframe = \"4h\"
book_depth = 50
heatmap = false
```

Reuse the `mutate_tui_toml_at` helper from #28 so unrelated keys (theme, tick_rate, watchlist, custom themes) are preserved.

## When to persist

**Option A — on every change:** write on each mutation. Simple, but O(n) disk writes per session.

**Option B — on quit only:** single write in the shutdown path. Lower-friction, but any crash loses the session.

**Option C — debounced (every ~5s if dirty):** best of both. Adds complexity.

Recommendation: **Option B** to start. Fast, simple, one integration point. If we notice state loss from crashes later, upgrade to C.

## Scope / sequencing

Land in small increments, each an independently-useful PR:

1. **Phase 1 (minimum useful):** active_tab + selected_instrument + market.sort + market.category. Roughly half the annoyance, small diff.
2. **Phase 2:** timeframe, book_depth, heatmap, volume_unit, split_view.
3. **Phase 3:** sort state on Orders / Portfolio / Positions, compare-view instrument list.

Deliberately NOT in scope for the first cut: search query, help overlay page, history pagination, workflow modals, spotlight.

## Non-goals
- **Not** a full settings-UI-exposed preference system. This is silent state capture; the user doesn't configure it.
- **Not** a per-profile state store (yet). One global `[session]` block. Add per-profile later if someone hits the edge case.
- **Not** a remote-sync system. Local file only.

## Risk
- **Stale instrument on restore:** if `selected_instrument` was delisted, fall back to index 0 of the filtered list. Don't panic, don't toast.
- **Schema evolution:** treat `[session]` as a purely additive, tolerant block. Missing keys → sensible defaults. Unknown keys → ignore. Malformed values → fall through to default and don't error the user.
- **File-size creep:** negligible. Even with all phases, the `[session]` block stays under a few hundred bytes.

## Related
- #23 — established the `tui.toml` round-trip pattern + `save_watchlist_at` testable seam.
- #26 — `book_depth` preset that would become persisted under `[session.market]`.
- #30 — help overlay pagination (explicitly NOT persisted; called out here to avoid confusion).

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.