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();
|
||||
}
|
||||
crossterm::event::Event::Key(KeyEvent {
|
||||
code: KeyCode::Char('c'),
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
..
|
||||
}) => {
|
||||
app.ui.cli_enable();
|
||||
}
|
||||
input => match app.ui.input_position() {
|
||||
ui::MainInputPosition::MessageCompose => {
|
||||
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) {
|
||||
self.state = state;
|
||||
}
|
||||
|
||||
pub fn cli_event(&mut self, event: String) {
|
||||
info!("CLI Event: {}", event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,13 +32,14 @@ pub enum SetupInputPosition {
|
|||
Ok,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum MainInputPosition {
|
||||
Status,
|
||||
Rooms,
|
||||
Messages,
|
||||
MessageCompose,
|
||||
RoomInfo,
|
||||
CLI,
|
||||
}
|
||||
|
||||
pub struct SetupUI<'a> {
|
||||
|
@ -55,6 +56,7 @@ pub struct UI<'a> {
|
|||
input_position: MainInputPosition,
|
||||
pub rooms_state: ListState,
|
||||
pub message_compose: TextArea<'a>,
|
||||
pub cli: Option<TextArea<'a>>,
|
||||
|
||||
pub setup_ui: Option<SetupUI<'a>>,
|
||||
}
|
||||
|
@ -266,6 +268,7 @@ impl UI<'_> {
|
|||
input_position: MainInputPosition::Rooms,
|
||||
rooms_state: ListState::default(),
|
||||
message_compose,
|
||||
cli: None,
|
||||
setup_ui: None,
|
||||
}
|
||||
}
|
||||
|
@ -276,17 +279,25 @@ impl UI<'_> {
|
|||
MainInputPosition::Rooms => MainInputPosition::Messages,
|
||||
MainInputPosition::Messages => MainInputPosition::MessageCompose,
|
||||
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) {
|
||||
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::Messages => MainInputPosition::Rooms,
|
||||
MainInputPosition::MessageCompose => MainInputPosition::Messages,
|
||||
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<()> {
|
||||
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()
|
||||
.direction(Direction::Horizontal)
|
||||
|
@ -316,7 +350,7 @@ impl UI<'_> {
|
|||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(chunk);
|
||||
.split(chunks[0]);
|
||||
|
||||
let left_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
|
@ -450,6 +484,9 @@ impl UI<'_> {
|
|||
let colors = match self.input_position {
|
||||
MainInputPosition::Status => {
|
||||
textarea_inactivate(&mut self.message_compose);
|
||||
if let Some(cli) = &mut self.cli {
|
||||
textarea_inactivate(cli);
|
||||
}
|
||||
vec![
|
||||
Color::White,
|
||||
Color::DarkGray,
|
||||
|
@ -460,6 +497,9 @@ impl UI<'_> {
|
|||
}
|
||||
MainInputPosition::Rooms => {
|
||||
textarea_inactivate(&mut self.message_compose);
|
||||
if let Some(cli) = &mut self.cli {
|
||||
textarea_inactivate(cli);
|
||||
}
|
||||
vec![
|
||||
Color::DarkGray,
|
||||
Color::White,
|
||||
|
@ -470,6 +510,9 @@ impl UI<'_> {
|
|||
}
|
||||
MainInputPosition::Messages => {
|
||||
textarea_inactivate(&mut self.message_compose);
|
||||
if let Some(cli) = &mut self.cli {
|
||||
textarea_inactivate(cli);
|
||||
}
|
||||
vec![
|
||||
Color::DarkGray,
|
||||
Color::DarkGray,
|
||||
|
@ -480,6 +523,9 @@ impl UI<'_> {
|
|||
}
|
||||
MainInputPosition::MessageCompose => {
|
||||
textarea_activate(&mut self.message_compose);
|
||||
if let Some(cli) = &mut self.cli {
|
||||
textarea_inactivate(cli);
|
||||
}
|
||||
vec![
|
||||
Color::DarkGray,
|
||||
Color::DarkGray,
|
||||
|
@ -490,6 +536,9 @@ impl UI<'_> {
|
|||
}
|
||||
MainInputPosition::RoomInfo => {
|
||||
textarea_inactivate(&mut self.message_compose);
|
||||
if let Some(cli) = &mut self.cli {
|
||||
textarea_inactivate(cli);
|
||||
}
|
||||
vec![
|
||||
Color::DarkGray,
|
||||
Color::DarkGray,
|
||||
|
@ -498,6 +547,19 @@ impl UI<'_> {
|
|||
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
|
||||
|
@ -555,6 +617,10 @@ impl UI<'_> {
|
|||
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_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]);
|
||||
})?;
|
||||
|
||||
|
|
Reference in New Issue