diff --git a/rq-cli/src/app.rs b/rq-cli/src/app.rs index e800bdd..664e960 100644 --- a/rq-cli/src/app.rs +++ b/rq-cli/src/app.rs @@ -181,6 +181,9 @@ impl App { KeyCode::Enter => match self.focus { FocusState::RequestsList => self.focus = FocusState::ResponseBuffer, FocusState::ResponseBuffer => { + let index = self.request_menu.idx(); + self.responses[index].set_loading(); + self.req_tx .send(( self.request_menu.selected().clone(), @@ -232,7 +235,7 @@ impl App { pub fn update(&mut self) { // Poll for request responses if let Ok((res, i)) = self.res_rx.try_recv() { - self.responses[i] = ResponsePanel::from(res); + self.responses[i].set_response(res); } if self.message_popup.is_none() { diff --git a/rq-cli/src/components/response_panel.rs b/rq-cli/src/components/response_panel.rs index 5b3d6e1..0bd7c30 100644 --- a/rq-cli/src/components/response_panel.rs +++ b/rq-cli/src/components/response_panel.rs @@ -1,7 +1,7 @@ use anyhow::anyhow; use crossterm::event::KeyCode; use ratatui::{ - style::{Color, Style}, + style::{Color, Modifier, Style}, text::{Line, Span}, widgets::{Block, Borders, Paragraph, Scrollbar, ScrollbarState, Wrap}, }; @@ -44,23 +44,30 @@ impl MenuItem for SaveOption { } } +#[derive(Clone, Default)] +enum State { + #[default] + Empty, + Loading, + Received(Response), +} + #[derive(Clone, Default)] pub struct ResponsePanel { - content: Option, + state: State, scroll: u16, input_popup: Option>, save_option: SaveOption, save_menu: Option>>, } -impl From for ResponsePanel { - fn from(value: Response) -> Self { - let default = Self::default(); +impl ResponsePanel { + pub fn set_loading(&mut self) { + self.state = State::Loading; + } - Self { - content: Some(value), - ..default - } + pub fn set_response(&mut self, value: Response) { + self.state = State::Received(value) } } @@ -74,15 +81,15 @@ impl ResponsePanel { } fn body(&self) -> anyhow::Result { - match &self.content { - Some(response) => Ok(response.body.clone()), - None => Err(anyhow!("Request not sent")), + match &self.state { + State::Received(response) => Ok(response.body.clone()), + State::Empty | State::Loading => Err(anyhow!("Request not sent")), } } fn to_string(&self) -> anyhow::Result { - match &self.content { - Some(response) => { + match &self.state { + State::Received(response) => { let headers = response .headers .iter() @@ -100,7 +107,7 @@ impl ResponsePanel { Ok(s) } - None => Err(anyhow!("Request not sent")), + State::Empty | State::Loading => Err(anyhow!("Request not sent")), } } } @@ -187,8 +194,8 @@ impl BlockComponent for ResponsePanel { Err(e) => e.to_string(), }; - let content = match &self.content { - Some(response) => { + let content = match &self.state { + State::Received(response) => { let mut lines = vec![]; // First line @@ -221,7 +228,18 @@ impl BlockComponent for ResponsePanel { lines } - None => vec![Line::styled("", Style::default().fg(Color::Yellow))], + State::Empty => vec![Line::styled( + "Empty", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::ITALIC), + )], + State::Loading => vec![Line::styled( + "Loading...", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::ITALIC), + )], }; let content_length = content.len();