Move login business logic to LoginManager
Signed-off-by: kernelkind <kernelkind@gmail.com> Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
committed by
William Casarin
parent
5396085d96
commit
b8229fb9a9
@@ -1,5 +1,5 @@
|
|||||||
use crate::app_style::NotedeckTextStyle;
|
use crate::app_style::NotedeckTextStyle;
|
||||||
use crate::key_parsing::{perform_key_retrieval, LoginError};
|
use crate::key_parsing::LoginError;
|
||||||
use crate::login_manager::LoginManager;
|
use crate::login_manager::LoginManager;
|
||||||
use crate::ui;
|
use crate::ui;
|
||||||
use crate::ui::{Preview, View};
|
use crate::ui::{Preview, View};
|
||||||
@@ -7,7 +7,7 @@ use egui::{
|
|||||||
Align, Align2, Button, Color32, Frame, Id, LayerId, Margin, Pos2, Rect, RichText, Rounding, Ui,
|
Align, Align2, Button, Color32, Frame, Id, LayerId, Margin, Pos2, Rect, RichText, Rounding, Ui,
|
||||||
Vec2, Window,
|
Vec2, Window,
|
||||||
};
|
};
|
||||||
use egui::{Image, TextBuffer, TextEdit};
|
use egui::{Image, TextEdit};
|
||||||
|
|
||||||
pub struct AccountLoginView<'a> {
|
pub struct AccountLoginView<'a> {
|
||||||
manager: &'a mut LoginManager,
|
manager: &'a mut LoginManager,
|
||||||
@@ -92,10 +92,10 @@ impl<'a> AccountLoginView<'a> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ui.vertical_centered_justified(|ui| {
|
ui.vertical_centered_justified(|ui| {
|
||||||
ui.add(login_textedit(&mut self.manager.login_key));
|
ui.add(login_textedit(self.manager));
|
||||||
|
|
||||||
if ui.add(login_button()).clicked() {
|
if ui.add(login_button()).clicked() {
|
||||||
self.manager.promise = Some(perform_key_retrieval(&self.manager.login_key));
|
self.manager.apply_login();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -217,23 +217,17 @@ impl<'a> AccountLoginView<'a> {
|
|||||||
|
|
||||||
ui.add_space(8f32);
|
ui.add_space(8f32);
|
||||||
|
|
||||||
ui.add(login_textedit(&mut self.manager.login_key).min_size(Vec2::new(440.0, 40.0)));
|
ui.add(login_textedit(self.manager).min_size(Vec2::new(440.0, 40.0)));
|
||||||
|
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
|
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
if self.manager.promise.is_some() {
|
if self.manager.is_awaiting_network() {
|
||||||
ui.add(egui::Spinner::new());
|
ui.add(egui::Spinner::new());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(error_key) = &self.manager.key_on_error {
|
if let Some(err) = self.manager.check_for_error() {
|
||||||
if self.manager.login_key != *error_key {
|
|
||||||
self.manager.error = None;
|
|
||||||
self.manager.key_on_error = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(err) = &self.manager.error {
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let error_label = match err {
|
let error_label = match err {
|
||||||
LoginError::InvalidKey => egui::Label::new(
|
LoginError::InvalidKey => egui::Label::new(
|
||||||
@@ -252,7 +246,7 @@ impl<'a> AccountLoginView<'a> {
|
|||||||
let login_button = login_button().min_size(Vec2::new(442.0, 40.0));
|
let login_button = login_button().min_size(Vec2::new(442.0, 40.0));
|
||||||
|
|
||||||
if ui.add(login_button).clicked() {
|
if ui.add(login_button).clicked() {
|
||||||
self.manager.promise = Some(perform_key_retrieval(&self.manager.login_key));
|
self.manager.apply_login()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -332,14 +326,16 @@ fn login_button() -> Button<'static> {
|
|||||||
.min_size(Vec2::new(0.0, 40.0))
|
.min_size(Vec2::new(0.0, 40.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn login_textedit(text: &mut dyn TextBuffer) -> TextEdit {
|
fn login_textedit(manager: &mut LoginManager) -> TextEdit {
|
||||||
egui::TextEdit::singleline(text)
|
manager.get_login_textedit(|text| {
|
||||||
.hint_text(
|
egui::TextEdit::singleline(text)
|
||||||
RichText::new("Your key here...").text_style(NotedeckTextStyle::Body.text_style()),
|
.hint_text(
|
||||||
)
|
RichText::new("Your key here...").text_style(NotedeckTextStyle::Body.text_style()),
|
||||||
.vertical_align(Align::Center)
|
)
|
||||||
.min_size(Vec2::new(0.0, 40.0))
|
.vertical_align(Align::Center)
|
||||||
.margin(Margin::same(12.0))
|
.min_size(Vec2::new(0.0, 40.0))
|
||||||
|
.margin(Margin::same(12.0))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AccountLoginPreview {
|
pub struct AccountLoginPreview {
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
use crate::key_parsing::perform_key_retrieval;
|
||||||
use crate::key_parsing::LoginError;
|
use crate::key_parsing::LoginError;
|
||||||
|
use egui::{TextBuffer, TextEdit};
|
||||||
use nostr_sdk::Keys;
|
use nostr_sdk::Keys;
|
||||||
use poll_promise::Promise;
|
use poll_promise::Promise;
|
||||||
|
|
||||||
@@ -6,14 +8,105 @@ use poll_promise::Promise;
|
|||||||
/// nostr-sdk Keys object if possible.
|
/// nostr-sdk Keys object if possible.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct LoginManager {
|
pub struct LoginManager {
|
||||||
pub login_key: String,
|
login_key: String,
|
||||||
pub promise: Option<Promise<Result<Keys, LoginError>>>,
|
promise: Option<Promise<Result<Keys, LoginError>>>,
|
||||||
pub error: Option<LoginError>,
|
error: Option<LoginError>,
|
||||||
pub key_on_error: Option<String>,
|
key_on_error: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LoginManager {
|
impl<'a> LoginManager {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
LoginManager::default()
|
LoginManager {
|
||||||
|
login_key: String::new(),
|
||||||
|
promise: None,
|
||||||
|
error: None,
|
||||||
|
key_on_error: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_login_textedit(
|
||||||
|
&'a mut self,
|
||||||
|
textedit_closure: fn(&'a mut dyn TextBuffer) -> TextEdit<'a>,
|
||||||
|
) -> TextEdit<'a> {
|
||||||
|
textedit_closure(&mut self.login_key)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply_login(&'a mut self) {
|
||||||
|
self.promise = Some(perform_key_retrieval(&self.login_key));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_awaiting_network(&self) -> bool {
|
||||||
|
self.promise.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_for_error(&'a mut self) -> Option<&'a LoginError> {
|
||||||
|
if let Some(error_key) = &self.key_on_error {
|
||||||
|
if self.login_key != *error_key {
|
||||||
|
self.error = None;
|
||||||
|
self.key_on_error = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.error.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_for_successful_login(&mut self) -> Option<Keys> {
|
||||||
|
if let Some(promise) = &mut self.promise {
|
||||||
|
if promise.ready().is_some() {
|
||||||
|
if let Some(promise) = self.promise.take() {
|
||||||
|
match promise.block_and_take() {
|
||||||
|
Ok(key) => {
|
||||||
|
return Some(key);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
self.error = Some(e);
|
||||||
|
self.key_on_error = Some(self.login_key.clone());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use nostr_sdk::PublicKey;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_retrieve_key() {
|
||||||
|
let mut manager = LoginManager::new();
|
||||||
|
let manager_ref = &mut manager;
|
||||||
|
let expected_str = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681";
|
||||||
|
let expected_key = Keys::from_public_key(PublicKey::from_hex(expected_str).unwrap());
|
||||||
|
|
||||||
|
let start_time = Instant::now();
|
||||||
|
|
||||||
|
while start_time.elapsed() < Duration::from_millis(50u64) {
|
||||||
|
let cur_time = start_time.elapsed();
|
||||||
|
|
||||||
|
if cur_time < Duration::from_millis(10u64) {
|
||||||
|
let key = "test";
|
||||||
|
manager_ref.login_key = String::from(key);
|
||||||
|
manager_ref.promise = Some(perform_key_retrieval(key));
|
||||||
|
} else if cur_time < Duration::from_millis(30u64) {
|
||||||
|
let key = "test2";
|
||||||
|
manager_ref.login_key = String::from(key);
|
||||||
|
manager_ref.promise = Some(perform_key_retrieval(key));
|
||||||
|
} else {
|
||||||
|
manager_ref.login_key = String::from(expected_str);
|
||||||
|
manager_ref.promise = Some(perform_key_retrieval(expected_str));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(key) = manager_ref.check_for_successful_login() {
|
||||||
|
assert_eq!(expected_key, key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user