mirror of https://github.com/M66B/FairEmail.git
Allow moving drafts, improved flags handling
This commit is contained in:
parent
7beb824d79
commit
b40c23b23d
|
@ -741,7 +741,7 @@ public class FragmentMessages extends FragmentBase {
|
|||
if (values.containsKey("expanded") && values.get("expanded").contains(message.id))
|
||||
return null;
|
||||
|
||||
if (EntityFolder.DRAFTS.equals(message.folderType) || EntityFolder.OUTBOX.equals(message.folderType))
|
||||
if (EntityFolder.OUTBOX.equals(message.folderType))
|
||||
return null;
|
||||
|
||||
return message;
|
||||
|
@ -914,7 +914,7 @@ public class FragmentMessages extends FragmentBase {
|
|||
if (result.flagged)
|
||||
popupMenu.getMenu().add(Menu.NONE, action_unflag, 5, R.string.title_unflag);
|
||||
|
||||
if (result.hasArchive && !result.isArchive && !result.isDrafts) // has archive and not is archive/drafts
|
||||
if (result.hasArchive && !result.isArchive) // has archive and not is archive/drafts
|
||||
popupMenu.getMenu().add(Menu.NONE, action_archive, 6, R.string.title_archive);
|
||||
|
||||
if (result.isTrash) // is trash
|
||||
|
@ -926,16 +926,14 @@ public class FragmentMessages extends FragmentBase {
|
|||
if (result.hasJunk && !result.isJunk && !result.isDrafts) // has junk and not junk/drafts
|
||||
popupMenu.getMenu().add(Menu.NONE, action_junk, 9, R.string.title_spam);
|
||||
|
||||
if (!result.isDrafts) { // not drafts
|
||||
int order = 11;
|
||||
for (EntityAccount account : result.accounts) {
|
||||
SubMenu smenu = popupMenu.getMenu()
|
||||
.addSubMenu(Menu.NONE, 0, order++, getString(R.string.title_move_to, account.name));
|
||||
int sorder = 1;
|
||||
for (EntityFolder target : result.targets.get(account)) {
|
||||
MenuItem item = smenu.add(Menu.NONE, action_move, sorder++, target.getDisplayName(getContext()));
|
||||
item.setIntent(new Intent().putExtra("target", target.id));
|
||||
}
|
||||
int order = 11;
|
||||
for (EntityAccount account : result.accounts) {
|
||||
SubMenu smenu = popupMenu.getMenu()
|
||||
.addSubMenu(Menu.NONE, 0, order++, getString(R.string.title_move_to, account.name));
|
||||
int sorder = 1;
|
||||
for (EntityFolder target : result.targets.get(account)) {
|
||||
MenuItem item = smenu.add(Menu.NONE, action_move, sorder++, target.getDisplayName(getContext()));
|
||||
item.setIntent(new Intent().putExtra("target", target.id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ import org.json.JSONException;
|
|||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
@ -122,6 +124,7 @@ import javax.mail.search.FlagTerm;
|
|||
import javax.mail.search.MessageIDTerm;
|
||||
import javax.mail.search.OrTerm;
|
||||
import javax.mail.search.ReceivedDateTerm;
|
||||
import javax.mail.search.SearchTerm;
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -1716,17 +1719,18 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
boolean autoread = false;
|
||||
if (jargs.length() > 1) {
|
||||
autoread = jargs.getBoolean(1);
|
||||
if (autoread && !imessage.isSet(Flags.Flag.SEEN)) {
|
||||
Log.i(folder.name + " autoread");
|
||||
imessage.setFlag(Flags.Flag.SEEN, true);
|
||||
if (ifolder.getPermanentFlags().contains(Flags.Flag.SEEN)) {
|
||||
if (autoread && !imessage.isSet(Flags.Flag.SEEN)) {
|
||||
Log.i(folder.name + " autoread");
|
||||
imessage.setFlag(Flags.Flag.SEEN, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle draft
|
||||
if (EntityFolder.DRAFTS.equals(folder.type)) {
|
||||
if (EntityFolder.DRAFTS.equals(folder.type))
|
||||
if (ifolder.getPermanentFlags().contains(Flags.Flag.DRAFT))
|
||||
imessage.setFlag(Flags.Flag.DRAFT, true);
|
||||
}
|
||||
|
||||
// Add message
|
||||
if (istore.hasCapability("UIDPLUS")) {
|
||||
|
@ -1741,17 +1745,7 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
ifolder.appendMessages(new Message[]{imessage});
|
||||
|
||||
Log.i(folder.name + " lookup id=" + message.id);
|
||||
long uid = -1;
|
||||
Message[] iappended = ifolder.search(new MessageIDTerm(message.msgid));
|
||||
if (iappended != null)
|
||||
for (Message m : iappended) {
|
||||
long auid = ifolder.getUID(m);
|
||||
Log.i(folder.name + " " + message.msgid + " uid=" + auid);
|
||||
if ((message.uid == null || auid != message.uid) && auid > uid)
|
||||
uid = auid;
|
||||
}
|
||||
if (uid < 0)
|
||||
throw new MessageRemovedException("Message not found back");
|
||||
long uid = getUid(folder, ifolder, message.msgid);
|
||||
|
||||
Log.i(folder.name + " lookup id=" + message.id + " uid=" + uid);
|
||||
db.message().setMessageUid(message.id, uid);
|
||||
|
@ -1783,34 +1777,75 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
|
||||
private void doMove(EntityFolder folder, Session isession, IMAPStore istore, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws JSONException, MessagingException, IOException {
|
||||
// Move message
|
||||
long id = jargs.getLong(0);
|
||||
EntityFolder target = db.folder().getFolder(id);
|
||||
if (target == null)
|
||||
throw new FolderNotFoundException();
|
||||
|
||||
// Get message
|
||||
Message imessage = ifolder.getMessageByUID(message.uid);
|
||||
if (imessage == null)
|
||||
throw new MessageRemovedException();
|
||||
|
||||
// Get parameters
|
||||
boolean autoread = jargs.getBoolean(1);
|
||||
if (autoread && !imessage.isSet(Flags.Flag.SEEN))
|
||||
imessage.setFlag(Flags.Flag.SEEN, true);
|
||||
|
||||
if (istore.hasCapability("MOVE") && !EntityFolder.DRAFTS.equals(folder.type)) {
|
||||
Folder itarget = istore.getFolder(target.name);
|
||||
// Get target folder
|
||||
long id = jargs.getLong(0);
|
||||
EntityFolder target = db.folder().getFolder(id);
|
||||
if (target == null)
|
||||
throw new FolderNotFoundException();
|
||||
IMAPFolder itarget = (IMAPFolder) istore.getFolder(target.name);
|
||||
|
||||
if (istore.hasCapability("MOVE") &&
|
||||
!EntityFolder.DRAFTS.equals(folder.type) &&
|
||||
!EntityFolder.DRAFTS.equals(target.type)) {
|
||||
// Autoread
|
||||
if (ifolder.getPermanentFlags().contains(Flags.Flag.SEEN)) {
|
||||
if (autoread && !imessage.isSet(Flags.Flag.SEEN))
|
||||
imessage.setFlag(Flags.Flag.SEEN, true);
|
||||
}
|
||||
|
||||
// Move message to
|
||||
ifolder.moveMessages(new Message[]{imessage}, itarget);
|
||||
} else {
|
||||
Log.w(folder.name + " MOVE by DELETE/APPEND");
|
||||
|
||||
// Delete source
|
||||
imessage.setFlag(Flags.Flag.DELETED, true);
|
||||
ifolder.expunge();
|
||||
// Serialize source message
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
imessage.writeTo(bos);
|
||||
|
||||
// Append target
|
||||
MimeMessageEx icopy = MessageHelper.from(this, message, isession);
|
||||
Folder itarget = istore.getFolder(target.name);
|
||||
itarget.appendMessages(new Message[]{icopy});
|
||||
// Deserialize target message
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
|
||||
Message icopy = new MimeMessage(isession, bis);
|
||||
|
||||
try {
|
||||
// Needed to read flags
|
||||
itarget.open(Folder.READ_WRITE);
|
||||
|
||||
// Auto read
|
||||
if (itarget.getPermanentFlags().contains(Flags.Flag.SEEN)) {
|
||||
if (autoread && !icopy.isSet(Flags.Flag.SEEN)) {
|
||||
Log.i("Copy autoread");
|
||||
icopy.setFlag(Flags.Flag.SEEN, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Move from drafts
|
||||
if (EntityFolder.DRAFTS.equals(folder.type))
|
||||
if (itarget.getPermanentFlags().contains(Flags.Flag.DRAFT))
|
||||
icopy.setFlag(Flags.Flag.DRAFT, false);
|
||||
|
||||
// Move to drafts
|
||||
if (EntityFolder.DRAFTS.equals(target.type))
|
||||
if (itarget.getPermanentFlags().contains(Flags.Flag.DRAFT))
|
||||
icopy.setFlag(Flags.Flag.DRAFT, true);
|
||||
|
||||
// Append target
|
||||
itarget.appendMessages(new Message[]{icopy});
|
||||
|
||||
// Delete source
|
||||
imessage.setFlag(Flags.Flag.DELETED, true);
|
||||
ifolder.expunge();
|
||||
} catch (Throwable ex) {
|
||||
if (itarget.isOpen())
|
||||
itarget.close();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2113,6 +2148,24 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
parts.downloadAttachment(this, db, attachment.id, sequence);
|
||||
}
|
||||
|
||||
private long getUid(EntityFolder folder, IMAPFolder ifolder, String msgid) throws MessagingException {
|
||||
long uid = -1;
|
||||
Message[] messages = ifolder.search(new MessageIDTerm(msgid));
|
||||
if (messages != null)
|
||||
for (Message message : messages) {
|
||||
long muid = ifolder.getUID(message);
|
||||
Log.i(folder.name + " " + msgid + " uid=" + muid);
|
||||
// RFC3501: Unique identifiers are assigned in a strictly ascending fashion
|
||||
if (muid > uid)
|
||||
uid = muid;
|
||||
}
|
||||
|
||||
if (uid < 0)
|
||||
throw new MessageRemovedException("uid not found");
|
||||
|
||||
return uid;
|
||||
}
|
||||
|
||||
private void synchronizeFolders(EntityAccount account, IMAPStore istore, ServiceState state) throws MessagingException {
|
||||
DB db = DB.getInstance(this);
|
||||
try {
|
||||
|
@ -2284,13 +2337,12 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
Log.i(folder.name + " local count=" + uids.size());
|
||||
|
||||
// Reduce list of local uids
|
||||
SearchTerm searchTerm = new ReceivedDateTerm(ComparisonTerm.GE, new Date(sync_time));
|
||||
if (ifolder.getPermanentFlags().contains(Flags.Flag.FLAGGED))
|
||||
searchTerm = new OrTerm(searchTerm, new FlagTerm(new Flags(Flags.Flag.FLAGGED), true));
|
||||
|
||||
long search = SystemClock.elapsedRealtime();
|
||||
Message[] imessages = ifolder.search(
|
||||
new OrTerm(
|
||||
new ReceivedDateTerm(ComparisonTerm.GE, new Date(sync_time)),
|
||||
new FlagTerm(new Flags(Flags.Flag.FLAGGED), true)
|
||||
)
|
||||
);
|
||||
Message[] imessages = ifolder.search(searchTerm);
|
||||
Log.i(folder.name + " remote count=" + imessages.length +
|
||||
" search=" + (SystemClock.elapsedRealtime() - search) + " ms");
|
||||
|
||||
|
|
Loading…
Reference in New Issue