Skip to content

Commit

Permalink
Merge pull request #22 from zaghaghi/hz/footer-commands
Browse files Browse the repository at this point in the history
feat: ✨ added basic commands, and timed status lines
  • Loading branch information
zaghaghi authored Apr 9, 2024
2 parents 19cdbee + e657d42 commit 0abdd5d
Show file tree
Hide file tree
Showing 14 changed files with 169 additions and 137 deletions.
10 changes: 8 additions & 2 deletions src/action.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use serde::{Deserialize, Serialize};
use strum::Display;

type Command = String;
type Args = Option<String>;

#[derive(Debug, Clone, PartialEq, Serialize, Display, Deserialize)]
pub enum Action {
Tick,
Expand All @@ -14,6 +17,8 @@ pub enum Action {
Help,
FocusNext,
FocusPrev,
Focus,
UnFocus,
Up,
Down,
Submit,
Expand All @@ -25,8 +30,9 @@ pub enum Action {
Back,
ToggleFullScreen,
StatusLine(String),
FocusFooter(String),
FooterResult(String),
TimedStatusLine(String, u64),
FocusFooter(Command, Args),
FooterResult(Command, Args),
Noop,
NewCall,
HangUp(Option<String>),
Expand Down
55 changes: 41 additions & 14 deletions src/pages/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ impl Page for Home {
fn focus(&mut self) -> Result<()> {
if let Some(command_tx) = &self.command_tx {
const ARROW: &str = symbols::scrollbar::HORIZONTAL.end;
let status_line = format!("[l,h,j,k {ARROW} movement] [/ {ARROW} filter] [1-9 {ARROW} select tab] [g,b {ARROW} go/back definitions] [q {ARROW} quit]");
let status_line =
format!("[l,h {ARROW} pane movement] [/ {ARROW} api filter] [: {ARROW} commands] [q {ARROW} quit]");
command_tx.send(Action::StatusLine(status_line))?;
}
Ok(())
Expand All @@ -70,56 +71,80 @@ impl Page for Home {
}

fn update(&mut self, action: Action, state: &mut State) -> Result<Option<Action>> {
let mut actions: Vec<Option<Action>> = vec![];
match action {
Action::Tick => {},
Action::FocusNext => {
let next_index = self.focused_pane_index.saturating_add(1) % self.panes.len();
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
pane.unfocus()?;
actions.push(pane.update(Action::UnFocus, state)?);
}
self.focused_pane_index = next_index;
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
pane.focus()?;
actions.push(pane.update(Action::Focus, state)?);
}
},
Action::FocusPrev => {
let prev_index = self.focused_pane_index.saturating_add(self.panes.len() - 1) % self.panes.len();
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
pane.unfocus()?;
actions.push(pane.update(Action::UnFocus, state)?);
}
self.focused_pane_index = prev_index;
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
pane.focus()?;
actions.push(pane.update(Action::Focus, state)?);
}
},
Action::Update => {
for pane in self.panes.iter_mut() {
pane.update(action.clone(), state)?;
actions.push(pane.update(action.clone(), state)?);
}
},
Action::ToggleFullScreen => {
self.fullscreen_pane_index = self.fullscreen_pane_index.map_or(Some(self.focused_pane_index), |_| None);
},
Action::FocusFooter(_) => {
Action::FocusFooter(..) => {
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
pane.unfocus()?;
actions.push(pane.update(Action::UnFocus, state)?);
}
},
Action::FooterResult(filter) => {
Action::FooterResult(cmd, Some(args)) if cmd.eq("/") => {
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
pane.focus()?;
actions.push(pane.update(Action::Focus, state)?);
}
state.active_operation_index = 0;
state.active_filter = filter;
state.active_filter = args;

return Ok(Some(Action::Update));
actions.push(Some(Action::Update));
},
Action::FooterResult(cmd, Some(args)) if cmd.eq(":") => {
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
pane.update(Action::Focus, state)?;
}
if args.eq("q") {
actions.push(Some(Action::Quit));
} else if args.eq("request") {
actions.push(Some(Action::NewCall));
} else {
actions.push(Some(Action::TimedStatusLine("unknown command".into(), 1)));
}
},
Action::FooterResult(_cmd, None) => {
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
actions.push(pane.update(Action::Focus, state)?);
}
},
_ => {
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
return pane.update(action, state);
actions.push(pane.update(action, state)?);
}
},
}

if let Some(tx) = &mut self.command_tx {
actions.into_iter().flatten().for_each(|action| {
tx.send(action).ok();
});
}
Ok(None)
}

