Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #7344 from mozsquib/email-as-move

Bug 826585 - [email/activesync] Deleting/moving messages causes them to show up twice in the target folder
  • Loading branch information...
commit 31737604a2ba0accb7ae3f18d086f33e873decc4 2 parents e95e507 + 3b372ee
@jimporter jimporter authored
Showing with 66 additions and 24 deletions.
  1. +66 −24 apps/email/js/ext/gaia-email-opt.js
View
90 apps/email/js/ext/gaia-email-opt.js
@@ -26699,6 +26699,19 @@ FolderStorage.prototype = {
this._curSyncSlice.onHeaderAdded(header, true, false);
},
+ hasMessageWithServerId: function(srvid) {
+ if (!this._serverIdHeaderBlockMapping)
+ throw new Error('Server ID mapping not supported for this storage!');
+
+ var blockId = this._serverIdHeaderBlockMapping[srvid];
+ if (srvid === undefined) {
+ this._LOG.serverIdMappingMissing(srvid);
+ return false;
+ }
+
+ return !!blockId;
+ },
+
deleteMessageHeaderAndBody: function(header, callback) {
if (this._pendingLoads.length) {
this._deferredCalls.push(this.deleteMessageHeaderAndBody.bind(
@@ -32707,7 +32720,6 @@ function FakeAccount(universe, accountDef, folderInfo, receiveProtoConn, _LOG) {
this.meta = folderInfo.$meta;
this.mutations = folderInfo.$mutations;
- this.deferredMutations = folderInfo.$deferredMutations;
}
exports.FakeAccount = FakeAccount;
FakeAccount.prototype = {
@@ -33588,29 +33600,53 @@ ActiveSyncFolderConn.prototype = {
return;
}
+ let addedMessages = 0;
for (let [,message] in Iterator(added)) {
+ // If we already have this message, it's probably because we moved it as
+ // part of a local op, so let's assume that the data we already have is
+ // ok. XXX: We might want to verify this, to be safe.
+ if (storage.hasMessageWithServerId(message.header.srvid))
+ continue;
+
storage.addMessageHeader(message.header);
storage.addMessageBody(message.header, message.body);
+ addedMessages++;
}
+ let changedMessages = 0;
for (let [,message] in Iterator(changed)) {
+ // If we don't know about this message, just bail out.
+ if (!storage.hasMessageWithServerId(message.header.srvid))
+ continue;
+
storage.updateMessageHeaderByServerId(message.header.srvid, true,
function(oldHeader) {
message.header.mergeInto(oldHeader);
return true;
});
+ changedMessages++;
// XXX: update bodies
}
+ let deletedMessages = 0;
for (let [,messageGuid] in Iterator(deleted)) {
+ // If we don't know about this message, it's probably because we already
+ // deleted it.
+ if (!storage.hasMessageWithServerId(messageGuid))
+ continue;
+
storage.deleteMessageByServerId(messageGuid);
+ deletedMessages++;
}
- messagesSeen += added.length + changed.length + deleted.length;
+ messagesSeen += addedMessages + changedMessages + deletedMessages;
if (!moreAvailable) {
- folderConn._LOG.syncDateRange_end(added.length, changed.length,
- deleted.length, startTS, endTS);
+ // Note: For the second argument here, we report the number of messages
+ // we saw that *changed*. This differs from IMAP, which reports the
+ // number of messages it *saw*.
+ folderConn._LOG.syncDateRange_end(addedMessages, changedMessages,
+ deletedMessages, startTS, endTS);
storage.markSyncRange(startTS, endTS, 'XXX', accuracyStamp);
doneCallback(null, null, messagesSeen);
}
@@ -33688,7 +33724,7 @@ ActiveSyncFolderConn.prototype = {
e.run(aResponse);
}
catch (ex) {
- console.error('Error parsing Sync reponse:', ex, '\n', ex.stack);
+ console.error('Error parsing Sync response:', ex, '\n', ex.stack);
callWhenDone('unknown');
return;
}
@@ -34051,17 +34087,21 @@ ActiveSyncJobDriver.prototype = {
if (--modsToGo === 0)
callWhenDone();
}
+
+ // Filter out any offline headers, since the server naturally can't do
+ // anything for them. If this means we have no headers at all, just bail
+ // out.
+ serverIds = serverIds.filter(function(srvid) { return !!srvid; });
+ if (!serverIds.length) {
+ callWhenDone();
+ return;
+ }
+
folderConn.performMutation(
function withWriter(w) {
for (let i = 0; i < serverIds.length; i++) {
- let srvid = serverIds[i];
- // If the header is somehow an offline header, it will be null and
- // there is nothing we can really do for it.
- if (!srvid)
- continue;
-
w.stag(as.Change)
- .tag(as.ServerId, srvid)
+ .tag(as.ServerId, serverIds[i])
.stag(as.ApplicationData);
if (markRead !== undefined)
@@ -34124,8 +34164,6 @@ ActiveSyncJobDriver.prototype = {
let aggrErr = null, account = this.account,
targetFolderStorage = this.account.getFolderStorageForFolderId(
op.targetFolder);
- const as = $ascp.AirSync.Tags;
- const em = $ascp.Email.Tags;
const mo = $ascp.Move.Tags;
this._partitionAndAccessFoldersSequentially(
@@ -34134,17 +34172,21 @@ ActiveSyncJobDriver.prototype = {
let w = new $wbxml.Writer('1.3', 1, 'UTF-8');
w.stag(mo.MoveItems);
+ // Filter out any offline headers, since the server naturally can't do
+ // anything for them. If this means we have no headers at all, just bail
+ // out.
+ serverIds = serverIds.filter(function(srvid) { return !!srvid; });
+ if (!serverIds.length) {
+ callWhenDone();
+ return;
+ }
+
for (let i = 0; i < serverIds.length; i++) {
- let srvid = serverIds[i];
- // If the header is somehow an offline header, it will be null and
- // there is nothing we can really do for it.
- if (!srvid)
- continue;
w.stag(mo.Move)
- .tag(mo.SrcMsgId, srvid)
- .tag(mo.SrcFldId, storage.folderMeta.serverId)
- .tag(mo.DstFldId, targetFolderStorage.folderMeta.serverId)
- .etag(mo.Move);
+ .tag(mo.SrcMsgId, serverIds[i])
+ .tag(mo.SrcFldId, storage.folderMeta.serverId)
+ .tag(mo.DstFldId, targetFolderStorage.folderMeta.serverId)
+ .etag(mo.Move);
}
w.etag(mo.MoveItems);
@@ -37237,7 +37279,7 @@ MailUniverse.prototype = {
* and transferred across to the non-deferred queue at account-load time.
*/
_deferOp: function(account, op) {
- account.deferredMutations.push(op.longtermId);
+ this._opsByAccount[account.id].deferred.push(op.longtermId);
if (this._deferredOpTimeout !== null)
this._deferredOpTimeout = window.setTimeout(
this._boundQueueDeferredOps, $syncbase.DEFERRED_OP_DELAY_MS);
Please sign in to comment.
Something went wrong with that request. Please try again.