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.
This commit is contained in:
Michael Gratton 2019-03-13 17:50:47 +11:00 committed by Michael James Gratton
parent 26c15e9897
commit ec14a0c98d
5 changed files with 93 additions and 30 deletions

View file

@ -8,7 +8,11 @@
[GtkTemplate (ui = "/org/gnome/Geary/main-window.ui")] [GtkTemplate (ui = "/org/gnome/Geary/main-window.ui")]
public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface { public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
private const int STATUS_BAR_HEIGHT = 18; private const int STATUS_BAR_HEIGHT = 18;
private const int UPDATE_UI_INTERVAL = 60;
public new GearyApplication application { public new GearyApplication application {
get { return (GearyApplication) base.get_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(); } public StatusBar status_bar { get; private set; default = new StatusBar(); }
private MonitoredSpinner spinner = new MonitoredSpinner(); private MonitoredSpinner spinner = new MonitoredSpinner();
private Geary.TimeoutManager update_ui_timeout;
private int64 update_ui_last = 0;
[GtkChild] [GtkChild]
private Gtk.Box main_layout; private Gtk.Box main_layout;
[GtkChild] [GtkChild]
@ -104,10 +112,16 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
setup_layout(application.config); setup_layout(application.config);
on_change_orientation(); 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(); this.main_layout.show_all();
} }
~MainWindow() { ~MainWindow() {
this.update_ui_timeout.reset();
base_unref(); base_unref();
} }
@ -381,6 +395,24 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
return base.key_release_event(event); 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() { private void on_conversation_monitor_changed() {
ConversationListStore? old_model = this.conversation_list_view.get_model(); ConversationListStore? old_model = this.conversation_list_view.get_model();
if (old_model != null) { if (old_model != null) {
@ -542,6 +574,17 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
return service; 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] [GtkCallback]
private bool on_focus_event() { private bool on_focus_event() {
on_shift_key(false); on_shift_key(false);
@ -608,4 +651,8 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
update_infobar_frame(); update_infobar_frame();
} }
private void on_update_ui_timeout() {
update_ui();
}
} }

View file

@ -97,7 +97,6 @@ public class ConversationListStore : Gtk.ListStore {
private Cancellable cancellable = new Cancellable(); private Cancellable cancellable = new Cancellable();
private bool loading_local_only = true; private bool loading_local_only = true;
private Geary.Nonblocking.Mutex refresh_mutex = new Geary.Nonblocking.Mutex(); 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_added(bool start);
public signal void conversations_removed(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); set_sort_column_id(Gtk.SortColumn.DEFAULT, Gtk.SortType.DESCENDING);
this.conversations = conversations; this.conversations = conversations;
this.update_id = Timeout.add_seconds_full(
Priority.LOW, 60, update_date_strings
);
this.email_store = new Geary.App.EmailStore( this.email_store = new Geary.App.EmailStore(
conversations.base_folder.account conversations.base_folder.account
); );
@ -135,10 +131,10 @@ public class ConversationListStore : Gtk.ListStore {
// Release circular refs. // Release circular refs.
this.row_map.clear(); 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) { 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); 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) { private bool update_date_string(Gtk.TreeModel model, Gtk.TreePath path, Gtk.TreeIter iter) {
FormattedConversationData? message_data; FormattedConversationData? message_data;
model.get(iter, Column.CONVERSATION_DATA, out message_data); model.get(iter, Column.CONVERSATION_DATA, out message_data);
@ -496,4 +487,3 @@ public class ConversationListStore : Gtk.ListStore {
} }
} }

View file

@ -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. */ /** Returns the email row for the given id, if any. */
internal EmailRow? get_email_row_by_id(Geary.EmailIdentifier id) { internal EmailRow? get_email_row_by_id(Geary.EmailIdentifier id) {
return this.email_rows.get(id); return this.email_rows.get(id);

View file

@ -158,8 +158,12 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
/** HTML view that displays the message body. */ /** HTML view that displays the message body. */
internal ConversationWebView web_view { get; private set; } internal ConversationWebView web_view { get; private set; }
private Configuration config;
private Geary.RFC822.MailboxAddress? primary_originator; private Geary.RFC822.MailboxAddress? primary_originator;
private GLib.DateTime? local_date = null;
[GtkChild] [GtkChild]
private Gtk.Image avatar; private Gtk.Image avatar;
@ -345,6 +349,7 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
base_ref(); base_ref();
this.is_loading_images = load_remote_images; this.is_loading_images = load_remote_images;
this.primary_originator = primary_originator; this.primary_originator = primary_originator;
this.config = config;
// Actions // Actions
@ -387,6 +392,9 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
(MenuModel) builder.get_object("context_menu_inspector"); (MenuModel) builder.get_object("context_menu_inspector");
} }
this.local_date = date.value.to_local();
update_display();
// Compact headers // Compact headers
// Translators: This is displayed in place of the from address // 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.set_text(format_originator_compact(from, empty_from));
this.compact_from.get_style_context().add_class(FROM_CLASS); 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 = Util.Date.pretty_print(
local_date, config.clock_format
);
date_tooltip = Util.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) { if (preview != null) {
string clean_preview = preview; string clean_preview = preview;
if (preview.length > MAX_PREVIEW_BYTES) { 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); 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) { if (subject != null) {
this.subject.set_text(subject.value); this.subject.set_text(subject.value);
this.subject.set_visible(true); this.subject.set_visible(true);
@ -706,6 +698,28 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
this.web_view.unmark_search_terms(); 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 = Util.Date.pretty_print(
this.local_date, this.config.clock_format
);
date_tooltip = Util.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) { private SimpleAction add_action(string name, bool enabled, VariantType? type = null) {
SimpleAction action = new SimpleAction(name, type); SimpleAction action = new SimpleAction(name, type);
action.set_enabled(enabled); action.set_enabled(enabled);

View file

@ -9,6 +9,8 @@
<property name="show_menubar">False</property> <property name="show_menubar">False</property>
<signal name="delete-event" handler="on_delete_event" swapped="no"/> <signal name="delete-event" handler="on_delete_event" swapped="no"/>
<signal name="focus-in-event" handler="on_focus_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"> <child type="titlebar">
<placeholder/> <placeholder/>
</child> </child>