login: prefill dialog after a failed login attempt
After a failed login the dialog was recreated empty, so a single mistyped password meant retyping the server URL and username too, and on a first-time login everything the user had just typed was lost. Fill the form with the credentials of the last attempt so that a wrong password only needs retyping. Nothing is written to the keyring on failure: credentials are stored on success and cleared only on explicit logout.
This commit is contained in:
parent
36bac44395
commit
037e5a1c7e
2 changed files with 19 additions and 6 deletions
|
|
@ -1,4 +1,6 @@
|
|||
use gtk4::glib;
|
||||
use gtk4::prelude::*;
|
||||
use gtk4::subclass::prelude::*;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct LoginDialog(ObjectSubclass<imp::LoginDialog>)
|
||||
|
|
@ -10,12 +12,19 @@ impl LoginDialog {
|
|||
pub fn new() -> Self {
|
||||
glib::Object::new()
|
||||
}
|
||||
|
||||
/// Pre-fill the form, e.g. after a failed login attempt so that the
|
||||
/// server URL, username and password don't have to be retyped.
|
||||
pub fn set_prefill(&self, server_url: &str, username: &str, password: &str) {
|
||||
let imp = self.imp();
|
||||
imp.server_url_row.set_text(server_url);
|
||||
imp.username_row.set_text(username);
|
||||
imp.password_row.set_text(password);
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
use gtk4::prelude::*;
|
||||
use gtk4::subclass::prelude::*;
|
||||
use gtk4::CompositeTemplate;
|
||||
use libadwaita::prelude::*;
|
||||
use libadwaita::subclass::prelude::*;
|
||||
|
|
|
|||
|
|
@ -557,12 +557,15 @@ pub mod imp {
|
|||
if let Some((server_url, username, password)) = credentials::load_credentials() {
|
||||
self.do_login(server_url, username, password, false);
|
||||
} else {
|
||||
self.show_login_dialog();
|
||||
self.show_login_dialog(None);
|
||||
}
|
||||
}
|
||||
|
||||
fn show_login_dialog(&self) {
|
||||
fn show_login_dialog(&self, prefill: Option<(String, String, String)>) {
|
||||
let dialog = LoginDialog::new();
|
||||
if let Some((server_url, username, password)) = prefill {
|
||||
dialog.set_prefill(&server_url, &username, &password);
|
||||
}
|
||||
let win = self.obj();
|
||||
let win_weak = win.downgrade();
|
||||
dialog.connect_local("logged-in", false, move |args| {
|
||||
|
|
@ -580,6 +583,7 @@ pub mod imp {
|
|||
fn do_login(&self, server_url: String, username: String, password: String, store: bool) {
|
||||
let is_auto = !store;
|
||||
let win_weak = self.obj().downgrade();
|
||||
let prefill = (server_url.clone(), username.clone(), password.clone());
|
||||
crate::runtime::spawn(
|
||||
async move { Api::login(&server_url, &username, &password).await
|
||||
.map(|api| (api, server_url, username, password)) },
|
||||
|
|
@ -615,7 +619,7 @@ pub mod imp {
|
|||
let toast = libadwaita::Toast::new("Offline — showing cached articles");
|
||||
win.imp().toast_overlay.add_toast(toast);
|
||||
} else {
|
||||
win.imp().show_login_dialog();
|
||||
win.imp().show_login_dialog(Some(prefill));
|
||||
win.imp().show_error_dialog("Login Failed", &e);
|
||||
}
|
||||
}
|
||||
|
|
@ -652,7 +656,7 @@ pub mod imp {
|
|||
}
|
||||
win.imp().sidebar_content.set_visible_child_name("placeholder");
|
||||
win.imp().article_menu_button.set_visible(false);
|
||||
win.imp().show_login_dialog();
|
||||
win.imp().show_login_dialog(None);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue