Skip to content

Commit

Permalink
fix: fixing resizing crashing when drawing hint
Browse files Browse the repository at this point in the history
  • Loading branch information
wllfaria committed Jun 7, 2024
1 parent db523e3 commit 1151fe7
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 110 deletions.
13 changes: 10 additions & 3 deletions hac-client/src/pages/collection_viewer/collection_viewer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub enum CollectionViewerOverlay {
RequestMethod,
HeadersHelp,
HeadersDelete,
HeadersForm(usize),
}

#[derive(Debug, Clone, Copy, PartialEq)]
Expand Down Expand Up @@ -173,7 +174,6 @@ impl<'cv> CollectionViewer<'cv> {
config,
collection_store.clone(),
layout.req_editor,
layout.hint_pane,
),
response_viewer: ResponseViewer::new(
colors,
Expand Down Expand Up @@ -677,8 +677,15 @@ impl Renderable for CollectionViewer<'_> {
match overlay {
CollectionViewerOverlay::CreateRequest => self.draw_create_request_form(frame),
CollectionViewerOverlay::RequestMethod => self.draw_request_method_form(frame),
CollectionViewerOverlay::HeadersHelp => self.request_editor.draw_overlay(frame)?,
CollectionViewerOverlay::HeadersDelete => self.request_editor.draw_overlay(frame)?,
CollectionViewerOverlay::HeadersHelp => {
self.request_editor.draw_overlay(frame, overlay)?
}
CollectionViewerOverlay::HeadersDelete => {
self.request_editor.draw_overlay(frame, overlay)?
}
CollectionViewerOverlay::HeadersForm(_) => {
self.request_editor.draw_overlay(frame, overlay)?
}
CollectionViewerOverlay::None => {}
}

Expand Down
16 changes: 9 additions & 7 deletions hac-client/src/pages/collection_viewer/request_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod auth_editor;
mod body_editor;
mod headers_editor;
mod headers_editor_delete_prompt;
mod headers_editor_form;

use auth_editor::AuthEditor;
use body_editor::{BodyEditor, BodyEditorEvent};
Expand All @@ -27,7 +28,7 @@ use ratatui::style::{Style, Stylize};
use ratatui::widgets::{Block, Borders, Tabs};
use ratatui::Frame;

use super::collection_viewer::PaneFocus;
use super::collection_viewer::{CollectionViewerOverlay, PaneFocus};

/// set of possible events the edtior can send to the parent
#[derive(Debug)]
Expand Down Expand Up @@ -102,7 +103,6 @@ pub struct RequestEditor<'re> {

layout: ReqEditorLayout,
curr_tab: ReqEditorTabs,
hint_size: Rect,
}

impl<'re> RequestEditor<'re> {
Expand All @@ -111,7 +111,6 @@ impl<'re> RequestEditor<'re> {
config: &'re hac_config::Config,
collection_store: Rc<RefCell<CollectionStore>>,
size: Rect,
hint_size: Rect,
) -> Self {
let curr_tab = collection_store
.borrow()
Expand All @@ -136,13 +135,11 @@ impl<'re> RequestEditor<'re> {
colors,
collection_store.clone(),
layout.content_pane,
hint_size,
),
auth_editor: AuthEditor::new(colors),
layout,
curr_tab,
collection_store,
hint_size,
}
}

