Commit 5212730d authored by Michael Gratton's avatar Michael Gratton 🤞

Merge branch 'wip/219-unbreak-sroll-vector-expansion' into 'master'

Unbreak folder vector expansion on scrolling the conversation list to the bottom

Closes #219

See merge request !122

(cherry picked from commit 6a8f8a15)

f7f69e9e Fix one very wrong word in a comment
9378795d Trivial code cleanup
2b2f99d1 Fix FillWindowOperation not expanding vector when at end of it
parent a5e7f928
Pipeline #60922 failed with stages
in 6 minutes and 49 seconds
......@@ -234,7 +234,7 @@ private class Geary.ImapEngine.CheckFolderSync : RefreshFolderSync {
null,
1,
Email.Field.PROPERTIES,
ImapDB.Folder.ListFlags.NONE | ImapDB.Folder.ListFlags.OLDEST_TO_NEWEST,
ImapDB.Folder.ListFlags.OLDEST_TO_NEWEST,
cancellable
);
......@@ -335,9 +335,11 @@ private class Geary.ImapEngine.CheckFolderSync : RefreshFolderSync {
(id != null) ? " earlier than oldest local" : ""
);
yield this.folder.list_email_by_id_async(
id, 1,
id,
1,
Geary.Email.Field.NONE,
Geary.Folder.ListFlags.NONE, cancellable
Geary.Folder.ListFlags.NONE,
cancellable
);
}
......
......@@ -219,7 +219,7 @@ private abstract class Geary.ImapEngine.AbstractListEmail : Geary.ImapEngine.Sen
* start of the vector if the OLDEST_TO_NEWEST flag is set, else
* from `initial_uid` (inclusive) back at most by `count` number
* of messages. If `initial_uid` is null, the start or end of the
* remote is used, respectively.
* vector is used, respectively.
*
* The returned UIDs are those added to the vector, which can then
* be examined and added to the messages to be fulfilled if
......
......@@ -17,54 +17,55 @@ private class Geary.ImapEngine.ListEmailByID : Geary.ImapEngine.AbstractListEmai
this.initial_id = initial_id;
this.count = count;
}
public override async ReplayOperation.Status replay_local_async() throws Error {
if (flags.is_force_update())
return ReplayOperation.Status.CONTINUE;
// get everything from local store, even partial matches, that fit range
ImapDB.Folder.ListFlags list_flags = ImapDB.Folder.ListFlags.from_folder_flags(flags);
list_flags |= ImapDB.Folder.ListFlags.PARTIAL_OK;
Gee.List<Geary.Email>? list = yield owner.local_folder.list_email_by_id_async(initial_id,
count, required_fields, list_flags, cancellable);
// walk list, breaking out unfulfilled items from fulfilled items
// Fetch the initial ID to a) make sure it exists, and b) so
// its UID is available when expanding the vector
if (this.initial_id != null) {
Email email = yield owner.local_folder.fetch_email_async(
this.initial_id,
// Only need the id here
Email.Field.NONE,
ImapDB.Folder.ListFlags.NONE,
cancellable
);
this.initial_uid = ((ImapDB.EmailIdentifier) email.id).uid;
}
// List all locally known, desired email that fits the list
// range. Include partial matches so there's potentially less
// to fetch from the remote if not all are fulfilled.
ImapDB.Folder.ListFlags local_flags = (
ImapDB.Folder.ListFlags.from_folder_flags(flags) |
ImapDB.Folder.ListFlags.PARTIAL_OK
);
Gee.List<Geary.Email>? list =
yield owner.local_folder.list_email_by_id_async(
initial_id,
count,
required_fields,
local_flags,
cancellable
);
// Break out unfulfilled email from fulfilled ones
Gee.ArrayList<Geary.Email> fulfilled = new Gee.ArrayList<Geary.Email>();
if (list != null) {
foreach (Geary.Email email in list) {
Imap.UID uid = ((ImapDB.EmailIdentifier) email.id).uid;
// if INCLUDING_ID, then find the initial UID for the initial_id (if specified)
if (flags.is_including_id()) {
if (initial_id != null && email.id.equal_to(initial_id))
initial_uid = uid;
if (email.fields.fulfills(required_fields)) {
fulfilled.add(email);
} else {
// !INCLUDING_ID, so find the earliest UID (for oldest-to-newest) or latest
// UID (newest-to-oldest)
if (flags.is_oldest_to_newest()) {
if (initial_uid == null || uid.compare_to(initial_uid) < 0)
initial_uid = uid;
} else {
// newest-to-oldest
if (initial_uid == null || uid.compare_to(initial_uid) > 0)
initial_uid = uid;
}
Imap.UID uid = ((ImapDB.EmailIdentifier) email.id).uid;
add_unfulfilled_fields(
uid, required_fields.clear(email.fields)
);
}
if (email.fields.fulfills(required_fields))
fulfilled.add(email);
else
add_unfulfilled_fields(uid, required_fields.clear(email.fields));
}
}
if (this.flags.is_including_id() && this.initial_uid == null) {
throw new EngineError.NOT_FOUND(
"Initial id not found in local set: %s",
this.initial_id.to_string()
);
}
// report fulfilled items
fulfilled_count = fulfilled.size;
if (fulfilled_count > 0)
......@@ -103,26 +104,21 @@ private class Geary.ImapEngine.ListEmailByID : Geary.ImapEngine.AbstractListEmai
bool expansion_required = false;
if (!(yield is_fully_expanded_async(remote))) {
if (flags.is_oldest_to_newest()) {
if (initial_id != null) {
// expand vector if not initial_id not discovered
expansion_required = (initial_uid == null);
} else {
// initial_id == null, expansion required if not fully already
expansion_required = true;
}
// Expansion is required since there are
// unfulfilled email within the vector.
expansion_required = true;
} else {
// newest-to-oldest
if (count == int.MAX) {
// if infinite count, expansion required if not already
// Infinite count, expand to fill in all
// unfulfilled or not-yet-found email.
expansion_required = true;
} else if (initial_id != null) {
// finite count, expansion required if initial not found *or* not enough
// items were pulled in
expansion_required = (initial_uid == null) || (fulfilled_count + get_unfulfilled_count() < count);
} else {
// initial_id == null
// finite count, expansion required if not enough found
expansion_required = (fulfilled_count + get_unfulfilled_count() < count);
// Finite count, expansion required only if not
// enough items were pulled in, in total.
expansion_required = (
fulfilled_count + get_unfulfilled_count() < count
);
}
}
}
......
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