Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Empty Spam command #8126

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import com.fsck.k9.controller.MessagingControllerCommands.PendingAppend;
import com.fsck.k9.controller.MessagingControllerCommands.PendingCommand;
import com.fsck.k9.controller.MessagingControllerCommands.PendingDelete;
import com.fsck.k9.controller.MessagingControllerCommands.PendingEmptySpam;
import com.fsck.k9.controller.MessagingControllerCommands.PendingEmptyTrash;
import com.fsck.k9.controller.MessagingControllerCommands.PendingExpunge;
import com.fsck.k9.controller.MessagingControllerCommands.PendingMarkAllAsRead;
Expand Down Expand Up @@ -2080,6 +2081,66 @@ private static List<String> getUidsFromMessages(List<LocalMessage> messages) {
return uids;
}

void processPendingEmptySpam(Account account) throws MessagingException {
if (!account.hasSpamFolder()) {
return;
}

long spamFolderId = account.getSpamFolderId();
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder folder = localStore.getFolder(spamFolderId);
folder.open();
String spamFolderServerId = folder.getServerId();

Backend backend = getBackend(account);
backend.deleteAllMessages(spamFolderServerId);

// Remove all messages marked as deleted
folder.destroyDeletedMessages();

compact(account);
}

public void emptySpam(final Account account, MessagingListener listener) {
putBackground("emptySpam", listener, new Runnable() {
@Override
public void run() {
try {
Long spamFolderId = account.getSpamFolderId();
if (spamFolderId == null) {
Timber.w("No Spam folder configured. Can't empty spam.");
return;
}

LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(spamFolderId);
localFolder.open();

boolean isSpamLocalOnly = isSpamLocalOnly(account);
if (isSpamLocalOnly) {
localFolder.clearAllMessages();
} else {
localFolder.destroyLocalOnlyMessages();
localFolder.setFlags(Collections.singleton(Flag.DELETED), true);
}

for (MessagingListener l : getListeners()) {
l.folderStatusChanged(account, spamFolderId);
}

if (!isSpamLocalOnly) {
PendingCommand command = PendingEmptySpam.create();
queuePendingCommand(account, command);
processPendingCommands(account);
}
} catch (Exception e) {
Timber.e(e, "emptySpam failed");
}
}
});
}


