Migrate account popup to AsyncWidget

This commit is contained in:
Joscha 2023-04-13 02:08:10 +02:00
parent 03766802fd
commit 91d8d7ba97
2 changed files with 61 additions and 56 deletions

View file

@ -1,18 +1,13 @@
use crossterm::style::Stylize; use crossterm::style::Stylize;
use euphoxide::api::PersonalAccountView; use euphoxide::api::PersonalAccountView;
use euphoxide::conn; use euphoxide::conn;
use toss::{Style, Terminal}; use toss::widgets::{BoxedAsync, EditorState, Empty, Join3, Join4, Text};
use toss::{Style, Terminal, WidgetExt};
use crate::euph::{self, Room}; use crate::euph::{self, Room};
use crate::ui::input::{key, InputEvent, KeyBindingsList}; use crate::ui::input::{key, InputEvent, KeyBindingsList};
use crate::ui::util; use crate::ui::widgets2::Popup;
use crate::ui::widgets::editor::EditorState; use crate::ui::{util2, UiError};
use crate::ui::widgets::empty::Empty;
use crate::ui::widgets::join::{HJoin, Segment, VJoin};
use crate::ui::widgets::popup::Popup;
use crate::ui::widgets::resize::Resize;
use crate::ui::widgets::text::Text;
use crate::ui::widgets::BoxedWidget;
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Focus { enum Focus {
@ -35,46 +30,55 @@ impl LoggedOut {
} }
} }
fn widget(&self) -> BoxedWidget { fn widget(&mut self) -> BoxedAsync<'_, UiError> {
let bold = Style::new().bold(); let bold = Style::new().bold();
VJoin::new(vec![ Join4::vertical(
Segment::new(Text::new(("Not logged in", bold.yellow()))), Text::new(("Not logged in", bold.yellow())).segment(),
Segment::new(Empty::new().height(1)), Empty::new().with_height(1).segment(),
Segment::new(HJoin::new(vec![ Join3::horizontal(
Segment::new(Text::new(("Email address:", bold))), Text::new(("Email address:", bold))
Segment::new(Empty::new().width(1)), .segment()
Segment::new(self.email.widget().focus(self.focus == Focus::Email)), .with_fixed(true),
])), Empty::new().with_width(1).segment().with_fixed(true),
Segment::new(HJoin::new(vec![ self.email
Segment::new(Text::new(("Password:", bold))), .widget()
Segment::new(Empty::new().width(5 + 1)), .with_focus(self.focus == Focus::Email)
Segment::new( .segment(),
)
.segment(),
Join3::horizontal(
Text::new(("Password:", bold)).segment().with_fixed(true),
Empty::new().with_width(5 + 1).segment().with_fixed(true),
self.password self.password
.widget() .widget()
.focus(self.focus == Focus::Password) .with_focus(self.focus == Focus::Password)
.hidden(), .with_hidden_default_placeholder()
), .segment(),
])), )
]) .segment(),
.into() )
.boxed_async()
} }
} }
pub struct LoggedIn(PersonalAccountView); pub struct LoggedIn(PersonalAccountView);
impl LoggedIn { impl LoggedIn {
fn widget(&self) -> BoxedWidget { fn widget(&self) -> BoxedAsync<'_, UiError> {
let bold = Style::new().bold(); let bold = Style::new().bold();
VJoin::new(vec![ Join3::vertical(
Segment::new(Text::new(("Logged in", bold.green()))), Text::new(("Logged in", bold.green())).segment(),
Segment::new(Empty::new().height(1)), Empty::new().with_height(1).segment(),
Segment::new(HJoin::new(vec![ Join3::horizontal(
Segment::new(Text::new(("Email address:", bold))), Text::new(("Email address:", bold))
Segment::new(Empty::new().width(1)), .segment()
Segment::new(Text::new((&self.0.email,))), .with_fixed(true),
])), Empty::new().with_width(1).segment().with_fixed(true),
]) Text::new((&self.0.email,)).segment(),
.into() )
.segment(),
)
.boxed_async()
} }
} }
@ -108,14 +112,15 @@ impl AccountUiState {
} }
} }
pub fn widget(&self) -> BoxedWidget { pub fn widget(&mut self) -> BoxedAsync<'_, UiError> {
let inner = match self { let inner = match self {
Self::LoggedOut(logged_out) => logged_out.widget(), Self::LoggedOut(logged_out) => logged_out.widget(),
Self::LoggedIn(logged_in) => logged_in.widget(), Self::LoggedIn(logged_in) => logged_in.widget(),
}; }
Popup::new(Resize::new(inner).min_width(40)) .resize()
.title("Account") .with_min_width(40);
.build()
Popup::new(inner, "Account").boxed_async()
} }
pub fn list_key_bindings(&self, bindings: &mut KeyBindingsList) { pub fn list_key_bindings(&self, bindings: &mut KeyBindingsList) {
@ -128,7 +133,7 @@ impl AccountUiState {
Focus::Password => bindings.binding("enter", "log in"), Focus::Password => bindings.binding("enter", "log in"),
} }
bindings.binding("tab", "switch focus"); bindings.binding("tab", "switch focus");
util::list_editor_key_bindings(bindings, |c| c != '\n'); util2::list_editor_key_bindings(bindings, |c| c != '\n');
} }
Self::LoggedIn(_) => bindings.binding("L", "log out"), Self::LoggedIn(_) => bindings.binding("L", "log out"),
} }
@ -161,8 +166,8 @@ impl AccountUiState {
return EventResult::Handled; return EventResult::Handled;
} }
if util::handle_editor_input_event( if util2::handle_editor_input_event(
&logged_out.email, &mut logged_out.email,
terminal, terminal,
event, event,
|c| c != '\n', |c| c != '\n',
@ -175,14 +180,16 @@ impl AccountUiState {
Focus::Password => { Focus::Password => {
if let key!(Enter) = event { if let key!(Enter) = event {
if let Some(room) = room { if let Some(room) = room {
let _ = let _ = room.login(
room.login(logged_out.email.text(), logged_out.password.text()); logged_out.email.text().to_string(),
logged_out.password.text().to_string(),
);
} }
return EventResult::Handled; return EventResult::Handled;
} }
if util::handle_editor_input_event( if util2::handle_editor_input_event(
&logged_out.password, &mut logged_out.password,
terminal, terminal,
event, event,
|c| c != '\n', |c| c != '\n',

View file

@ -226,9 +226,7 @@ impl EuphRoom {
State::Normal => {} State::Normal => {}
State::Auth(editor) => layers.push(auth::widget(editor)), State::Auth(editor) => layers.push(auth::widget(editor)),
State::Nick(editor) => layers.push(nick::widget(editor)), State::Nick(editor) => layers.push(nick::widget(editor)),
State::Account(account) => { State::Account(account) => layers.push(account.widget()),
layers.push(WidgetWrapper::new(account.widget()).boxed_async())
}
State::Links(links) => layers.push(WidgetWrapper::new(links.widget()).boxed_async()), State::Links(links) => layers.push(WidgetWrapper::new(links.widget()).boxed_async()),
State::InspectMessage(message) => { State::InspectMessage(message) => {
layers.push(WidgetWrapper::new(inspect::message_widget(message)).boxed_async()) layers.push(WidgetWrapper::new(inspect::message_widget(message)).boxed_async())