[fractal/get-widgets-from-ui-struct: 18/21] Move stuff in account from AppOp to UI
- From: Alejandro Domínguez <aledomu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/get-widgets-from-ui-struct: 18/21] Move stuff in account from AppOp to UI
- Date: Wed, 30 Dec 2020 23:00:06 +0000 (UTC)
commit 5b26fc2fbea5237e2bd295490a6a12b21b8cbf79
Author: Alejandro Domínguez <adomu net-c com>
Date: Mon Dec 7 20:27:33 2020 +0100
Move stuff in account from AppOp to UI
fractal-gtk/src/appop/account.rs | 338 +++++----------------------------------
fractal-gtk/src/ui/account.rs | 242 ++++++++++++++++++++++++++++
fractal-gtk/src/ui/mod.rs | 14 ++
3 files changed, 293 insertions(+), 301 deletions(-)
---
diff --git a/fractal-gtk/src/appop/account.rs b/fractal-gtk/src/appop/account.rs
index 33afe9d5..e3a24155 100644
--- a/fractal-gtk/src/appop/account.rs
+++ b/fractal-gtk/src/appop/account.rs
@@ -1,27 +1,20 @@
-use crate::backend::user;
-use gtk::prelude::*;
-use log::info;
-use std::path::PathBuf;
-
+use super::LoginData;
use crate::actions::global::activate_action;
use crate::app::RUNTIME;
use crate::appop::AppOp;
use crate::appop::AppState;
+use crate::backend::user;
use crate::backend::HandleError;
-
+use crate::cache::remove_from_cache;
use crate::util::i18n::i18n;
-use crate::widgets;
-use crate::widgets::AvatarExt;
-
-use crate::cache::{download_to_cache, remove_from_cache};
+use gtk::prelude::*;
+use log::info;
use matrix_sdk::api::r0::contact::get_contacts::ThirdPartyIdentifier;
-use matrix_sdk::thirdparty::Medium;
-
-use super::LoginData;
+use std::path::PathBuf;
impl AppOp {
pub fn set_three_pid(&self, data: Option<Vec<ThirdPartyIdentifier>>) {
- self.update_address(data);
+ self.ui.account_settings.set_three_pid(data, self);
}
pub fn get_three_pid(&self) {
@@ -181,35 +174,19 @@ impl AppOp {
}
pub fn show_error_dialog_in_settings(&self, error: String) {
- let dialog = self.create_error_dialog(error);
- dialog.connect_response(move |w, _| w.close());
self.get_three_pid();
- dialog.show_all();
+ self.ui
+ .account_settings
+ .show_error_dialog_in_settings(&self.ui, &error);
}
pub fn show_load_settings_error_dialog(&self, error: String) {
- let dialog = self.create_error_dialog(error);
- dialog.connect_response(move |w, _| w.close());
- dialog.show_all();
+ self.ui
+ .account_settings
+ .show_load_settings_error_dialog(&self.ui, &error);
activate_action(&self.app_runtime, "app", "back");
}
- pub fn create_error_dialog(&self, error: String) -> gtk::MessageDialog {
- let msg = error;
- let flags = gtk::DialogFlags::MODAL | gtk::DialogFlags::DESTROY_WITH_PARENT;
- let dialog = gtk::MessageDialog::new(
- Some(&self.ui.main_window),
- flags,
- gtk::MessageType::Error,
- gtk::ButtonsType::None,
- &msg,
- );
-
- dialog.add_button(&i18n("OK"), gtk::ResponseType::Ok);
-
- dialog
- }
-
pub fn get_token_email(&mut self, sid: Option<String>, secret: Option<String>) {
if let Some(sid) = sid {
if let Some(secret) = secret {
@@ -228,257 +205,51 @@ impl AppOp {
pub fn show_account_settings_dialog(&mut self) {
let login_data = unwrap_or_unit_return!(self.login_data.clone());
- // Reset view before displaying it
- self.close_account_settings_dialog();
- self.ui
- .account_settings
- .stack
- .set_visible_child_name("loading");
self.get_three_pid();
- self.ui
- .account_settings
- .uid
- .set_text(&login_data.uid.to_string());
- self.ui
- .account_settings
- .device_id
- .set_text(login_data.device_id.as_str());
- self.ui
- .account_settings
- .homeserver
- .set_text(login_data.session_client.homeserver().as_str());
- self.ui
- .account_settings
- .name
- .set_text(&login_data.username.unwrap_or_default());
- self.ui.account_settings.name.grab_focus_without_selecting();
- self.ui.account_settings.name.set_position(-1);
-
- self.ui.account_settings.avatar_spinner.hide();
- self.ui.account_settings.avatar_button.set_sensitive(true);
- self.show_avatar();
-
- self.ui.account_settings.name_button.hide();
- self.ui.account_settings.name.set_editable(true);
- let image = gtk::Image::from_icon_name(Some("emblem-ok-symbolic"), gtk::IconSize::Menu);
- self.ui.account_settings.name_button.set_image(Some(&image));
- self.ui.account_settings.name_button.set_sensitive(true);
-
- // reset the password button
- self.ui
- .account_settings
- .password_stack
- .set_visible_child_name("label");
- self.ui.account_settings.password.set_sensitive(true);
-
- self.ui.account_settings.delete_check.set_active(false);
- self.ui.account_settings.delete_btn.set_sensitive(false);
- self.ui
- .account_settings
- .delete_password_confirm
- .set_text("");
- self.ui
- .account_settings
- .advanced_box
- .set_redraw_on_allocate(true);
- self.ui
- .account_settings
- .delete_box
- .set_redraw_on_allocate(true);
-
self.set_state(AppState::AccountSettings);
- }
- pub fn update_address(&self, data: Option<Vec<ThirdPartyIdentifier>>) {
- let mut first_email = true;
- let mut first_phone = true;
-
- let grid = &self.ui.account_settings.grid;
- let mut child = grid.get_child_at(1, 1);
- let email = &self.ui.account_settings.email;
- let phone = &self.ui.account_settings.phone;
- let password = &self.ui.account_settings.password;
-
- let mut i = 1;
- while child.is_some() {
- if let Some(child) = child.as_ref() {
- if child != phone && child != email && child != password {
- grid.remove_row(i);
- } else {
- for w in email.get_children().iter() {
- email.remove(w);
- }
- for w in phone.get_children().iter() {
- phone.remove(w);
- }
- i += 1;
- }
- }
- child = grid.get_child_at(1, i);
- }
-
- /* Make sure we have at least one empty entry for email and phone */
- let mut empty_email = widgets::Address::new(widgets::AddressType::Email, &self);
- let mut empty_phone = widgets::Address::new(widgets::AddressType::Phone, &self);
- self.ui
- .account_settings
- .email
- .pack_start(&empty_email.create(None), true, true, 0);
- phone.pack_start(&empty_phone.create(None), true, true, 0);
- if let Some(data) = data {
- for item in data {
- match item.medium {
- Medium::Email => {
- if first_email {
- empty_email.update(Some(item.address));
- let entry = widgets::Address::new(widgets::AddressType::Email, &self)
- .create(None);
- grid.insert_next_to(email, gtk::PositionType::Bottom);
- grid.attach_next_to(
- &entry,
- Some(email),
- gtk::PositionType::Bottom,
- 1,
- 1,
- );
- first_email = false;
- } else {
- let entry = widgets::Address::new(widgets::AddressType::Email, &self)
- .create(Some(item.address));
- grid.insert_next_to(email, gtk::PositionType::Bottom);
- grid.attach_next_to(
- &entry,
- Some(email),
- gtk::PositionType::Bottom,
- 1,
- 1,
- );
- }
- }
- Medium::MSISDN => {
- if first_phone {
- empty_phone.update(Some(item.address));
- let entry = widgets::Address::new(widgets::AddressType::Phone, &self)
- .create(None);
- grid.insert_next_to(phone, gtk::PositionType::Bottom);
- grid.attach_next_to(
- &entry,
- Some(phone),
- gtk::PositionType::Bottom,
- 1,
- 1,
- );
- first_phone = false;
- } else {
- let s = String::from("+") + &item.address;
- let entry = widgets::Address::new(widgets::AddressType::Phone, &self)
- .create(Some(s));
- grid.insert_next_to(phone, gtk::PositionType::Bottom);
- grid.attach_next_to(
- &entry,
- Some(phone),
- gtk::PositionType::Bottom,
- 1,
- 1,
- );
- }
- }
- medium => log::warn!("Medium type not managed: {:?}", medium),
- }
- }
- }
- self.ui
- .account_settings
- .stack
- .set_visible_child_name("info");
+ self.ui.account_settings.show_dialog(
+ login_data.session_client,
+ self.user_info_cache.clone(),
+ login_data.uid,
+ login_data.username,
+ &login_data.device_id,
+ );
}
pub fn show_password_dialog(&self) {
- let dialog = self
- .ui
- .builder
- .get_object::<gtk::Dialog>("password_dialog")
- .expect("Can't find password_dialog in ui file.");
- let confirm_password = self
- .ui
- .builder
- .get_object::<gtk::Button>("password-dialog-apply")
- .expect("Can't find password-dialog-apply in ui file.");
- confirm_password.set_sensitive(false);
- dialog.present();
+ self.ui
+ .account_settings
+ .show_password_dialog(&self.ui.builder);
}
pub fn show_new_avatar(&mut self, path: PathBuf) {
let login_data = unwrap_or_unit_return!(self.login_data.clone());
-
info!("Request finished");
self.set_login_data(LoginData {
avatar: Some(path),
- ..login_data
+ ..login_data.clone()
});
- self.ui.account_settings.avatar_spinner.hide();
- self.ui.account_settings.avatar_button.set_sensitive(true);
- if let Some(login_data) = &self.login_data {
- remove_from_cache(self.user_info_cache.clone(), &login_data.uid);
- }
- self.show_avatar();
- }
-
- pub fn show_avatar(&self) {
- let login_data = unwrap_or_unit_return!(self.login_data.clone());
- /* remove all old avatar */
- for w in self.ui.account_settings.avatar.get_children().iter() {
- if w != &self.ui.account_settings.avatar_spinner {
- self.ui.account_settings.avatar.remove(w);
- }
- }
-
- let w = widgets::Avatar::avatar_new(Some(100));
- self.ui.account_settings.avatar.add(&w);
-
- let data = w.circle(
- login_data.uid.to_string(),
- login_data.username,
- 100,
- None,
- None,
- );
- download_to_cache(
+ remove_from_cache(self.user_info_cache.clone(), &login_data.uid);
+ self.ui.account_settings.show_new_avatar(
login_data.session_client,
self.user_info_cache.clone(),
login_data.uid,
- data,
+ login_data.username,
);
-
- /* FIXME: hack to make the avatar drawing area clickable*/
- let current = self.ui.account_settings.stack.get_visible_child_name();
- self.ui
- .account_settings
- .stack
- .set_visible_child_name("loading");
- if let Some(current) = current {
- self.ui
- .account_settings
- .stack
- .set_visible_child_name(¤t);
- }
}
pub fn show_new_username(&mut self, name: Option<String>) {
let login_data = unwrap_or_unit_return!(self.login_data.clone());
- if let Some(name) = name.clone() {
- self.ui.account_settings.name_button.hide();
- let image = gtk::Image::from_icon_name(Some("emblem-ok-symbolic"), gtk::IconSize::Menu);
- self.ui.account_settings.name_button.set_image(Some(&image));
- self.ui.account_settings.name_button.set_sensitive(true);
- self.ui.account_settings.name.set_editable(true);
- self.ui.account_settings.name.set_text(&name);
- }
self.set_login_data(LoginData {
- username: name,
+ username: name.clone(),
..login_data
});
+
+ if let Some(name) = name.as_deref() {
+ self.ui.account_settings.show_new_username(name);
+ }
}
pub fn update_username_account_settings(&self) {
@@ -518,12 +289,6 @@ impl AppOp {
}
}
- pub fn close_account_settings_dialog(&self) {
- self.ui.account_settings.advanced_box.queue_draw();
- self.ui.account_settings.delete_box.queue_draw();
- self.ui.account_settings.root.queue_draw();
- }
-
pub fn set_new_password(&mut self) {
let (session_client, user_id) = unwrap_or_unit_return!(self
.login_data
@@ -562,48 +327,19 @@ impl AppOp {
}
pub fn password_changed(&self) {
- self.ui.account_settings.password.set_sensitive(true);
- self.ui
- .account_settings
- .password_stack
- .set_visible_child_name("label");
+ self.ui.account_settings.password_changed();
}
pub fn show_password_error_dialog(&self, error: String) {
- self.show_error_dialog_in_settings(error);
- self.ui.account_settings.password.set_sensitive(true);
self.ui
.account_settings
- .password_stack
- .set_visible_child_name("label");
+ .show_password_error_dialog(&self.ui, &error);
}
pub fn close_password_dialog(&mut self) {
- let dialog = self
- .ui
- .builder
- .get_object::<gtk::Dialog>("password_dialog")
- .expect("Can't find password_dialog in ui file.");
- let old_password = self
- .ui
- .builder
- .get_object::<gtk::Entry>("password-dialog-old-entry")
- .expect("Can't find password-dialog-old-entry in ui file.");
- let new_password = self
- .ui
- .builder
- .get_object::<gtk::Entry>("password-dialog-entry")
- .expect("Can't find password-dialog-entry in ui file.");
- let verify_password = self
- .ui
- .builder
- .get_object::<gtk::Entry>("password-dialog-verify-entry")
- .expect("Can't find password-dialog-verify-entry in ui file.");
- /* Clear all user input */
- old_password.set_text("");
- new_password.set_text("");
- verify_password.set_text("");
- dialog.hide();
+ self.ui
+ .account_settings
+ .close_password_dialog(&self.ui.builder);
}
pub fn account_destruction(&self) {
diff --git a/fractal-gtk/src/ui/account.rs b/fractal-gtk/src/ui/account.rs
index 79c6f86d..0153d406 100644
--- a/fractal-gtk/src/ui/account.rs
+++ b/fractal-gtk/src/ui/account.rs
@@ -1,4 +1,14 @@
+use super::UI;
+use crate::appop::AppOp;
+use crate::appop::UserInfoCache;
+use crate::cache::{download_to_cache, remove_from_cache};
+use crate::widgets;
+use crate::widgets::AvatarExt;
use gtk::prelude::*;
+use matrix_sdk::api::r0::contact::get_contacts::ThirdPartyIdentifier;
+use matrix_sdk::identifiers::{DeviceId, UserId};
+use matrix_sdk::thirdparty::Medium;
+use matrix_sdk::Client as MatrixClient;
pub struct AccountSettings {
pub root: gtk::Box,
@@ -88,4 +98,236 @@ impl AccountSettings {
.expect("Can't find account_settings_uid in ui file."),
}
}
+
+ pub fn set_three_pid(&self, data: Option<Vec<ThirdPartyIdentifier>>, op: &AppOp) {
+ let mut first_email = true;
+ let mut first_phone = true;
+
+ let mut maybe_child = self.grid.get_child_at(1, 1);
+
+ let mut i = 1;
+ while let Some(child) = maybe_child.as_ref() {
+ if child != &self.phone && child != &self.email && child != &self.password {
+ self.grid.remove_row(i);
+ } else {
+ for w in self.email.get_children().iter() {
+ self.email.remove(w);
+ }
+ for w in self.phone.get_children().iter() {
+ self.phone.remove(w);
+ }
+ i += 1;
+ }
+ maybe_child = self.grid.get_child_at(1, i);
+ }
+
+ /* Make sure we have at least one empty entry for email and phone */
+ let mut empty_email = widgets::Address::new(widgets::AddressType::Email, op);
+ let mut empty_phone = widgets::Address::new(widgets::AddressType::Phone, op);
+ self.email
+ .pack_start(&empty_email.create(None), true, true, 0);
+ self.phone
+ .pack_start(&empty_phone.create(None), true, true, 0);
+ for item in data.unwrap_or_default() {
+ match item.medium {
+ Medium::Email => {
+ let item_address = if first_email {
+ empty_email.update(Some(item.address));
+ first_email = false;
+
+ None
+ } else {
+ Some(item.address)
+ };
+
+ let entry = widgets::Address::new(widgets::AddressType::Email, &op)
+ .create(item_address);
+ self.grid
+ .insert_next_to(&self.email, gtk::PositionType::Bottom);
+ self.grid.attach_next_to(
+ &entry,
+ Some(&self.email),
+ gtk::PositionType::Bottom,
+ 1,
+ 1,
+ );
+ }
+ Medium::MSISDN => {
+ let s = if first_phone {
+ empty_phone.update(Some(item.address));
+ first_phone = false;
+
+ None
+ } else {
+ Some(String::from("+") + &item.address)
+ };
+
+ let entry = widgets::Address::new(widgets::AddressType::Phone, op).create(s);
+ self.grid
+ .insert_next_to(&self.phone, gtk::PositionType::Bottom);
+ self.grid.attach_next_to(
+ &entry,
+ Some(&self.phone),
+ gtk::PositionType::Bottom,
+ 1,
+ 1,
+ );
+ }
+ medium => log::warn!("Medium type not managed: {:?}", medium),
+ }
+ }
+ self.stack.set_visible_child_name("info");
+ }
+
+ pub fn show_error_dialog_in_settings(&self, ui: &UI, error_msg: &str) {
+ let dialog = ui.create_error_dialog(error_msg);
+ dialog.connect_response(move |w, _| w.close());
+ dialog.show_all();
+ }
+
+ pub fn show_load_settings_error_dialog(&self, ui: &UI, error_msg: &str) {
+ let dialog = ui.create_error_dialog(error_msg);
+ dialog.connect_response(move |w, _| w.close());
+ dialog.show_all();
+ }
+
+ pub fn show_dialog(
+ &mut self,
+ session_client: MatrixClient,
+ user_info_cache: UserInfoCache,
+ user_id: UserId,
+ username: Option<String>,
+ device_id: &DeviceId,
+ ) {
+ // Reset view before displaying it
+ self.close_dialog();
+
+ self.stack.set_visible_child_name("loading");
+ self.uid.set_text(user_id.as_str());
+ self.device_id.set_text(device_id.as_str());
+ self.homeserver
+ .set_text(session_client.homeserver().as_str());
+ self.name.set_text(username.as_deref().unwrap_or_default());
+ self.name.grab_focus_without_selecting();
+ self.name.set_position(-1);
+
+ self.avatar_spinner.hide();
+ self.avatar_button.set_sensitive(true);
+
+ self.name_button.hide();
+ self.name.set_editable(true);
+ let image = gtk::Image::from_icon_name(Some("emblem-ok-symbolic"), gtk::IconSize::Menu);
+ self.name_button.set_image(Some(&image));
+ self.name_button.set_sensitive(true);
+
+ // reset the password button
+ self.password_stack.set_visible_child_name("label");
+ self.password.set_sensitive(true);
+
+ self.delete_check.set_active(false);
+ self.delete_btn.set_sensitive(false);
+ self.delete_password_confirm.set_text("");
+ self.advanced_box.set_redraw_on_allocate(true);
+ self.delete_box.set_redraw_on_allocate(true);
+
+ self.show_avatar(session_client, user_info_cache, user_id, username);
+ }
+
+ pub fn show_password_dialog(&self, builder: >k::Builder) {
+ let dialog = builder
+ .get_object::<gtk::Dialog>("password_dialog")
+ .expect("Can't find password_dialog in ui file.");
+ let confirm_password = builder
+ .get_object::<gtk::Button>("password-dialog-apply")
+ .expect("Can't find password-dialog-apply in ui file.");
+ confirm_password.set_sensitive(false);
+ dialog.present();
+ }
+
+ fn show_avatar(
+ &self,
+ session_client: MatrixClient,
+ user_info_cache: UserInfoCache,
+ user_id: UserId,
+ username: Option<String>,
+ ) {
+ /* remove all old avatar */
+ for w in self.avatar.get_children().iter() {
+ if w != &self.avatar_spinner {
+ self.avatar.remove(w);
+ }
+ }
+
+ let w = widgets::Avatar::avatar_new(Some(100));
+ self.avatar.add(&w);
+
+ let data = w.circle(user_id.to_string(), username, 100, None, None);
+ download_to_cache(session_client, user_info_cache, user_id, data);
+
+ /* FIXME: hack to make the avatar drawing area clickable*/
+ let current = self.stack.get_visible_child_name();
+ self.stack.set_visible_child_name("loading");
+ if let Some(current) = current {
+ self.stack.set_visible_child_name(¤t);
+ }
+ }
+
+ pub fn show_new_avatar(
+ &mut self,
+ session_client: MatrixClient,
+ user_info_cache: UserInfoCache,
+ user_id: UserId,
+ username: Option<String>,
+ ) {
+ self.avatar_spinner.hide();
+ self.avatar_button.set_sensitive(true);
+ remove_from_cache(user_info_cache.clone(), &user_id);
+ self.show_avatar(session_client, user_info_cache, user_id, username);
+ }
+
+ pub fn show_new_username(&mut self, name: &str) {
+ self.name_button.hide();
+ let image = gtk::Image::from_icon_name(Some("emblem-ok-symbolic"), gtk::IconSize::Menu);
+ self.name_button.set_image(Some(&image));
+ self.name_button.set_sensitive(true);
+ self.name.set_editable(true);
+ self.name.set_text(name);
+ }
+
+ fn close_dialog(&self) {
+ self.advanced_box.queue_draw();
+ self.delete_box.queue_draw();
+ self.root.queue_draw();
+ }
+
+ pub fn password_changed(&self) {
+ self.password.set_sensitive(true);
+ self.password_stack.set_visible_child_name("label");
+ }
+
+ pub fn show_password_error_dialog(&self, ui: &UI, error_msg: &str) {
+ self.show_error_dialog_in_settings(ui, error_msg);
+ self.password.set_sensitive(true);
+ self.password_stack.set_visible_child_name("label");
+ }
+
+ pub fn close_password_dialog(&mut self, builder: >k::Builder) {
+ let dialog = builder
+ .get_object::<gtk::Dialog>("password_dialog")
+ .expect("Can't find password_dialog in ui file.");
+ let old_password = builder
+ .get_object::<gtk::Entry>("password-dialog-old-entry")
+ .expect("Can't find password-dialog-old-entry in ui file.");
+ let new_password = builder
+ .get_object::<gtk::Entry>("password-dialog-entry")
+ .expect("Can't find password-dialog-entry in ui file.");
+ let verify_password = builder
+ .get_object::<gtk::Entry>("password-dialog-verify-entry")
+ .expect("Can't find password-dialog-verify-entry in ui file.");
+ /* Clear all user input */
+ old_password.set_text("");
+ new_password.set_text("");
+ verify_password.set_text("");
+ dialog.hide();
+ }
}
diff --git a/fractal-gtk/src/ui/mod.rs b/fractal-gtk/src/ui/mod.rs
index 916e0505..7f5e678b 100644
--- a/fractal-gtk/src/ui/mod.rs
+++ b/fractal-gtk/src/ui/mod.rs
@@ -145,6 +145,20 @@ impl UI {
account_settings,
}
}
+
+ pub fn create_error_dialog(&self, msg: &str) -> gtk::MessageDialog {
+ let flags = gtk::DialogFlags::MODAL | gtk::DialogFlags::DESTROY_WITH_PARENT;
+ let dialog = gtk::MessageDialog::new(
+ Some(&self.main_window),
+ flags,
+ gtk::MessageType::Error,
+ gtk::ButtonsType::None,
+ msg,
+ );
+ dialog.add_button(&i18n("OK"), gtk::ResponseType::Ok);
+
+ dialog
+ }
}
/* MessageContent contains all data needed to display one row
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]