void processPendingEmptyTrash(Account account) throws MessagingException {
if (!account.hasTrashFolder()) {
return;
Expand Down Expand Up @@ -2157,6 +2218,22 @@ protected void clearFolderSynchronous(Account account, long folderId) {
}


/**
* Find out whether the account type only supports a local Spam folder.
* <p>
* <p>Note: Currently this is only the case for POP3 accounts.</p>
*
* @param account
* The account to check.
*
* @return {@code true} if the account only has a local Spam folder that is not synchronized
* with a folder on the server. {@code false} otherwise.
*/
private boolean isSpamLocalOnly(Account account) {
Backend backend = getBackend(account);
return !backend.getSupportsSpamFolder();
}

/**
* Find out whether the account type only supports a local Trash folder.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class MessagingControllerCommands {
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_SPAM = "empty_spam";
static final String COMMAND_EMPTY_TRASH = "empty_trash";

public abstract static class PendingCommand {
Expand Down Expand Up @@ -95,6 +96,22 @@ public void execute(MessagingController controller, Account account) throws Mess
}
}

public static class PendingEmptySpam extends PendingCommand {
public static PendingEmptySpam create() {
return new PendingEmptySpam();
}

@Override
public String getCommandName() {
return COMMAND_EMPTY_SPAM;
}

@Override
public void execute(MessagingController controller, Account account) throws MessagingException {
controller.processPendingEmptySpam(account);
}
}

public static class PendingEmptyTrash extends PendingCommand {
public static PendingEmptyTrash create() {
return new PendingEmptyTrash();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.fsck.k9.controller.MessagingControllerCommands.PendingAppend;
import com.fsck.k9.controller.MessagingControllerCommands.PendingCommand;
import com.fsck.k9.controller.MessagingControllerCommands.PendingDelete;
import com.fsck.k9.controller.MessagingControllerCommands.PendingEmptySpam;
import com.fsck.k9.controller.MessagingControllerCommands.PendingEmptyTrash;
import com.fsck.k9.controller.MessagingControllerCommands.PendingExpunge;
import com.fsck.k9.controller.MessagingControllerCommands.PendingMarkAllAsRead;
Expand Down Expand Up @@ -37,6 +38,7 @@ private PendingCommandSerializer() {
moshi.adapter(PendingMoveAndMarkAsRead.class));
adapters.put(MessagingControllerCommands.COMMAND_APPEND, moshi.adapter(PendingAppend.class));
adapters.put(MessagingControllerCommands.COMMAND_REPLACE, moshi.adapter(PendingReplace.class));
adapters.put(MessagingControllerCommands.COMMAND_EMPTY_SPAM, moshi.adapter(PendingEmptySpam.class));
adapters.put(MessagingControllerCommands.COMMAND_EMPTY_TRASH, moshi.adapter(PendingEmptyTrash.class));
adapters.put(MessagingControllerCommands.COMMAND_EXPUNGE, moshi.adapter(PendingExpunge.class));
adapters.put(MessagingControllerCommands.COMMAND_MARK_ALL_AS_READ, moshi.adapter(PendingMarkAllAsRead.class));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,12 @@ class MessageListFragment :
}
}

private fun onEmptySpam() {
if (isShowingSpamFolder) {
showDialog(R.id.dialog_confirm_empty_spam)
}
}

private fun onEmptyTrash() {
if (isShowingTrashFolder) {
showDialog(R.id.dialog_confirm_empty_trash)
Expand Down Expand Up @@ -786,6 +792,14 @@ class MessageListFragment :
ConfirmationDialogFragment.newInstance(dialogId, title, message, confirmText, cancelText)
}

R.id.dialog_confirm_empty_spam -> {
val title = getString(R.string.dialog_confirm_empty_spam_title)
val message = getString(R.string.dialog_confirm_empty_spam_message)
val confirmText = getString(R.string.dialog_confirm_delete_confirm_button)
val cancelText = getString(R.string.dialog_confirm_delete_cancel_button)
ConfirmationDialogFragment.newInstance(dialogId, title, message, confirmText, cancelText)
}

R.id.dialog_confirm_empty_trash -> {
val title = getString(R.string.dialog_confirm_empty_trash_title)
val message = getString(R.string.dialog_confirm_empty_trash_message)
Expand Down Expand Up @@ -820,6 +834,7 @@ class MessageListFragment :
menu.findItem(R.id.set_sort).isVisible = true
menu.findItem(R.id.select_all).isVisible = true
menu.findItem(R.id.mark_all_as_read).isVisible = isMarkAllAsReadSupported
menu.findItem(R.id.empty_spam).isVisible = isShowingSpamFolder
menu.findItem(R.id.empty_trash).isVisible = isShowingTrashFolder

if (isSingleAccountMode) {
Expand All @@ -843,6 +858,7 @@ class MessageListFragment :
menu.findItem(R.id.select_all).isVisible = false
menu.findItem(R.id.mark_all_as_read).isVisible = false
menu.findItem(R.id.send_messages).isVisible = false
menu.findItem(R.id.empty_spam).isVisible = false
menu.findItem(R.id.empty_trash).isVisible = false
menu.findItem(R.id.expunge).isVisible = false
menu.findItem(R.id.search_everywhere).isVisible = false
Expand All @@ -862,6 +878,7 @@ class MessageListFragment :
R.id.select_all -> selectAll()
R.id.mark_all_as_read -> confirmMarkAllAsRead()
R.id.send_messages -> onSendPendingMessages()
R.id.empty_spam -> onEmptySpam()
R.id.empty_trash -> onEmptyTrash()
R.id.expunge -> onExpunge()
R.id.search_everywhere -> onSearchEverywhere()
Expand Down Expand Up @@ -1225,6 +1242,10 @@ class MessageListFragment :
markAllAsRead()
}

R.id.dialog_confirm_empty_spam -> {
messagingController.emptySpam(account, null)
}

R.id.dialog_confirm_empty_trash -> {
messagingController.emptyTrash(account, null)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,13 @@
app:showAsAction="never"
/>

<!-- MessageList -->
<item
android:id="@+id/empty_spam"
android:title="@string/empty_spam_action"
app:showAsAction="never"
/>

<!-- MessageList -->
<item
android:id="@+id/empty_trash"
Expand Down
1 change: 1 addition & 0 deletions legacy/ui/legacy/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
<string name="read_receipt_enabled">Will request read receipt</string>
<string name="read_receipt_disabled">Will not request read receipt</string>
<string name="add_attachment_action">Add attachment</string>
<string name="empty_spam_action">Empty Spam</string>
<string name="empty_trash_action">Empty Trash</string>
<string name="expunge_action">Expunge</string>
<string name="about_action">About</string>
Expand Down