theater_cli/tui/event_explorer/
input.rs

1use crate::error::CliResult;
2use crossterm::event::{self, Event, KeyCode, KeyModifiers};
3
4#[derive(Debug)]
5pub enum ExplorerAction {
6    Quit,
7    NavigateUp,
8    NavigateDown,
9    PageUp,
10    PageDown,
11    ScrollDetailUp,
12    ScrollDetailDown,
13    ScrollDetailPageUp,
14    ScrollDetailPageDown,
15    ToggleDetailMode,
16    ShowHelp,
17    TogglePause,
18    ToggleFollow,
19    StartSearch,
20    ClearSearch,
21    StartFilter,
22    ExportEvent,
23    CopyToClipboard,
24    None,
25}
26
27pub fn handle_input() -> CliResult<ExplorerAction> {
28    if event::poll(std::time::Duration::from_millis(100)).map_err(|e| {
29        crate::error::CliError::Internal(anyhow::anyhow!("Failed to poll for input: {}", e))
30    })? {
31        if let Event::Key(key) = event::read().map_err(|e| {
32            crate::error::CliError::Internal(anyhow::anyhow!("Failed to read input: {}", e))
33        })? {
34            return Ok(match key.code {
35                KeyCode::Char('q') | KeyCode::Esc => ExplorerAction::Quit,
36                KeyCode::Up | KeyCode::Char('k') => ExplorerAction::NavigateUp,
37                KeyCode::Down | KeyCode::Char('j') => ExplorerAction::NavigateDown,
38                KeyCode::PageUp => ExplorerAction::PageUp,
39                KeyCode::PageDown => ExplorerAction::PageDown,
40                KeyCode::Char('u') if key.modifiers.contains(KeyModifiers::CONTROL) => {
41                    ExplorerAction::ScrollDetailPageUp
42                }
43                KeyCode::Char('d') if key.modifiers.contains(KeyModifiers::CONTROL) => {
44                    ExplorerAction::ScrollDetailPageDown
45                }
46                KeyCode::Left => ExplorerAction::ScrollDetailUp,
47                KeyCode::Right => ExplorerAction::ScrollDetailDown,
48                KeyCode::Tab => ExplorerAction::ToggleDetailMode,
49                KeyCode::Char('h') | KeyCode::F(1) => ExplorerAction::ShowHelp,
50                KeyCode::Char('p') => ExplorerAction::TogglePause,
51                KeyCode::Char(' ') => ExplorerAction::ToggleFollow,
52                KeyCode::Char('/') => ExplorerAction::StartSearch,
53                KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => {
54                    ExplorerAction::ClearSearch
55                }
56                KeyCode::Char('f') => ExplorerAction::StartFilter,
57                KeyCode::Char('e') if key.modifiers.contains(KeyModifiers::CONTROL) => {
58                    ExplorerAction::ExportEvent
59                }
60                KeyCode::Char('y') => ExplorerAction::CopyToClipboard,
61                _ => ExplorerAction::None,
62            });
63        }
64    }
65    Ok(ExplorerAction::None)
66}
67
68pub const HELP_TEXT: &str = r#"
69Theater Event Explorer - Keyboard Controls
70
71Navigation:
72  ↑/k          Move up in event list
73  ↓/j          Move down in event list  
74  Page Up/Down Page through events
75  
76Detail Panel Scrolling:
77  ←/→          Scroll detail content up/down
78  Ctrl+U/D     Page up/down in detail content
79  
80Detail Views:
81  Tab          Cycle through detail modes:
82               Overview → Data → Raw → Chain
83               • Overview: Metadata + data preview
84               • Data: Full stringified/JSON content  
85               • Raw: Hex dump with ASCII
86               • Chain: Parent/child relationships
87  
88Filtering & Search:
89  f            Open filter dialog (future)
90  /            Start search mode (future)
91  Ctrl+C       Clear current search/filter
92  
93Live Mode:
94  p            Pause/resume live updates
95  Space        Toggle auto-scroll (follow mode)
96  
97Export & Clipboard:
98  Ctrl+E       Export selected event (future)
99  y            Copy event data to clipboard (future)
100  
101Other:
102  h/?/F1       Show/hide this help
103  q/Esc        Quit explorer
104
105Phase 1 Implementation:
106- Basic navigation and detail view cycling
107- Help system
108- Live mode controls (if --live)
109"#;