diff --git a/src/FoldersView/AccountSourceItem.vala b/src/FoldersView/AccountSourceItem.vala index a3c0c018d..91bd6ad37 100644 --- a/src/FoldersView/AccountSourceItem.vala +++ b/src/FoldersView/AccountSourceItem.vala @@ -27,6 +27,7 @@ public class Mail.AccountSourceItem : Granite.Widgets.SourceList.ExpandableItem private GLib.Cancellable connect_cancellable; private Gee.HashMap folder_items; + private Gee.HashMap folders; private AccountSavedState saved_state; private unowned Camel.OfflineStore offlinestore; @@ -38,6 +39,7 @@ public class Mail.AccountSourceItem : Granite.Widgets.SourceList.ExpandableItem visible = true; connect_cancellable = new GLib.Cancellable (); folder_items = new Gee.HashMap (); + folders = new Gee.HashMap (); saved_state = new AccountSavedState (account); saved_state.bind_with_expandable_item (this); @@ -61,7 +63,7 @@ public class Mail.AccountSourceItem : Granite.Widgets.SourceList.ExpandableItem try { var folderinfo = yield offlinestore.get_folder_info (null, Camel.StoreGetFolderInfoFlags.RECURSIVE, GLib.Priority.DEFAULT, connect_cancellable); if (folderinfo != null) { - show_info (folderinfo, this); + folder_created (folderinfo); } } catch (Error e) { critical (e.message); @@ -89,6 +91,17 @@ public class Mail.AccountSourceItem : Granite.Widgets.SourceList.ExpandableItem private void folder_renamed (string old_name, Camel.FolderInfo folder_info) { var item = folder_items[old_name]; item.update_infos (folder_info); + + lock (folders) { + if (folders.has_key (old_name)) { + Camel.Folder folder; + if (folders.unset (old_name, out folder)) { + folders.set (folder_info.full_name, folder); + + folder.refresh_info.begin (GLib.Priority.DEFAULT, null); + } + } + } } private void folder_deleted (Camel.FolderInfo folder_info) { @@ -96,12 +109,18 @@ public class Mail.AccountSourceItem : Granite.Widgets.SourceList.ExpandableItem if (item != null) { item.parent.remove (item); folder_items.unset (folder_info.full_name); + + lock (folders) { + folders.unset (folder_info.full_name); + } } } private void folder_created (Camel.FolderInfo folder_info) { if (folder_info.parent == null) { show_info (folder_info, this); + connect_folder_changed (folder_info); + } else { unowned Camel.FolderInfo parent_info = (Camel.FolderInfo) folder_info.parent; var parent_item = folder_items[parent_info.full_name]; @@ -111,10 +130,47 @@ public class Mail.AccountSourceItem : Granite.Widgets.SourceList.ExpandableItem folder_created (folder_info); } else { show_info (folder_info, parent_item); + connect_folder_changed (folder_info); } } } + private void connect_folder_changed (Camel.FolderInfo folder_info) { + offlinestore.get_folder.begin (folder_info.full_name, Camel.StoreGetFolderFlags.NONE, GLib.Priority.DEFAULT, null, (obj, res) => { + try { + var folder = offlinestore.get_folder.end (res); + folder.changed.connect ((changes) => { + folder_changed (folder, changes); + }); + + lock (folders) { + folders.set (folder_info.full_name, folder); + } + + } catch (Error e) { + warning ("Error retrieving folder '%s' from store: %s", folder_info.full_name, e.message); + } + }); + } + + private void folder_changed (Camel.Folder folder, Camel.FolderChangeInfo changes) { + Mail.FolderSourceItem? item = folder_items[folder.full_name]; + + if (item != null && account.service is Camel.Store) { + var store = (Camel.Store) account.service; + + store.get_folder_info.begin (folder.full_name, Camel.StoreGetFolderInfoFlags.REFRESH, GLib.Priority.DEFAULT, null, (obj, res) => { + try { + var folder_info = store.get_folder_info.end (res); + item.update_infos (folder_info); + + } catch (Error e) { + warning ("Error refreshing folder info for '%s': %s", folder.full_name, e.message); + } + }); + } + } + private async void reload_folders () { var offlinestore = (Camel.OfflineStore) account.service; foreach (var folder_item in folder_items.values) { diff --git a/src/FoldersView/FolderSourceItem.vala b/src/FoldersView/FolderSourceItem.vala index 5bfa59772..fb9f11629 100644 --- a/src/FoldersView/FolderSourceItem.vala +++ b/src/FoldersView/FolderSourceItem.vala @@ -46,6 +46,8 @@ public class Mail.FolderSourceItem : Granite.Widgets.SourceList.ExpandableItem { public void update_infos (Camel.FolderInfo folderinfo) { name = folderinfo.display_name; full_name = folderinfo.full_name; + + badge = ""; if (folderinfo.unread > 0) { badge = "%d".printf (folderinfo.unread); } @@ -63,7 +65,7 @@ public class Mail.FolderSourceItem : Granite.Widgets.SourceList.ExpandableItem { case Camel.FolderInfoFlags.TYPE_TRASH: icon = new ThemedIcon (folderinfo.total == 0 ? "user-trash" : "user-trash-full"); can_modify = false; - badge = null; + badge = ""; break; case Camel.FolderInfoFlags.TYPE_JUNK: icon = new ThemedIcon ("edit-flag"); @@ -72,11 +74,12 @@ public class Mail.FolderSourceItem : Granite.Widgets.SourceList.ExpandableItem { case Camel.FolderInfoFlags.TYPE_SENT: icon = new ThemedIcon ("mail-sent"); can_modify = false; + badge = ""; break; case Camel.FolderInfoFlags.TYPE_ARCHIVE: icon = new ThemedIcon ("mail-archive"); can_modify = false; - badge = null; + badge = ""; break; case Camel.FolderInfoFlags.TYPE_DRAFTS: icon = new ThemedIcon ("mail-drafts"); diff --git a/src/FoldersView/GroupedFolderSourceItem.vala b/src/FoldersView/GroupedFolderSourceItem.vala index 994ee6a4b..049dca7d0 100644 --- a/src/FoldersView/GroupedFolderSourceItem.vala +++ b/src/FoldersView/GroupedFolderSourceItem.vala @@ -23,6 +23,7 @@ public class Mail.GroupedFolderSourceItem : Granite.Widgets.SourceList.Item { private GLib.Cancellable connect_cancellable; private Gee.HashMap account_folderinfo; + private Gee.HashMap account_folders; public GroupedFolderSourceItem (Mail.Backend.Session session, Camel.FolderInfoFlags folder_type) { Object (session: session, folder_type: folder_type); @@ -32,6 +33,7 @@ public class Mail.GroupedFolderSourceItem : Granite.Widgets.SourceList.Item { visible = true; connect_cancellable = new GLib.Cancellable (); account_folderinfo = new Gee.HashMap (); + account_folders = new Gee.HashMap (); switch (folder_type & Camel.FOLDER_TYPE_MASK) { case Camel.FolderInfoFlags.TYPE_INBOX: @@ -91,7 +93,9 @@ public class Mail.GroupedFolderSourceItem : Granite.Widgets.SourceList.Item { private async void load_folder_info (Mail.Backend.Account account) { var offlinestore = (Camel.OfflineStore) account.service; var full_name = build_folder_full_name (account); + Camel.FolderInfo? folderinfo = null; + Camel.Folder? folder = null; if (full_name != null) { try { @@ -102,11 +106,26 @@ public class Mail.GroupedFolderSourceItem : Granite.Widgets.SourceList.Item { warning ("Unable to fetch %s of account '%s': %s", full_name, account.service.display_name, e.message); } } + + try { + folder = yield offlinestore.get_folder (full_name, Camel.StoreGetFolderFlags.NONE, GLib.Priority.DEFAULT, connect_cancellable); + + folder.changed.connect ((changes) => { + account_folder_changed (account, folder, changes); + }); + + } catch (Error e) { + warning ("Error retrieving folder '%s' from store: %s", full_name, e.message); + } } lock (account_folderinfo) { account_folderinfo.set (account, folderinfo); } + + lock (account_folders) { + account_folders.set (account, folder); + } update_infos (); } @@ -116,20 +135,43 @@ public class Mail.GroupedFolderSourceItem : Granite.Widgets.SourceList.Item { } } + private void account_folder_changed (Mail.Backend.Account account, Camel.Folder folder, Camel.FolderChangeInfo changes) { + if (account.service is Camel.Store) { + var store = (Camel.Store) account.service; + + store.get_folder_info.begin (folder.full_name, Camel.StoreGetFolderInfoFlags.REFRESH, GLib.Priority.DEFAULT, null, (obj, res) => { + try { + var folder_info = store.get_folder_info.end (res); + lock (account_folderinfo) { + account_folderinfo.set (account, folder_info); + } + + update_infos (); + + } catch (Error e) { + warning ("Error refreshing folder info for '%s': %s", folder.full_name, e.message); + } + }); + } + } + private void update_infos () { - badge = null; - var total_unread = 0; - lock (account_folderinfo) { - foreach (var entry in account_folderinfo) { - if (entry.value == null) { - continue; + badge = ""; + + if (Camel.FolderInfoFlags.TYPE_INBOX == (folder_type & Camel.FOLDER_TYPE_MASK)) { + var total_unread = 0; + lock (account_folderinfo) { + foreach (var entry in account_folderinfo) { + if (entry.value == null) { + continue; + } + total_unread += entry.value.unread; } - total_unread += entry.value.unread; } - } - if (total_unread > 0) { - badge = "%d".printf (total_unread); + if (total_unread > 0) { + badge = "%d".printf (total_unread); + } } }