[geary/wip/unread-status-714865: 5/10] WIP
- From: Charles Lindsay <clindsay src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/unread-status-714865: 5/10] WIP
- Date: Fri, 21 Feb 2014 01:29:21 +0000 (UTC)
commit e64233539cb2a51209789c4ee3b97d263b0204f1
Author: Charles Lindsay <chaz yorba org>
Date: Wed Feb 19 18:18:42 2014 -0800
WIP
.../imap-engine/imap-engine-generic-account.vala | 66 ++++++++++++++++++++
src/engine/imap/api/imap-account.vala | 28 ++++++++
2 files changed, 94 insertions(+), 0 deletions(-)
---
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala
b/src/engine/imap-engine/imap-engine-generic-account.vala
index cd3b24c..0b764c1 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -6,6 +6,7 @@
private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
private const int REFRESH_FOLDER_LIST_SEC = 4 * 60;
+ private const int REFRESH_UNSEEN_SEC = 1;
private static Geary.FolderPath? outbox_path = null;
private static Geary.FolderPath? search_path = null;
@@ -16,6 +17,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
private Gee.HashMap<FolderPath, MinimalFolder> folder_map = new Gee.HashMap<
FolderPath, MinimalFolder>();
private Gee.HashMap<FolderPath, Folder> local_only = new Gee.HashMap<FolderPath, Folder>();
+ private uint refresh_unseen_timeout_id = 0;
private uint refresh_folder_timeout_id = 0;
private bool in_refresh_enumerate = false;
private Cancellable refresh_cancellable = new Cancellable();
@@ -68,6 +70,27 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
}
}
+ protected override void notify_email_appended(Geary.Folder folder, Gee.Collection<Geary.EmailIdentifier>
ids) {
+ base.notify_email_appended(folder, ids);
+ reschedule_unseen_update();
+ }
+
+ protected override void notify_email_inserted(Geary.Folder folder, Gee.Collection<Geary.EmailIdentifier>
ids) {
+ base.notify_email_inserted(folder, ids);
+ reschedule_unseen_update();
+ }
+
+ protected override void notify_email_removed(Geary.Folder folder, Gee.Collection<Geary.EmailIdentifier>
ids) {
+ base.notify_email_removed(folder, ids);
+ reschedule_unseen_update();
+ }
+
+ protected override void notify_email_flags_changed(Geary.Folder folder,
+ Gee.Map<Geary.EmailIdentifier, Geary.EmailFlags> flag_map) {
+ base.notify_email_flags_changed(folder, flag_map);
+ reschedule_unseen_update();
+ }
+
private void check_open() throws EngineError {
if (!open)
throw new EngineError.OPEN_REQUIRED("Account %s not opened", to_string());
@@ -261,6 +284,49 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
return all_folders;
}
+ private void reschedule_unseen_update() {
+ if (refresh_unseen_timeout_id != 0) {
+ Source.remove(refresh_unseen_timeout_id);
+ refresh_unseen_timeout_id = 0;
+ }
+
+ refresh_unseen_timeout_id = Timeout.add_seconds(REFRESH_UNSEEN_SEC, on_refresh_unseen);
+ }
+
+ private bool on_refresh_unseen() {
+ // TODO: prevent recursion?
+
+ // TODO: cancellable?
+ refresh_unseen_async.begin(null, on_refresh_unseen_completed);
+
+ refresh_unseen_timeout_id = 0;
+ return false;
+ }
+
+ private void on_refresh_unseen_completed(Object? source, AsyncResult result) {
+ try {
+ refresh_unseen_async.end(result);
+ } catch (Error e) {
+ debug("Error refreshing unseen counts: %s", e.message);
+ }
+ }
+
+ private async void refresh_unseen_async(Cancellable? cancellable) throws Error {
+ debug("Refreshing unseen counts");
+
+ Gee.Map<FolderPath, int> unseen_counts = yield remote.fetch_all_unseen_async(cancellable);
+ foreach (FolderPath path in unseen_counts.keys) {
+ if (!folder_map.has_key(path)) {
+ debug("Unknown folder path %s returned from unseen counts", path.to_string());
+ continue;
+ }
+
+ MinimalFolder folder = folder_map.get(path);
+ folder.remote_folder.properties.set_status_unseen(unseen_counts.get(path));
+ yield local.update_folder_status_async(folder.remote_folder, false, cancellable);
+ }
+ }
+
private void reschedule_folder_refresh(bool immediate) {
if (in_refresh_enumerate)
return;
diff --git a/src/engine/imap/api/imap-account.vala b/src/engine/imap/api/imap-account.vala
index d3a9092..72f905d 100644
--- a/src/engine/imap/api/imap-account.vala
+++ b/src/engine/imap/api/imap-account.vala
@@ -224,6 +224,34 @@ private class Geary.Imap.Account : BaseObject {
}
}
+ public async Gee.Map<FolderPath, int> fetch_all_unseen_async(Cancellable? cancellable) throws Error {
+ Gee.HashMap<MailboxSpecifier, FolderPath> paths = new Gee.HashMap<MailboxSpecifier, FolderPath>();
+ foreach (FolderPath p in folders.keys) {
+ try {
+ paths.set(new MailboxSpecifier.from_folder_path(p, null), p);
+ } catch (Error e) {
+ debug("Error converting folder path %s to mailbox specifier: %s", p.to_string(), e.message);
+ }
+ }
+
+ Gee.ArrayList<StatusCommand> commands = Geary.traverse<MailboxSpecifier>(paths.keys)
+ .map<StatusCommand>(m => new StatusCommand(m, { StatusDataType.UNSEEN }))
+ .to_array_list();
+ Gee.ArrayList<StatusData> status_results = new Gee.ArrayList<StatusData>();
+ Gee.Map<Command, StatusResponse> responses = yield send_multiple_async(commands,
+ null, status_results, cancellable);
+
+ // TODO: check responses?
+ (void) responses;
+
+ Gee.HashMap<FolderPath, int> unseen_counts = new Gee.HashMap<FolderPath, int>();
+ foreach (StatusData data in status_results) {
+ assert(paths.has_key(data.mailbox));
+ unseen_counts.set(paths.get(data.mailbox), data.unseen);
+ }
+ return unseen_counts;
+ }
+
public async Gee.List<Imap.Folder>? list_child_folders_async(FolderPath? parent, Cancellable?
cancellable)
throws Error {
check_open();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]