From 021011dcc5e7088d07f2cd851279d13dd3b32346 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Thu, 4 Jul 2019 13:48:51 +0200 Subject: [PATCH 1/2] contact-editor: improve UX/UI for unlinking contacts This moves the unlink feature to the editor. The unlink dialog was removed. This imporves the UX as well as the UI for performing unlink of personas. This also adds the possibility to undo the unlink and to cancel the complete operation like before only for the contact infromation. --- data/contacts.gresource.xml | 1 - data/ui/contacts-contact-editor.ui | 6 -- data/ui/contacts-linked-personas-dialog.ui | 53 ------------ src/contacts-contact-editor.vala | 29 +++++-- src/contacts-contact-pane.vala | 19 ++--- src/contacts-linked-personas-dialog.vala | 97 ---------------------- src/meson.build | 1 - 7 files changed, 32 insertions(+), 174 deletions(-) delete mode 100644 data/ui/contacts-linked-personas-dialog.ui delete mode 100644 src/contacts-linked-personas-dialog.vala diff --git a/data/contacts.gresource.xml b/data/contacts.gresource.xml index 6618f43d..4ae3f7a0 100644 --- a/data/contacts.gresource.xml +++ b/data/contacts.gresource.xml @@ -11,7 +11,6 @@ ui/contacts-crop-cheese-dialog.ui ui/contacts-in-app-notification.ui ui/contacts-link-suggestion-grid.ui - ui/contacts-linked-personas-dialog.ui ui/contacts-list-pane.ui ui/contacts-setup-window.ui ui/contacts-window.ui diff --git a/data/ui/contacts-contact-editor.ui b/data/ui/contacts-contact-editor.ui index 57558d03..7a19f34b 100644 --- a/data/ui/contacts-contact-editor.ui +++ b/data/ui/contacts-contact-editor.ui @@ -84,12 +84,6 @@ - - - True - Linked Accounts - - True diff --git a/data/ui/contacts-linked-personas-dialog.ui b/data/ui/contacts-linked-personas-dialog.ui deleted file mode 100644 index 16e46105..00000000 --- a/data/ui/contacts-linked-personas-dialog.ui +++ /dev/null @@ -1,53 +0,0 @@ - - - - - diff --git a/src/contacts-contact-editor.vala b/src/contacts-contact-editor.vala index 7450ee39..c1b72dec 100644 --- a/src/contacts-contact-editor.vala +++ b/src/contacts-contact-editor.vala @@ -242,9 +242,6 @@ public class Contacts.ContactEditor : ContactForm { [GtkChild] private MenuButton add_detail_button; - [GtkChild] - public Button linked_button; - [GtkChild] public Button remove_button; @@ -262,6 +259,7 @@ public class Contacts.ContactEditor : ContactForm { HashMap rows; } + private ArrayList unlink_personas; /* the key of the hash_map is the uid of the persona */ private HashMap> writable_personas; @@ -280,6 +278,7 @@ public class Contacts.ContactEditor : ContactForm { } construct { + this.unlink_personas = new ArrayList (); this.writable_personas = new HashMap> (); this.container_grid.size_allocate.connect(on_container_grid_size_allocate); @@ -315,10 +314,8 @@ public class Contacts.ContactEditor : ContactForm { if (contact != null) { this.remove_button.sensitive = contact.can_remove_personas (); - this.linked_button.sensitive = contact.individual.personas.size > 1; } else { this.remove_button.hide (); - this.linked_button.hide (); } /* Set the initial remove_button content based on the width */ @@ -349,6 +346,24 @@ public class Contacts.ContactEditor : ContactForm { foreach (var p in personas) { if (!is_first_persona) { this.container_grid.attach (create_persona_store_label (p), 0, i, 2); + var unlink_button = new Button.with_label(_("unlink")); + unlink_button.set_halign (Align.END); + + /* Keep the state of the button */ + var unlink = true; + unlink_button.clicked.connect(() => { + if (unlink) { + unlink_button.set_label(_("link")); + unlink = false; + unlink_personas.add (p); + } else { + unlink_button.set_label(_("unlink")); + unlink = true; + unlink_personas.remove (p); + } + }); + + this.container_grid.attach (unlink_button, 1, i, 2); last_store_position = ++i; } @@ -1006,6 +1021,10 @@ public class Contacts.ContactEditor : ContactForm { return props_set; } + public ArrayList get_unlink_personas () { + return unlink_personas; + } + public void add_new_row_for_property (Persona? p, string prop_name, string? type = null) { /* Somehow, I need to ensure that p is the main/default/first persona */ Persona persona = null; diff --git a/src/contacts-contact-pane.vala b/src/contacts-contact-pane.vala index d4b46af7..63866437 100644 --- a/src/contacts-contact-pane.vala +++ b/src/contacts-contact-pane.vala @@ -153,7 +153,7 @@ public class Contacts.ContactPane : Stack { remove_contact_editor (); this.editor = new ContactEditor (this.contact, this.store, this.edit_contact_actions); - this.editor.linked_button.clicked.connect (linked_accounts); + this.editor.remove_button.clicked.connect (delete_contact); /* enable/disable actions*/ @@ -190,16 +190,6 @@ public class Contacts.ContactPane : Stack { } } - private void linked_accounts () { - var dialog = new LinkedPersonasDialog (this.parent_window, this.store, contact); - if (dialog.run () == ResponseType.CLOSE && dialog.any_unlinked) { - /* update edited contact if any_unlinked */ - stop_editing (); - start_editing (); - } - dialog.destroy (); - } - void delete_contact () { if (contact != null) { contact.hidden = true; @@ -244,6 +234,13 @@ public class Contacts.ContactPane : Stack { } } + /* unlink personas */ + foreach (var persona in this.editor.get_unlink_personas()) { + unlink_persona.begin (store, contact, persona, (obj, result) => { + unlink_persona.end (result); + }); + } + if (this.editor.name_changed ()) { var v = this.editor.get_full_name_value (); try { diff --git a/src/contacts-linked-personas-dialog.vala b/src/contacts-linked-personas-dialog.vala deleted file mode 100644 index be3e0e16..00000000 --- a/src/contacts-linked-personas-dialog.vala +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2011 Alexander Larsson - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -using Gtk; -using Folks; - -[GtkTemplate (ui = "/org/gnome/Contacts/ui/contacts-linked-personas-dialog.ui")] -public class Contacts.LinkedPersonasDialog : Dialog { - private const int AVATAR_SIZE = 54; - - [GtkChild] - private ListBox linked_accounts_view; - - private Contact contact; - - public bool any_unlinked = false; - - public LinkedPersonasDialog (Window main_win, Store store, Contact contact) { - Object ( - use_header_bar: 1, - transient_for: main_win, - title: contact.individual.display_name - ); - - this.contact = contact; - this.linked_accounts_view.set_header_func (add_separator); - - // loading personas for display - var personas = contact.get_personas_for_display (); - bool is_first = true; - foreach (var p in personas) { - if (is_first) { - is_first = false; - continue; - } - - var row_grid = new Grid (); - - var image_frame = new Avatar (AVATAR_SIZE, contact); - image_frame.set_hexpand (false); - image_frame.margin = 6; - image_frame.margin_end = 12; - row_grid.attach (image_frame, 0, 0, 1, 2); - - var display_name = new Label (""); - display_name.set_halign (Align.START); - display_name.set_valign (Align.END); - display_name.set_hexpand (true); - display_name.set_markup (Markup.printf_escaped ("%s", p.display_id)); - - row_grid.attach (display_name, 1, 0, 1, 1); - - var store_name = new Label (Contact.format_persona_store_name_for_contact (p)); - store_name.set_halign (Align.START); - store_name.set_valign (Align.START); - store_name.set_hexpand (true); - store_name.get_style_context ().add_class ("dim-label"); - row_grid.attach (store_name, 1, 1, 1, 1); - - var button = new Button.with_label (_("Unlink")); - button.margin_end = 6; - button.set_valign (Align.CENTER); - button.get_child ().margin = 1; - row_grid.attach (button, 2, 0, 1, 2); - - /* signal */ - button.clicked.connect (() => { - unlink_persona.begin (store, contact, p, (obj, result) => { - unlink_persona.end (result); - - row_grid.destroy (); - - this.any_unlinked = true; - /* TODO: Support undo */ - /* TODO: Ensure we don't get suggestion for this linkage again */ - }); - }); - - row_grid.show_all (); - this.linked_accounts_view.add (row_grid); - } - } -} diff --git a/src/meson.build b/src/meson.build index 773c3dcf..81baac34 100644 --- a/src/meson.build +++ b/src/meson.build @@ -86,7 +86,6 @@ contacts_vala_sources = files( 'contacts-crop-cheese-dialog.vala', 'contacts-in-app-notification.vala', 'contacts-link-suggestion-grid.vala', - 'contacts-linked-personas-dialog.vala', 'contacts-linking.vala', 'contacts-list-pane.vala', 'contacts-max-width-bin.vala', -- GitLab From 745e69a3c787de1aa61cd9ed58668b45e7eecb52 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Thu, 4 Jul 2019 15:04:24 +0200 Subject: [PATCH 2/2] contact-editor: fix styling for persona labels and unlink button --- src/contacts-contact-editor.vala | 18 +++++++++++++----- src/contacts-contact-form.vala | 10 +++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/contacts-contact-editor.vala b/src/contacts-contact-editor.vala index c1b72dec..be556df9 100644 --- a/src/contacts-contact-editor.vala +++ b/src/contacts-contact-editor.vala @@ -345,25 +345,33 @@ public class Contacts.ContactEditor : ContactForm { var personas = this.contact.get_personas_for_display (); foreach (var p in personas) { if (!is_first_persona) { - this.container_grid.attach (create_persona_store_label (p), 0, i, 2); - var unlink_button = new Button.with_label(_("unlink")); + var box = new Box (Orientation.HORIZONTAL, 12); + box.set_margin_top (18); + box.set_margin_bottom (9); + + box.pack_start (create_persona_store_label (p)); + + var unlink_button = new Button.with_label(_("Unlink Account")); unlink_button.set_halign (Align.END); + /* Keep the state of the button */ var unlink = true; unlink_button.clicked.connect(() => { if (unlink) { - unlink_button.set_label(_("link")); + unlink_button.set_label(_("Link Account")); unlink = false; unlink_personas.add (p); } else { - unlink_button.set_label(_("unlink")); + unlink_button.set_label(_("Unlink Account")); unlink = true; unlink_personas.remove (p); } }); - this.container_grid.attach (unlink_button, 1, i, 2); + box.pack_end (unlink_button); + + this.container_grid.attach (box, 0, i, 3); last_store_position = ++i; } diff --git a/src/contacts-contact-form.vala b/src/contacts-contact-form.vala index f44a2fb5..d8dc6f5a 100644 --- a/src/contacts-contact-form.vala +++ b/src/contacts-contact-form.vala @@ -78,12 +78,12 @@ public abstract class Contacts.ContactForm : Grid { } protected Label create_persona_store_label (Persona p) { - var store_name = new Label(""); - store_name.set_markup (Markup.printf_escaped ("%s", - Contact.format_persona_store_name_for_contact (p))); + var store_name = new Label (Contact.format_persona_store_name_for_contact (p)); + var attrList = new Pango.AttrList(); + attrList.insert (Pango.attr_weight_new (Pango.Weight.BOLD)); + store_name.set_attributes(attrList); store_name.set_halign (Align.START); - store_name.xalign = 0.0f; - store_name.margin_start = 6; + store_name.set_ellipsize (Pango.EllipsizeMode.MIDDLE); return store_name; } -- GitLab