Skip to content

Commit

Permalink
refactor: centralizing state management
Browse files Browse the repository at this point in the history
  • Loading branch information
wllfaria committed Jun 3, 2024
1 parent 34773b6 commit f593c4f
Show file tree
Hide file tree
Showing 22 changed files with 609 additions and 521 deletions.
30 changes: 11 additions & 19 deletions hac-client/benches/collection_viewer_bench.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
use std::{
cell::RefCell,
rc::Rc,
sync::{Arc, RwLock},
};
use hac_core::collection::types::{BodyType, Info, Request, RequestKind, RequestMethod};
use hac_core::collection::Collection;
use hac_core::syntax::highlighter::Highlighter;

use hac_client::pages::collection_viewer::{collection_store::CollectionStore, CollectionViewer};
use hac_client::pages::{Eventful, Renderable};
use hac_client::utils::build_syntax_highlighted_lines;

use std::cell::RefCell;
use std::rc::Rc;
use std::sync::{Arc, RwLock};

use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers};
use hac_client::{
pages::{
collection_viewer::{collection_store::CollectionStore, CollectionViewer},
Eventful, Page,
},
utils::build_syntax_highlighted_lines,
};
use hac_core::{
collection::{
types::{BodyType, Info, Request, RequestKind, RequestMethod},
Collection,
},
syntax::highlighter::Highlighter,
};
use lazy_static::lazy_static;
use ratatui::{backend::TestBackend, layout::Rect, Terminal};
use tree_sitter::Tree;
Expand Down
13 changes: 7 additions & 6 deletions hac-client/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::{
event_pool::{Event, EventPool},
pages::{Eventful, Page},
screen_manager::ScreenManager,
};
use hac_core::{collection::Collection, command::Command};
use ratatui::{backend::CrosstermBackend, Terminal};

use crate::event_pool::{Event, EventPool};
use crate::pages::{Eventful, Renderable};
use crate::screen_manager::ScreenManager;

use std::io::Stdout;

use ratatui::{backend::CrosstermBackend, Terminal};
use tokio::sync::mpsc;

pub struct App<'app> {
Expand Down
35 changes: 2 additions & 33 deletions hac-client/src/pages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ use ratatui::{layout::Rect, Frame};
use tokio::sync::mpsc::UnboundedSender;

