Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4bbae28 authored by cketti's avatar cketti
Browse files

Hide the "Load up to X more" footer when there are no more relevant messages on the server

This is tricky for IMAP because we only care about non-deleted messages and
there's no easy way to count these. So when necessary we list all remaining
messages on the server to check whether any of them are relevant for us.
parent ebfd5b39
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
package com.fsck.k9.mail;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -86,6 +87,9 @@ public abstract class Folder<T extends Message> {
     */
    public abstract List<T> getMessages(int start, int end, Date earliestDate, MessageRetrievalListener<T> listener) throws MessagingException;

    public abstract boolean areMoreMessagesAvailable(int indexOfOldestMessage, Date earliestDate)
            throws IOException, MessagingException;

    /**
     * Fetches the given list of messages. The specified listener is notified as
     * each fetch completes. Messages are downloaded as (as) lightweight (as
+59 −7
Original line number Diff line number Diff line
@@ -670,6 +670,8 @@ public class ImapStore extends RemoteStore {


    protected class ImapFolder extends Folder<ImapMessage> {
        private static final int MORE_MESSAGES_WINDOW_SIZE = 500;

        private String mName;
        protected volatile int mMessageCount = -1;
        protected volatile long uidNext = -1L;
@@ -1202,14 +1204,8 @@ public class ImapStore extends RemoteStore {
                    String.format(Locale.US, "Invalid message set %d %d",
                                  start, end));
            }
            final StringBuilder dateSearchString = new StringBuilder();
            if (earliestDate != null) {
                dateSearchString.append(" SINCE ");
                synchronized (RFC3501_DATE) {
                    dateSearchString.append(RFC3501_DATE.format(earliestDate));
                }
            }

            final String dateSearchString = getDateSearchString(earliestDate);

            ImapSearcher searcher = new ImapSearcher() {
                @Override
@@ -1220,6 +1216,62 @@ public class ImapStore extends RemoteStore {
            return search(searcher, listener);

        }

        private String getDateSearchString(Date earliestDate) {
            if (earliestDate == null) {
                return "";
            }

            synchronized (RFC3501_DATE) {
                return " SINCE " + RFC3501_DATE.format(earliestDate);
            }
        }

        @Override
        public boolean areMoreMessagesAvailable(int indexOfOldestMessage, Date earliestDate)
                throws IOException, MessagingException {

            checkOpen();

            if (indexOfOldestMessage == 1) {
                return false;
            }

            String dateSearchString = getDateSearchString(earliestDate);

            int endIndex = indexOfOldestMessage - 1;

            while (endIndex > 0) {
                int startIndex = Math.max(0, endIndex - MORE_MESSAGES_WINDOW_SIZE) + 1;

                if (existsNonDeletedMessageInRange(startIndex, endIndex, dateSearchString)) {
                    return true;
                }

                endIndex = endIndex - MORE_MESSAGES_WINDOW_SIZE;
            }

            return false;
        }

        private boolean existsNonDeletedMessageInRange(int startIndex, int endIndex, String dateSearchString)
                throws MessagingException, IOException {

            String command = String.format(Locale.US, "SEARCH %d:%d%s NOT DELETED",
                    startIndex, endIndex, dateSearchString);

            List<ImapResponse> responses = executeSimpleCommand(command);
            for (ImapResponse response : responses) {
                if (response.getTag() == null && ImapResponseParser.equalsIgnoreCase(response.get(0), "SEARCH")) {
                    if (response.size() > 1) {
                        return true;
                    }
                }
            }

            return false;
        }

        protected List<ImapMessage> getMessages(final List<Long> mesgSeqs,
                                                      final boolean includeDeleted,
                                                      final MessageRetrievalListener<ImapMessage> listener)
+5 −0
Original line number Diff line number Diff line
@@ -610,6 +610,11 @@ public class Pop3Store extends RemoteStore {
            return messages;
        }

        @Override
        public boolean areMoreMessagesAvailable(int indexOfOldestMessage, Date earliestDate) {
            return indexOfOldestMessage > 1;
        }

        /**
         * Ensures that the given message set (from start to end inclusive)
         * has been queried so that uids are available in the local cache.
+5 −0
Original line number Diff line number Diff line
@@ -1448,6 +1448,11 @@ public class WebDavStore extends RemoteStore {
            return messages;
        }

        @Override
        public boolean areMoreMessagesAvailable(int indexOfOldestMessage, Date earliestDate) {
            return indexOfOldestMessage > 1;
        }

        @Override
        public List<WebDavMessage> getMessages(MessageRetrievalListener<WebDavMessage> listener) throws MessagingException {
            return getMessages(null, listener);
+2 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import com.fsck.k9.R;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.controller.MessagingListener;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mailstore.LocalFolder;


public class ChooseFolder extends K9ListActivity {
@@ -260,7 +261,7 @@ public class ChooseFolder extends K9ListActivity {
            mHandler.progress(false);
        }
        @Override
        public void listFolders(Account account, List<? extends Folder> folders) {
        public void listFolders(Account account, List<LocalFolder> folders) {
            if (!account.equals(mAccount)) {
                return;
            }
Loading