Commit 3a44628d authored by Michael Gratton's avatar Michael Gratton 🤞

Fix ConversationMonitor sometimes not loading more from remote

If a FillWindowOperation didn't load a full amount of messages, it just
assumed that there were no more to load. This is not true however when
loading locally, the folder's vector isn't fully expanded, and it gets
to the end of the vector.

This patch fixes the operation to also queue another fill if the
monitor's folder message window is smaller than the folder's total
message count.

Fixes #289
parent 29389bc3
Pipeline #73042 passed with stages
in 25 minutes and 2 seconds
...@@ -85,6 +85,16 @@ public class Geary.App.ConversationMonitor : BaseObject { ...@@ -85,6 +85,16 @@ public class Geary.App.ConversationMonitor : BaseObject {
/** Determines if this monitor is monitoring the base folder. */ /** Determines if this monitor is monitoring the base folder. */
public bool is_monitoring { get; private set; default = false; } public bool is_monitoring { get; private set; default = false; }
/** Determines if more conversations can be loaded. */
public bool can_load_more {
get {
return (
this.base_folder.properties.email_total >
this.folder_window_size
);
}
}
/** Minimum number of emails large conversations should contain. */ /** Minimum number of emails large conversations should contain. */
public int min_window_count { public int min_window_count {
get { return _min_window_count; } get { return _min_window_count; }
...@@ -103,6 +113,13 @@ public class Geary.App.ConversationMonitor : BaseObject { ...@@ -103,6 +113,13 @@ public class Geary.App.ConversationMonitor : BaseObject {
/** The set of all conversations loaded by the monitor. */ /** The set of all conversations loaded by the monitor. */
internal ConversationSet conversations { get; private set; } internal ConversationSet conversations { get; private set; }
/** The number of messages currently loaded from the base folder. */
internal uint folder_window_size {
get {
return (this.window.is_empty) ? 0 : this.window.size;
}
}
/** The oldest message from the base folder in the loaded window. */ /** The oldest message from the base folder in the loaded window. */
internal EmailIdentifier? window_lowest { internal EmailIdentifier? window_lowest {
owned get { owned get {
...@@ -116,10 +133,10 @@ public class Geary.App.ConversationMonitor : BaseObject { ...@@ -116,10 +133,10 @@ public class Geary.App.ConversationMonitor : BaseObject {
private Cancellable? operation_cancellable = null; private Cancellable? operation_cancellable = null;
// Set of known, in-folder emails, explicitly loaded for the // Set of known, in-folder emails, explicitly loaded for the
// monitor's window. This exists purely to support the // monitor's window. This exists purely to support the window_size
// window_lowest property above, but we need to maintain a sorted // and window_lowest properties above, but we need to maintain a
// set of all known messages since if the last known email is // sorted set of all known messages since if the last known email
// removed, we won't know what the next lowest is. Only email // is removed, we won't know what the next lowest is. Only email
// listed by one of the load_by_*_id methods are added here. Other // listed by one of the load_by_*_id methods are added here. Other
// in-folder messages pulled in for a conversation aren't added, // in-folder messages pulled in for a conversation aren't added,
// since they may not be within the load window. // since they may not be within the load window.
...@@ -345,7 +362,9 @@ public class Geary.App.ConversationMonitor : BaseObject { ...@@ -345,7 +362,9 @@ public class Geary.App.ConversationMonitor : BaseObject {
/** Ensures enough conversations are present, otherwise loads more. */ /** Ensures enough conversations are present, otherwise loads more. */
internal void check_window_count() { internal void check_window_count() {
if (this.is_monitoring && this.conversations.size < this.min_window_count) { if (this.is_monitoring &&
this.can_load_more &&
this.conversations.size < this.min_window_count) {
this.queue.add(new FillWindowOperation(this)); this.queue.add(new FillWindowOperation(this));
} }
} }
......
...@@ -46,10 +46,12 @@ private class Geary.App.FillWindowOperation : ConversationOperation { ...@@ -46,10 +46,12 @@ private class Geary.App.FillWindowOperation : ConversationOperation {
this.monitor.window_lowest, num_to_load this.monitor.window_lowest, num_to_load
); );
// Check to see if we need any more, but only if we actually // Check to see if we need any more, but only if there might
// loaded some, so we don't keep loop loading when we have // be some more to load either locally or from the remote. If
// already loaded all in the folder. // we loaded the full amount, there might be some more
if (loaded == num_to_load) { // locally, so try that. If not, but the monitor thinks there
// are more to load, then we have go check the remote.
if (loaded == num_to_load || this.monitor.can_load_more) {
this.monitor.check_window_count(); this.monitor.check_window_count();
} }
} }
......
...@@ -46,7 +46,7 @@ public class Geary.MockFolder : Folder, MockObject { ...@@ -46,7 +46,7 @@ public class Geary.MockFolder : Folder, MockObject {
SpecialFolderType type, SpecialFolderType type,
ProgressMonitor? monitor) { ProgressMonitor? monitor) {
this._account = account; this._account = account;
this._properties = properties; this._properties = properties ?? new MockFolderPoperties();
this._path = path; this._path = path;
this._type = type; this._type = type;
this._opening_monitor = monitor; this._opening_monitor = monitor;
......
/*
* Copyright 2019 Michael Gratton <mike@vee.net>
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
public class Geary.MockFolderPoperties : FolderProperties {
public MockFolderPoperties() {
base(
0,
0,
Trillian.UNKNOWN,
Trillian.UNKNOWN,
Trillian.UNKNOWN,
false,
false,
false
);
}
}
...@@ -235,9 +235,6 @@ class Geary.App.ConversationMonitorTest : TestCase { ...@@ -235,9 +235,6 @@ class Geary.App.ConversationMonitorTest : TestCase {
assert_int(2, monitor.size, "Initial conversation count"); assert_int(2, monitor.size, "Initial conversation count");
assert_equal(e2.id, monitor.window_lowest, "Lowest window id"); assert_equal(e2.id, monitor.window_lowest, "Lowest window id");
// Removing a message will trigger another async load
this.base_folder.expect_call("list_email_by_id_async");
this.base_folder.email_removed(new Gee.ArrayList<EmailIdentifier>.wrap({e2.id})); this.base_folder.email_removed(new Gee.ArrayList<EmailIdentifier>.wrap({e2.id}));
wait_for_signal(monitor, "conversations-removed"); wait_for_signal(monitor, "conversations-removed");
assert_int(1, monitor.size, "Conversation count"); assert_int(1, monitor.size, "Conversation count");
......
...@@ -18,6 +18,7 @@ geary_test_engine_sources = [ ...@@ -18,6 +18,7 @@ geary_test_engine_sources = [
'engine/api/geary-email-identifier-mock.vala', 'engine/api/geary-email-identifier-mock.vala',
'engine/api/geary-email-properties-mock.vala', 'engine/api/geary-email-properties-mock.vala',
'engine/api/geary-folder-mock.vala', 'engine/api/geary-folder-mock.vala',
'engine/api/geary-folder-properties-mock.vala',
'engine/api/geary-account-information-test.vala', 'engine/api/geary-account-information-test.vala',
'engine/api/geary-attachment-test.vala', 'engine/api/geary-attachment-test.vala',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment