diff --git a/src/components/cred.rs b/src/components/cred.rs index 916f50ba..8f0d526a 100644 --- a/src/components/cred.rs +++ b/src/components/cred.rs @@ -4,7 +4,7 @@ use tui::{backend::Backend, layout::Rect, Frame}; use asyncgit::sync::cred::BasicAuthCredential; -use crate::components::TextInputComponent; +use crate::components::{InputType, TextInputComponent}; use crate::{ components::{ visibility_blocking, CommandBlocking, CommandInfo, Component, @@ -37,13 +37,15 @@ impl CredComponent { key_config.clone(), &strings::username_popup_title(&key_config), &strings::username_popup_msg(&key_config), - ), + ) + .with_input_type(InputType::Singleline), input_password: TextInputComponent::new( theme, key_config.clone(), &strings::password_popup_title(&key_config), &strings::password_popup_msg(&key_config), - ), + ) + .with_input_type(InputType::Password), key_config, cred: BasicAuthCredential::new(None, None), } diff --git a/src/components/mod.rs b/src/components/mod.rs index 1fbd41f5..aa73b686 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -41,7 +41,7 @@ pub use reset::ResetComponent; pub use select_branch::SelectBranchComponent; pub use stashmsg::StashMsgComponent; pub use tag_commit::TagCommitComponent; -pub use textinput::TextInputComponent; +pub use textinput::{InputType, TextInputComponent}; pub use utils::filetree::FileTreeItemKind; use crate::ui::style::Theme; diff --git a/src/components/textinput.rs b/src/components/textinput.rs index 9cd6299d..267c9578 100644 --- a/src/components/textinput.rs +++ b/src/components/textinput.rs @@ -9,11 +9,20 @@ use crate::{ }; use anyhow::Result; use crossterm::event::{Event, KeyCode, KeyModifiers}; +use itertools::Itertools; +use std::ops::Range; use tui::{ backend::Backend, layout::Rect, style::Modifier, text::Span, widgets::Clear, Frame, }; +#[derive(PartialEq)] +pub enum InputType { + Singleline, + Multiline, + Password, +} + /// primarily a subcomponet for user input of text (used in `CommitComponent`) pub struct TextInputComponent { title: String, @@ -23,6 +32,7 @@ pub struct TextInputComponent { theme: SharedTheme, key_config: SharedKeyConfig, cursor_position: usize, + input_type: InputType, } impl TextInputComponent { @@ -41,9 +51,18 @@ impl TextInputComponent { title: title.to_string(), default_msg: default_msg.to_string(), cursor_position: 0, + input_type: InputType::Multiline, } } + pub const fn with_input_type( + mut self, + input_type: InputType, + ) -> Self { + self.input_type = input_type; + self + } + /// Clear the `msg`. pub fn clear(&mut self) { self.msg.clear(); @@ -113,7 +132,7 @@ impl TextInputComponent { // if the cursor is not at the first character. if self.cursor_position > 0 { txt.push(Span::styled( - &self.msg[..self.cursor_position], + self.get_msg(0..self.cursor_position), style, )); } @@ -122,7 +141,9 @@ impl TextInputComponent { .next_char_position() // if the cursor is at the end of the msg // a whitespace is used to underline - .map_or(" ", |pos| &self.msg[self.cursor_position..pos]); + .map_or(" ".to_owned(), |pos| { + self.get_msg(self.cursor_position..pos) + }); if cursor_str == "\n" { txt.push(Span::styled( @@ -142,12 +163,22 @@ impl TextInputComponent { // still remaining characters. if let Some(pos) = self.next_char_position() { if pos < self.msg.len() { - txt.push(Span::styled(&self.msg[pos..], style)); + txt.push(Span::styled( + self.get_msg(pos..self.msg.len()), + style, + )); } } txt } + + fn get_msg(&self, range: Range) -> String { + match self.input_type { + InputType::Password => range.map(|_| "*").join(""), + _ => self.msg[range].to_owned(), + } + } } impl DrawableComponent for TextInputComponent { @@ -166,8 +197,13 @@ impl DrawableComponent for TextInputComponent { self.get_draw_text() }; - let area = ui::centered_rect(60, 20, f.size()); - let area = ui::rect_min(10, 3, area); + let area = match self.input_type { + InputType::Multiline => { + let area = ui::centered_rect(60, 20, f.size()); + ui::rect_min(10, 3, area) + } + _ => ui::centered_rect_absolute(32, 3, f.size()), + }; f.render_widget(Clear, area); f.render_widget(