[geary/Community/Purism/geary-hdy-avatar: 2/3] avatar: Use HdyAvatar for displaying avatars
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/Community/Purism/geary-hdy-avatar: 2/3] avatar: Use HdyAvatar for displaying avatars
- Date: Sun, 4 Apr 2021 02:45:10 +0000 (UTC)
commit 6a052031df579556ada034d0a9bb00797d368d63
Author: Julian Sparber <julian sparber net>
Date: Thu Jan 14 17:33:58 2021 +0100
avatar: Use HdyAvatar for displaying avatars
.../application/application-avatar-store.vala | 166 ---------------------
.../application/application-contact-store.vala | 5 +-
src/client/application/application-contact.vala | 29 ++--
src/client/application/application-controller.vala | 6 +-
.../conversation-contact-popover.vala | 39 ++---
.../conversation-viewer/conversation-message.vala | 34 ++---
src/client/meson.build | 1 -
.../desktop-notifications.vala | 42 +++---
test/client/composer/composer-widget-test.vala | 3 +-
ui/conversation-contact-popover.ui | 6 +-
ui/conversation-message.ui | 8 +-
11 files changed, 66 insertions(+), 273 deletions(-)
---
diff --git a/src/client/application/application-contact-store.vala
b/src/client/application/application-contact-store.vala
index 981483fd3..bf9916491 100644
--- a/src/client/application/application-contact-store.vala
+++ b/src/client/application/application-contact-store.vala
@@ -44,7 +44,6 @@ public class Application.ContactStore : Geary.BaseObject {
public Geary.Account account { get; private set; }
internal Folks.IndividualAggregator individuals;
- internal AvatarStore avatars;
// Cache for storing Folks individuals by email address. Store
// nulls so that negative lookups are cached as well.
@@ -62,14 +61,12 @@ public class Application.ContactStore : Geary.BaseObject {
/** Constructs a new contact store for an account. */
internal ContactStore(Geary.Account account,
- Folks.IndividualAggregator individuals,
- AvatarStore avatars) {
+ Folks.IndividualAggregator individuals) {
this.account = account;
this.individuals = individuals;
this.individuals.individuals_changed_detailed.connect(
on_individuals_changed
);
- this.avatars = avatars;
}
~ContactStore() {
diff --git a/src/client/application/application-contact.vala b/src/client/application/application-contact.vala
index 7f9a7cc51..71397cf04 100644
--- a/src/client/application/application-contact.vala
+++ b/src/client/application/application-contact.vala
@@ -19,6 +19,14 @@ public class Application.Contact : Geary.BaseObject {
/** The human-readable name of the contact. */
public string display_name { get; private set; }
+ /** The avatar of the contact. */
+ public GLib.LoadableIcon? avatar { get {
+ if (this.individual != null)
+ return this.individual.avatar;
+ else
+ return null;
+ }}
+
/** Determines if {@link display_name} the same as its email address. */
public bool display_name_is_email { get; private set; default = false; }
@@ -265,21 +273,6 @@ public class Application.Contact : Geary.BaseObject {
);
}
- /** Returns the avatar for this contact. */
- public async Gdk.Pixbuf? load_avatar(Geary.RFC822.MailboxAddress source,
- int pixel_size,
- GLib.Cancellable cancellable)
- throws GLib.Error {
- Gdk.Pixbuf? avatar = null;
- ContactStore? store = this.store;
- if (store != null) {
- avatar = yield store.avatars.load(
- this, source, pixel_size, cancellable
- );
- }
- return avatar;
- }
-
/** Sets remote resource loading for this contact. */
public async void set_remote_resource_loading(bool enabled,
GLib.Cancellable? cancellable)
@@ -332,8 +325,13 @@ public class Application.Contact : Geary.BaseObject {
Geary.RFC822.MailboxAddress.is_valid_address(name);
}
+ private void on_individual_avatar_notify() {
+ notify_property("avatar");
+ }
+
private void update_from_individual(Folks.Individual? replacement) {
if (this.individual != null) {
+ this.individual.notify["avatar"].disconnect(this.on_individual_avatar_notify);
this.individual.notify.disconnect(this.on_individual_notify);
this.individual.removed.disconnect(this.on_individual_removed);
}
@@ -341,6 +339,7 @@ public class Application.Contact : Geary.BaseObject {
this.individual = replacement;
if (this.individual != null) {
+ this.individual.notify["avatar"].connect(this.on_individual_avatar_notify);
this.individual.notify.connect(this.on_individual_notify);
this.individual.removed.connect(this.on_individual_removed);
}
diff --git a/src/client/application/application-controller.vala
b/src/client/application/application-controller.vala
index 4bb2f631f..e6c5dfe46 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -73,9 +73,6 @@ internal class Application.Controller :
get; private set;
}
- // Avatar store for the application.
- private Application.AvatarStore avatars = new Application.AvatarStore();
-
// Primary collection of the application's open accounts
private Gee.Map<Geary.AccountInformation,AccountContext> accounts =
new Gee.HashMap<Geary.AccountInformation,AccountContext>();
@@ -317,7 +314,6 @@ internal class Application.Controller :
} catch (GLib.Error err) {
warning("Error closing plugin manager: %s", err.message);
}
- this.avatars.close();
this.pending_mailtos.clear();
this.composer_widgets.clear();
@@ -983,7 +979,7 @@ internal class Application.Controller :
account,
new Geary.App.SearchFolder(account, account.local_folder_root),
new Geary.App.EmailStore(account),
- new Application.ContactStore(account, this.folks, this.avatars)
+ new Application.ContactStore(account, this.folks)
);
this.accounts.set(account.information, context);
diff --git a/src/client/conversation-viewer/conversation-contact-popover.vala
b/src/client/conversation-viewer/conversation-contact-popover.vala
index 97d27bb19..1ec220f1a 100644
--- a/src/client/conversation-viewer/conversation-contact-popover.vala
+++ b/src/client/conversation-viewer/conversation-contact-popover.vala
@@ -43,7 +43,8 @@ public class Conversation.ContactPopover : Gtk.Popover {
[GtkChild] private unowned Gtk.Grid contact_pane;
- [GtkChild] private unowned Gtk.Image avatar;
+ [GtkChild]
+ private Hdy.Avatar avatar;
[GtkChild] private unowned Gtk.Label contact_name;
@@ -82,6 +83,16 @@ public class Conversation.ContactPopover : Gtk.Popover {
this.load_remote_button.role = CHECK;
+ this.contact.bind_property("display-name",
+ this.avatar,
+ "text",
+ BindingFlags.SYNC_CREATE);
+
+ this.contact.bind_property("avatar",
+ this.avatar,
+ "loadable-icon",
+ BindingFlags.SYNC_CREATE);
+
this.actions.add_action_entries(ACTION_ENTRIES, this);
insert_action_group(ACTION_GROUP, this.actions);
@@ -92,32 +103,6 @@ public class Conversation.ContactPopover : Gtk.Popover {
/**
* Starts loading the avatar for the message's sender.
*/
- public async void load_avatar() {
- var main = this.get_toplevel() as Application.MainWindow;
- if (main != null) {
- int window_scale = get_scale_factor();
- int pixel_size = (
- Application.Client.AVATAR_SIZE_PIXELS * window_scale
- );
- try {
- Gdk.Pixbuf? avatar_buf = yield contact.load_avatar(
- this.mailbox,
- pixel_size,
- this.load_cancellable
- );
- if (avatar_buf != null) {
- this.avatar.set_from_surface(
- Gdk.cairo_surface_create_from_pixbuf(
- avatar_buf, window_scale, get_window()
- )
- );
- }
- } catch (GLib.Error err) {
- debug("Conversation load failed: %s", err.message);
- }
- }
- }
-
public override void destroy() {
this.contact.changed.disconnect(this.on_contact_changed);
this.load_cancellable.cancel();
diff --git a/src/client/conversation-viewer/conversation-message.vala
b/src/client/conversation-viewer/conversation-message.vala
index b987dbdd6..becf3bf77 100644
--- a/src/client/conversation-viewer/conversation-message.vala
+++ b/src/client/conversation-viewer/conversation-message.vala
@@ -335,7 +335,7 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
private GLib.DateTime? local_date = null;
- [GtkChild] private unowned Gtk.Image avatar;
+ [GtkChild] private unowned Hdy.Avatar avatar;
[GtkChild] private unowned Gtk.Revealer compact_revealer;
[GtkChild] private unowned Gtk.Label compact_from;
@@ -822,31 +822,18 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
this.primary_originator, cancellable
);
- int window_scale = get_scale_factor();
- int pixel_size =
- Application.Client.AVATAR_SIZE_PIXELS * window_scale;
- Gdk.Pixbuf? avatar_buf = yield this.primary_contact.load_avatar(
- this.primary_originator,
- pixel_size,
- cancellable
- );
- if (avatar_buf != null) {
- this.avatar.set_from_surface(
- Gdk.cairo_surface_create_from_pixbuf(
- avatar_buf, window_scale, get_window()
- )
- );
+ if (this.primary_contact != null) {
+ this.primary_contact.bind_property("display-name",
+ this.avatar,
+ "text",
+ BindingFlags.SYNC_CREATE);
+ this.primary_contact.bind_property("avatar",
+ this.avatar,
+ "loadable-icon",
+ BindingFlags.SYNC_CREATE);
}
- } else {
- this.avatar.set_from_icon_name(
- "avatar-default-symbolic", Gtk.IconSize.DIALOG
- );
- this.avatar.set_pixel_size(
- Application.Client.AVATAR_SIZE_PIXELS
- );
}
-
// Preview headers
this.compact_from.set_text(
yield format_originator_compact(cancellable)
@@ -1268,7 +1255,6 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
address_child.contact,
address
);
- popover.load_avatar.begin();
popover.set_position(Gtk.PositionType.BOTTOM);
popover.load_remote_resources_changed.connect((enabled) => {
if (this.primary_contact.equal_to(address_child.contact) &&
diff --git a/src/client/meson.build b/src/client/meson.build
index f20fe5c83..11cf375f5 100644
--- a/src/client/meson.build
+++ b/src/client/meson.build
@@ -14,7 +14,6 @@ client_vala_sources = files(
'application/application-account-context.vala',
'application/application-account-interface.vala',
'application/application-attachment-manager.vala',
- 'application/application-avatar-store.vala',
'application/application-certificate-manager.vala',
'application/application-client.vala',
'application/application-command.vala',
diff --git a/src/client/plugin/desktop-notifications/desktop-notifications.vala
b/src/client/plugin/desktop-notifications/desktop-notifications.vala
index 68dfa6185..255e4ec7e 100644
--- a/src/client/plugin/desktop-notifications/desktop-notifications.vala
+++ b/src/client/plugin/desktop-notifications/desktop-notifications.vala
@@ -97,7 +97,7 @@ public class Plugin.DesktopNotifications :
Email email
) throws GLib.Error {
string title = to_notitication_title(folder.account, total);
- Gdk.Pixbuf? icon = null;
+ GLib.Icon icon = null;
Geary.RFC822.MailboxAddress? originator = email.get_primary_originator();
if (originator != null) {
ContactStore contacts =
@@ -112,19 +112,7 @@ public class Plugin.DesktopNotifications :
: originator.to_short_display()
);
- int window_scale = 1;
- Gdk.Display? display = Gdk.Display.get_default();
- if (display != null) {
- Gdk.Monitor? monitor = display.get_primary_monitor();
- if (monitor != null) {
- window_scale = monitor.scale_factor;
- }
- }
- icon = yield contact.load_avatar(
- originator,
- global::Application.Client.AVATAR_SIZE_PIXELS * window_scale,
- this.cancellable
- );
+ icon = contact.avatar;
}
string body = Util.Email.strip_subject_prefixes(email);
@@ -144,10 +132,24 @@ public class Plugin.DesktopNotifications :
);
}
+ int window_scale = 1;
+ Gdk.Display? display = Gdk.Display.get_default();
+ if (display != null) {
+ Gdk.Monitor? monitor = display.get_primary_monitor();
+ if (monitor != null) {
+ window_scale = monitor.scale_factor;
+ }
+ }
+
+ var avatar = new Hdy.Avatar(32, title, true);
+ avatar.loadable_icon = icon as GLib.LoadableIcon;
+ icon = yield avatar.draw_to_pixbuf_async(32, window_scale, null);
+
issue_arrived_notification(title, body, icon, folder, email.identifier);
}
private void notify_general(Folder folder, int total, int added) {
+ GLib.Icon icon = new GLib.ThemedIcon("%s-symbolic".printf(global::Application.Client.APP_ID));
string title = to_notitication_title(folder.account, total);
string body = ngettext(
/// Notification body when multiple messages have been
@@ -170,12 +172,12 @@ public class Plugin.DesktopNotifications :
).printf(body, total);
}
- issue_arrived_notification(title, body, null, folder, null);
+ issue_arrived_notification(title, body, icon, folder, null);
}
private void issue_arrived_notification(string summary,
string body,
- Gdk.Pixbuf? icon,
+ GLib.Icon icon,
Folder folder,
EmailIdentifier? id) {
// only one outstanding notification at a time
@@ -204,15 +206,9 @@ public class Plugin.DesktopNotifications :
private GLib.Notification issue_notification(string id,
string summary,
string body,
- Gdk.Pixbuf? avatar,
+ GLib.Icon icon,
string? action,
GLib.Variant? action_target) {
- GLib.Icon icon = avatar;
- if (avatar == null) {
- icon = new GLib.ThemedIcon(
- "%s-symbolic".printf(global::Application.Client.APP_ID)
- );
- }
GLib.Notification notification = new GLib.Notification(summary);
notification.set_body(body);
notification.set_icon(icon);
diff --git a/test/client/composer/composer-widget-test.vala b/test/client/composer/composer-widget-test.vala
index 6b31c9435..cdbcd3d61 100644
--- a/test/client/composer/composer-widget-test.vala
+++ b/test/client/composer/composer-widget-test.vala
@@ -125,8 +125,7 @@ public class Composer.WidgetTest : TestCase {
new Geary.App.EmailStore(mock_account),
new Application.ContactStore(
mock_account,
- Folks.IndividualAggregator.dup(),
- new Application.AvatarStore()
+ Folks.IndividualAggregator.dup()
)
);
}
diff --git a/ui/conversation-contact-popover.ui b/ui/conversation-contact-popover.ui
index 113f718c6..6030fee15 100644
--- a/ui/conversation-contact-popover.ui
+++ b/ui/conversation-contact-popover.ui
@@ -60,9 +60,11 @@
</packing>
</child>
<child>
- <object class="GtkImage" id="avatar">
+ <object class="HdyAvatar" id="avatar">
<property name="visible">True</property>
- <property name="pixel_size">48</property>
+ <property name="can_focus">False</property>
+ <property name="show-initials">True</property>
+ <property name="size">48</property>
</object>
<packing>
<property name="left_attach">0</property>
diff --git a/ui/conversation-message.ui b/ui/conversation-message.ui
index 769a3e5f6..c6afd79c4 100644
--- a/ui/conversation-message.ui
+++ b/ui/conversation-message.ui
@@ -2,6 +2,7 @@
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.14"/>
+ <requires lib="libhandy" version="1.0"/>
<template class="ConversationMessage" parent="GtkGrid">
<property name="visible">True</property>
<property name="orientation">vertical</property>
@@ -11,12 +12,11 @@
<property name="hexpand">True</property>
<property name="column_spacing">6</property>
<child>
- <object class="GtkImage" id="avatar">
- <property name="width_request">18</property>
- <property name="height_request">18</property>
+ <object class="HdyAvatar" id="avatar">
<property name="visible">True</property>
<property name="valign">start</property>
- <property name="pixel_size">48</property>
+ <property name="show-initials">True</property>
+ <property name="size">48</property>
</object>
<packing>
<property name="left_attach">0</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]