Closed Bug 1924853 Opened 3 months ago Closed 1 month ago

[EWS] Finish up save-to-drafts support

Categories

(Thunderbird :: Account Manager, task)

Tracking

(Not tracked)

RESOLVED INVALID

People

(Reporter: babolivier, Assigned: leftmostcat)

References

Details

When saving a draft of a message that already had a previous draft saved, nsIMsgFolder::CopyFromFile is given the nsIMsgHdr of this previous draft, so the folder can replace the old draft with the new one.

If possible, we should use UpdateItem to update the MimeContent of an item. It's difficult to tell from documentation whether this is allowed, so a first step should be to figure this out. If not, we'll have to do this by deleting the old draft and creating a new one.

While we're there, we should also look into updating the new message's flag using newMsgFlags (which hopefully should be fairly easy to do through MessageOperationCallbacks/MessageSyncListener).

We should also look into whether using UpdateItem unsets the MSGFLAG_UNMODIFIED flag from the message; if not (or if we cannot use UpdateItem to change the draft's content) we should unset it manually.

Blocks: 1908652
No longer blocks: tb-ms-exchange

Did you mean EwsFolder.CopyFileMessage instead of nsIMsgFolder::CopyFromFile?

In order for this to work, we also need to get around the fact that we're not using nsIMsgMailNewsUrl so when we load the Draft into the Compose window its currently failing here: https://searchfox.org/comm-central/source/mailnews/compose/src/nsMsgComposeService.cpp#1200

EwsService::GetUrlForUri always returns a generic nsIURI whereas the imap version of this typically returns an nsIImapUrl
which implements nsIMsgMailNewsUrl

Flags: needinfo?(brendan)

Yes, sorry I did mean EwsFolder::CopyFileMessage.

If we can't currently load drafts into the compose window, this sounds like a bug in the current implementation and should be filed as such, separately from this feature work.

Flags: needinfo?(brendan)
Assignee: nobody → leftmostcat

Not sure it will help but here my notes on this in addition to the important issue raised in comment 2:

EwsFolder.CopyFileMessage is not finished as it doesn't handle the msgToReplace param so can't yet be used for saving something that already exists:

  • Saved draft
  • Saved template
  • Message with attachments detached
  • Message with attachments replaced

I looked at the IMAP implementation to see how to handle changes - it looks like it runs a few things to set size, then copies locally:

1.) Handle Message Replacement:
If msgToReplace is provided:
Retrieves the key and temporarily sets the offline message size to zero to avoid redundant operations in SetPendingAttributes.
Marks the message to replace with pending attributes.
Adds the message header to a messages array for processing.

2.) Initialize Copy State:
Calls InitCopyState to set up the context for the copy operation.
Stores relevant details such as whether the operation is a move (isMove), whether it is a draft/template operation, and metadata like flags and keywords.

3.) Invoke IMAP Service:
Obtains a reference to the nsIImapService and invokes its AppendMessageFromFile method.
This appends the message in file to the IMAP folder (this).

4.) Error Handling:
If any error occurs during the setup or appending of the message, the method terminates and calls OnCopyCompleted to notify the system about the failure.

5.) On Success:
On successful appending of the message, the operation is completed, and OnCopyCompleted is called to finalize the process.

Key Components used in .CopyFileMessage

InitCopyState:
    Prepares the state for the copy operation, including whether it is a move or copy, associated metadata, and listener objects for notifications.

AppendMessageFromFile:
    Handles the actual appending of the message content from the file to the IMAP folder.
    Invokes the IMAP service's functionality to handle the transfer.

SetPendingAttributes:
    Ensures that attributes like flags, keywords, and offline message size are properly set for the message being replaced or added.

OnCopyCompleted:
    Called at the end of the operation to clean up and notify any registered listeners about the completion status.

I've investigated how save as draft and draft replacement is implemented and concluded that the msgToReplace mechanism of copyFileMessage() is not used; its use appears to be limited to removing attachments from messages. Instead, a new draft message is created with copyFileMessage() (and nullptr consistently passed for msgToReplace) and the previous is deleted via the standard deleteMessages() mechanism. As such, there are no changes needed for saving as draft and msgToReplace will be handled as part of work on attachment remove/detach at a later time.

Status: NEW → RESOLVED
Closed: 1 month ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.