Implement chat and markdown views, enhance status bar, and add workflow panel
- Added `chat.rs` for rendering chat messages with timestamps and roles. - Introduced `markdown.rs` for rendering markdown content with styling. - Created `status.rs` to display the application status bar with session and message counts. - Developed `workflow.rs` to show the current workflow status, including tool calls and active jobs. - Established a `theme.rs` for centralized color management across the UI. - Updated `mod.rs` to include new modules and manage rendering logic.
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
||||
|
||||
use crate::app::runtime::actions::Action;
|
||||
use crate::app::state::rest::AppStateRest;
|
||||
use crate::app::state::types::Overlay;
|
||||
|
||||
pub fn handle_key(key: KeyEvent, state: &AppStateRest) -> Vec<Action> {
|
||||
match key.code {
|
||||
KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::QuitConfirm]
|
||||
}
|
||||
KeyCode::Char('d') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::CloseOverlay]
|
||||
}
|
||||
KeyCode::Enter => {
|
||||
if state.misc.overlay.is_active() {
|
||||
return handle_overlay_enter(state);
|
||||
}
|
||||
let text = state.input.buffer.clone();
|
||||
if text.starts_with('/') {
|
||||
return Vec::new();
|
||||
}
|
||||
vec![Action::SubmitInput(text)]
|
||||
}
|
||||
KeyCode::Backspace => {
|
||||
vec![Action::DeleteChar]
|
||||
}
|
||||
KeyCode::Delete => {
|
||||
vec![Action::DeleteCharRight]
|
||||
}
|
||||
KeyCode::Left => {
|
||||
vec![Action::CursorLeft]
|
||||
}
|
||||
KeyCode::Right => {
|
||||
vec![Action::CursorRight]
|
||||
}
|
||||
KeyCode::Up => {
|
||||
vec![Action::HistoryUp]
|
||||
}
|
||||
KeyCode::Down => {
|
||||
vec![Action::HistoryDown]
|
||||
}
|
||||
KeyCode::PageUp => {
|
||||
vec![Action::ScrollUp]
|
||||
}
|
||||
KeyCode::PageDown => {
|
||||
vec![Action::ScrollDown]
|
||||
}
|
||||
KeyCode::Char('h') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::OpenOverlay(Overlay::Help)]
|
||||
}
|
||||
KeyCode::Char('p') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::OpenOverlay(Overlay::Settings)]
|
||||
}
|
||||
KeyCode::Char('a') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::ToggleYoloArm]
|
||||
}
|
||||
KeyCode::Char('b') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::OpenOverlay(Overlay::Bash)]
|
||||
}
|
||||
KeyCode::Char('s') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::OpenOverlay(Overlay::SessionHub)]
|
||||
}
|
||||
KeyCode::Char('t') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::OpenOverlay(Overlay::Todo)]
|
||||
}
|
||||
KeyCode::Char('w') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::OpenOverlay(Overlay::Workflow)]
|
||||
}
|
||||
KeyCode::Char('k') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::OpenOverlay(Overlay::KeyInput)]
|
||||
}
|
||||
KeyCode::Esc => {
|
||||
if state.misc.overlay.is_active() {
|
||||
vec![Action::CloseOverlay]
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
KeyCode::Tab => {
|
||||
Vec::new()
|
||||
}
|
||||
KeyCode::Char('l') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::OpenOverlay(Overlay::Learning)]
|
||||
}
|
||||
KeyCode::Char('u') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
vec![Action::OpenOverlay(Overlay::Usage)]
|
||||
}
|
||||
KeyCode::Char(c) => {
|
||||
vec![Action::InsertChar(c)]
|
||||
}
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_overlay_enter(state: &AppStateRest) -> Vec<Action> {
|
||||
match state.misc.overlay {
|
||||
Overlay::QuitConfirm => {
|
||||
vec![Action::ForceQuit]
|
||||
}
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user