chore: fix test breaking changes
All checks were successful
continuous-integration/drone/push Build is passing

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
2024-05-10 12:03:38 +02:00
parent f284171f5a
commit 86310c6764
13 changed files with 763 additions and 270 deletions

View File

@@ -1,4 +1,3 @@
use itertools::Itertools;
use ratatui::{prelude::*, widgets::*};
use crate::models::{EditMsg, Msg};
@@ -74,7 +73,16 @@ pub struct InputBuffer {
}
impl InputBuffer {
fn transform_focused(&mut self) {
pub fn new(input: String) -> Self {
Self {
state: BufferState::Static {
content: input,
position: 0,
},
}
}
pub fn transform_focused(&mut self) {
match &mut self.state {
BufferState::Focused { .. } => {}
BufferState::Static { content, position } => {
@@ -136,6 +144,14 @@ impl InputBuffer {
BufferState::Static { content, .. } => content.to_owned(),
}
}
fn set_position(&mut self, title_len: usize) {
match &mut self.state {
BufferState::Focused { position, .. } | BufferState::Static { position, .. } => {
*position = title_len
}
}
}
}
pub struct InputField<'a> {
@@ -189,110 +205,5 @@ fn clamp_x(area: &Rect, x: u16) -> u16 {
}
}
enum CreateItemFocused {
Title,
Description,
}
impl Default for CreateItemFocused {
fn default() -> Self {
Self::Title
}
}
pub struct CreateItemState {
root: String,
path: Vec<String>,
title: InputBuffer,
description: InputBuffer,
focused: CreateItemFocused,
}
impl CreateItemState {
pub fn new(root: impl Into<String>, path: impl IntoIterator<Item = impl Into<String>>) -> Self {
let root = root.into();
let path = path.into_iter().map(|p| p.into()).collect_vec();
Self {
root,
path,
title: Default::default(),
description: Default::default(),
focused: Default::default(),
}
}
pub fn update(&mut self, msg: &Msg) -> anyhow::Result<()> {
match &msg {
Msg::MoveDown | Msg::MoveUp => match self.focused {
CreateItemFocused::Title => self.focused = CreateItemFocused::Description,
CreateItemFocused::Description => self.focused = CreateItemFocused::Title,
},
_ => {}
}
match self.focused {
CreateItemFocused::Title => {
self.title.update(msg)?;
}
CreateItemFocused::Description => {
self.description.update(msg)?;
}
}
Ok(())
}
pub fn get_command(&self) -> Option<hyperlog_core::commander::Command> {
let title = self.title.string();
let description = self.description.string();
if !title.is_empty() {
let mut path = self.path.clone();
path.push(title.replace([' ', '.'], "-"));
Some(hyperlog_core::commander::Command::CreateItem {
root: self.root.clone(),
path,
title: title.trim().into(),
description: description.trim().into(),
state: hyperlog_core::log::ItemState::NotDone,
})
} else {
None
}
}
}
#[derive(Default)]
pub struct CreateItem {}
impl StatefulWidget for &mut CreateItem {
type State = CreateItemState;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let chunks = Layout::vertical(vec![
Constraint::Length(2),
Constraint::Length(3),
Constraint::Length(3),
])
.split(area);
let path = format!("path: {}.{}", state.root, state.path.join("."));
let path_header = Paragraph::new(path).dark_gray();
path_header.render(chunks[0], buf);
let mut title_input = InputField::new("title");
let mut description_input = InputField::new("description");
match state.focused {
CreateItemFocused::Title => title_input.focused = true,
CreateItemFocused::Description => description_input.focused = true,
}
title_input.render(chunks[1], buf, &mut state.title);
description_input.render(chunks[2], buf, &mut state.description);
}
}
pub mod create_item;
pub mod edit_item;

View File

@@ -0,0 +1,114 @@
use itertools::Itertools;
use ratatui::{prelude::*, widgets::*};
use crate::models::Msg;
use super::{InputBuffer, InputField};
enum CreateItemFocused {
Title,
Description,
}
impl Default for CreateItemFocused {
fn default() -> Self {
Self::Title
}
}
pub struct CreateItemState {
root: String,
path: Vec<String>,
title: InputBuffer,
description: InputBuffer,
focused: CreateItemFocused,
}
impl CreateItemState {
pub fn new(root: impl Into<String>, path: impl IntoIterator<Item = impl Into<String>>) -> Self {
let root = root.into();
let path = path.into_iter().map(|p| p.into()).collect_vec();
Self {
root,
path,
title: Default::default(),
description: Default::default(),
focused: Default::default(),
}
}
pub fn update(&mut self, msg: &Msg) -> anyhow::Result<()> {
match &msg {
Msg::MoveDown | Msg::MoveUp => match self.focused {
CreateItemFocused::Title => self.focused = CreateItemFocused::Description,
CreateItemFocused::Description => self.focused = CreateItemFocused::Title,
},
_ => {}
}
match self.focused {
CreateItemFocused::Title => {
self.title.update(msg)?;
}
CreateItemFocused::Description => {
self.description.update(msg)?;
}
}
Ok(())
}
pub fn get_command(&self) -> Option<hyperlog_core::commander::Command> {
let title = self.title.string();
let description = self.description.string();
if !title.is_empty() {
let mut path = self.path.clone();
path.push(title.replace([' ', '.'], "-"));
Some(hyperlog_core::commander::Command::CreateItem {
root: self.root.clone(),
path,
title: title.trim().into(),
description: description.trim().into(),
state: hyperlog_core::log::ItemState::NotDone,
})
} else {
None
}
}
}
#[derive(Default)]
pub struct CreateItem {}
impl StatefulWidget for &mut CreateItem {
type State = CreateItemState;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let chunks = Layout::vertical(vec![
Constraint::Length(2),
Constraint::Length(3),
Constraint::Length(3),
])
.split(area);
let path = format!("path: {}.{}", state.root, state.path.join("."));
let path_header = Paragraph::new(path).dark_gray();
path_header.render(chunks[0], buf);
let mut title_input = InputField::new("title");
let mut description_input = InputField::new("description");
match state.focused {
CreateItemFocused::Title => title_input.focused = true,
CreateItemFocused::Description => description_input.focused = true,
}
title_input.render(chunks[1], buf, &mut state.title);
description_input.render(chunks[2], buf, &mut state.description);
}
}

