diff --git a/crates/hyperlog-core/src/commander.rs b/crates/hyperlog-core/src/commander.rs index dc7e599..64a5fa7 100644 --- a/crates/hyperlog-core/src/commander.rs +++ b/crates/hyperlog-core/src/commander.rs @@ -25,6 +25,10 @@ pub enum Command { description: String, state: ItemState, }, + ToggleItem { + root: String, + path: Vec, + }, Move { root: String, src: Vec, @@ -81,6 +85,9 @@ impl Commander { &src.iter().map(|p| p.as_str()).collect::>(), &dest.iter().map(|p| p.as_str()).collect::>(), )?, + Command::ToggleItem { root, path } => self + .engine + .toggle_item(&root, &path.iter().map(|p| p.as_str()).collect::>())?, } self.storage.store(&self.engine)?; diff --git a/crates/hyperlog-core/src/engine.rs b/crates/hyperlog-core/src/engine.rs index 9816b49..2b89077 100644 --- a/crates/hyperlog-core/src/engine.rs +++ b/crates/hyperlog-core/src/engine.rs @@ -2,7 +2,7 @@ use std::{collections::BTreeMap, fmt::Display}; use anyhow::{anyhow, Context}; -use crate::log::{Graph, GraphItem}; +use crate::log::{Graph, GraphItem, ItemState}; #[derive(Default)] pub struct Engine { @@ -129,6 +129,22 @@ impl Engine { .map(|_| ()) .ok_or(anyhow!("item was not found")) } + + pub fn toggle_item(&mut self, root: &str, path: &[&str]) -> anyhow::Result<()> { + if let Some(item) = self.get_mut(root, path) { + match item { + GraphItem::Item { state, .. } => match state { + ItemState::NotDone => *state = ItemState::Done, + ItemState::Done => *state = ItemState::NotDone, + }, + _ => { + anyhow::bail!("{}.{:?} is not an item", root, path) + } + } + } + + Ok(()) + } } impl Display for Engine { diff --git a/crates/hyperlog-core/src/shared_engine.rs b/crates/hyperlog-core/src/shared_engine.rs index bb53bda..d5edab2 100644 --- a/crates/hyperlog-core/src/shared_engine.rs +++ b/crates/hyperlog-core/src/shared_engine.rs @@ -43,4 +43,10 @@ impl SharedEngine { .unwrap() .section_move(root, src_path, dest_path) } + + pub fn toggle_item(&self, root: &str, path: &[&str]) -> anyhow::Result<()> { + self.inner.write().unwrap().toggle_item(root, path)?; + + Ok(()) + } } diff --git a/crates/hyperlog-tui/src/app.rs b/crates/hyperlog-tui/src/app.rs index b9bdde0..ca51b0f 100644 --- a/crates/hyperlog-tui/src/app.rs +++ b/crates/hyperlog-tui/src/app.rs @@ -63,12 +63,15 @@ impl<'a> App<'a> { graph_explorer: GraphExplorer<'a>, ) -> Self { Self { + state, root: root.into(), - mode: Mode::View, + dialog: None, command: None, - state, + graph_explorer, + + mode: Mode::View, focus: AppFocus::Graph, } } @@ -109,6 +112,7 @@ impl<'a> App<'a> { } if command.is_quit() { + self.focus = AppFocus::Graph; self.dialog = None; } } @@ -138,6 +142,7 @@ impl<'a> App<'a> { let root = self.root.clone(); let path = self.graph_explorer.get_current_path(); + self.focus = AppFocus::Dialog; self.dialog = Some(Dialog::CreateItem { state: CreateItemState::new(root, path), }); @@ -151,7 +156,7 @@ impl<'a> Widget for &mut App<'a> { Self: Sized, { StatefulWidget::render( - GraphExplorer::new(self.state.clone()), + GraphExplorer::new(self.root.clone(), self.state.clone()), area, buf, &mut self.graph_explorer.inner, diff --git a/crates/hyperlog-tui/src/components.rs b/crates/hyperlog-tui/src/components.rs index 72473e1..3f5767d 100644 --- a/crates/hyperlog-tui/src/components.rs +++ b/crates/hyperlog-tui/src/components.rs @@ -5,7 +5,7 @@ use hyperlog_core::log::GraphItem; use itertools::Itertools; use ratatui::{prelude::*, widgets::*}; -use crate::{command_parser::Commands, state::SharedState}; +use crate::{command_parser::Commands, commands::Command, state::SharedState}; pub struct GraphExplorer<'a> { state: SharedState, @@ -14,17 +14,20 @@ pub struct GraphExplorer<'a> { } pub struct GraphExplorerState<'a> { + root: String, + current_path: Option<&'a str>, current_position: Vec, graph: Option, } -impl GraphExplorer<'_> { - pub fn new(state: SharedState) -> Self { +impl<'a> GraphExplorer<'a> { + pub fn new(root: String, state: SharedState) -> Self { Self { state, - inner: GraphExplorerState::<'_> { + inner: GraphExplorerState::<'a> { + root, current_path: None, current_position: Vec::new(), graph: None, @@ -151,6 +154,13 @@ impl GraphExplorer<'_> { pub(crate) fn interact(&mut self) -> anyhow::Result<()> { if !self.get_current_path().is_empty() { tracing::info!("toggling state of items"); + + self.state + .commander + .execute(hyperlog_core::commander::Command::ToggleItem { + root: self.inner.root.to_string(), + path: self.get_current_path(), + })?; } Ok(()) diff --git a/crates/hyperlog-tui/src/lib.rs b/crates/hyperlog-tui/src/lib.rs index a7987b1..335f4d8 100644 --- a/crates/hyperlog-tui/src/lib.rs +++ b/crates/hyperlog-tui/src/lib.rs @@ -39,10 +39,12 @@ pub async fn execute(state: State) -> Result<()> { } fn run(terminal: &mut Terminal>, state: SharedState) -> Result<()> { - let mut graph_explorer = GraphExplorer::new(state.clone()); + let root = "kjuulh".to_string(); + + let mut graph_explorer = GraphExplorer::new(root.clone(), state.clone()); graph_explorer.update_graph()?; - let mut app = App::new("kjuulh", state.clone(), graph_explorer); + let mut app = App::new(&root, state.clone(), graph_explorer); loop { terminal.draw(|f| render_app(f, &mut app))?;