mirror of
https://github.com/kdheepak/taskwarrior-tui.git
synced 2025-08-23 20:16:41 +02:00
WIP
This commit is contained in:
parent
1ec93c0913
commit
0c9b3b03dc
5 changed files with 56 additions and 55 deletions
|
@ -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)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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>> {
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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(())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue