feat: add archive
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
9ceaa4cd38
commit
56a63dbb7d
@ -25,6 +25,10 @@ pub enum Command {
|
|||||||
description: String,
|
description: String,
|
||||||
state: ItemState,
|
state: ItemState,
|
||||||
},
|
},
|
||||||
|
ToggleItem {
|
||||||
|
root: String,
|
||||||
|
path: Vec<String>,
|
||||||
|
},
|
||||||
Move {
|
Move {
|
||||||
root: String,
|
root: String,
|
||||||
src: Vec<String>,
|
src: Vec<String>,
|
||||||
@ -81,6 +85,9 @@ impl Commander {
|
|||||||
&src.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
&src.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||||
&dest.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
&dest.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||||
)?,
|
)?,
|
||||||
|
Command::ToggleItem { root, path } => self
|
||||||
|
.engine
|
||||||
|
.toggle_item(&root, &path.iter().map(|p| p.as_str()).collect::<Vec<_>>())?,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.storage.store(&self.engine)?;
|
self.storage.store(&self.engine)?;
|
||||||
|
@ -2,7 +2,7 @@ use std::{collections::BTreeMap, fmt::Display};
|
|||||||
|
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
|
|
||||||
use crate::log::{Graph, GraphItem};
|
use crate::log::{Graph, GraphItem, ItemState};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Engine {
|
pub struct Engine {
|
||||||
@ -129,6 +129,22 @@ impl Engine {
|
|||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.ok_or(anyhow!("item was not found"))
|
.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 {
|
impl Display for Engine {
|
||||||
|
@ -43,4 +43,10 @@ impl SharedEngine {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.section_move(root, src_path, dest_path)
|
.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(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,12 +63,15 @@ impl<'a> App<'a> {
|
|||||||
graph_explorer: GraphExplorer<'a>,
|
graph_explorer: GraphExplorer<'a>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
state,
|
||||||
root: root.into(),
|
root: root.into(),
|
||||||
mode: Mode::View,
|
|
||||||
dialog: None,
|
dialog: None,
|
||||||
command: None,
|
command: None,
|
||||||
state,
|
|
||||||
graph_explorer,
|
graph_explorer,
|
||||||
|
|
||||||
|
mode: Mode::View,
|
||||||
focus: AppFocus::Graph,
|
focus: AppFocus::Graph,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,6 +112,7 @@ impl<'a> App<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if command.is_quit() {
|
if command.is_quit() {
|
||||||
|
self.focus = AppFocus::Graph;
|
||||||
self.dialog = None;
|
self.dialog = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,6 +142,7 @@ impl<'a> App<'a> {
|
|||||||
let root = self.root.clone();
|
let root = self.root.clone();
|
||||||
let path = self.graph_explorer.get_current_path();
|
let path = self.graph_explorer.get_current_path();
|
||||||
|
|
||||||
|
self.focus = AppFocus::Dialog;
|
||||||
self.dialog = Some(Dialog::CreateItem {
|
self.dialog = Some(Dialog::CreateItem {
|
||||||
state: CreateItemState::new(root, path),
|
state: CreateItemState::new(root, path),
|
||||||
});
|
});
|
||||||
@ -151,7 +156,7 @@ impl<'a> Widget for &mut App<'a> {
|
|||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
StatefulWidget::render(
|
StatefulWidget::render(
|
||||||
GraphExplorer::new(self.state.clone()),
|
GraphExplorer::new(self.root.clone(), self.state.clone()),
|
||||||
area,
|
area,
|
||||||
buf,
|
buf,
|
||||||
&mut self.graph_explorer.inner,
|
&mut self.graph_explorer.inner,
|
||||||
|
@ -5,7 +5,7 @@ use hyperlog_core::log::GraphItem;
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use ratatui::{prelude::*, widgets::*};
|
use ratatui::{prelude::*, widgets::*};
|
||||||
|
|
||||||
use crate::{command_parser::Commands, state::SharedState};
|
use crate::{command_parser::Commands, commands::Command, state::SharedState};
|
||||||
|
|
||||||
pub struct GraphExplorer<'a> {
|
pub struct GraphExplorer<'a> {
|
||||||
state: SharedState,
|
state: SharedState,
|
||||||
@ -14,17 +14,20 @@ pub struct GraphExplorer<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct GraphExplorerState<'a> {
|
pub struct GraphExplorerState<'a> {
|
||||||
|
root: String,
|
||||||
|
|
||||||
current_path: Option<&'a str>,
|
current_path: Option<&'a str>,
|
||||||
current_position: Vec<usize>,
|
current_position: Vec<usize>,
|
||||||
|
|
||||||
graph: Option<GraphItem>,
|
graph: Option<GraphItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GraphExplorer<'_> {
|
impl<'a> GraphExplorer<'a> {
|
||||||
pub fn new(state: SharedState) -> Self {
|
pub fn new(root: String, state: SharedState) -> Self {
|
||||||
Self {
|
Self {
|
||||||
state,
|
state,
|
||||||
inner: GraphExplorerState::<'_> {
|
inner: GraphExplorerState::<'a> {
|
||||||
|
root,
|
||||||
current_path: None,
|
current_path: None,
|
||||||
current_position: Vec::new(),
|
current_position: Vec::new(),
|
||||||
graph: None,
|
graph: None,
|
||||||
@ -151,6 +154,13 @@ impl GraphExplorer<'_> {
|
|||||||
pub(crate) fn interact(&mut self) -> anyhow::Result<()> {
|
pub(crate) fn interact(&mut self) -> anyhow::Result<()> {
|
||||||
if !self.get_current_path().is_empty() {
|
if !self.get_current_path().is_empty() {
|
||||||
tracing::info!("toggling state of items");
|
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(())
|
Ok(())
|
||||||
|
@ -39,10 +39,12 @@ pub async fn execute(state: State) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(terminal: &mut Terminal<CrosstermBackend<Stdout>>, state: SharedState) -> Result<()> {
|
fn run(terminal: &mut Terminal<CrosstermBackend<Stdout>>, 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()?;
|
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 {
|
loop {
|
||||||
terminal.draw(|f| render_app(f, &mut app))?;
|
terminal.draw(|f| render_app(f, &mut app))?;
|
||||||
|
Loading…
Reference in New Issue
Block a user