From f8c004630f56914438fa1b114530f639748e41c1 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Mon, 16 Sep 2024 22:47:49 +0200 Subject: Add change password functionality Co-authored-by: Stanislav Malishevskiy --- main/src/view_model/preferences_window.vala | 20 +++++++ .../account_preferences_subpage.vala | 16 ++++-- .../preferences_window/change_password_dialog.vala | 66 ++++++++++++++++++++++ .../preferences_window/preferences_window.vala | 2 - 4 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 main/src/windows/preferences_window/change_password_dialog.vala (limited to 'main/src') diff --git a/main/src/view_model/preferences_window.vala b/main/src/view_model/preferences_window.vala index 9cc5a80e..7d967605 100644 --- a/main/src/view_model/preferences_window.vala +++ b/main/src/view_model/preferences_window.vala @@ -98,6 +98,13 @@ public class Dino.Ui.ViewModel.PreferencesWindow : Object { update_data(); } + public ChangePasswordDialog get_change_password_dialog_model() { + return new ChangePasswordDialog() { + account = selected_account.account, + stream_interactor = stream_interactor + }; + } + private void bind_general_page() { var settings = Dino.Application.get_default().settings; settings.bind_property("send-typing", general_page, "send-typing", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL); @@ -107,3 +114,16 @@ public class Dino.Ui.ViewModel.PreferencesWindow : Object { } } +public class Dino.Ui.ViewModel.ChangePasswordDialog : Object { + public Entities.Account account { get; set; } + public StreamInteractor stream_interactor { get; set; } + + public async string? change_password(string new_password) { + var res = yield stream_interactor.get_module(Register.IDENTITY).change_password(account, new_password); + if (res == null) { + account.password = new_password; + } + return res; + } +} + diff --git a/main/src/windows/preferences_window/account_preferences_subpage.vala b/main/src/windows/preferences_window/account_preferences_subpage.vala index d6ddb2b4..1a7d5696 100644 --- a/main/src/windows/preferences_window/account_preferences_subpage.vala +++ b/main/src/windows/preferences_window/account_preferences_subpage.vala @@ -13,6 +13,7 @@ public class Dino.Ui.AccountPreferencesSubpage : Gtk.Box { [GtkChild] public unowned AvatarPicture avatar; [GtkChild] public unowned Adw.ActionRow xmpp_address; [GtkChild] public unowned Adw.EntryRow local_alias; + [GtkChild] public unowned Adw.ActionRow password_change; [GtkChild] public unowned Adw.ActionRow connection_status; [GtkChild] public unowned Button enter_password_button; [GtkChild] public unowned Box avatar_menu_box; @@ -50,6 +51,12 @@ public class Dino.Ui.AccountPreferencesSubpage : Gtk.Box { remove_account_button.clicked.connect(() => { show_remove_account_dialog(); }); + password_change.activatable_widget = new Label(""); + password_change.activated.connect(() => { + var dialog = new ChangePasswordDialog(model.get_change_password_dialog_model()); + dialog.set_transient_for((Gtk.Window)this.get_root()); + dialog.present(); + }); enter_password_button.clicked.connect(() => { var dialog = new Adw.MessageDialog((Window)this.get_root(), "Enter password for %s".printf(account.bare_jid.to_string()), null); var password = new PasswordEntry() { show_peek_icon=true }; @@ -76,10 +83,10 @@ public class Dino.Ui.AccountPreferencesSubpage : Gtk.Box { avatar.model = model.selected_account.avatar_model; xmpp_address.subtitle = account.bare_jid.to_string(); - if (alias_entry_changed != 0) local_alias_entry.disconnect(alias_entry_changed); - local_alias_entry.text = account.alias ?? ""; - alias_entry_changed = local_alias_entry.changed.connect(() => { - account.alias = local_alias_entry.text; + if (alias_entry_changed != 0) local_alias.disconnect(alias_entry_changed); + local_alias.text = account.alias ?? ""; + alias_entry_changed = local_alias.changed.connect(() => { + account.alias = local_alias.text; }); bindings += account.bind_property("enabled", disable_account_button, "label", BindingFlags.SYNC_CREATE, (binding, from, ref to) => { @@ -88,6 +95,7 @@ public class Dino.Ui.AccountPreferencesSubpage : Gtk.Box { return true; }); bindings += account.bind_property("enabled", avatar_menu_box, "visible", BindingFlags.SYNC_CREATE); + bindings += account.bind_property("enabled", password_change, "visible", BindingFlags.SYNC_CREATE); bindings += account.bind_property("enabled", connection_status, "visible", BindingFlags.SYNC_CREATE); bindings += model.selected_account.bind_property("connection-state", connection_status, "subtitle", BindingFlags.SYNC_CREATE, (binding, from, ref to) => { to = get_status_label(); diff --git a/main/src/windows/preferences_window/change_password_dialog.vala b/main/src/windows/preferences_window/change_password_dialog.vala new file mode 100644 index 00000000..f0c7dcf9 --- /dev/null +++ b/main/src/windows/preferences_window/change_password_dialog.vala @@ -0,0 +1,66 @@ +using Gee; +using Gtk; + +using Dino.Entities; +using Xmpp; + +namespace Dino.Ui{ + + [GtkTemplate (ui = "/im/dino/Dino/preferences_window/change_password_dialog.ui")] + public class ChangePasswordDialog : Gtk.Dialog { + + [GtkChild] private unowned Button change_password_button; + [GtkChild] private unowned Stack change_password_stack; + [GtkChild] private unowned Button cancel_button; + [GtkChild] private unowned Adw.PasswordEntryRow current_password_entry; + [GtkChild] private unowned Adw.PasswordEntryRow new_password_entry; + [GtkChild] private unowned Adw.PasswordEntryRow confirm_new_password_entry; + [GtkChild] private unowned Label change_password_error_label; + + private ViewModel.ChangePasswordDialog model; + + public ChangePasswordDialog(ViewModel.ChangePasswordDialog model) { + Object(use_header_bar : 1); + this.model = model; + + Util.force_error_color(change_password_error_label); + cancel_button.clicked.connect(() => { close(); }); + current_password_entry.changed.connect(is_form_filled); + new_password_entry.changed.connect(is_form_filled); + confirm_new_password_entry.changed.connect(is_form_filled); + change_password_button.clicked.connect(on_change_password_button_clicked); + } + + private void is_form_filled(){ + if (current_password_entry.get_text().length > 0 + && new_password_entry.get_text().length > 0 + && confirm_new_password_entry.get_text().length > 0 + && new_password_entry.get_text() == confirm_new_password_entry.get_text()){ + change_password_button.sensitive = true; + } else { + change_password_button.sensitive = false; + } + } + + private async void on_change_password_button_clicked(){ + string? pw_input = current_password_entry.get_text(); + string? new_pw_input = new_password_entry.get_text(); + + if (pw_input != null && model.account.password == pw_input){ + change_password_button.sensitive = false; + change_password_stack.visible_child_name = "spinner"; + string? ret = yield model.change_password(new_pw_input); + change_password_button.sensitive = true; + change_password_stack.visible_child_name = "label"; + if (ret == null) { + close(); + } + + change_password_error_label.label = "Error: %s".printf(ret); + + } else { + change_password_error_label.label = "Wrong current password"; + } + } + } +} \ No newline at end of file diff --git a/main/src/windows/preferences_window/preferences_window.vala b/main/src/windows/preferences_window/preferences_window.vala index 1a75aa0a..662a6924 100644 --- a/main/src/windows/preferences_window/preferences_window.vala +++ b/main/src/windows/preferences_window/preferences_window.vala @@ -15,8 +15,6 @@ public class Dino.Ui.PreferencesWindow : Adw.PreferencesWindow { [GtkChild] public unowned ViewModel.PreferencesWindow model { get; } construct { - this.default_height = 500; - this.default_width = 700; this.can_navigate_back = true; // remove once we require Adw > 1.4 this.bind_property("model", accounts_page, "model", BindingFlags.SYNC_CREATE); this.bind_property("model", account_page, "model", BindingFlags.SYNC_CREATE); -- cgit v1.2.3-70-g09d2