Expand All @@ -158,6 +155,7 @@ impl<'re> RequestEditor<'re> {

pub fn resize(&mut self, new_size: Rect) {
self.layout = build_layout(new_size);
self.headers_editor.resize(self.layout.content_pane);
self.body_editor.resize(self.layout.content_pane);
}

Expand Down Expand Up @@ -218,10 +216,14 @@ impl<'re> RequestEditor<'re> {
frame.render_widget(block, size);
}

pub fn draw_overlay(&mut self, frame: &mut Frame) -> anyhow::Result<()> {
pub fn draw_overlay(
&mut self,
frame: &mut Frame,
overlay: CollectionViewerOverlay,
) -> anyhow::Result<()> {
match self.curr_tab {
ReqEditorTabs::Body => todo!(),
ReqEditorTabs::Headers => self.headers_editor.draw_overlay(frame),
ReqEditorTabs::Headers => self.headers_editor.draw_overlay(frame, overlay),
ReqEditorTabs::Query => todo!(),
ReqEditorTabs::Auth => todo!(),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ use rand::Rng;
use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::style::{Style, Stylize};
use ratatui::text::Line;
use ratatui::widgets::{Block, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState};
use ratatui::widgets::{Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState};
use ratatui::Frame;

use super::headers_editor_delete_prompt::{
HeadersEditorDeletePrompt, HeadersEditorDeletePromptEvent,
};
use super::headers_editor_form::HeadersEditorForm;

#[derive(Debug)]
pub enum HeadersEditorEvent {
Expand All @@ -42,31 +43,33 @@ pub struct HeadersEditor<'he> {
row_height: u16,
amount_on_view: usize,
layout: HeadersEditorLayout,
hint_size: Rect,
delete_prompt: HeadersEditorDeletePrompt<'he>,
logo_idx: usize,

delete_prompt: HeadersEditorDeletePrompt<'he>,
header_form: HeadersEditorForm<'he>,
}

impl<'he> HeadersEditor<'he> {
pub fn new(
colors: &'he hac_colors::colors::Colors,
collection_store: Rc<RefCell<CollectionStore>>,
size: Rect,
hint_size: Rect,
) -> Self {
let row_height = 2;
let layout = build_layout(size, row_height);
let logo_idx = rand::thread_rng().gen_range(0..LOGO_ASCII.len());

HeadersEditor {
delete_prompt: HeadersEditorDeletePrompt::new(colors),
header_form: HeadersEditorForm::new(colors, collection_store.clone()),

colors,
collection_store,
scroll: 0,
selected_row: 5,
row_height,
amount_on_view: layout.content_size.height.div(row_height).into(),
layout,
hint_size,
delete_prompt: HeadersEditorDeletePrompt::new(colors),
logo_idx,
}
}
Expand Down Expand Up @@ -98,110 +101,117 @@ impl<'he> HeadersEditor<'he> {
frame.render_widget(Paragraph::new(checkbox).fg(decor_fg).centered(), row[3]);
}

fn get_hint_size(&self, frame: &mut Frame) -> Rect {
let size = frame.size();
Rect::new(0, size.height.sub(1), size.width, 1)
}

fn draw_hint(&self, frame: &mut Frame) {
let hint = match self.hint_size.width {
let hint_size = self.get_hint_size(frame);
let hint = match hint_size.width {
w if w.le(&100) => "[j/k -> move down/up] [enter -> select] [space -> enable/disable] [? -> help]",
_ => "[j/k -> move down/up] [enter -> select] [space -> enable/disable] [d -> delete] [? -> help]",
};
frame.render_widget(
Paragraph::new(hint).fg(self.colors.bright.black).centered(),
self.hint_size,
hint_size,
);
}

fn draw_help_overlay(&self, frame: &mut Frame) {
make_overlay(self.colors, self.colors.normal.black, 0.1, frame);
let size = frame.size();
let logo = LOGO_ASCII[self.logo_idx];

let help_popup = Rect::new(
size.width.div(2).saturating_sub(20),
size.height.div(2).saturating_sub(3),
40,
6,
);

let logo_size = Rect::new(
size.width
.div(2)
.saturating_sub(logo[0].len().div(2) as u16),
size.y.add(4),
logo[0].len() as u16,
logo.len() as u16,
);

let logo = logo
.iter()
.map(|line| Line::from(line.fg(self.colors.normal.red)))
.collect::<Vec<_>>();

let hint_size = Rect::new(
help_popup.x,
help_popup.y.add(help_popup.height).add(2),
40,
1,
);

let hint = Line::from("press any key to close this dialog")
.fg(self.colors.bright.black)
.centered();

let lines = [
[
format!("j{}", " ".repeat(11)),
format!("- move down{}", " ".repeat(29)),
format!("j{}", " ".repeat(11)).fg(self.colors.normal.red),
format!("- move down{}", " ".repeat(29)).fg(self.colors.normal.yellow),
],
[
format!("k{}", " ".repeat(11)),
format!("- move up{}", " ".repeat(31)),
format!("k{}", " ".repeat(11)).fg(self.colors.normal.red),
format!("- move up{}", " ".repeat(31)).fg(self.colors.normal.yellow),
],
[
format!("d{}", " ".repeat(11)),
format!("- deletes header{}", " ".repeat(20)),
format!("d{}", " ".repeat(11)).fg(self.colors.normal.red),
format!("- deletes header{}", " ".repeat(20)).fg(self.colors.normal.yellow),
],
[
format!("space{}", " ".repeat(7)),
format!("- enables or disabled header{}", " ".repeat(12)),
format!("space{}", " ".repeat(7)).fg(self.colors.normal.red),
format!("- enables or disabled header{}", " ".repeat(12))
.fg(self.colors.normal.yellow),
],
[
format!("enter{}", " ".repeat(7)),
format!("- select header for editing{}", " ".repeat(13)),
format!("enter{}", " ".repeat(7)).fg(self.colors.normal.red),
format!("- select header for editing{}", " ".repeat(13))
.fg(self.colors.normal.yellow),
],
[
format!("?{}", " ".repeat(11)),
format!("- shows this help message{}", " ".repeat(15)),
format!("?{}", " ".repeat(11)).fg(self.colors.normal.red),
format!("- shows this help message{}", " ".repeat(15))
.fg(self.colors.normal.yellow),
],
];

Layout::default()
.direction(Direction::Vertical)
.constraints((0..help_popup.height).map(|_| Constraint::Length(1)))
.split(help_popup)
let lines: Vec<Line> = lines
.into_iter()
.map(|l| Line::from(l.into_iter().collect::<Vec<_>>()))
.collect();

let mut logo = LOGO_ASCII[1];
let size = frame.size();
let logo_size = logo.len();
// we are adding 2 spaces for the gap between the logo and the text
// 1 space for the gap between the help lines and the hint
// 1 space for the hint itself
// 1 space after the hint
let mut total_size = logo_size.add(lines.len()).add(5) as u16;

if total_size.ge(&size.height) {
logo = &[];
total_size = lines.len().add(2) as u16;
}

let popup_size = Rect::new(
size.width.div(2).saturating_sub(25),
size.height.div(2).saturating_sub(total_size.div(2)),
50,
total_size,
);

let components = logo
.iter()
.zip(lines)
.for_each(|(size, line)| {
let sizes = Layout::default()
.constraints([Constraint::Length(12), Constraint::Fill(1)])
.direction(Direction::Horizontal)
.split(*size);
.map(|line| Line::from(line.fg(self.colors.normal.red)))
.chain(std::iter::repeat(Line::from("")).take(2))
.chain(lines)
.collect::<Vec<_>>();

let prefix = line[0].to_string().fg(self.colors.normal.red);
let description = line[1].to_string().fg(self.colors.normal.white);
let hint_size = Rect::new(
popup_size.x,
popup_size.y.add(popup_size.height).add(1),
40,
1,
);

frame.render_widget(prefix, sizes[0]);
frame.render_widget(description, sizes[1]);
});
let hint = Line::from("press any key to close this dialog")
.fg(self.colors.bright.black)
.centered();

frame.render_widget(Paragraph::new(logo), logo_size);
frame.render_widget(Paragraph::new(components), popup_size);
frame.render_widget(Paragraph::new(hint), hint_size);
}

pub fn draw_overlay(&mut self, frame: &mut Frame) -> anyhow::Result<()> {
let overlay = self.collection_store.borrow().peek_overlay();
pub fn draw_overlay(
&mut self,
frame: &mut Frame,
overlay: CollectionViewerOverlay,
) -> anyhow::Result<()> {
match overlay {
CollectionViewerOverlay::HeadersHelp => self.draw_help_overlay(frame),
CollectionViewerOverlay::HeadersDelete => {
self.delete_prompt.draw(frame, frame.size())?
self.delete_prompt.draw(frame, frame.size())?;
}
CollectionViewerOverlay::HeadersForm(header_idx) => {
self.header_form.update(header_idx);
self.header_form.draw(frame, frame.size())?;
}
_ => {}
}
Expand Down Expand Up @@ -387,6 +397,21 @@ impl Eventful for HeadersEditor<'_> {
.borrow_mut()
.push_overlay(CollectionViewerOverlay::HeadersDelete);
}
KeyCode::Enter => {
if headers.is_empty() {
return Ok(None);
}

if headers.get(self.selected_row).is_none() {
tracing::error!("tried to edit a non-existing header");
anyhow::bail!("tried to edit a non-existing header");
};

drop(request);
self.collection_store
.borrow_mut()
.push_overlay(CollectionViewerOverlay::HeadersForm(self.selected_row));
}
_ => {}
}

Expand Down
Loading

0 comments on commit 1151fe7

Please sign in to comment.