[geary/wip/fix-date-handling: 60/60] Use a single timer to make sure relative email dates get updated



commit 315db92d763c304524bac0130ea669db61674f0e
Author: Michael Gratton <mike vee net>
Date:   Wed Mar 13 17:50:47 2019 +1100

    Use a single timer to make sure relative email dates get updated
    
    Move the timer from ConversationListStore to MainWindow, ensure that
    both the list and the viewer get their dates updated, but only when
    the main window is visible.

 src/client/components/main-window.vala             | 47 ++++++++++++++++++++++
 .../conversation-list/conversation-list-store.vala | 18 ++-------
 .../conversation-viewer/conversation-list-box.vala | 10 +++++
 .../conversation-viewer/conversation-message.vala  | 46 +++++++++++++--------
 ui/main-window.ui                                  |  2 +
 5 files changed, 93 insertions(+), 30 deletions(-)
---
diff --git a/src/client/components/main-window.vala b/src/client/components/main-window.vala
index 1b6bfbfa..2cd5e2bc 100644
--- a/src/client/components/main-window.vala
+++ b/src/client/components/main-window.vala
@@ -8,7 +8,11 @@
 
 [GtkTemplate (ui = "/org/gnome/Geary/main-window.ui")]
 public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
+
+
     private const int STATUS_BAR_HEIGHT = 18;
+    private const int UPDATE_UI_INTERVAL = 60;
+
 
     public new GearyApplication application {
         get { return (GearyApplication) base.get_application(); }
@@ -34,6 +38,10 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
     public StatusBar status_bar { get; private set; default = new StatusBar(); }
     private MonitoredSpinner spinner = new MonitoredSpinner();
 
+    private Geary.TimeoutManager update_ui_timeout;
+    private int64 update_ui_last = 0;
+
+
     [GtkChild]
     private Gtk.Box main_layout;
     [GtkChild]
@@ -104,10 +112,16 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
         setup_layout(application.config);
         on_change_orientation();
 
+        this.update_ui_timeout = new Geary.TimeoutManager.seconds(
+            UPDATE_UI_INTERVAL, on_update_ui_timeout
+        );
+        this.update_ui_timeout.repetition = FOREVER;
+
         this.main_layout.show_all();
     }
 
     ~MainWindow() {
+        this.update_ui_timeout.reset();
         base_unref();
     }
 
@@ -381,6 +395,24 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
         return base.key_release_event(event);
     }
 
+    private void update_ui() {
+        // Only update if we haven't done so within the last while
+        int64 now = GLib.get_monotonic_time() / (1000 * 1000);
+        if (this.update_ui_last + UPDATE_UI_INTERVAL < now) {
+            this.update_ui_last = now;
+
+            if (this.conversation_viewer.current_list != null) {
+                this.conversation_viewer.current_list.update_display();
+            }
+
+            ConversationListStore? list_store =
+                this.conversation_list_view.get_model() as ConversationListStore;
+            if (list_store != null) {
+                list_store.update_display();
+            }
+        }
+    }
+
     private void on_conversation_monitor_changed() {
         ConversationListStore? old_model = this.conversation_list_view.get_model();
         if (old_model != null) {
@@ -542,6 +574,17 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
         return service;
     }
 
+    [GtkCallback]
+    private void on_map() {
+        this.update_ui_timeout.start();
+        update_ui();
+    }
+
+    [GtkCallback]
+    private void on_unmap() {
+        this.update_ui_timeout.reset();
+    }
+
     [GtkCallback]
     private bool on_focus_event() {
         on_shift_key(false);
@@ -608,4 +651,8 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
         update_infobar_frame();
     }
 
+    private void on_update_ui_timeout() {
+        update_ui();
+    }
+
 }
