feature (ui): added a cli panel to contoll the UI similar to what you have when hitting colon in vim
This commit is contained in:
parent
8d6e7c976e
commit
200b9143b3
|
@ -132,6 +132,13 @@ impl Event {
|
||||||
}) => {
|
}) => {
|
||||||
app.ui.cycle_main_input_position_rev();
|
app.ui.cycle_main_input_position_rev();
|
||||||
}
|
}
|
||||||
|
crossterm::event::Event::Key(KeyEvent {
|
||||||
|
code: KeyCode::Char('c'),
|
||||||
|
modifiers: KeyModifiers::CONTROL,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
app.ui.cli_enable();
|
||||||
|
}
|
||||||
input => match app.ui.input_position() {
|
input => match app.ui.input_position() {
|
||||||
ui::MainInputPosition::MessageCompose => {
|
ui::MainInputPosition::MessageCompose => {
|
||||||
match input {
|
match input {
|
||||||
|
@ -239,6 +246,23 @@ impl Event {
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
ui::MainInputPosition::CLI => {
|
||||||
|
if let Some(cli) = &mut app.ui.cli {
|
||||||
|
match input {
|
||||||
|
crossterm::event::Event::Key(KeyEvent {
|
||||||
|
code: KeyCode::Enter,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
let cli_event = cli.lines()[0].clone();
|
||||||
|
app.status.cli_event(cli_event);
|
||||||
|
app.ui.cli_disable();
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
cli.input(tui_textarea::Input::from(input));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -206,4 +206,8 @@ impl Status {
|
||||||
pub fn set_state(&mut self, state: State) {
|
pub fn set_state(&mut self, state: State) {
|
||||||
self.state = state;
|
self.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cli_event(&mut self, event: String) {
|
||||||
|
info!("CLI Event: {}", event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,13 +32,14 @@ pub enum SetupInputPosition {
|
||||||
Ok,
|
Ok,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum MainInputPosition {
|
pub enum MainInputPosition {
|
||||||
Status,
|
Status,
|
||||||
Rooms,
|
Rooms,
|
||||||
Messages,
|
Messages,
|
||||||
MessageCompose,
|
MessageCompose,
|
||||||
RoomInfo,
|
RoomInfo,
|
||||||
|
CLI,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SetupUI<'a> {
|
pub struct SetupUI<'a> {
|
||||||
|
@ -55,6 +56,7 @@ pub struct UI<'a> {
|
||||||
input_position: MainInputPosition,
|
input_position: MainInputPosition,
|
||||||
pub rooms_state: ListState,
|
pub rooms_state: ListState,
|
||||||
pub message_compose: TextArea<'a>,
|
pub message_compose: TextArea<'a>,
|
||||||
|
pub cli: Option<TextArea<'a>>,
|
||||||
|
|
||||||
pub setup_ui: Option<SetupUI<'a>>,
|
pub setup_ui: Option<SetupUI<'a>>,
|
||||||
}
|
}
|
||||||
|
@ -266,6 +268,7 @@ impl UI<'_> {
|
||||||
input_position: MainInputPosition::Rooms,
|
input_position: MainInputPosition::Rooms,
|
||||||
rooms_state: ListState::default(),
|
rooms_state: ListState::default(),
|
||||||
message_compose,
|
message_compose,
|
||||||
|
cli: None,
|
||||||
setup_ui: None,
|
setup_ui: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,17 +279,25 @@ impl UI<'_> {
|
||||||
MainInputPosition::Rooms => MainInputPosition::Messages,
|
MainInputPosition::Rooms => MainInputPosition::Messages,
|
||||||
MainInputPosition::Messages => MainInputPosition::MessageCompose,
|
MainInputPosition::Messages => MainInputPosition::MessageCompose,
|
||||||
MainInputPosition::MessageCompose => MainInputPosition::RoomInfo,
|
MainInputPosition::MessageCompose => MainInputPosition::RoomInfo,
|
||||||
MainInputPosition::RoomInfo => MainInputPosition::Status,
|
MainInputPosition::RoomInfo => match self.cli {
|
||||||
|
Some(_) => MainInputPosition::CLI,
|
||||||
|
None => MainInputPosition::Status,
|
||||||
|
},
|
||||||
|
MainInputPosition::CLI => MainInputPosition::Status,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cycle_main_input_position_rev(&mut self) {
|
pub fn cycle_main_input_position_rev(&mut self) {
|
||||||
self.input_position = match self.input_position {
|
self.input_position = match self.input_position {
|
||||||
MainInputPosition::Status => MainInputPosition::RoomInfo,
|
MainInputPosition::Status => match self.cli {
|
||||||
|
Some(_) => MainInputPosition::CLI,
|
||||||
|
None => MainInputPosition::RoomInfo,
|
||||||
|
},
|
||||||
MainInputPosition::Rooms => MainInputPosition::Status,
|
MainInputPosition::Rooms => MainInputPosition::Status,
|
||||||
MainInputPosition::Messages => MainInputPosition::Rooms,
|
MainInputPosition::Messages => MainInputPosition::Rooms,
|
||||||
MainInputPosition::MessageCompose => MainInputPosition::Messages,
|
MainInputPosition::MessageCompose => MainInputPosition::Messages,
|
||||||
MainInputPosition::RoomInfo => MainInputPosition::MessageCompose,
|
MainInputPosition::RoomInfo => MainInputPosition::MessageCompose,
|
||||||
|
MainInputPosition::CLI => MainInputPosition::RoomInfo,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,8 +314,31 @@ impl UI<'_> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cli_enable(&mut self) {
|
||||||
|
self.input_position = MainInputPosition::CLI;
|
||||||
|
if self.cli.is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut cli = TextArea::default();
|
||||||
|
cli.set_block(Block::default().borders(Borders::ALL));
|
||||||
|
self.cli = Some(cli);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cli_disable(&mut self) {
|
||||||
|
if self.input_position == MainInputPosition::CLI {
|
||||||
|
self.cycle_main_input_position();
|
||||||
|
}
|
||||||
|
self.cli = None;
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update(&mut self, status: &Status) -> Result<()> {
|
pub async fn update(&mut self, status: &Status) -> Result<()> {
|
||||||
let chunk = self.terminal.size()?;
|
let chunks = match self.cli {
|
||||||
|
Some(_) => Layout::default()
|
||||||
|
.direction(Direction::Vertical)
|
||||||
|
.constraints([Constraint::Min(10), Constraint::Length(3)].as_ref())
|
||||||
|
.split(self.terminal.size()?),
|
||||||
|
None => vec![self.terminal.size()?],
|
||||||
|
};
|
||||||
|
|
||||||
let main_chunks = Layout::default()
|
let main_chunks = Layout::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
|
@ -316,7 +350,7 @@ impl UI<'_> {
|
||||||
]
|
]
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
)
|
)
|
||||||
.split(chunk);
|
.split(chunks[0]);
|
||||||
|
|
||||||
let left_chunks = Layout::default()
|
let left_chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
|
@ -450,6 +484,9 @@ impl UI<'_> {
|
||||||
let colors = match self.input_position {
|
let colors = match self.input_position {
|
||||||
MainInputPosition::Status => {
|
MainInputPosition::Status => {
|
||||||
textarea_inactivate(&mut self.message_compose);
|
textarea_inactivate(&mut self.message_compose);
|
||||||
|
if let Some(cli) = &mut self.cli {
|
||||||
|
textarea_inactivate(cli);
|
||||||
|
}
|
||||||
vec![
|
vec![
|
||||||
Color::White,
|
Color::White,
|
||||||
Color::DarkGray,
|
Color::DarkGray,
|
||||||
|
@ -460,6 +497,9 @@ impl UI<'_> {
|
||||||
}
|
}
|
||||||
MainInputPosition::Rooms => {
|
MainInputPosition::Rooms => {
|
||||||
textarea_inactivate(&mut self.message_compose);
|
textarea_inactivate(&mut self.message_compose);
|
||||||
|
if let Some(cli) = &mut self.cli {
|
||||||
|
textarea_inactivate(cli);
|
||||||
|
}
|
||||||
vec![
|
vec![
|
||||||
Color::DarkGray,
|
Color::DarkGray,
|
||||||
Color::White,
|
Color::White,
|
||||||
|
@ -470,6 +510,9 @@ impl UI<'_> {
|
||||||
}
|
}
|
||||||
MainInputPosition::Messages => {
|
MainInputPosition::Messages => {
|
||||||
textarea_inactivate(&mut self.message_compose);
|
textarea_inactivate(&mut self.message_compose);
|
||||||
|
if let Some(cli) = &mut self.cli {
|
||||||
|
textarea_inactivate(cli);
|
||||||
|
}
|
||||||
vec![
|
vec![
|
||||||
Color::DarkGray,
|
Color::DarkGray,
|
||||||
Color::DarkGray,
|
Color::DarkGray,
|
||||||
|
@ -480,6 +523,9 @@ impl UI<'_> {
|
||||||
}
|
}
|
||||||
MainInputPosition::MessageCompose => {
|
MainInputPosition::MessageCompose => {
|
||||||
textarea_activate(&mut self.message_compose);
|
textarea_activate(&mut self.message_compose);
|
||||||
|
if let Some(cli) = &mut self.cli {
|
||||||
|
textarea_inactivate(cli);
|
||||||
|
}
|
||||||
vec![
|
vec![
|
||||||
Color::DarkGray,
|
Color::DarkGray,
|
||||||
Color::DarkGray,
|
Color::DarkGray,
|
||||||
|
@ -490,6 +536,9 @@ impl UI<'_> {
|
||||||
}
|
}
|
||||||
MainInputPosition::RoomInfo => {
|
MainInputPosition::RoomInfo => {
|
||||||
textarea_inactivate(&mut self.message_compose);
|
textarea_inactivate(&mut self.message_compose);
|
||||||
|
if let Some(cli) = &mut self.cli {
|
||||||
|
textarea_inactivate(cli);
|
||||||
|
}
|
||||||
vec![
|
vec![
|
||||||
Color::DarkGray,
|
Color::DarkGray,
|
||||||
Color::DarkGray,
|
Color::DarkGray,
|
||||||
|
@ -498,6 +547,19 @@ impl UI<'_> {
|
||||||
Color::White,
|
Color::White,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
MainInputPosition::CLI => {
|
||||||
|
textarea_inactivate(&mut self.message_compose);
|
||||||
|
if let Some(cli) = &mut self.cli {
|
||||||
|
textarea_activate(cli);
|
||||||
|
}
|
||||||
|
vec![
|
||||||
|
Color::DarkGray,
|
||||||
|
Color::DarkGray,
|
||||||
|
Color::DarkGray,
|
||||||
|
Color::DarkGray,
|
||||||
|
Color::DarkGray,
|
||||||
|
]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// initiate the widgets
|
// initiate the widgets
|
||||||
|
@ -555,6 +617,10 @@ impl UI<'_> {
|
||||||
frame.render_stateful_widget(rooms_panel, left_chunks[1], &mut self.rooms_state);
|
frame.render_stateful_widget(rooms_panel, left_chunks[1], &mut self.rooms_state);
|
||||||
frame.render_stateful_widget(messages_panel, middle_chunks[0], &mut messages_state);
|
frame.render_stateful_widget(messages_panel, middle_chunks[0], &mut messages_state);
|
||||||
frame.render_widget(self.message_compose.widget(), middle_chunks[1]);
|
frame.render_widget(self.message_compose.widget(), middle_chunks[1]);
|
||||||
|
match &self.cli {
|
||||||
|
Some(cli) => frame.render_widget(cli.widget(), chunks[1]),
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
frame.render_widget(room_info_panel, right_chunks[0]);
|
frame.render_widget(room_info_panel, right_chunks[0]);
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|
Reference in New Issue