mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-10 17:59:43 +08:00
117 lines
6.1 KiB
Rust
117 lines
6.1 KiB
Rust
use anyhow::Result;
|
|
use crossterm::{
|
|
event::{self, Event, KeyCode, KeyModifiers},
|
|
execute,
|
|
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
|
};
|
|
use ratatui::prelude::*;
|
|
use std::io;
|
|
use std::time::Duration;
|
|
|
|
use super::dashboard::Dashboard;
|
|
use crate::config::Config;
|
|
use crate::session::store::StateStore;
|
|
|
|
pub async fn run(db: StateStore, cfg: Config) -> Result<()> {
|
|
enable_raw_mode()?;
|
|
let mut stdout = io::stdout();
|
|
execute!(stdout, EnterAlternateScreen)?;
|
|
|
|
let backend = CrosstermBackend::new(stdout);
|
|
let mut terminal = Terminal::new(backend)?;
|
|
|
|
let mut dashboard = Dashboard::new(db, cfg);
|
|
|
|
loop {
|
|
terminal.draw(|frame| dashboard.render(frame))?;
|
|
|
|
if event::poll(Duration::from_millis(250))? {
|
|
if let Event::Key(key) = event::read()? {
|
|
if dashboard.is_input_mode() {
|
|
match (key.modifiers, key.code) {
|
|
(KeyModifiers::CONTROL, KeyCode::Char('c')) => break,
|
|
(_, KeyCode::Esc) => dashboard.cancel_input(),
|
|
(_, KeyCode::Enter) => dashboard.submit_input().await,
|
|
(_, KeyCode::Backspace) => dashboard.pop_input_char(),
|
|
(modifiers, KeyCode::Char(ch))
|
|
if !modifiers.contains(KeyModifiers::CONTROL)
|
|
&& !modifiers.contains(KeyModifiers::ALT) =>
|
|
{
|
|
dashboard.push_input_char(ch);
|
|
}
|
|
_ => {}
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
match (key.modifiers, key.code) {
|
|
(KeyModifiers::CONTROL, KeyCode::Char('c')) => break,
|
|
(_, KeyCode::Char('q')) => break,
|
|
(_, KeyCode::Tab) => dashboard.next_pane(),
|
|
(KeyModifiers::SHIFT, KeyCode::BackTab) => dashboard.prev_pane(),
|
|
(_, KeyCode::Char('+')) | (_, KeyCode::Char('=')) => {
|
|
dashboard.increase_pane_size()
|
|
}
|
|
(_, KeyCode::Char('-')) => dashboard.decrease_pane_size(),
|
|
(_, KeyCode::Char('j')) | (_, KeyCode::Down) => dashboard.scroll_down(),
|
|
(_, KeyCode::Char('k')) | (_, KeyCode::Up) => dashboard.scroll_up(),
|
|
(_, KeyCode::Char('[')) => dashboard.focus_previous_delegate(),
|
|
(_, KeyCode::Char(']')) => dashboard.focus_next_delegate(),
|
|
(_, KeyCode::Enter) => dashboard.open_focused_delegate(),
|
|
(_, KeyCode::Char('/')) => dashboard.begin_search(),
|
|
(_, KeyCode::Esc) => dashboard.clear_search(),
|
|
(_, KeyCode::Char('n')) if dashboard.has_active_search() => {
|
|
dashboard.next_search_match()
|
|
}
|
|
(_, KeyCode::Char('N')) if dashboard.has_active_search() => {
|
|
dashboard.prev_search_match()
|
|
}
|
|
(_, KeyCode::Char('N')) => dashboard.begin_spawn_prompt(),
|
|
(_, KeyCode::Char('n')) => dashboard.new_session().await,
|
|
(_, KeyCode::Char('a')) => dashboard.assign_selected().await,
|
|
(_, KeyCode::Char('b')) => dashboard.rebalance_selected_team().await,
|
|
(_, KeyCode::Char('B')) => dashboard.rebalance_all_teams().await,
|
|
(_, KeyCode::Char('i')) => dashboard.drain_inbox_selected().await,
|
|
(_, KeyCode::Char('I')) => dashboard.focus_next_approval_target(),
|
|
(_, KeyCode::Char('g')) => dashboard.auto_dispatch_backlog().await,
|
|
(_, KeyCode::Char('G')) => dashboard.coordinate_backlog().await,
|
|
(_, KeyCode::Char('h')) => dashboard.collapse_selected_pane(),
|
|
(_, KeyCode::Char('H')) => dashboard.restore_collapsed_panes(),
|
|
(_, KeyCode::Char('y')) => dashboard.toggle_timeline_mode(),
|
|
(_, KeyCode::Char('E')) => dashboard.cycle_timeline_event_filter(),
|
|
(_, KeyCode::Char('v')) => dashboard.toggle_output_mode(),
|
|
(_, KeyCode::Char('c')) => dashboard.toggle_conflict_protocol_mode(),
|
|
(_, KeyCode::Char('e')) => dashboard.toggle_output_filter(),
|
|
(_, KeyCode::Char('f')) => dashboard.cycle_output_time_filter(),
|
|
(_, KeyCode::Char('A')) => dashboard.toggle_search_scope(),
|
|
(_, KeyCode::Char('o')) => dashboard.toggle_search_agent_filter(),
|
|
(_, KeyCode::Char('m')) => dashboard.merge_selected_worktree().await,
|
|
(_, KeyCode::Char('M')) => dashboard.merge_ready_worktrees().await,
|
|
(_, KeyCode::Char('l')) => dashboard.cycle_pane_layout(),
|
|
(_, KeyCode::Char('T')) => dashboard.toggle_theme(),
|
|
(_, KeyCode::Char('p')) => dashboard.toggle_auto_dispatch_policy(),
|
|
(_, KeyCode::Char('t')) => dashboard.toggle_auto_worktree_policy(),
|
|
(_, KeyCode::Char('w')) => dashboard.toggle_auto_merge_policy(),
|
|
(_, KeyCode::Char(',')) => dashboard.adjust_auto_dispatch_limit(-1),
|
|
(_, KeyCode::Char('.')) => dashboard.adjust_auto_dispatch_limit(1),
|
|
(_, KeyCode::Char('s')) => dashboard.stop_selected().await,
|
|
(_, KeyCode::Char('u')) => dashboard.resume_selected().await,
|
|
(_, KeyCode::Char('x')) => dashboard.cleanup_selected_worktree().await,
|
|
(_, KeyCode::Char('X')) => dashboard.prune_inactive_worktrees().await,
|
|
(_, KeyCode::Char('d')) => dashboard.delete_selected_session().await,
|
|
(_, KeyCode::Char('r')) => dashboard.refresh(),
|
|
(_, KeyCode::Char('?')) => dashboard.toggle_help(),
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
|
|
dashboard.tick().await;
|
|
}
|
|
|
|
disable_raw_mode()?;
|
|
execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
|
|
Ok(())
|
|
}
|