Lookup and use Folks individuals in client contact classes

This commit is contained in:
Michael Gratton 2019-03-15 09:00:52 +11:00 committed by Michael James Gratton
parent a5c87911af
commit 5a68152aca
3 changed files with 74 additions and 19 deletions

View file

@ -11,16 +11,20 @@
* This class aggregates data from for both the Engine and Folks,
* allowing contacts for a specific account to be queried.
*/
public class Application.ContactStore {
public class Application.ContactStore : Geary.BaseObject {
/** The account this store aggregates data for. */
public Geary.Account account { get; private set; }
private Folks.IndividualAggregator individuals;
/** Constructs a new contact store for an account. */
public ContactStore(Geary.Account account) {
public ContactStore(Geary.Account account,
Folks.IndividualAggregator individuals) {
this.account = account;
this.individuals = individuals;
}
/**
@ -31,10 +35,49 @@ public class Application.ContactStore {
* returned, so if no matching contact already exists a new,
* non-persistent contact will be returned.
*/
public Contact get(Geary.RFC822.MailboxAddress mailbox) {
public async Contact load(Geary.RFC822.MailboxAddress mailbox,
GLib.Cancellable? cancellable)
throws GLib.Error {
Folks.Individual? individual = yield search_match(
mailbox.address, cancellable
);
Geary.Contact? contact =
this.account.get_contact_store().get_by_rfc822(mailbox);
return new Contact(this, contact, mailbox);
return new Contact(this, individual, contact, mailbox);
}
private async Folks.Individual? search_match(string address,
GLib.Cancellable cancellable)
throws GLib.Error {
if (cancellable.is_cancelled()) {
throw new GLib.IOError.CANCELLED("Contact load was cancelled");
}
Folks.SearchView view = new Folks.SearchView(
this.individuals,
new Folks.SimpleQuery(
address,
new string[] {
Folks.PersonaStore.detail_key(
Folks.PersonaDetail.EMAIL_ADDRESSES
)
}
)
);
yield view.prepare();
Folks.Individual? match = null;
if (!view.individuals.is_empty) {
match = view.individuals.first();
}
try {
yield view.unprepare();
} catch (GLib.Error err) {
warning("Error unpreparing Folks search: %s", err.message);
}
return match;
}
}

View file

@ -13,39 +13,51 @@
* queried. Contacts are obtained from the {@link ContactStore} for an
* account.
*/
public class Application.Contact {
public class Application.Contact : Geary.BaseObject {
/** 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. */
/** Determines if this contact was loaded from Folks. */
public bool is_desktop_contact { get; private set; default = false; }
/**
* Determines if email from this contact should load remote resources.
*
* Will automatically load resources from contacts in the desktop
* database, or if the Engine's contact has been flagged to do so.
*/
public bool load_remote_resources {
get {
return (
this.contact != null &&
this.contact.contact_flags.always_load_remote_images()
this.individual != null ||
(this.contact != null &&
this.contact.always_load_remote_images())
);
}
}
private weak ContactStore store;
private Folks.Individual? individual;
private Geary.Contact? contact;
internal Contact(ContactStore store,
Folks.Individual? individual,
Geary.Contact? contact,
Geary.RFC822.MailboxAddress source) {
this.store = store;
this.individual = individual;
this.contact = contact;
if (contact != null) {
if (individual != null) {
this.display_name = individual.display_name;
this.is_desktop_contact = true;
} else if (contact != null) {
this.display_name = contact.real_name;
} else {
this.display_name = source.name;

View file

@ -140,6 +140,7 @@ public class GearyController : Geary.BaseObject {
// when closed.
private GLib.Cancellable? open_cancellable = null;
private Folks.IndividualAggregator? folks = null;
private Geary.Folder? current_folder = null;
private Cancellable cancellable_folder = new Cancellable();
private Cancellable cancellable_search = new Cancellable();
@ -267,21 +268,20 @@ public class GearyController : Geary.BaseObject {
error("Error loading web resources: %s", err.message);
}
Folks.IndividualAggregator individuals =
Folks.IndividualAggregator.dup();
if (!individuals.is_prepared) {
this.folks = Folks.IndividualAggregator.dup();
if (!this.folks.is_prepared) {
// Do this in the background since it can take a long time
// on some systems and the GUI shouldn't be blocked by it
individuals.prepare.begin((obj, res) => {
this.folks.prepare.begin((obj, res) => {
try {
individuals.prepare.end(res);
this.folks.prepare.end(res);
} catch (GLib.Error err) {
warning("Error preparing Folks: %s", err.message);
}
});
}
this.avatars = new Application.AvatarStore(individuals);
this.avatars = new Application.AvatarStore(this.folks);
// Create the main window (must be done after creating actions.)
main_window = new MainWindow(this.application);
@ -915,7 +915,7 @@ public class GearyController : Geary.BaseObject {
AccountContext context = new AccountContext(
account,
new Geary.App.EmailStore(account),
new Application.ContactStore(account)
new Application.ContactStore(account, this.folks)
);
// XXX Need to set this early since