Skip to content

Commit

Permalink
feat: horizontal scroll on headers
Browse files Browse the repository at this point in the history
  • Loading branch information
wllfaria committed May 8, 2024
1 parent 3022a99 commit 9e1b6f6
Show file tree
Hide file tree
Showing 6 changed files with 267 additions and 38 deletions.
6 changes: 6 additions & 0 deletions reqtui/src/net/request_manager.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use reqwest::header::{HeaderMap, HeaderValue};
use tokio::sync::mpsc::UnboundedSender;

use crate::{
Expand All @@ -9,6 +10,7 @@ use crate::{
pub struct ReqtuiResponse {
pub body: String,
pub pretty_body: TextObject<Readonly>,
pub headers: HeaderMap<HeaderValue>,
}

#[derive(Debug, PartialEq)]
Expand All @@ -26,6 +28,9 @@ pub fn handle_request(request: Request, response_tx: UnboundedSender<ReqtuiNetRe
match client.get(request.uri).send().await {
Ok(res) => {
tracing::debug!("request handled successfully, sending response");

let headers = res.headers().to_owned();

let body: serde_json::Value = res
.json()
.await
Expand All @@ -51,6 +56,7 @@ pub fn handle_request(request: Request, response_tx: UnboundedSender<ReqtuiNetRe
.send(ReqtuiNetRequest::Response(ReqtuiResponse {
body,
pretty_body,
headers,
}))
.expect("failed to send response through channel");
}
Expand Down
20 changes: 20 additions & 0 deletions reqtui/src/text_object/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ pub struct Cursor {
row: usize,
col: usize,
snapback_col: usize,
// offsets are used for commands that visually should move the cursor but shouldn't influence in
// the actual cursor position on the content
col_offset: usize,
row_offset: usize,
}

impl Cursor {
Expand Down Expand Up @@ -55,6 +59,22 @@ impl Cursor {
self.col
}

pub fn row_with_offset(&self) -> usize {
self.row + self.row_offset
}

pub fn col_with_offset(&self) -> usize {
self.col + self.col_offset
}

pub fn set_col_offset(&mut self, offset: usize) {
self.col_offset = offset;
}

pub fn set_row_offset(&mut self, offset: usize) {
self.row_offset = offset;
}

pub fn readable_position(&self) -> (usize, usize) {
(self.col.add(1), self.row.add(1))
}
Expand Down
67 changes: 61 additions & 6 deletions tui/src/components/api_explorer/api_explorer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ use reqtui::{
use std::{cell::RefCell, collections::HashMap, ops::Add, rc::Rc};
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};

use super::req_editor::EditorMode;

#[derive(Debug, PartialEq)]
pub struct ExplorerLayout {
pub sidebar: Rect,
Expand Down Expand Up @@ -61,6 +63,9 @@ pub struct ApiExplorer<'a> {
res_viewer: ResViewer<'a>,
preview_tab: ResViewerTabs,
raw_preview_scroll: usize,
preview_header_scroll_y: usize,
preview_header_scroll_x: usize,
pretty_preview_scroll: usize,

editor: ReqEditor<'a>,
editor_tab: ReqEditorTabs,
Expand Down Expand Up @@ -110,6 +115,9 @@ impl<'a> ApiExplorer<'a> {

preview_tab: ResViewerTabs::Preview,
raw_preview_scroll: 0,
preview_header_scroll_y: 0,
preview_header_scroll_x: 0,
pretty_preview_scroll: 0,

response_rx,
request_tx,
Expand Down Expand Up @@ -183,8 +191,18 @@ impl<'a> ApiExplorer<'a> {
}

fn handle_editor_key_event(&mut self, key_event: KeyEvent) -> anyhow::Result<Option<Command>> {
match (key_event.code, &self.selected_pane) {
(KeyCode::Enter, None) => {
self.selected_pane = Some(PaneFocus::Editor);
return Ok(None);
}
(KeyCode::Esc, Some(_)) if self.editor.mode().eq(&EditorMode::Normal) => {
self.selected_pane = None;
return Ok(None);
}
_ => {}
}
if key_event.code.eq(&KeyCode::Enter) && self.selected_pane.is_none() {
self.selected_pane = Some(PaneFocus::Editor);
return Ok(None);
}
self.editor.handle_key_event(key_event)
Expand Down Expand Up @@ -224,6 +242,9 @@ impl<'a> ApiExplorer<'a> {
.unwrap_or(false),
&self.preview_tab,
&mut self.raw_preview_scroll,
&mut self.pretty_preview_scroll,
&mut self.preview_header_scroll_y,
&mut self.preview_header_scroll_x,
);

frame.render_stateful_widget(
Expand Down Expand Up @@ -262,10 +283,38 @@ impl<'a> ApiExplorer<'a> {
KeyCode::Enter => self.selected_pane = Some(PaneFocus::Preview),
KeyCode::Tab => self.preview_tab = ResViewerTabs::next(&self.preview_tab),
KeyCode::Esc => self.selected_pane = None,
KeyCode::Char('k') => {
self.raw_preview_scroll = self.raw_preview_scroll.saturating_sub(1)
KeyCode::Char('h') => {
if let ResViewerTabs::Headers = self.preview_tab {
self.preview_header_scroll_x = self.preview_header_scroll_x.saturating_sub(1)
}
}
KeyCode::Char('j') => match self.preview_tab {
ResViewerTabs::Preview => {
self.pretty_preview_scroll = self.pretty_preview_scroll.add(1)
}
ResViewerTabs::Raw => self.raw_preview_scroll = self.raw_preview_scroll.add(1),
ResViewerTabs::Headers => {
self.preview_header_scroll_y = self.preview_header_scroll_y.add(1)
}
ResViewerTabs::Cookies => {}
},
KeyCode::Char('k') => match self.preview_tab {
ResViewerTabs::Preview => {
self.pretty_preview_scroll = self.pretty_preview_scroll.saturating_sub(1)
}
ResViewerTabs::Raw => {
self.raw_preview_scroll = self.raw_preview_scroll.saturating_sub(1)
}
ResViewerTabs::Headers => {
self.preview_header_scroll_y = self.preview_header_scroll_y.saturating_sub(1)
}
ResViewerTabs::Cookies => {}
},
KeyCode::Char('l') => {
if let ResViewerTabs::Headers = self.preview_tab {
self.preview_header_scroll_x = self.preview_header_scroll_x.add(1)
}
}
KeyCode::Char('j') => self.raw_preview_scroll = self.raw_preview_scroll.add(1),
_ => {}
}

Expand All @@ -292,8 +341,14 @@ impl Component for ApiExplorer<'_> {
{
let editor_position = self.layout.req_editor;
let cursor = self.editor.cursor();
let row_with_offset = editor_position.y.add(cursor.row() as u16).add(3);
let col_with_offset = editor_position.x.add(cursor.col() as u16).add(1);
let row_with_offset = editor_position
.y
.add(cursor.row_with_offset() as u16)
.add(3);
let col_with_offset = editor_position
.x
.add(cursor.col_with_offset() as u16)
.add(1);
frame.set_cursor(col_with_offset, row_with_offset);
}

Expand Down
15 changes: 13 additions & 2 deletions tui/src/components/api_explorer/req_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use std::{
use tree_sitter::Tree;

#[derive(PartialEq, Debug, Clone)]
enum EditorMode {
pub enum EditorMode {
Insert,
Normal,
}
Expand Down Expand Up @@ -135,6 +135,10 @@ impl<'a> ReqEditor<'a> {
}
}

pub fn mode(&self) -> &EditorMode {
&self.editor_mode
}

fn draw_statusline(&self, buf: &mut Buffer, size: Rect) {
let cursor_pos = self.cursor.readable_position();

Expand Down Expand Up @@ -346,13 +350,20 @@ impl Eventful for ReqEditor<'_> {
}
}
(EditorMode::Normal, KeyCode::Char('a'), KeyModifiers::NONE) => {
self.cursor.move_right(1);
let current_line_len = self.body.line_len(self.cursor.row());
if current_line_len.gt(&0) {
self.cursor.move_right(1);
}
self.editor_mode = EditorMode::Insert;
}
(EditorMode::Normal, KeyCode::Char('i'), KeyModifiers::NONE) => {
self.editor_mode = EditorMode::Insert;
}
(EditorMode::Insert, KeyCode::Esc, KeyModifiers::NONE) => {
let current_line_len = self.body.line_len(self.cursor.row());
if self.cursor.col().ge(&current_line_len) {
self.cursor.move_left(1);
}
self.editor_mode = EditorMode::Normal;
}
_ => {}
Expand Down
24 changes: 14 additions & 10 deletions tui/src/components/api_explorer/req_uri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,19 @@ impl<'a> StatefulWidget for ReqUri<'a> {
Style::default().fg(self.colors.bright.black)
};

if let Some(req) = state.selected_request {
Paragraph::new(req.borrow().uri.clone())
.fg(self.colors.normal.white)
.block(
Block::default()
.borders(Borders::ALL)
.border_style(block_border),
)
.render(size, buf)
}
let uri = state
.selected_request
.as_ref()
.map(|req| req.borrow().uri.to_string())
.unwrap_or_default();

Paragraph::new(uri)
.fg(self.colors.normal.white)
.block(
Block::default()
.borders(Borders::ALL)
.border_style(block_border),
)
.render(size, buf);
}
}
Loading

0 comments on commit 9e1b6f6

Please sign in to comment.