diff --git a/src/client/conversation-list/conversation-list-store.vala 
b/src/client/conversation-list/conversation-list-store.vala
index cbf11b88..43ad6b46 100644
--- a/src/client/conversation-list/conversation-list-store.vala
+++ b/src/client/conversation-list/conversation-list-store.vala
@@ -97,7 +97,6 @@ public class ConversationListStore : Gtk.ListStore {
     private Cancellable cancellable = new Cancellable();
     private bool loading_local_only = true;
     private Geary.Nonblocking.Mutex refresh_mutex = new Geary.Nonblocking.Mutex();
-    private uint update_id = 0;
 
     public signal void conversations_added(bool start);
     public signal void conversations_removed(bool start);
@@ -108,9 +107,6 @@ public class ConversationListStore : Gtk.ListStore {
         set_sort_column_id(Gtk.SortColumn.DEFAULT, Gtk.SortType.DESCENDING);
 
         this.conversations = conversations;
-        this.update_id = Timeout.add_seconds_full(
-            Priority.LOW, 60, update_date_strings
-        );
         this.email_store = new Geary.App.EmailStore(
             conversations.base_folder.account
         );
@@ -135,10 +131,10 @@ public class ConversationListStore : Gtk.ListStore {
 
         // Release circular refs.
         this.row_map.clear();
-        if (this.update_id != 0) {
-            Source.remove(this.update_id);
-            this.update_id = 0;
-        }
+    }
+
+    public void update_display() {
+        this.foreach(update_date_string);
     }
 
     public Geary.App.Conversation? get_conversation_at_path(Gtk.TreePath path) {
@@ -479,11 +475,6 @@ public class ConversationListStore : Gtk.ListStore {
         refresh_previews_async.begin(this.conversations);
     }
 
-    private bool update_date_strings() {
-        this.foreach(update_date_string);
-        return Source.CONTINUE;
-    }
-
     private bool update_date_string(Gtk.TreeModel model, Gtk.TreePath path, Gtk.TreeIter iter) {
         FormattedConversationData? message_data;
         model.get(iter, Column.CONVERSATION_DATA, out message_data);
@@ -496,4 +487,3 @@ public class ConversationListStore : Gtk.ListStore {
     }
 
 }
-
diff --git a/src/client/conversation-viewer/conversation-list-box.vala 
b/src/client/conversation-viewer/conversation-list-box.vala
index a4250f39..781ada34 100644
--- a/src/client/conversation-viewer/conversation-list-box.vala
+++ b/src/client/conversation-viewer/conversation-list-box.vala
@@ -782,6 +782,16 @@ public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface {
             });
     }
 
+    /**
+     * Updates the displayed date for each conversation row.
+     */
+    public void update_display() {
+        message_view_iterator().foreach((msg_view) => {
+                msg_view.update_display();
+                return true;
+            });
+    }
+
     /** Returns the email row for the given id, if any. */
     internal EmailRow? get_email_row_by_id(Geary.EmailIdentifier id) {
         return this.email_rows.get(id);
diff --git a/src/client/conversation-viewer/conversation-message.vala 
b/src/client/conversation-viewer/conversation-message.vala
index 6e8dad28..9324aab2 100644
--- a/src/client/conversation-viewer/conversation-message.vala
+++ b/src/client/conversation-viewer/conversation-message.vala
@@ -158,8 +158,12 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
     /** HTML view that displays the message body. */
     internal ConversationWebView web_view { get; private set; }
 
+    private Configuration config;
+
     private Geary.RFC822.MailboxAddress? primary_originator;
 
+    private GLib.DateTime? local_date = null;
+
     [GtkChild]
     private Gtk.Image avatar;
 
@@ -345,6 +349,7 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
         base_ref();
         this.is_loading_images = load_remote_images;
         this.primary_originator = primary_originator;
+        this.config = config;
 
         // Actions
 
@@ -387,6 +392,9 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
                 (MenuModel) builder.get_object("context_menu_inspector");
         }
 
+        this.local_date = date.value.to_local();
+        update_display();
+
         // Compact headers
 
         // Translators: This is displayed in place of the from address
@@ -396,20 +404,6 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
         this.compact_from.set_text(format_originator_compact(from, empty_from));
         this.compact_from.get_style_context().add_class(FROM_CLASS);
 
-        string date_text = "";
-        string date_tooltip = "";
-        if (date != null) {
-            GLib.DateTime local_date = date.value.to_local();
-            date_text = Date.pretty_print(
-                local_date, config.clock_format
-            );
-            date_tooltip = Date.pretty_print_verbose(
-                local_date, config.clock_format
-            );
-        }
-        this.compact_date.set_text(date_text);
-        this.compact_date.set_tooltip_text(date_tooltip);
-
         if (preview != null) {
             string clean_preview = preview;
             if (preview.length > MAX_PREVIEW_BYTES) {
@@ -427,8 +421,6 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
 
         fill_originator_addresses(from, reply_to, sender, empty_from);
 
-        this.date.set_text(date_text);
-        this.date.set_tooltip_text(date_tooltip);
         if (subject != null) {
             this.subject.set_text(subject.value);
             this.subject.set_visible(true);
@@ -706,6 +698,28 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
         this.web_view.unmark_search_terms();
     }
 
+    /**
+     * Updates the displayed date for each conversation row.
+     */
+    public void update_display() {
+        string date_text = "";
+        string date_tooltip = "";
+        if (this.local_date != null) {
+            date_text = Date.pretty_print(
+                this.local_date, this.config.clock_format
+            );
+            date_tooltip = Date.pretty_print_verbose(
+                this.local_date, this.config.clock_format
+            );
+        }
+
+        this.compact_date.set_text(date_text);
+        this.compact_date.set_tooltip_text(date_tooltip);
+
+        this.date.set_text(date_text);
+        this.date.set_tooltip_text(date_tooltip);
+    }
+
     private SimpleAction add_action(string name, bool enabled, VariantType? type = null) {
         SimpleAction action = new SimpleAction(name, type);
         action.set_enabled(enabled);
diff --git a/ui/main-window.ui b/ui/main-window.ui
index 7a1b0210..428f40f7 100644
--- a/ui/main-window.ui
+++ b/ui/main-window.ui
@@ -9,6 +9,8 @@
     <property name="show_menubar">False</property>
     <signal name="delete-event" handler="on_delete_event" swapped="no"/>
     <signal name="focus-in-event" handler="on_focus_event" swapped="no"/>
+    <signal name="map" handler="on_map" swapped="no"/>
+    <signal name="unmap" handler="on_unmap" swapped="no"/>
     <child type="titlebar">
       <placeholder/>
     </child>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]