Skip to content

feat(tray): routing switch, live tooltip/icon, ping in recent list - #188

Merged
loss-and-quick merged 3 commits into
mainfrom
feat/tray-context-menu-ux
Aug 18, 2026
Merged

feat(tray): routing switch, live tooltip/icon, ping in recent list#188
loss-and-quick merged 3 commits into
mainfrom
feat/tray-context-menu-ux

Conversation

@loss-and-quick

Copy link
Copy Markdown
Owner

Summary

Overhauls the system-tray right-click menu, borrowing v2rayN's tray UX where it fits kasumi's TUN-only model (system-proxy set/clear/PAC was intentionally left out — kasumi has no OS-proxy concept).

  • Routing-mode radio submenu (Rules / Global / Custom) — a check-marked submenu that writes settings.routingMode without opening the window, mirroring v2rayN's routing submenu. Clicks come back through the existing TrayAction catch-all as routing:<mode>; Tauri has no native radio item, so (like v2rayN) exactly one entry is check-marked.
  • Live tooltip + state icon — a new lightweight set_tray_status command pushes a tooltip (Kasumi Proxy — <state> · <profile> + live ↓/↑ rate) and a state icon on every status tick. Icon variants (full colour / desaturated / muted) are derived at runtime from the bundled icon, so no new art is committed. The menu is rebuilt only when its contents change (not per traffic tick), and the icon is swapped only on a state transition.
  • Ping in the recent list — recent-profile entries append the last measured latency (· N ms) when a result exists.

Reuses existing settings.routing* i18n keys, formatRate, and testResults — no new locale keys, no duplicated values.

Tooltips are honoured on Windows/macOS; the Linux app-indicator ignores them, but the state icon still updates there.

Affected layer

  • frontend/ — React Web UI
  • crates/ · src-tauri/ — Rust core / backend / Tauri desktop
  • module/ — Android installable zip (thin launcher over the Rust daemon)
  • scripts/ — build / release helpers
  • CI / .github/
  • Docs only

Verification

Rust (crates/ · src-tauri/):

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace — green except one pre-existing, network-dependent test (net::tcp_ping_fails_on_unreachable_host) that also fails on main in the sandbox; unrelated to this change. cargo test -p kasumi-desktop is fully green (28/28).
  • Codegen drift: cargo run -p kasumi-desktop --bin codegen leaves git clean

Web UI (frontend/):

  • bun run check — Biome lint + format clean
  • bun run test — vitest green (68/68)
  • bun run buildtsc -b + vite build succeed
  • bun run check:i18n — locale dictionaries in sync

Module shell (module/):

  • shellcheck -s sh module/*.sh — n/a, not touched

Checklist

  • Title is a scoped Conventional Commit; commits are logically split
  • No build artifacts committed
  • Generated frontend/src/generated/ was regenerated from Rust, not hand-edited
  • If user-visible strings changed: n/a — no new strings, reuses existing settings.routing* keys
  • Renames touching the project id were grepped in all case forms — n/a, no renames

Notes for reviewers

  • The three sub-features form one cohesive tray overhaul and their diffs interleave (a single useEffect deps line and the regenerated bindings.ts both mix features), so they land as one commit rather than an artificial split into non-compiling intermediates.
  • State icons are generated in-process (desaturate + dim the bundled 128x128.png via Image::from_bytes / new_owned) rather than shipping extra PNGs — image-png is already enabled.
  • Manual runtime check (right-click → switch routing mode, watch icon change on connect/disconnect) is left to a desktop run; static + unit checks all pass.

@github-actions github-actions Bot added frontend React Web UI (frontend/) backend Rust core/backend/desktop (crates/, src-tauri/) labels Jul 1, 2026
@loss-and-quick
loss-and-quick force-pushed the feat/tray-context-menu-ux branch from 0803166 to 0ee3db5 Compare July 1, 2026 20:44
Borrow v2rayN's tray UX where it fits kasumi's TUN model:

- Routing-mode radio submenu (Rules/Global/Custom) that writes settings.routingMode; clicks route through the existing TrayAction catch-all as routing:<mode>.
- Live tooltip + state icon via a new lightweight set_tray_status command called each status tick; icon variants (colour/desaturated/muted) are derived at runtime from the bundled icon, so no new assets. Menu is rebuilt only on content changes, not per traffic tick; the icon only swaps on a state transition.
- Recent-profile entries show the last ping when available.

Reuses settings.routing* i18n keys and formatRate/testResults; no new locale keys.
@loss-and-quick
loss-and-quick force-pushed the feat/tray-context-menu-ux branch from 0ee3db5 to d1406f2 Compare August 18, 2026 19:11
The routing submenu writes settings.routingMode, which the running core
only picks up on restart. Overview says so in its banner; the tray said
nothing, so a mode switched from the tray looked applied while traffic
kept flowing under the old rules.
tray_icon ran inside set_tray_status, which fires on every status tick,
so a decode failure would panic in a command handler rather than leave
the tray on the icon it already had.
@loss-and-quick
loss-and-quick merged commit d05f7a8 into main Aug 18, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Rust core/backend/desktop (crates/, src-tauri/) frontend React Web UI (frontend/)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant