This commit is contained in:
Dheepak Krishnamurthy 2023-09-25 05:27:20 -04:00
parent 1ec93c0913
commit 0c9b3b03dc
5 changed files with 56 additions and 55 deletions

View file

@ -1,27 +1,38 @@
use color_eyre::eyre::Result;
use serde_derive::{Deserialize, Serialize};
use tokio::sync::mpsc;
use crate::{
command::Command,
components::{app::App, Component},
components::{task_report::TaskReport, Component},
config::Config,
tui,
};
pub struct Runner {
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Mode {
#[default]
TaskReport,
TaskContext,
Calendar,
Error,
}
pub struct App {
pub config: Config,
pub tick_rate: f64,
pub frame_rate: f64,
pub components: Vec<Box<dyn Component>>,
pub should_quit: bool,
pub should_suspend: bool,
pub mode: Mode,
}
impl Runner {
impl App {
pub fn new(tick_rate: f64, frame_rate: f64) -> Result<Self> {
let app = App::new();
let app = TaskReport::new();
let config = Config::new()?;
let app = app.keybindings(config.keybindings.clone());
let mode = Mode::TaskReport;
Ok(Self {
tick_rate,
frame_rate,
@ -29,6 +40,7 @@ impl Runner {
should_quit: false,
should_suspend: false,
config,
mode,
})
}
@ -44,6 +56,10 @@ impl Runner {
component.register_command_handler(command_tx.clone())?;
}
for component in self.components.iter_mut() {
component.register_config_handler(self.config.clone())?;
}
for component in self.components.iter_mut() {
component.init()?;
}
@ -55,13 +71,19 @@ impl Runner {
tui::Event::Tick => command_tx.send(Command::Tick)?,
tui::Event::Render => command_tx.send(Command::Render)?,
tui::Event::Resize(x, y) => command_tx.send(Command::Resize(x, y))?,
e => {
for component in self.components.iter_mut() {
if let Some(command) = component.handle_events(Some(e.clone()))? {
command_tx.send(command)?;
}
}
tui::Event::Key(key) => {
let command = if let Some(keymap) = self.config.keybindings.get(&self.mode) {
if let Some(command) = keymap.get(&vec![key]) {
command_tx.send(command.clone())?;
};
};
},
_ => {},
}
for component in self.components.iter_mut() {
if let Some(command) = component.handle_events(Some(e.clone()))? {
command_tx.send(command)?;
}
}
}

View file

@ -5,16 +5,21 @@ use tokio::sync::mpsc::UnboundedSender;
use crate::{
command::Command,
config::Config,
tui::{Event, Frame},
};
pub mod app;
pub mod task_report;
pub trait Component {
#[allow(unused_variables)]
fn register_command_handler(&mut self, tx: UnboundedSender<Command>) -> Result<()> {
Ok(())
}
#[allow(unused_variables)]
fn register_config_handler(&mut self, config: Config) -> Result<()> {
Ok(())
}
fn init(&mut self) -> Result<()> {
Ok(())
}

View file

@ -10,22 +10,15 @@ use tui_input::backend::crossterm::EventHandler;
use uuid::Uuid;
use super::{Component, Frame};
use crate::{command::Command, config::KeyBindings};
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Mode {
#[default]
TaskReport,
TaskContext,
Calendar,
Error,
}
use crate::{
command::Command,
config::{Config, KeyBindings},
};
#[derive(Default)]
pub struct App {
pub mode: Mode,
pub struct TaskReport {
pub config: Config,
pub command_tx: Option<UnboundedSender<Command>>,
pub keybindings: KeyBindings,
pub last_export: Option<std::time::SystemTime>,
pub report: String,
pub filter: String,
@ -33,16 +26,11 @@ pub struct App {
pub tasks: Vec<Task>,
}
impl App {
impl TaskReport {
pub fn new() -> Self {
Self::default()
}
pub fn keybindings(mut self, keybindings: KeyBindings) -> Self {
self.keybindings = keybindings;
self
}
pub fn refresh(&mut self) -> Result<()> {
self.last_export = Some(std::time::SystemTime::now());
Ok(())
@ -93,39 +81,25 @@ impl App {
if let Ok(imported) = import(data.as_bytes()) {
self.tasks = imported;
log::info!("Imported {} tasks", self.tasks.len());
if self.mode == Mode::Error {
self.send_command(Command::ShowTaskReport)?;
};
// } else {
// self.error = Some(format!("Unable to parse output of `{:?}`:\n`{:?}`", task, data));
// self.mode = Mode::Tasks(Action::Error);
// debug!("Unable to parse output: {:?}", data);
self.send_command(Command::ShowTaskReport)?;
}
} else {
// self.error = Some(format!("Cannot run `{:?}` - ({}) error:\n{}", &task, output.status, error));
self.send_command(Command::Error(format!("Unable to parse output of `{:?}`:\n`{:?}`", task, data)))?;
}
Ok(())
}
}
impl Component for App {
impl Component for TaskReport {
fn register_command_handler(&mut self, tx: UnboundedSender<Command>) -> Result<()> {
self.command_tx = Some(tx);
Ok(())
}
fn handle_key_events(&mut self, key: KeyEvent) -> Result<Option<Command>> {
let command = if let Some(keymap) = self.keybindings.get(&self.mode) {
if let Some(command) = keymap.get(&vec![key]) {
command
} else {
return Ok(None);
}
} else {
return Ok(None);
};
Ok(Some(command.clone()))
fn register_config_handler(&mut self, config: Config) -> Result<()> {
self.config = config;
Ok(())
}
fn update(&mut self, command: Command) -> Result<Option<Command>> {

View file

@ -7,7 +7,7 @@ use ratatui::style::{Color, Modifier, Style};
use serde::de::{self, Deserialize, Deserializer, MapAccess, Visitor};
use serde_derive::Deserialize;
use crate::{command::Command, components::app::Mode};
use crate::{app::Mode, command::Command};
const CONFIG: &'static str = include_str!("../.config/config.json5");

View file

@ -2,11 +2,11 @@
#![allow(unused_imports)]
#![allow(unused_variables)]
pub mod app;
pub mod cli;
pub mod command;
pub mod components;
pub mod config;
pub mod runner;
pub mod tui;
pub mod utils;
@ -15,7 +15,7 @@ use cli::Cli;
use color_eyre::eyre::Result;
use crate::{
runner::Runner,
app::App,
utils::{initialize_logging, initialize_panic_handler, version},
};
@ -25,7 +25,7 @@ async fn tokio_main() -> Result<()> {
initialize_panic_handler()?;
let args = Cli::parse();
let mut runner = Runner::new(args.tick_rate, args.frame_rate)?;
let mut runner = App::new(args.tick_rate, args.frame_rate)?;
runner.run().await?;
Ok(())