From 3e45ac3a694c20443eb13b12391d731e2b756fee Mon Sep 17 00:00:00 2001 From: chungquantin Date: Mon, 16 Feb 2026 17:26:58 +0700 Subject: [PATCH] chore: add key shortcut to quit the TUI --- src/tui.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/tui.rs b/src/tui.rs index 9a55a6c..d0a3979 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -5,7 +5,7 @@ use crate::providers::ProviderRegistry; use anyhow::Result; use chrono::{DateTime, Local, Utc}; use crossterm::cursor::{Hide, Show}; -use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind}; +use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers}; use crossterm::execute; use crossterm::terminal::{ EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode, @@ -44,6 +44,7 @@ pub async fn run_usage_watch( let ctrl_c = tokio::signal::ctrl_c(); tokio::pin!(ctrl_c); let mut needs_redraw = true; + let mut should_quit = false; loop { tokio::select! { @@ -65,14 +66,22 @@ pub async fn run_usage_watch( _ = ui_tick.tick() => { if event::poll(Duration::from_millis(0))? && let Event::Key(key) = event::read()? { - let tabs = build_account_tabs(&state.outputs); - if handle_key_event(key, &mut state, &tabs) { - needs_redraw = true; + if is_ctrl_c(key) { + should_quit = true; + } else { + let tabs = build_account_tabs(&state.outputs); + if handle_key_event(key, &mut state, &tabs) { + needs_redraw = true; + } } } } } + if should_quit { + break; + } + if needs_redraw { let tabs = build_account_tabs(&state.outputs); sync_active_tab(&mut state, &tabs); @@ -424,6 +433,12 @@ fn handle_key_event(key: KeyEvent, state: &mut LiveState, tabs: &[AccountTab]) - false } +fn is_ctrl_c(key: KeyEvent) -> bool { + key.kind == KeyEventKind::Press + && key.code == KeyCode::Char('c') + && key.modifiers.contains(KeyModifiers::CONTROL) +} + fn tab_key_for_payload(payload: &ProviderPayload) -> String { let account = resolve_account(payload).unwrap_or_else(|| "default".to_string()); format!("{}::{}", payload.provider, account)