[geary/wip/135-contact-popovers: 8/13] Add client Contact and ContactStore classes
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/135-contact-popovers: 8/13] Add client Contact and ContactStore classes
- Date: Thu, 14 Mar 2019 22:18:28 +0000 (UTC)
commit 2b424cea8521f7995d31c0c50afce347fc338560
Author: Michael Gratton <mike vee net>
Date: Thu Mar 14 21:41:57 2019 +1100
Add client Contact and ContactStore classes
These simply wrap the Engine equivalents for the moment, but will also
incorporate Folks data as well. Construct a per-account store and add it
to the controller's account context object.
po/POTFILES.in | 2 +
.../application/application-contact-store.vala | 40 ++++++++++
src/client/application/application-contact.vala | 88 ++++++++++++++++++++++
src/client/application/geary-controller.vala | 37 +++++----
src/client/meson.build | 2 +
5 files changed, 155 insertions(+), 14 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 58fd048c..0bf3df22 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -18,6 +18,8 @@ src/client/accounts/accounts-signature-web-view.vala
src/client/application/application-avatar-store.vala
src/client/application/application-certificate-manager.vala
src/client/application/application-command.vala
+src/client/application/application-contact-store.vala
+src/client/application/application-contact.vala
src/client/application/autostart-manager.vala
src/client/application/geary-application.vala
src/client/application/geary-args.vala
diff --git a/src/client/application/application-contact-store.vala
b/src/client/application/application-contact-store.vala
new file mode 100644
index 00000000..c6df7b76
--- /dev/null
+++ b/src/client/application/application-contact-store.vala
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+/**
+ * A source of contacts for an account.
+ *
+ * This class aggregates data from for both the Engine and Folks,
+ * allowing contacts for a specific account to be queried.
+ */
+public class Application.ContactStore {
+
+
+ /** The account this store aggregates data for. */
+ public Geary.Account account { get; private set; }
+
+
+ /** Constructs a new contact store for an account. */
+ public ContactStore(Geary.Account account) {
+ this.account = account;
+ }
+
+ /**
+ * Returns a contact for a specific mailbox.
+ *
+ * Returns a contact that has the given mailbox address listed as
+ * a primary or secondary email. A contact will always be
+ * returned, so if no matching contact already exists a new,
+ * non-persistent contact will be returned.
+ */
+ public Contact get(Geary.RFC822.MailboxAddress mailbox) {
+ Geary.Contact? contact =
+ this.account.get_contact_store().get_by_rfc822(mailbox);
+ return new Contact(this, contact, mailbox);
+ }
+
+}
diff --git a/src/client/application/application-contact.vala b/src/client/application/application-contact.vala
new file mode 100644
index 00000000..c325a062
--- /dev/null
+++ b/src/client/application/application-contact.vala
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2019 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+/**
+ * Contact information for an individual.
+ *
+ * This class aggregates data from for both the Engine and Folks,
+ * allowing contacts information for a specific mailbox to be
+ * queried. Contacts are obtained from the {@link ContactStore} for an
+ * account.
+ */
+public class Application.Contact {
+
+
+ /** The human-readable name of the contact. */
+ public string display_name { get; private set; }
+
+ /** Determines if {@link display_name} is trusted by the user. */
+ public bool display_name_is_trusted { get; private set; default = false; }
+
+ /** Determines if {@link display_name} the same as its email address. */
+ public bool display_name_is_email { get; private set; default = false; }
+
+ /** Determines if email from this contact should load remote resources. */
+ public bool load_remote_resources {
+ get {
+ return (
+ this.contact != null &&
+ this.contact.contact_flags.always_load_remote_images()
+ );
+ }
+ }
+
+ private weak ContactStore store;
+ private Geary.Contact? contact;
+
+
+ internal Contact(ContactStore store,
+ Geary.Contact? contact,
+ Geary.RFC822.MailboxAddress source) {
+ this.store = store;
+ this.contact = contact;
+
+ if (contact != null) {
+ this.display_name = contact.real_name;
+ } else {
+ this.display_name = source.name;
+ }
+
+ // Use the email address as the display name if the existing
+ // display name looks in any way sketchy, regardless of where
+ // it came from
+ if (source.is_spoofed() ||
+ Geary.String.is_empty_or_whitespace(this.display_name) ||
+ Geary.RFC822.MailboxAddress.is_valid_address(this.display_name)) {
+ this.display_name = source.address;
+ this.display_name_is_email = true;
+ }
+ }
+
+ /** Sets remote resource loading for this contact. */
+ public async void set_remote_resource_loading(bool enabled,
+ GLib.Cancellable? cancellable)
+ throws GLib.Error {
+ ContactStore? store = this.store;
+ if (store != null && this.contact != null) {
+ Geary.ContactFlags flags = new Geary.ContactFlags();
+ flags.add(Geary.ContactFlags.ALWAYS_LOAD_REMOTE_IMAGES);
+
+ yield store.account.get_contact_store().mark_contacts_async(
+ Geary.Collection.single(this.contact),
+ enabled ? flags : null,
+ !enabled ? flags : null //,
+ // XXX cancellable
+ );
+ }
+ }
+
+ /** Returns a string representation for debugging */
+ public string to_string() {
+ return "Contact(\"%s\")".printf(this.display_name);
+ }
+
+}
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index 8603f615..2a43765d 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -63,7 +63,8 @@ public class GearyController : Geary.BaseObject {
public Geary.Account account { get; private set; }
public Geary.Folder? inbox = null;
- public Geary.App.EmailStore store { get; private set; }
+ public Geary.App.EmailStore emails { get; private set; }
+ public Application.ContactStore contacts { get; private set; }
public bool authentication_failed = false;
public bool authentication_prompting = false;
@@ -74,9 +75,12 @@ public class GearyController : Geary.BaseObject {
public Cancellable cancellable { get; private set; default = new Cancellable(); }
- public AccountContext(Geary.Account account) {
+ public AccountContext(Geary.Account account,
+ Geary.App.EmailStore emails,
+ Application.ContactStore contacts) {
this.account = account;
- this.store = new Geary.App.EmailStore(account);
+ this.emails = emails;
+ this.contacts = contacts;
}
public Geary.Account.Status get_effective_status() {
@@ -922,7 +926,11 @@ public class GearyController : Geary.BaseObject {
}
private async void connect_account_async(Geary.Account account, Cancellable? cancellable = null) {
- AccountContext context = new AccountContext(account);
+ AccountContext context = new AccountContext(
+ account,
+ new Geary.App.EmailStore(account),
+ new Application.ContactStore(account)
+ );
// XXX Need to set this early since
// on_folders_available_unavailable expects it to be there
@@ -1329,8 +1337,9 @@ public class GearyController : Geary.BaseObject {
Geary.App.Conversation convo = Geary.Collection.get_first(
selected
);
- Geary.App.EmailStore? store = get_store_for_folder(
- convo.base_folder
+
+ AccountContext? context = this.accounts.get(
+ convo.base_folder.account.information
);
// It's possible for a conversation with zero email to
@@ -1338,10 +1347,10 @@ public class GearyController : Geary.BaseObject {
// last email was removed but the conversation monitor
// hasn't signalled its removal yet. In this case,
// just don't load it since it will soon disappear.
- if (store != null && convo.get_count() > 0) {
+ if (context != null && convo.get_count() > 0) {
viewer.load_conversation.begin(
convo,
- store,
+ context.emails,
(obj, ret) => {
try {
viewer.load_conversation.end(ret);
@@ -1630,7 +1639,7 @@ public class GearyController : Geary.BaseObject {
private void mark_email(Gee.Collection<Geary.EmailIdentifier> ids,
Geary.EmailFlags? flags_to_add, Geary.EmailFlags? flags_to_remove) {
if (ids.size > 0) {
- Geary.App.EmailStore? store = get_store_for_folder(current_folder);
+ Geary.App.EmailStore? store = get_email_store_for_folder(current_folder);
if (store != null) {
store.mark_email_async.begin(
ids, flags_to_add, flags_to_remove, cancellable_folder
@@ -1802,7 +1811,7 @@ public class GearyController : Geary.BaseObject {
private void copy_email(Gee.Collection<Geary.EmailIdentifier> ids,
Geary.FolderPath destination) {
if (ids.size > 0) {
- Geary.App.EmailStore? store = get_store_for_folder(current_folder);
+ Geary.App.EmailStore? store = get_email_store_for_folder(current_folder);
if (store != null) {
store.copy_email_async.begin(
ids, destination, cancellable_folder
@@ -2186,7 +2195,7 @@ public class GearyController : Geary.BaseObject {
// Load the widget's content
Geary.Email? full = null;
if (referred != null) {
- Geary.App.EmailStore? store = get_store_for_folder(current_folder);
+ Geary.App.EmailStore? store = get_email_store_for_folder(current_folder);
if (store != null) {
try {
full = yield store.fetch_email_async(
@@ -2757,7 +2766,7 @@ public class GearyController : Geary.BaseObject {
Gee.MultiMap<Geary.EmailIdentifier, Type>? selected_operations = null;
try {
if (current_folder != null) {
- Geary.App.EmailStore? store = get_store_for_folder(current_folder);
+ Geary.App.EmailStore? store = get_email_store_for_folder(current_folder);
if (store != null) {
selected_operations = yield store
.get_supported_operations_async(get_selected_email_ids(false), cancellable);
@@ -2837,9 +2846,9 @@ public class GearyController : Geary.BaseObject {
return selected_conversations.read_only_view;
}
- private inline Geary.App.EmailStore? get_store_for_folder(Geary.Folder target) {
+ private inline Geary.App.EmailStore? get_email_store_for_folder(Geary.Folder target) {
AccountContext? context = this.accounts.get(target.account.information);
- return context != null ? context.store : null;
+ return context != null ? context.emails : null;
}
private bool should_add_folder(Gee.Collection<Geary.Folder>? all,
diff --git a/src/client/meson.build b/src/client/meson.build
index 77db6b1a..1f3f15a7 100644
--- a/src/client/meson.build
+++ b/src/client/meson.build
@@ -3,6 +3,8 @@ geary_client_vala_sources = files(
'application/application-avatar-store.vala',
'application/application-certificate-manager.vala',
'application/application-command.vala',
+ 'application/application-contact-store.vala',
+ 'application/application-contact.vala',
'application/autostart-manager.vala',
'application/geary-application.vala',
'application/geary-args.vala',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]