From 79023ea970984b162bb5d7f081c2dc5538f66c28 Mon Sep 17 00:00:00 2001 From: wiru Date: Sun, 11 Aug 2024 02:22:22 -0300 Subject: [PATCH] wip: implementing auth kind selector --- hac-client/src/components/list_item.rs | 10 ++- .../collection_viewer/collection_viewer.rs | 8 +++ .../pages/collection_viewer/request_editor.rs | 1 + .../request_editor/auth_editor/auth_editor.rs | 34 +++++++-- .../auth_editor/auth_kind_prompt.rs | 64 ++++++++++++----- .../pages/collection_viewer/request_uri.rs | 6 ++ .../collection_viewer/response_viewer.rs | 1 - hac-core/src/collection/types.rs | 70 ++++++++++++++++++- hac-core/src/lib.rs | 40 ----------- 9 files changed, 166 insertions(+), 68 deletions(-) diff --git a/hac-client/src/components/list_item.rs b/hac-client/src/components/list_item.rs index 7b05ff5..3207270 100644 --- a/hac-client/src/components/list_item.rs +++ b/hac-client/src/components/list_item.rs @@ -1,12 +1,10 @@ use std::borrow::Cow; -use ratatui::{ - style::{Style, Stylize}, - text::{Line, Span}, - widgets::{Block, Borders, Paragraph}, -}; +use ratatui::style::{Style, Stylize}; +use ratatui::text::{Line, Span}; +use ratatui::widgets::{Block, Borders, Paragraph}; -use super::component_styles::{color_from_focus, ComponentBorder, ComponentFocus}; +use crate::components::component_styles::{color_from_focus, ComponentBorder, ComponentFocus}; pub enum ListItemKind { _Regular, diff --git a/hac-client/src/pages/collection_viewer/collection_viewer.rs b/hac-client/src/pages/collection_viewer/collection_viewer.rs index b5637b6..0a3f0a4 100755 --- a/hac-client/src/pages/collection_viewer/collection_viewer.rs +++ b/hac-client/src/pages/collection_viewer/collection_viewer.rs @@ -482,6 +482,14 @@ impl Eventful for CollectionViewer<'_> { self.request_tx.clone(), ), Some(RequestUriEvent::RemoveSelection) => self.update_selection(None), + Some(RequestUriEvent::SelectNext) => { + self.update_selection(None); + self.focus_next(); + } + Some(RequestUriEvent::SelectPrev) => { + self.update_selection(None); + self.focus_prev(); + } // when theres no event we do nothing None => {} }, diff --git a/hac-client/src/pages/collection_viewer/request_editor.rs b/hac-client/src/pages/collection_viewer/request_editor.rs index 0514e26..f36438d 100755 --- a/hac-client/src/pages/collection_viewer/request_editor.rs +++ b/hac-client/src/pages/collection_viewer/request_editor.rs @@ -294,6 +294,7 @@ impl Eventful for RequestEditor<'_> { let mut store = self.collection_store.borrow_mut(); store.push_overlay(CollectionViewerOverlay::ChangeAuthMethod); } + Some(AuthEditorEvent::Quit) => return Ok(Some(RequestEditorEvent::Quit)), None => {} }, } diff --git a/hac-client/src/pages/collection_viewer/request_editor/auth_editor/auth_editor.rs b/hac-client/src/pages/collection_viewer/request_editor/auth_editor/auth_editor.rs index 09278dc..9d12781 100755 --- a/hac-client/src/pages/collection_viewer/request_editor/auth_editor/auth_editor.rs +++ b/hac-client/src/pages/collection_viewer/request_editor/auth_editor/auth_editor.rs @@ -1,4 +1,4 @@ -use super::auth_kind_prompt::AuthKindPrompt; +use super::auth_kind_prompt::{AuthKindPrompt, AuthKindPromptEvent}; use crate::pages::collection_viewer::collection_store::CollectionStore; use crate::pages::collection_viewer::collection_viewer::CollectionViewerOverlay; use crate::pages::{Eventful, Renderable}; @@ -7,7 +7,8 @@ use std::cell::RefCell; use std::ops::{Add, Sub}; use std::rc::Rc; -use crossterm::event::{KeyCode, KeyEvent}; +use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; +use hac_core::collection::types::AuthMethod; use ratatui::layout::Rect; use ratatui::style::Stylize; use ratatui::widgets::{Block, Borders, Paragraph}; @@ -15,6 +16,7 @@ use ratatui::Frame; pub enum AuthEditorEvent { ChangeAuthMethod, + Quit, } #[derive(Debug)] @@ -81,7 +83,10 @@ impl Renderable for AuthEditor<'_> { }; let request = request.read().unwrap(); - let has_auth = request.auth_method.is_some(); + let has_auth = request + .auth_method + .as_ref() + .is_some_and(|method| !matches!(method, AuthMethod::None)); self.draw_hint(frame, has_auth); if !has_auth { @@ -107,8 +112,29 @@ impl Eventful for AuthEditor<'_> { fn handle_key_event(&mut self, key_event: KeyEvent) -> anyhow::Result> { let overlay = self.collection_store.borrow().peek_overlay(); + if let (KeyCode::Char('c'), KeyModifiers::CONTROL) = (key_event.code, key_event.modifiers) { + return Ok(Some(AuthEditorEvent::Quit)); + } + + let mut store = self.collection_store.borrow_mut(); + let Some(request) = store.get_selected_request() else { + return Ok(None); + }; + + let mut request = request.write().unwrap(); + if let CollectionViewerOverlay::ChangeAuthMethod = overlay { - self.collection_store.borrow_mut().pop_overlay(); + match self.auth_kind_prompt.handle_key_event(key_event)? { + Some(AuthKindPromptEvent::Cancel) => { + store.pop_overlay(); + } + Some(AuthKindPromptEvent::Confirm(auth_kind)) => { + request.auth_method = Some(auth_kind); + store.pop_overlay(); + } + None => (), + }; + return Ok(None); } diff --git a/hac-client/src/pages/collection_viewer/request_editor/auth_editor/auth_kind_prompt.rs b/hac-client/src/pages/collection_viewer/request_editor/auth_editor/auth_kind_prompt.rs index c160513..4cacae9 100644 --- a/hac-client/src/pages/collection_viewer/request_editor/auth_editor/auth_kind_prompt.rs +++ b/hac-client/src/pages/collection_viewer/request_editor/auth_editor/auth_kind_prompt.rs @@ -1,20 +1,24 @@ use crate::ascii::LOGO_ASCII; -use crate::components::component_styles::{ComponentBorder, ComponentFocus}; +use crate::components::component_styles::ComponentBorder; use crate::components::list_item::{list_item, ListItemKind}; use crate::pages::collection_viewer::collection_store::CollectionStore; use crate::pages::{overlay::make_overlay, Eventful, Renderable}; use std::cell::RefCell; +use std::ops::{Add, Div, Sub}; use std::rc::Rc; use crossterm::event::{KeyCode, KeyEvent}; -use hac_core::AuthKind; +use hac_core::collection::types::AuthMethod; use rand::Rng; -use ratatui::layout::{Constraint, Direction, Layout, Rect}; +use ratatui::layout::{Constraint, Direction, Flex, Layout, Rect}; +use ratatui::style::Stylize; +use ratatui::text::Line; +use ratatui::widgets::Paragraph; use ratatui::Frame; pub enum AuthKindPromptEvent { - Placeholder, + Confirm(AuthMethod), Cancel, } @@ -46,10 +50,29 @@ impl Renderable for AuthKindPrompt<'_> { fn draw(&mut self, frame: &mut Frame, size: Rect) -> anyhow::Result<()> { make_overlay(self.colors, self.colors.normal.black, 0.1, frame); - //let mut logo = LOGO_ASCII[self.logo_idx]; - //let mut logo_size = logo.len() as u16; + let logo = LOGO_ASCII[self.logo_idx]; + let logo_size = logo.len() as u16; + // adding size of the form + spacing + hint + + let [_, center, _] = Layout::default() + .constraints([ + Constraint::Fill(1), + Constraint::Min(80), + Constraint::Fill(1), + ]) + .direction(Direction::Horizontal) + .areas(size); + + let [logo_size, _, options_size] = Layout::default() + .constraints([ + Constraint::Length(logo_size), + Constraint::Length(2), + Constraint::Fill(1), + ]) + .direction(Direction::Vertical) + .areas(center); - let auth_kinds = AuthKind::iter() + let auth_kinds = AuthMethod::iter() .enumerate() .map(|(idx, v)| { list_item( @@ -64,20 +87,26 @@ impl Renderable for AuthKindPrompt<'_> { let constraints = auth_kinds .iter() - .flat_map(|_| vec![Constraint::Length(3), Constraint::Length(1)]) + .flat_map(|_| vec![Constraint::Length(3)]) .collect::>(); let layout = Layout::default() - .constraints(constraints) + .constraints(constraints.clone()) + .flex(Flex::Center) + .spacing(1) .direction(Direction::Vertical) - .split(size); + .split(options_size); - let mut idx = 0; - for item in auth_kinds { + for (idx, item) in auth_kinds.iter().enumerate() { frame.render_widget(item, layout[idx]); - idx += 2; } + let logo = logo + .iter() + .map(|line| Line::from(line.fg(self.colors.normal.red)).centered()) + .collect::>(); + frame.render_widget(Paragraph::new(logo), logo_size); + Ok(()) } } @@ -88,12 +117,15 @@ impl Eventful for AuthKindPrompt<'_> { fn handle_key_event(&mut self, key_event: KeyEvent) -> anyhow::Result> { match key_event.code { KeyCode::Esc => return Ok(Some(AuthKindPromptEvent::Cancel)), - KeyCode::Enter => {} + KeyCode::Enter => { + let selected_auth_kind = AuthMethod::from(self.selected_idx); + return Ok(Some(AuthKindPromptEvent::Confirm(selected_auth_kind))); + } KeyCode::Char('j') | KeyCode::Down => { - self.selected_idx = self.selected_idx.min(self.selected_idx + 1) + self.selected_idx = AuthMethod::len().min(self.selected_idx + 1); } KeyCode::Char('k') | KeyCode::Up => { - self.selected_idx = self.selected_idx.saturating_sub(1) + self.selected_idx = self.selected_idx.saturating_sub(1); } _ => {} } diff --git a/hac-client/src/pages/collection_viewer/request_uri.rs b/hac-client/src/pages/collection_viewer/request_uri.rs index 93c30bf..1e651c3 100755 --- a/hac-client/src/pages/collection_viewer/request_uri.rs +++ b/hac-client/src/pages/collection_viewer/request_uri.rs @@ -21,6 +21,10 @@ pub enum RequestUriEvent { /// user pressed `Esc` while request uri was selected, so we bubble /// the event up for the parent to handle RemoveSelection, + /// requests the parent to select the next pane + SelectNext, + /// requests the parent to select the previous pane + SelectPrev, /// user pressed `C-c` hotkey so we bubble up the event for the parent to handle Quit, } @@ -115,6 +119,8 @@ impl Eventful for RequestUri<'_> { match key_event.code { KeyCode::Esc => return Ok(Some(RequestUriEvent::RemoveSelection)), + KeyCode::Tab => return Ok(Some(RequestUriEvent::SelectNext)), + KeyCode::BackTab => return Ok(Some(RequestUriEvent::SelectPrev)), KeyCode::Char(c) => { if let Some(req) = self .collection_store diff --git a/hac-client/src/pages/collection_viewer/response_viewer.rs b/hac-client/src/pages/collection_viewer/response_viewer.rs index 09972f7..ce1c89a 100755 --- a/hac-client/src/pages/collection_viewer/response_viewer.rs +++ b/hac-client/src/pages/collection_viewer/response_viewer.rs @@ -93,7 +93,6 @@ pub struct ResponseViewer<'a> { preview_layout: PreviewLayout, layout: ResViewerLayout, collection_store: Rc>, - active_tab: ResViewerTabs, raw_scroll: usize, headers_scroll_y: usize, diff --git a/hac-core/src/collection/types.rs b/hac-core/src/collection/types.rs index f5222d8..31f65a7 100755 --- a/hac-core/src/collection/types.rs +++ b/hac-core/src/collection/types.rs @@ -186,7 +186,75 @@ pub struct Request { #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum AuthMethod { Bearer, - Basic, + None, + A, + B, + C, + D, + E, +} + +#[derive(Default)] +pub struct AuthKindIter { + inner: u8, +} + +impl std::fmt::Display for AuthMethod { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AuthMethod::None => write!(f, "None"), + AuthMethod::Bearer => write!(f, "Bearer"), + AuthMethod::A => write!(f, "Bearer"), + AuthMethod::B => write!(f, "Bearer"), + AuthMethod::C => write!(f, "Bearer"), + AuthMethod::D => write!(f, "Bearer"), + AuthMethod::E => write!(f, "Bearer"), + } + } +} + +impl From for AuthMethod { + fn from(value: usize) -> Self { + match value { + 0 => AuthMethod::None, + 1 => AuthMethod::Bearer, + 2 => AuthMethod::A, + 3 => AuthMethod::B, + 4 => AuthMethod::C, + 5 => AuthMethod::D, + 6 => AuthMethod::E, + _ => AuthMethod::None, + } + } +} + +impl AuthMethod { + pub fn iter() -> AuthKindIter { + AuthKindIter::default() + } + + pub fn len() -> usize { + AuthKindIter::default().count() + } +} + +impl Iterator for AuthKindIter { + type Item = AuthMethod; + + fn next(&mut self) -> Option { + let variant = match self.inner { + 0 => Some(AuthMethod::None), + 1 => Some(AuthMethod::Bearer), + 2 => Some(AuthMethod::A), + 3 => Some(AuthMethod::B), + 4 => Some(AuthMethod::C), + 5 => Some(AuthMethod::D), + 6 => Some(AuthMethod::E), + _ => None, + }; + self.inner += 1; + variant + } } /// a collection of all available body types we support. diff --git a/hac-core/src/lib.rs b/hac-core/src/lib.rs index aa88cf9..7acc170 100755 --- a/hac-core/src/lib.rs +++ b/hac-core/src/lib.rs @@ -4,43 +4,3 @@ pub mod fs; pub mod net; pub mod syntax; pub mod text_object; - -#[derive(Debug, Copy, Clone)] -pub enum AuthKind { - Bearer, - None, -} - -#[derive(Default)] -pub struct AuthKindIter { - inner: u8, -} - -impl std::fmt::Display for AuthKind { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - AuthKind::None => write!(f, "None"), - AuthKind::Bearer => write!(f, "Bearer"), - } - } -} - -impl AuthKind { - pub fn iter() -> AuthKindIter { - AuthKindIter::default() - } -} - -impl Iterator for AuthKindIter { - type Item = AuthKind; - - fn next(&mut self) -> Option { - let variant = match self.inner { - 0 => Some(AuthKind::Bearer), - 1 => Some(AuthKind::None), - _ => None, - }; - self.inner += 1; - variant - } -}