168 lines
4.9 KiB
Rust
168 lines
4.9 KiB
Rust
use kkdisp::{
|
|
component::{Plan, Widget},
|
|
theme::Color,
|
|
token::Token,
|
|
view::{Event, Key},
|
|
Action,
|
|
};
|
|
|
|
use crate::Message;
|
|
pub enum LoginFocus {
|
|
Hostname,
|
|
Token,
|
|
OK,
|
|
}
|
|
|
|
impl LoginFocus {
|
|
fn ok(&self) -> bool {
|
|
match self {
|
|
LoginFocus::OK => true,
|
|
_ => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct LoginPrompt {
|
|
hostname: String,
|
|
token: String,
|
|
error: Option<String>,
|
|
focus: LoginFocus,
|
|
}
|
|
|
|
impl From<&LoginPrompt> for Plan {
|
|
fn from(value: &LoginPrompt) -> Self {
|
|
Plan::start()
|
|
.fill(vec![])
|
|
.fixed(8, vec![Widget::new(100, value.tokens())])
|
|
.fill(vec![])
|
|
}
|
|
}
|
|
|
|
impl LoginPrompt {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
hostname: String::new(),
|
|
token: String::new(),
|
|
error: None,
|
|
focus: LoginFocus::Hostname,
|
|
}
|
|
}
|
|
|
|
fn backspace(&mut self) {
|
|
match self.focus {
|
|
LoginFocus::Hostname => {
|
|
self.hostname.pop();
|
|
}
|
|
LoginFocus::Token => {
|
|
self.token.pop();
|
|
}
|
|
LoginFocus::OK => {}
|
|
}
|
|
}
|
|
|
|
pub fn attempt(&self) -> Result<(), anyhow::Error> {
|
|
todo!()
|
|
}
|
|
|
|
pub fn update(
|
|
&mut self,
|
|
event: Event<Message>,
|
|
) -> Result<Action, anyhow::Error> {
|
|
match event {
|
|
Event::Link(lnk) => {
|
|
if lnk == "ok" {
|
|
todo!()
|
|
} else {
|
|
Ok(Action::Nothing)
|
|
}
|
|
}
|
|
Event::Input(input) => {
|
|
match input {
|
|
Key::Backspace => self.backspace(),
|
|
Key::Up => {
|
|
self.focus = match self.focus {
|
|
LoginFocus::Hostname => LoginFocus::OK,
|
|
LoginFocus::Token => LoginFocus::Hostname,
|
|
LoginFocus::OK => LoginFocus::Token,
|
|
};
|
|
}
|
|
Key::Down => {
|
|
self.focus = match self.focus {
|
|
LoginFocus::Hostname => LoginFocus::Token,
|
|
LoginFocus::Token => LoginFocus::OK,
|
|
LoginFocus::OK => LoginFocus::Hostname,
|
|
};
|
|
}
|
|
Key::Char(c) => {
|
|
if c == '\n' {
|
|
if self.focus.ok() {
|
|
self.attempt()?;
|
|
}
|
|
} else if c == '\t' {
|
|
} else {
|
|
match self.focus {
|
|
LoginFocus::Hostname => {
|
|
self.hostname.push(c)
|
|
}
|
|
LoginFocus::Token => {
|
|
self.token.push(c)
|
|
}
|
|
LoginFocus::OK => {}
|
|
}
|
|
}
|
|
}
|
|
Key::Ctrl(c) => {
|
|
if c == 'u' || c == 'U' {
|
|
match self.focus {
|
|
LoginFocus::Hostname => {
|
|
self.hostname = String::new();
|
|
}
|
|
LoginFocus::Token => {
|
|
self.token = String::new()
|
|
}
|
|
LoginFocus::OK => {}
|
|
}
|
|
}
|
|
}
|
|
Key::Esc => {
|
|
self.focus = LoginFocus::OK;
|
|
}
|
|
_ => {
|
|
return Ok(Action::Nothing);
|
|
}
|
|
};
|
|
Ok(Action::ReplaceAll(vec![(&*self).into()]))
|
|
}
|
|
Event::Message(_) => todo!(),
|
|
}
|
|
}
|
|
|
|
fn tokens(&self) -> Vec<Token> {
|
|
let mut hostname =
|
|
Token::text(self.hostname.clone()).padded(10);
|
|
let mut token = Token::text(self.token.clone()).padded(10);
|
|
let mut ok = Token::text("[ok]");
|
|
match self.focus {
|
|
LoginFocus::Hostname => {
|
|
hostname = hostname.bg(Color::BLUE)
|
|
}
|
|
LoginFocus::Token => token = token.bg(Color::BLUE),
|
|
LoginFocus::OK => ok = ok.bg(Color::BLUE),
|
|
};
|
|
vec![
|
|
Token::text("kkx cfg")
|
|
.bg(Color::BLUE)
|
|
.fg(Color::WHITE)
|
|
.centered(),
|
|
Token::End,
|
|
match &self.error {
|
|
Some(e) => Token::text(e).fg(Color::RED),
|
|
None => Token::End,
|
|
},
|
|
hostname.string("hostname: ").centered(),
|
|
token.string("token: ").centered(),
|
|
ok.link("ok").centered(),
|
|
]
|
|
}
|
|
}
|