use super::event::{AppActionEvent, AppEvent, ScrollDir};
use super::{AppTx, ExitTx};
use crate::Result;
use crate::exec::{ExecActionEvent, ExecutorTx};
use crate::hub::HubEvent;
use crate::model::{LogBmc, LogForCreate, LogKind, ModelEvent, ModelManager};
use crossterm::event::{Event, KeyCode, KeyEventKind, KeyModifiers};
use ratatui::DefaultTerminal;
pub async fn handle_app_event(
terminal: &mut DefaultTerminal,
mm: &ModelManager,
executor_tx: &ExecutorTx,
app_tx: &AppTx,
exit_tx: &ExitTx,
app_event: &AppEvent,
) -> Result<()> {
match app_event {
AppEvent::DoRedraw => (), AppEvent::Tick(_ts) => (),
AppEvent::Term(term_event) => {
handle_term_event(term_event, app_tx).await?;
}
AppEvent::Action(action_event) => {
handle_action_event(action_event, terminal, executor_tx, exit_tx).await?;
}
AppEvent::Model(model_event) => {
handle_model_event(model_event).await?;
}
AppEvent::Hub(hub_event) => {
handle_hub_event(mm, hub_event).await?;
}
};
Ok(())
}
async fn handle_term_event(term_event: &Event, app_tx: &AppTx) -> Result<()> {
if let Event::Key(key) = term_event
&& let KeyEventKind::Press = key.kind
{
let mod_ctrl = key.modifiers.contains(KeyModifiers::CONTROL);
let mod_shift = key.modifiers.contains(KeyModifiers::SHIFT);
match (key.code, mod_ctrl, mod_shift) {
(KeyCode::Char('q'), _, _) | (KeyCode::Char('c'), true, _) => app_tx.send(AppActionEvent::Quit).await?,
(KeyCode::Char('r'), _, _) => app_tx.send(AppActionEvent::Redo).await?,
(KeyCode::Char('x'), _, _) => app_tx.send(AppActionEvent::CancelRun).await?,
(KeyCode::Up, _, true) | (KeyCode::Home, _, _) => {
app_tx.send(AppActionEvent::ScrollToEnd(ScrollDir::Up)).await?
}
(KeyCode::Down, _, true) | (KeyCode::End, _, _) => {
app_tx.send(AppActionEvent::ScrollToEnd(ScrollDir::Down)).await?
}
(KeyCode::PageUp, _, _) => app_tx.send(AppActionEvent::ScrollPage(ScrollDir::Up)).await?,
(KeyCode::PageDown, _, _) => app_tx.send(AppActionEvent::ScrollPage(ScrollDir::Down)).await?,
(KeyCode::Up, _, false) => app_tx.send(AppActionEvent::Scroll(ScrollDir::Up)).await?,
(KeyCode::Down, _, false) => app_tx.send(AppActionEvent::Scroll(ScrollDir::Down)).await?,
_ => (),
}
}
Ok(())
}
async fn handle_action_event(
action_event: &AppActionEvent,
_terminal: &mut DefaultTerminal,
executor_tx: &ExecutorTx,
_exit_tx: &ExitTx,
) -> Result<()> {
match action_event {
AppActionEvent::Quit => {
}
AppActionEvent::Redo => {
executor_tx.send(ExecActionEvent::Redo).await;
}
AppActionEvent::CancelRun => {
executor_tx.send(ExecActionEvent::CancelRun).await;
}
AppActionEvent::Scroll(_) => (),
AppActionEvent::ScrollPage(_) => (),
AppActionEvent::ScrollToEnd(_) => (),
AppActionEvent::WorkConfirm(id) => {
executor_tx.send(ExecActionEvent::WorkConfirm(*id)).await;
}
AppActionEvent::WorkCancel(id) => {
executor_tx.send(ExecActionEvent::WorkCancel(*id)).await;
}
AppActionEvent::Run(run_args) => {
executor_tx.send(ExecActionEvent::Run(run_args.clone())).await;
}
}
Ok(())
}
async fn handle_model_event(_model_event: &ModelEvent) -> Result<()> {
Ok(())
}
#[allow(clippy::single_match)]
async fn handle_hub_event(mm: &ModelManager, hub_event: &HubEvent) -> Result<()> {
match hub_event {
HubEvent::Message(_msg) => {
}
HubEvent::LuaPrint(_msg) => {
}
HubEvent::Error { error } => {
LogBmc::create(
mm,
LogForCreate {
run_id: 0.into(),
task_id: None,
kind: Some(LogKind::SysError),
step: None,
stage: None,
message: Some(error.to_string()),
},
)?;
}
_ => (),
};
Ok(())
}