/// A `Page` is anything that is a top level page and can be drawn to the screen
pub trait Page {
pub trait Renderable {
fn draw(&mut self, frame: &mut Frame, size: Rect) -> anyhow::Result<()>;

/// pages need to adapt to change of sizes on the application, this function is called
/// by the top level event loop whenever a resize event is produced
#[allow(unused_variables)]
fn resize(&mut self, new_size: Rect);
fn resize(&mut self, new_size: Rect) {}

/// register a page to be a command handler, which means this page will now receive
/// commands from the channel to handle whatever the commands it is interested into
Expand Down Expand Up @@ -56,34 +56,3 @@ pub trait Eventful {
Ok(None)
}
}

/// An `EventfulWithContext` component is a component that can handle events but requires
/// additional information which can be specified by its implementer. Such as defining a
/// associate type required to re-render properly or information that it needs to decide
/// on how to behave
///
/// besides the contextful behavior, this is exactly as `Eventful`
pub trait EventfulWithContext {
type Result;
type Context;

fn handle_event(
&mut self,
event: Option<Event>,
context: Self::Context,
) -> anyhow::Result<Option<Self::Result>> {
match event {
Some(Event::Key(key_event)) => self.handle_key_event(key_event, context),
_ => Ok(None),
}
}

#[allow(unused_variables)]
fn handle_key_event(
&mut self,
key_event: KeyEvent,
context: Self::Context,
) -> anyhow::Result<Option<Self::Result>> {
Ok(None)
}
}
34 changes: 16 additions & 18 deletions hac-client/src/pages/collection_dashboard/collection_dashboard.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
use crate::pages::{
collection_dashboard::{
collection_list::{CollectionList, CollectionListState},
new_collection_form::{FormFocus, FormState, NewCollectionForm},
},
confirm_popup::ConfirmPopup,
error_popup::ErrorPopup,
overlay::draw_overlay,
Eventful, Page,
};
use hac_core::{collection::types::Collection, command::Command};

use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use ratatui::{
layout::{Alignment, Constraint, Direction, Flex, Layout, Rect},
style::{Style, Stylize},
text::Line,
widgets::{Block, Clear, Padding, Paragraph, StatefulWidget, Widget, Wrap},
Frame,
use crate::pages::collection_dashboard::collection_list::{CollectionList, CollectionListState};
use crate::pages::collection_dashboard::new_collection_form::{
FormFocus, FormState, NewCollectionForm,
};
use crate::pages::confirm_popup::ConfirmPopup;
use crate::pages::error_popup::ErrorPopup;
use crate::pages::overlay::draw_overlay;
use crate::pages::{Eventful, Renderable};

use std::ops::{Add, Div, Not, Sub};

use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use ratatui::layout::{Alignment, Constraint, Direction, Flex, Layout, Rect};
use ratatui::style::{Style, Stylize};
use ratatui::text::Line;
use ratatui::widgets::{Block, Clear, Padding, Paragraph, StatefulWidget, Widget, Wrap};
use ratatui::Frame;
use tokio::sync::mpsc::UnboundedSender;
use tui_big_text::{BigText, PixelSize};

Expand Down Expand Up @@ -520,7 +518,7 @@ impl<'a> CollectionDashboard<'a> {
}
}

impl Page for CollectionDashboard<'_> {
impl Renderable for CollectionDashboard<'_> {
fn draw(&mut self, frame: &mut Frame, size: Rect) -> anyhow::Result<()> {
self.draw_background(size, frame);
self.draw_title(frame)?;
Expand Down
23 changes: 10 additions & 13 deletions hac-client/src/pages/collection_dashboard/collection_list.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
use std::{
collections::VecDeque,
ops::{Add, Div, Mul},
};

use hac_core::collection::Collection;
use ratatui::{
buffer::Buffer,
layout::{Constraint, Direction, Flex, Layout, Rect},
style::{Style, Stylize},
widgets::{
Block, BorderType, Borders, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState,
StatefulWidget, Widget,
},

use std::collections::VecDeque;
use std::ops::{Add, Div, Mul};

use ratatui::buffer::Buffer;
use ratatui::layout::{Constraint, Direction, Flex, Layout, Rect};
use ratatui::style::{Style, Stylize};
use ratatui::widgets::{
Block, BorderType, Borders, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState,
StatefulWidget, Widget,
};

#[derive(Debug)]
Expand Down
16 changes: 8 additions & 8 deletions hac-client/src/pages/collection_dashboard/new_collection_form.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use ratatui::{
buffer::Buffer,
layout::{Constraint, Direction, Flex, Layout, Rect},
style::{Style, Stylize},
text::Line,
widgets::{Block, BorderType, Borders, Clear, Padding, Paragraph, StatefulWidget, Widget},
};

use crate::pages::input::Input;

use ratatui::buffer::Buffer;
use ratatui::layout::{Constraint, Direction, Flex, Layout, Rect};
use ratatui::style::{Style, Stylize};
use ratatui::text::Line;
use ratatui::widgets::{
Block, BorderType, Borders, Clear, Padding, Paragraph, StatefulWidget, Widget,
};

#[derive(Debug, Default, PartialEq, Eq)]
pub enum FormFocus {
#[default]
Expand Down
66 changes: 51 additions & 15 deletions hac-client/src/pages/collection_viewer/collection_store.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
use std::{
cell::RefCell,
collections::HashMap,
rc::Rc,
sync::{Arc, RwLock},
};

use hac_core::collection::{
types::{Request, RequestKind},
Collection,
};
use hac_core::collection::types::{Request, RequestKind};
use hac_core::collection::Collection;

use crate::pages::collection_viewer::collection_viewer::PaneFocus;

use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::{Arc, RwLock};

#[derive(Debug)]
pub struct CollectionState {
collection: Rc<RefCell<Collection>>,
hovered_request: Option<String>,
selected_request: Option<Arc<RwLock<Request>>>,
dirs_expanded: Rc<RefCell<HashMap<String, bool>>>,
selected_pane: Option<PaneFocus>,
focused_pane: PaneFocus,
has_pending_request: bool,
}

#[derive(Debug, Default)]
Expand All @@ -30,6 +31,9 @@ pub enum CollectionStoreAction {
HoverPrev,
HoverNext,
ToggleDirectory(String),
SetFocusedPane(PaneFocus),
SetSelectedPane(Option<PaneFocus>),
SetPendingRequest(bool),
}

impl CollectionStore {
Expand All @@ -54,6 +58,9 @@ impl CollectionStore {
hovered_request,
dirs_expanded: Rc::new(RefCell::new(HashMap::default())),
collection: Rc::new(RefCell::new(collection)),
focused_pane: PaneFocus::Sidebar,
selected_pane: None,
has_pending_request: false,
};

self.state = Some(Rc::new(RefCell::new(state)));
Expand All @@ -79,14 +86,23 @@ impl CollectionStore {
.unwrap()
.push(request_kind);
}
CollectionStoreAction::HoverPrev => self.hover_prev(),
CollectionStoreAction::HoverNext => self.hover_next(),
CollectionStoreAction::HoverPrev => self.maybe_hover_prev(),
CollectionStoreAction::HoverNext => self.maybe_hover_next(),
CollectionStoreAction::ToggleDirectory(dir_id) => {
let state = state.borrow_mut();
let mut dirs = state.dirs_expanded.borrow_mut();
let entry = dirs.entry(dir_id).or_insert(false);
*entry = !*entry;
}
CollectionStoreAction::SetFocusedPane(pane) => {
state.borrow_mut().focused_pane = pane
}
CollectionStoreAction::SetSelectedPane(pane) => {
state.borrow_mut().selected_pane = pane
}
CollectionStoreAction::SetPendingRequest(is_pending) => {
state.borrow_mut().has_pending_request = is_pending;
}
}
}
}
Expand All @@ -97,6 +113,20 @@ impl CollectionStore {
.and_then(|state| state.borrow().selected_request.clone())
}

pub fn get_focused_pane(&self) -> PaneFocus {
self.state
.as_ref()
.map(|state| state.borrow().focused_pane)
.expect("tried to get the focused pane without a state")
}

pub fn get_selected_pane(&self) -> Option<PaneFocus> {
self.state
.as_ref()
.map(|state| state.borrow().selected_pane)
.expect("tried to get the selected pane without a state")
}

pub fn get_hovered_request(&self) -> Option<String> {
self.state
.as_ref()
Expand Down Expand Up @@ -127,7 +157,13 @@ impl CollectionStore {
})
}

fn hover_prev(&mut self) {
pub fn has_pending_request(&self) -> bool {
self.state
.as_ref()
.is_some_and(|state| state.borrow().has_pending_request)
}

fn maybe_hover_prev(&mut self) {
if self.get_hovered_request().is_some() && self.get_requests().is_some() {
let id = self.get_hovered_request().unwrap();
let requests = self.get_requests().unwrap();
Expand All @@ -145,7 +181,7 @@ impl CollectionStore {
}
}

fn hover_next(&mut self) {
fn maybe_hover_next(&mut self) {
if self.get_hovered_request().is_some() && self.get_requests().is_some() {
let id = self.get_hovered_request().unwrap();
let requests = self.get_requests().unwrap();
Expand Down
Loading

0 comments on commit f593c4f

Please sign in to comment.