Expand All @@ -140,14 +165,16 @@ impl Page for Home {
},
KeyCode::Char(']') => EventResponse::Stop(Action::TabNext),
KeyCode::Char('[') => EventResponse::Stop(Action::TabPrev),
KeyCode::Char('/') => EventResponse::Stop(Action::FocusFooter(String::from("Filter:"))),
KeyCode::Char('/') => EventResponse::Stop(Action::FocusFooter("/".into(), Some(state.active_filter.clone()))),
KeyCode::Char(':') => EventResponse::Stop(Action::FocusFooter(":".into(), None)),
_ => {
return Ok(None);
},
};
Ok(Some(response))
},
InputMode::Insert => Ok(None),
InputMode::Command => Ok(None),
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/pages/phone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ impl Page for Phone {
}
Ok(None)
},
InputMode::Command => Ok(None),
}
}

Expand All @@ -160,21 +161,21 @@ impl Page for Phone {
Action::FocusNext => {
let next_index = self.focused_pane_index.saturating_add(1) % self.panes.len();
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
pane.unfocus()?;
pane.update(Action::UnFocus, state)?;
}
self.focused_pane_index = next_index;
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
pane.focus()?;
pane.update(Action::Focus, state)?;
}
},
Action::FocusPrev => {
let prev_index = self.focused_pane_index.saturating_add(self.panes.len() - 1) % self.panes.len();
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
pane.unfocus()?;
pane.update(Action::UnFocus, state)?;
}
self.focused_pane_index = prev_index;
if let Some(pane) = self.panes.get_mut(self.focused_pane_index) {
pane.focus()?;
pane.update(Action::Focus, state)?;
}
},
Action::ToggleFullScreen => {
Expand Down
18 changes: 8 additions & 10 deletions src/panes/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,20 @@ impl AddressPane {
}
}
impl Pane for AddressPane {
fn focus(&mut self) -> Result<()> {
self.focused = true;
Ok(())
}

fn unfocus(&mut self) -> Result<()> {
self.focused = false;
Ok(())
}

fn height_constraint(&self) -> Constraint {
Constraint::Max(3)
}

fn update(&mut self, action: Action, _state: &mut State) -> Result<Option<Action>> {
match action {
Action::Focus => {
self.focused = true;
static STATUS_LINE: &str = "[ENTER → request]";
return Ok(Some(Action::TimedStatusLine(STATUS_LINE.into(), 3)));
},
Action::UnFocus => {
self.focused = false;
},
Action::Update => {},
Action::Submit => {},
_ => {},
Expand Down
19 changes: 9 additions & 10 deletions src/panes/apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,8 @@ impl ApisPane {
}
}
}
impl Pane for ApisPane {
fn focus(&mut self) -> Result<()> {
self.focused = true;
Ok(())
}

fn unfocus(&mut self) -> Result<()> {
self.focused = false;
Ok(())
}

impl Pane for ApisPane {
fn height_constraint(&self) -> Constraint {
match self.focused {
true => Constraint::Fill(3),
Expand All @@ -83,6 +74,14 @@ impl Pane for ApisPane {
state.active_operation_index = self.current_operation_index;
return Ok(Some(Action::Update));
},
Action::Focus => {
self.focused = true;
static STATUS_LINE: &str = "[j,k → movement] [ENTER → request]";
return Ok(Some(Action::TimedStatusLine(STATUS_LINE.into(), 3)));
},
Action::UnFocus => {
self.focused = false;
},
Action::Submit => {},
Action::Update => {
self.current_operation_index = state.active_operation_index;
Expand Down
18 changes: 7 additions & 11 deletions src/panes/body_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,6 @@ impl Pane for BodyEditor<'_> {
Ok(())
}

fn focus(&mut self) -> Result<()> {
self.focused = true;
Ok(())
}

fn unfocus(&mut self) -> Result<()> {
self.focused = false;
Ok(())
}

fn height_constraint(&self) -> Constraint {
if self.content_types.is_empty() {
return Constraint::Fill(1);
Expand All @@ -102,7 +92,6 @@ impl Pane for BodyEditor<'_> {

fn handle_key_events(&mut self, key: KeyEvent, state: &mut State) -> Result<Option<EventResponse<Action>>> {
match state.input_mode {
InputMode::Normal => Ok(None),
InputMode::Insert => {
match key.code {
KeyCode::Esc => Ok(Some(EventResponse::Stop(Action::Submit))),
Expand All @@ -112,6 +101,7 @@ impl Pane for BodyEditor<'_> {
},
}
},
_ => Ok(None),
}
}

Expand Down Expand Up @@ -139,6 +129,12 @@ impl Pane for BodyEditor<'_> {
self.content_type_index =
if self.content_type_index > 0 { self.content_type_index - 1 } else { self.content_type_index };
},
Action::Focus => {
self.focused = true;
},
Action::UnFocus => {
self.focused = false;
},
_ => {},
}
Ok(None)
Expand Down
Loading

0 comments on commit 0abdd5d

Please sign in to comment.