View File

@@ -0,0 +1,138 @@
use hyperlog_core::log::GraphItem;
use itertools::Itertools;
use ratatui::{prelude::*, widgets::*};
use crate::models::Msg;
use super::{InputBuffer, InputField};
enum EditItemFocused {
Title,
Description,
}
impl Default for EditItemFocused {
fn default() -> Self {
Self::Title
}
}
pub struct EditItemState {
root: String,
path: Vec<String>,
title: InputBuffer,
description: InputBuffer,
item: GraphItem,
focused: EditItemFocused,
}
impl EditItemState {
pub fn new(
root: impl Into<String>,
path: impl IntoIterator<Item = impl Into<String>>,
item: &GraphItem,
) -> Self {
let root = root.into();
let path = path.into_iter().map(|p| p.into()).collect_vec();
match item {
GraphItem::Item {
title, description, ..
} => {
let title_len = title.len();
let mut title = InputBuffer::new(title.clone());
title.transform_focused();
title.set_position(title_len);
Self {
root,
path,
item: item.clone(),
title,
description: InputBuffer::new(description.clone()),
focused: Default::default(),
}
}
_ => todo!("cannot edit item from other than GraphItem::Item"),
}
}
pub fn update(&mut self, msg: &Msg) -> anyhow::Result<()> {
match &msg {
Msg::MoveDown | Msg::MoveUp => match self.focused {
EditItemFocused::Title => self.focused = EditItemFocused::Description,
EditItemFocused::Description => self.focused = EditItemFocused::Title,
},
_ => {}
}
match self.focused {
EditItemFocused::Title => {
self.title.update(msg)?;
}
EditItemFocused::Description => {
self.description.update(msg)?;
}
}
Ok(())
}
pub fn get_command(&self) -> Option<hyperlog_core::commander::Command> {
let title = self.title.string();
let description = self.description.string();
if !title.is_empty() {
let path = self.path.clone();
Some(hyperlog_core::commander::Command::UpdateItem {
root: self.root.clone(),
path,
title: title.trim().into(),
description: description.trim().into(),
state: match &self.item {
GraphItem::User(_) => Default::default(),
GraphItem::Section(_) => Default::default(),
GraphItem::Item { state, .. } => state.clone(),
},
})
} else {
None
}
}
}
#[derive(Default)]
pub struct EditItem {}
impl StatefulWidget for &mut EditItem {
type State = EditItemState;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let chunks = Layout::vertical(vec![
Constraint::Length(2),
Constraint::Length(3),
Constraint::Length(3),
])
.split(area);
let path = format!("path: {}.{}", state.root, state.path.join("."));
let path_header = Paragraph::new(path).dark_gray();
path_header.render(chunks[0], buf);
let mut title_input = InputField::new("title");
let mut description_input = InputField::new("description");
match state.focused {
EditItemFocused::Title => title_input.focused = true,
EditItemFocused::Description => description_input.focused = true,
}
title_input.render(chunks[1], buf, &mut state.title);
description_input.render(chunks[2], buf, &mut state.description);
}
}