diff --git a/app/core/src/main/java/com/fsck/k9/Account.java b/app/core/src/main/java/com/fsck/k9/Account.java index 094112261..04699289b 100644 --- a/app/core/src/main/java/com/fsck/k9/Account.java +++ b/app/core/src/main/java/com/fsck/k9/Account.java @@ -180,6 +180,7 @@ public class Account implements BaseAccount, StoreConfig { private boolean openPgpEncryptSubject; private boolean openPgpEncryptAllDrafts; private boolean markMessageAsReadOnView; + private boolean markMessageAsReadOnDelete; private boolean alwaysShowCcBcc; private boolean allowRemoteSearch; private boolean remoteSearchFullText; @@ -1039,6 +1040,14 @@ public class Account implements BaseAccount, StoreConfig { markMessageAsReadOnView = value; } + public synchronized boolean isMarkMessageAsReadOnDelete() { + return markMessageAsReadOnDelete; + } + + public synchronized void setMarkMessageAsReadOnDelete(boolean value) { + markMessageAsReadOnDelete = value; + } + public synchronized boolean isAlwaysShowCcBcc() { return alwaysShowCcBcc; } diff --git a/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt b/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt index 2369aa1a3..7cbb97a69 100644 --- a/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt +++ b/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt @@ -150,6 +150,7 @@ class AccountPreferenceSerializer( isEnabled = storage.getBoolean("$accountUuid.enabled", true) isMarkMessageAsReadOnView = storage.getBoolean("$accountUuid.markMessageAsReadOnView", true) + isMarkMessageAsReadOnDelete = storage.getBoolean("$accountUuid.markMessageAsReadOnDelete", true) isAlwaysShowCcBcc = storage.getBoolean("$accountUuid.alwaysShowCcBcc", false) // Use email address as account description if necessary @@ -290,6 +291,7 @@ class AccountPreferenceSerializer( editor.putBoolean("$accountUuid.uploadSentMessages", isUploadSentMessages) editor.putBoolean("$accountUuid.enabled", isEnabled) editor.putBoolean("$accountUuid.markMessageAsReadOnView", isMarkMessageAsReadOnView) + editor.putBoolean("$accountUuid.markMessageAsReadOnDelete", isMarkMessageAsReadOnDelete) editor.putBoolean("$accountUuid.alwaysShowCcBcc", isAlwaysShowCcBcc) editor.putBoolean("$accountUuid.vibrate", notificationSetting.isVibrateEnabled) @@ -400,6 +402,7 @@ class AccountPreferenceSerializer( editor.remove("$accountUuid.autocryptMutualMode") editor.remove("$accountUuid.enabled") editor.remove("$accountUuid.markMessageAsReadOnView") + editor.remove("$accountUuid.markMessageAsReadOnDelete") editor.remove("$accountUuid.alwaysShowCcBcc") editor.remove("$accountUuid.allowRemoteSearch") editor.remove("$accountUuid.remoteSearchFullText") @@ -547,6 +550,7 @@ class AccountPreferenceSerializer( isUploadSentMessages = true isEnabled = true isMarkMessageAsReadOnView = true + isMarkMessageAsReadOnDelete = true isAlwaysShowCcBcc = false setArchiveFolder(null, SpecialFolderSelection.AUTOMATIC) diff --git a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java index a56685c99..5320b856b 100644 --- a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java +++ b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java @@ -53,6 +53,7 @@ import com.fsck.k9.controller.MessagingControllerCommands.PendingDelete; import com.fsck.k9.controller.MessagingControllerCommands.PendingEmptyTrash; import com.fsck.k9.controller.MessagingControllerCommands.PendingExpunge; import com.fsck.k9.controller.MessagingControllerCommands.PendingMarkAllAsRead; +import com.fsck.k9.controller.MessagingControllerCommands.PendingMoveAndMarkAsRead; import com.fsck.k9.controller.MessagingControllerCommands.PendingMoveOrCopy; import com.fsck.k9.controller.MessagingControllerCommands.PendingSetFlag; import com.fsck.k9.controller.ProgressBodyFactory.ProgressListener; @@ -929,18 +930,44 @@ public class MessagingController { } } - private void queueMoveOrCopy(Account account, String srcFolder, String destFolder, boolean isCopy, - List uids) { - PendingCommand command = PendingMoveOrCopy.create(srcFolder, destFolder, isCopy, uids); + private void queueMoveOrCopy(Account account, String srcFolder, String destFolder, + MoveOrCopyFlavor operation, List uids) { + PendingCommand command; + switch (operation) { + case MOVE: + command = PendingMoveOrCopy.create(srcFolder, destFolder, false, uids); + break; + case COPY: + command = PendingMoveOrCopy.create(srcFolder, destFolder, true, uids); + break; + case MOVE_AND_MARK_AS_READ: + command = PendingMoveAndMarkAsRead.create(srcFolder, destFolder, uids); + break; + default: + return; + } queuePendingCommand(account, command); } private void queueMoveOrCopy(Account account, String srcFolder, String destFolder, - boolean isCopy, List uids, Map uidMap) { + MoveOrCopyFlavor operation, List uids, Map uidMap) { if (uidMap == null || uidMap.isEmpty()) { - queueMoveOrCopy(account, srcFolder, destFolder, isCopy, uids); + queueMoveOrCopy(account, srcFolder, destFolder, operation, uids); } else { - PendingCommand command = PendingMoveOrCopy.create(srcFolder, destFolder, isCopy, uidMap); + PendingCommand command; + switch (operation) { + case MOVE: + command = PendingMoveOrCopy.create(srcFolder, destFolder, false, uidMap); + break; + case COPY: + command = PendingMoveOrCopy.create(srcFolder, destFolder, true, uidMap); + break; + case MOVE_AND_MARK_AS_READ: + command = PendingMoveAndMarkAsRead.create(srcFolder, destFolder, uidMap); + break; + default: + return; + } queuePendingCommand(account, command); } } @@ -948,17 +975,28 @@ public class MessagingController { void processPendingMoveOrCopy(PendingMoveOrCopy command, Account account) throws MessagingException { String srcFolder = command.srcFolder; String destFolder = command.destFolder; - boolean isCopy = command.isCopy; + MoveOrCopyFlavor operation = command.isCopy ? MoveOrCopyFlavor.COPY : MoveOrCopyFlavor.MOVE; Map newUidMap = command.newUidMap; List uids = newUidMap != null ? new ArrayList<>(newUidMap.keySet()) : command.uids; - processPendingMoveOrCopy(account, srcFolder, destFolder, uids, isCopy, newUidMap); + processPendingMoveOrCopy(account, srcFolder, destFolder, uids, operation, newUidMap); + } + + void processPendingMoveAndRead(PendingMoveAndMarkAsRead command, Account account) throws MessagingException { + String srcFolder = command.srcFolder; + String destFolder = command.destFolder; + + Map newUidMap = command.newUidMap; + List uids = newUidMap != null ? new ArrayList<>(newUidMap.keySet()) : command.uids; + + processPendingMoveOrCopy(account, srcFolder, destFolder, uids, + MoveOrCopyFlavor.MOVE_AND_MARK_AS_READ, newUidMap); } @VisibleForTesting void processPendingMoveOrCopy(Account account, String srcFolder, String destFolder, List uids, - boolean isCopy, Map newUidMap) throws MessagingException { + MoveOrCopyFlavor operation, Map newUidMap) throws MessagingException { LocalFolder localDestFolder; LocalStore localStore = localStoreProvider.getInstance(account); @@ -967,13 +1005,22 @@ public class MessagingController { Backend backend = getBackend(account); Map remoteUidMap; - if (isCopy) { - remoteUidMap = backend.copyMessages(srcFolder, destFolder, uids); - } else { - remoteUidMap = backend.moveMessages(srcFolder, destFolder, uids); + switch (operation) { + case COPY: + remoteUidMap = backend.copyMessages(srcFolder, destFolder, uids); + break; + case MOVE: + remoteUidMap = backend.moveMessages(srcFolder, destFolder, uids); + break; + case MOVE_AND_MARK_AS_READ: + remoteUidMap = backend.moveMessagesAndMarkAsRead(srcFolder, destFolder, uids); + break; + default: + throw new RuntimeException("Unsupported messaging operation"); } - if (!isCopy && backend.getSupportsExpunge() && account.getExpungePolicy() == Expunge.EXPUNGE_IMMEDIATELY) { + if (operation != MoveOrCopyFlavor.COPY && backend.getSupportsExpunge() + && account.getExpungePolicy() == Expunge.EXPUNGE_IMMEDIATELY) { Timber.i("processingPendingMoveOrCopy expunging folder %s:%s", account.getDescription(), srcFolder); backend.expungeMessages(srcFolder, uids); } @@ -1831,7 +1878,7 @@ public class MessagingController { putBackground("moveMessages", null, new Runnable() { @Override public void run() { - moveOrCopyMessageSynchronous(account, srcFolder, messages, destFolder, false); + moveOrCopyMessageSynchronous(account, srcFolder, messages, destFolder, MoveOrCopyFlavor.MOVE); } }); } @@ -1850,7 +1897,8 @@ public class MessagingController { public void run() { try { List messagesInThreads = collectMessagesInThreads(account, messages); - moveOrCopyMessageSynchronous(account, srcFolder, messagesInThreads, destFolder, false); + moveOrCopyMessageSynchronous(account, srcFolder, messagesInThreads, destFolder, + MoveOrCopyFlavor.MOVE); } catch (MessagingException e) { Timber.e(e, "Exception while moving messages"); } @@ -1873,7 +1921,8 @@ public class MessagingController { putBackground("copyMessages", null, new Runnable() { @Override public void run() { - moveOrCopyMessageSynchronous(srcAccount, srcFolder, messages, destFolder, true); + moveOrCopyMessageSynchronous(srcAccount, srcFolder, messages, destFolder, + MoveOrCopyFlavor.COPY); } }); } @@ -1891,7 +1940,7 @@ public class MessagingController { try { List messagesInThreads = collectMessagesInThreads(account, messages); moveOrCopyMessageSynchronous(account, srcFolder, messagesInThreads, destFolder, - true); + MoveOrCopyFlavor.COPY); } catch (MessagingException e) { Timber.e(e, "Exception while copying messages"); } @@ -1908,14 +1957,17 @@ public class MessagingController { } private void moveOrCopyMessageSynchronous(final Account account, final String srcFolder, - final List inMessages, final String destFolder, final boolean isCopy) { + final List inMessages, final String destFolder, + MoveOrCopyFlavor operation) { try { LocalStore localStore = localStoreProvider.getInstance(account); - if (!isCopy && !isMoveCapable(account)) { + if ((operation == MoveOrCopyFlavor.MOVE + || operation == MoveOrCopyFlavor.MOVE_AND_MARK_AS_READ) + && !isMoveCapable(account)) { return; } - if (isCopy && !isCopyCapable(account)) { + if (operation == MoveOrCopyFlavor.COPY && !isCopyCapable(account)) { return; } @@ -1944,11 +1996,11 @@ public class MessagingController { } Timber.i("moveOrCopyMessageSynchronous: source folder = %s, %d messages, destination folder = %s, " + - "isCopy = %s", srcFolder, messages.size(), destFolder, isCopy); + "operation = %s", srcFolder, messages.size(), destFolder, operation.name()); Map uidMap; - if (isCopy) { + if (operation == MoveOrCopyFlavor.COPY) { FetchProfile fp = new FetchProfile(); fp.add(Item.ENVELOPE); fp.add(Item.BODY); @@ -1972,6 +2024,10 @@ public class MessagingController { l.messageUidChanged(account, srcFolder, origUid, message.getUid()); } } + if (operation == MoveOrCopyFlavor.MOVE_AND_MARK_AS_READ) { + localDestFolder.setFlags(messages, Collections.singleton(Flag.SEEN), true); + unreadCountAffected = true; + } unsuppressMessages(account, messages); if (unreadCountAffected) { @@ -1987,7 +2043,7 @@ public class MessagingController { } List origUidKeys = new ArrayList<>(origUidMap.keySet()); - queueMoveOrCopy(account, srcFolder, destFolder, isCopy, origUidKeys, uidMap); + queueMoveOrCopy(account, srcFolder, destFolder, operation, origUidKeys, uidMap); } processPendingCommands(account); @@ -2173,6 +2229,10 @@ public class MessagingController { Timber.d("Deleting messages in normal folder, moving"); localTrashFolder = localStore.getFolder(account.getTrashFolder()); uidMap = localFolder.moveMessages(messages, localTrashFolder); + + if (account.isMarkMessageAsReadOnDelete()) { + localTrashFolder.setFlags(messages, Collections.singleton(Flag.SEEN), true); + } } for (MessagingListener l : getListeners()) { @@ -2197,9 +2257,12 @@ public class MessagingController { if (account.getDeletePolicy() == DeletePolicy.ON_DELETE) { if (folder.equals(account.getTrashFolder()) || !backend.isDeleteMoveToTrash()) { queueDelete(account, folder, syncedMessageUids); + } else if (account.isMarkMessageAsReadOnDelete()) { + queueMoveOrCopy(account, folder, account.getTrashFolder(), + MoveOrCopyFlavor.MOVE_AND_MARK_AS_READ, syncedMessageUids, uidMap); } else { - queueMoveOrCopy(account, folder, account.getTrashFolder(), false, - syncedMessageUids, uidMap); + queueMoveOrCopy(account, folder, account.getTrashFolder(), + MoveOrCopyFlavor.MOVE, syncedMessageUids, uidMap); } processPendingCommands(account); } else if (account.getDeletePolicy() == DeletePolicy.MARK_AS_READ) { @@ -3117,4 +3180,8 @@ public class MessagingController { } } } + + private enum MoveOrCopyFlavor { + MOVE, COPY, MOVE_AND_MARK_AS_READ + } } diff --git a/app/core/src/main/java/com/fsck/k9/controller/MessagingControllerCommands.java b/app/core/src/main/java/com/fsck/k9/controller/MessagingControllerCommands.java index e4475f111..919510aab 100644 --- a/app/core/src/main/java/com/fsck/k9/controller/MessagingControllerCommands.java +++ b/app/core/src/main/java/com/fsck/k9/controller/MessagingControllerCommands.java @@ -16,9 +16,9 @@ public class MessagingControllerCommands { static final String COMMAND_DELETE = "delete"; static final String COMMAND_EXPUNGE = "expunge"; static final String COMMAND_MOVE_OR_COPY = "move_or_copy"; + static final String COMMAND_MOVE_AND_MARK_AS_READ = "move_and_mark_as_read"; static final String COMMAND_EMPTY_TRASH = "empty_trash"; - public abstract static class PendingCommand { public long databaseId; @@ -66,6 +66,41 @@ public class MessagingControllerCommands { } } + public static class PendingMoveAndMarkAsRead extends PendingCommand { + public final String srcFolder; + public final String destFolder; + public final List uids; + public final Map newUidMap; + + + public static PendingMoveAndMarkAsRead create(String srcFolder, String destFolder, + Map uidMap) { + return new PendingMoveAndMarkAsRead(srcFolder, destFolder, null, uidMap); + } + + public static PendingMoveAndMarkAsRead create(String srcFolder, String destFolder, List uids) { + return new PendingMoveAndMarkAsRead(srcFolder, destFolder, uids, null); + } + + private PendingMoveAndMarkAsRead(String srcFolder, String destFolder, List uids, + Map newUidMap) { + this.srcFolder = srcFolder; + this.destFolder = destFolder; + this.uids = uids; + this.newUidMap = newUidMap; + } + + @Override + public String getCommandName() { + return COMMAND_MOVE_AND_MARK_AS_READ; + } + + @Override + public void execute(MessagingController controller, Account account) throws MessagingException { + controller.processPendingMoveAndRead(this, account); + } + } + public static class PendingEmptyTrash extends PendingCommand { public static PendingEmptyTrash create() { return new PendingEmptyTrash(); diff --git a/app/core/src/main/java/com/fsck/k9/controller/PendingCommandSerializer.java b/app/core/src/main/java/com/fsck/k9/controller/PendingCommandSerializer.java index 0427e7e9f..8a71656a0 100644 --- a/app/core/src/main/java/com/fsck/k9/controller/PendingCommandSerializer.java +++ b/app/core/src/main/java/com/fsck/k9/controller/PendingCommandSerializer.java @@ -13,6 +13,7 @@ import com.fsck.k9.controller.MessagingControllerCommands.PendingDelete; import com.fsck.k9.controller.MessagingControllerCommands.PendingEmptyTrash; import com.fsck.k9.controller.MessagingControllerCommands.PendingExpunge; import com.fsck.k9.controller.MessagingControllerCommands.PendingMarkAllAsRead; +import com.fsck.k9.controller.MessagingControllerCommands.PendingMoveAndMarkAsRead; import com.fsck.k9.controller.MessagingControllerCommands.PendingMoveOrCopy; import com.fsck.k9.controller.MessagingControllerCommands.PendingSetFlag; import com.squareup.moshi.JsonAdapter; @@ -31,6 +32,8 @@ public class PendingCommandSerializer { HashMap> adapters = new HashMap<>(); adapters.put(MessagingControllerCommands.COMMAND_MOVE_OR_COPY, moshi.adapter(PendingMoveOrCopy.class)); + adapters.put(MessagingControllerCommands.COMMAND_MOVE_AND_MARK_AS_READ, + moshi.adapter(PendingMoveAndMarkAsRead.class)); adapters.put(MessagingControllerCommands.COMMAND_APPEND, moshi.adapter(PendingAppend.class)); adapters.put(MessagingControllerCommands.COMMAND_EMPTY_TRASH, moshi.adapter(PendingEmptyTrash.class)); adapters.put(MessagingControllerCommands.COMMAND_EXPUNGE, moshi.adapter(PendingExpunge.class)); diff --git a/app/core/src/main/java/com/fsck/k9/preferences/AccountSettings.java b/app/core/src/main/java/com/fsck/k9/preferences/AccountSettings.java index d8d0312c4..32c176cbb 100644 --- a/app/core/src/main/java/com/fsck/k9/preferences/AccountSettings.java +++ b/app/core/src/main/java/com/fsck/k9/preferences/AccountSettings.java @@ -117,6 +117,9 @@ public class AccountSettings { s.put("markMessageAsReadOnView", Settings.versions( new V(7, new BooleanSetting(true)) )); + s.put("markMessageAsReadOnDelete", Settings.versions( + new V(63, new BooleanSetting(true)) + )); s.put("maxPushFolders", Settings.versions( new V(1, new IntegerRangeSetting(0, 100, 10)) )); diff --git a/app/core/src/main/java/com/fsck/k9/preferences/Settings.java b/app/core/src/main/java/com/fsck/k9/preferences/Settings.java index 7725aab83..c0989eef4 100644 --- a/app/core/src/main/java/com/fsck/k9/preferences/Settings.java +++ b/app/core/src/main/java/com/fsck/k9/preferences/Settings.java @@ -36,7 +36,7 @@ public class Settings { * * @see SettingsExporter */ - public static final int VERSION = 62; + public static final int VERSION = 63; static Map validate(int version, Map> settings, Map importedSettings, boolean useDefaultValues) { diff --git a/app/ui/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt b/app/ui/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt index dcca4f2ae..c43faf2ea 100644 --- a/app/ui/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt +++ b/app/ui/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt @@ -18,6 +18,7 @@ class AccountSettingsDataStore( return when (key) { "account_default" -> account == preferences.defaultAccount "mark_message_as_read_on_view" -> account.isMarkMessageAsReadOnView + "mark_message_as_read_on_delete" -> account.isMarkMessageAsReadOnDelete "account_sync_remote_deletetions" -> account.isSyncRemoteDeletions "push_poll_on_connect" -> account.isPushPollOnConnect "always_show_cc_bcc" -> account.isAlwaysShowCcBcc @@ -51,6 +52,7 @@ class AccountSettingsDataStore( return } "mark_message_as_read_on_view" -> account.isMarkMessageAsReadOnView = value + "mark_message_as_read_on_delete" -> account.isMarkMessageAsReadOnDelete = value "account_sync_remote_deletetions" -> account.isSyncRemoteDeletions = value "push_poll_on_connect" -> account.isPushPollOnConnect = value "always_show_cc_bcc" -> account.isAlwaysShowCcBcc = value diff --git a/app/ui/src/main/res/values/strings.xml b/app/ui/src/main/res/values/strings.xml index b9b5402a5..a1739fc62 100644 --- a/app/ui/src/main/res/values/strings.xml +++ b/app/ui/src/main/res/values/strings.xml @@ -513,6 +513,8 @@ Please submit bug reports, contribute new features and ask questions at Searches for unread messages when Notification is opened Mark as read when opened Mark a message as read when it is opened for viewing + Mark as read when deleted + Mark a message as read when it is deleted Notification settings Open system notification settings diff --git a/app/ui/src/main/res/xml/account_settings.xml b/app/ui/src/main/res/xml/account_settings.xml index 7ab203b27..4d13fd232 100644 --- a/app/ui/src/main/res/xml/account_settings.xml +++ b/app/ui/src/main/res/xml/account_settings.xml @@ -110,6 +110,11 @@ android:summary="@string/account_settings_sync_remote_deletetions_summary" android:title="@string/account_settings_sync_remote_deletetions_label" /> + + ): Map? + @Throws(MessagingException::class) + fun moveMessagesAndMarkAsRead( + sourceFolderServerId: String, + targetFolderServerId: String, + messageServerIds: List + ): Map? + @Throws(MessagingException::class) fun copyMessages( sourceFolderServerId: String, diff --git a/backend/imap/src/main/java/com/fsck/k9/backend/imap/ImapBackend.java b/backend/imap/src/main/java/com/fsck/k9/backend/imap/ImapBackend.java index ac058a7e1..0bae0076e 100644 --- a/backend/imap/src/main/java/com/fsck/k9/backend/imap/ImapBackend.java +++ b/backend/imap/src/main/java/com/fsck/k9/backend/imap/ImapBackend.java @@ -1,6 +1,7 @@ package com.fsck.k9.backend.imap; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -162,6 +163,18 @@ public class ImapBackend implements Backend { return commandMoveOrCopyMessages.moveMessages(sourceFolderServerId, targetFolderServerId, messageServerIds); } + @Nullable + @Override + public Map moveMessagesAndMarkAsRead(@NotNull String sourceFolderServerId, + @NotNull String targetFolderServerId, @NotNull List messageServerIds) throws MessagingException { + Map uidMapping = commandMoveOrCopyMessages + .moveMessages(sourceFolderServerId, targetFolderServerId, messageServerIds); + if (uidMapping != null) { + setFlag(targetFolderServerId, new ArrayList<>(uidMapping.values()), Flag.SEEN, true); + } + return uidMapping; + } + @Nullable @Override public Map copyMessages(@NotNull String sourceFolderServerId, @NotNull String targetFolderServerId, diff --git a/backend/pop3/src/main/java/com/fsck/k9/backend/pop3/Pop3Backend.kt b/backend/pop3/src/main/java/com/fsck/k9/backend/pop3/Pop3Backend.kt index db5beef38..5994b8a85 100644 --- a/backend/pop3/src/main/java/com/fsck/k9/backend/pop3/Pop3Backend.kt +++ b/backend/pop3/src/main/java/com/fsck/k9/backend/pop3/Pop3Backend.kt @@ -88,6 +88,14 @@ class Pop3Backend( throw UnsupportedOperationException("not supported") } + override fun moveMessagesAndMarkAsRead( + sourceFolderServerId: String, + targetFolderServerId: String, + messageServerIds: List + ): Map? { + throw UnsupportedOperationException("not supported") + } + override fun search( folderServerId: String, query: String?, diff --git a/backend/webdav/src/main/java/com/fsck/k9/backend/webdav/WebDavBackend.kt b/backend/webdav/src/main/java/com/fsck/k9/backend/webdav/WebDavBackend.kt index 3fd57e00c..dae4b1eeb 100644 --- a/backend/webdav/src/main/java/com/fsck/k9/backend/webdav/WebDavBackend.kt +++ b/backend/webdav/src/main/java/com/fsck/k9/backend/webdav/WebDavBackend.kt @@ -85,6 +85,19 @@ class WebDavBackend( return commandMoveOrCopyMessages.moveMessages(sourceFolderServerId, targetFolderServerId, messageServerIds) } + override fun moveMessagesAndMarkAsRead( + sourceFolderServerId: String, + targetFolderServerId: String, + messageServerIds: List + ): Map? { + val uidMapping = commandMoveOrCopyMessages + .moveMessages(sourceFolderServerId, targetFolderServerId, messageServerIds) + if (uidMapping != null) { + setFlag(targetFolderServerId, uidMapping.values.toList(), Flag.SEEN, true) + } + return uidMapping + } + override fun copyMessages( sourceFolderServerId: String, targetFolderServerId: String,