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

Unverified Commit 2ac66fe9 authored by cketti's avatar cketti Committed by GitHub
Browse files

Merge pull request #6171 from thundernest/message_list_menu_cleanup

Clean up message list menu code
parents 4ab5f2c5 42daa056
Loading
Loading
Loading
Loading
+6 −110
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import androidx.fragment.app.FragmentTransaction
import androidx.fragment.app.commit
import androidx.lifecycle.Observer
import com.fsck.k9.Account
import com.fsck.k9.Account.SortType
import com.fsck.k9.K9
import com.fsck.k9.K9.SplitViewMode
import com.fsck.k9.Preferences
@@ -917,45 +916,12 @@ open class MessageList :
                goBack()
            }
            return true
        } else if (id == R.id.compose) {
            messageListFragment!!.onCompose()
            return true
        } else if (id == R.id.toggle_message_view_theme) {
            onToggleTheme()
            return true
        } else if (id == R.id.set_sort_date) { // MessageList
            messageListFragment!!.changeSort(SortType.SORT_DATE)
            return true
        } else if (id == R.id.set_sort_arrival) {
            messageListFragment!!.changeSort(SortType.SORT_ARRIVAL)
            return true
        } else if (id == R.id.set_sort_subject) {
            messageListFragment!!.changeSort(SortType.SORT_SUBJECT)
            return true
        } else if (id == R.id.set_sort_sender) {
            messageListFragment!!.changeSort(SortType.SORT_SENDER)
            return true
        } else if (id == R.id.set_sort_flag) {
            messageListFragment!!.changeSort(SortType.SORT_FLAGGED)
            return true
        } else if (id == R.id.set_sort_unread) {
            messageListFragment!!.changeSort(SortType.SORT_UNREAD)
            return true
        } else if (id == R.id.set_sort_attach) {
            messageListFragment!!.changeSort(SortType.SORT_ATTACHMENT)
            return true
        } else if (id == R.id.select_all) {
            messageListFragment!!.selectAll()
            return true
        } else if (id == R.id.search_remote) {
            messageListFragment!!.onRemoteSearch()
            return true
        } else if (id == R.id.search_everywhere) {
            searchEverywhere()
            return true
        } else if (id == R.id.mark_all_as_read) {
            messageListFragment!!.confirmMarkAllAsRead()
            return true
        } else if (id == R.id.next_message) { // MessageView
            showNextMessage()
            return true
@@ -1009,29 +975,7 @@ open class MessageList :
            return true
        }

        if (!singleFolderMode) {
            // None of the options after this point are "safe" for search results
            // TODO: This is not true for "unread" and "starred" searches in regular folders
            return false
        }

        return when (id) {
            R.id.send_messages -> {
                messageListFragment!!.onSendPendingMessages()
                true
            }
            R.id.expunge -> {
                messageListFragment!!.onExpunge()
                true
            }
            R.id.empty_trash -> {
                messageListFragment!!.onEmptyTrash()
                true
            }
            else -> {
                super.onOptionsItemSelected(item)
            }
        }
        return super.onOptionsItemSelected(item)
    }

    private fun searchEverywhere() {
@@ -1185,51 +1129,6 @@ open class MessageList :

            menu.findItem(R.id.unsubscribe).isVisible = messageViewFragment!!.canMessageBeUnsubscribed()
        }

        // Set visibility of menu items related to the message list

        // Hide search menu items by default and enable one when appropriate
        menu.findItem(R.id.search).isVisible = false
        menu.findItem(R.id.search_remote).isVisible = false
        menu.findItem(R.id.search_everywhere).isVisible = false

        if (displayMode == DisplayMode.MESSAGE_VIEW || messageListFragment == null ||
            !messageListFragment!!.isInitialized
        ) {
            menu.findItem(R.id.set_sort).isVisible = false
            menu.findItem(R.id.select_all).isVisible = false
            menu.findItem(R.id.send_messages).isVisible = false
            menu.findItem(R.id.expunge).isVisible = false
            menu.findItem(R.id.empty_trash).isVisible = false
            menu.findItem(R.id.mark_all_as_read).isVisible = false
        } else {
            menu.findItem(R.id.set_sort).isVisible = true
            menu.findItem(R.id.select_all).isVisible = true
            menu.findItem(R.id.compose).isVisible = true
            menu.findItem(R.id.mark_all_as_read).isVisible = messageListFragment!!.isMarkAllAsReadSupported

            if (!messageListFragment!!.isSingleAccountMode) {
                menu.findItem(R.id.expunge).isVisible = false
                menu.findItem(R.id.send_messages).isVisible = false
            } else {
                menu.findItem(R.id.send_messages).isVisible = messageListFragment!!.isOutbox
                menu.findItem(R.id.expunge).isVisible = messageListFragment!!.isRemoteFolder &&
                    messageListFragment!!.shouldShowExpungeAction()
            }
            menu.findItem(R.id.empty_trash).isVisible = messageListFragment!!.isShowingTrashFolder

            // If this is an explicit local search, show the option to search on the server
            if (!messageListFragment!!.isRemoteSearch && messageListFragment!!.isRemoteSearchAllowed) {
                menu.findItem(R.id.search_remote).isVisible = true
            } else if (!messageListFragment!!.isManualSearch) {
                menu.findItem(R.id.search).isVisible = true
            }

            val messageListFragment = messageListFragment!!
            if (messageListFragment.isManualSearch && !messageListFragment.localSearch.searchAllAccounts()) {
                menu.findItem(R.id.search_everywhere).isVisible = true
            }
        }
    }

    fun setActionBarTitle(title: String, subtitle: String? = null) {
@@ -1309,7 +1208,7 @@ open class MessageList :
            showMessageViewPlaceHolder()
        }

        configureMenu(menu)
        invalidateMenu()
    }

    private fun addMessageListFragment(fragment: MessageListFragment) {
@@ -1326,6 +1225,7 @@ open class MessageList :
        }

        messageListFragment = fragment
        fragment.onListVisible()

        if (isDrawerEnabled) {
            lockDrawer()
@@ -1402,7 +1302,7 @@ open class MessageList :

    override fun remoteSearchStarted() {
        // Remove action button for remote search
        configureMenu(menu)
        invalidateMenu()
    }

    override fun goBack() {
@@ -1477,7 +1377,7 @@ open class MessageList :
        setDrawerLockState()

        showDefaultTitleView()
        configureMenu(menu)
        invalidateMenu()

        onMessageListDisplayed()
    }
@@ -1506,11 +1406,7 @@ open class MessageList :
        }

        showMessageTitleView()
        configureMenu(menu)
    }

    override fun updateMenu() {
        invalidateOptionsMenu()
        invalidateMenu()
    }

    override fun disableDeleteAction() {
+79 −67
Original line number Diff line number Diff line
@@ -115,10 +115,8 @@ class MessageListFragment :
        private set
    var isSingleAccountMode = false
        private set
    var isSingleFolderMode = false
        private set
    var isRemoteSearch = false
        private set
    private var isSingleFolderMode = false
    private var isRemoteSearch = false

    private val isUnifiedInbox: Boolean
        get() = localSearch.id == SearchAccount.UNIFIED_INBOX
@@ -130,8 +128,7 @@ class MessageListFragment :
     * `true` after [.onCreate] was executed. Used in [.updateTitle] to
     * make sure we don't access member variables before initialization is complete.
     */
    var isInitialized = false
        private set
    private var isInitialized = false

    private var isListVisible = false

@@ -147,6 +144,7 @@ class MessageListFragment :

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)

        restoreInstanceState(savedInstanceState)
        decodeArguments() ?: return
@@ -506,7 +504,7 @@ class MessageListFragment :
        }
    }

    fun changeSort(sortType: SortType) {
    private fun changeSort(sortType: SortType) {
        val sortAscending = if (this.sortType == sortType) !sortAscending else null
        changeSort(sortType, sortAscending)
    }
@@ -628,23 +626,19 @@ class MessageListFragment :
        }
    }

    fun onExpunge() {
    private fun onExpunge() {
        currentFolder?.let { folderInfoHolder ->
            onExpunge(account, folderInfoHolder.databaseId)
            messagingController.expunge(account, folderInfoHolder.databaseId)
        }
    }

    private fun onExpunge(account: Account?, folderId: Long) {
        messagingController.expunge(account, folderId)
    }

    fun onEmptyTrash() {
    private fun onEmptyTrash() {
        if (isShowingTrashFolder) {
            showDialog(R.id.dialog_confirm_empty_trash)
        }
    }

    val isShowingTrashFolder: Boolean
    private val isShowingTrashFolder: Boolean
        get() {
            if (!isSingleFolderMode) return false
            return currentFolder!!.databaseId == account!!.trashFolderId
@@ -703,54 +697,69 @@ class MessageListFragment :
        return "dialog-$dialogId"
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        val id = item.itemId
        if (id == R.id.set_sort_date) {
            changeSort(SortType.SORT_DATE)
            return true
        } else if (id == R.id.set_sort_arrival) {
            changeSort(SortType.SORT_ARRIVAL)
            return true
        } else if (id == R.id.set_sort_subject) {
            changeSort(SortType.SORT_SUBJECT)
            return true
        } else if (id == R.id.set_sort_sender) {
            changeSort(SortType.SORT_SENDER)
            return true
        } else if (id == R.id.set_sort_flag) {
            changeSort(SortType.SORT_FLAGGED)
            return true
        } else if (id == R.id.set_sort_unread) {
            changeSort(SortType.SORT_UNREAD)
            return true
        } else if (id == R.id.set_sort_attach) {
            changeSort(SortType.SORT_ATTACHMENT)
            return true
        } else if (id == R.id.select_all) {
            selectAll()
            return true
    override fun onPrepareOptionsMenu(menu: Menu) {
        if (isListVisible) {
            prepareMenu(menu)
        } else {
            hideMenu(menu)
        }
    }

        if (!isSingleAccountMode) {
            // None of the options after this point are "safe" for search results
            // TODO: This is not true for "unread" and "starred" searches in regular folders
            return false
    private fun prepareMenu(menu: Menu) {
        menu.findItem(R.id.set_sort).isVisible = true
        menu.findItem(R.id.select_all).isVisible = true
        menu.findItem(R.id.compose).isVisible = true
        menu.findItem(R.id.mark_all_as_read).isVisible = isMarkAllAsReadSupported
        menu.findItem(R.id.empty_trash).isVisible = isShowingTrashFolder

        if (isSingleAccountMode) {
            menu.findItem(R.id.send_messages).isVisible = isOutbox
            menu.findItem(R.id.expunge).isVisible = isRemoteFolder && shouldShowExpungeAction()
        } else {
            menu.findItem(R.id.send_messages).isVisible = false
            menu.findItem(R.id.expunge).isVisible = false
        }

        if (id == R.id.send_messages) {
            onSendPendingMessages()
            return true
        } else if (id == R.id.expunge) {
            currentFolder?.let { folderInfoHolder ->
                onExpunge(account, folderInfoHolder.databaseId)
        menu.findItem(R.id.search).isVisible = !isManualSearch
        menu.findItem(R.id.search_remote).isVisible = !isRemoteSearch && isRemoteSearchAllowed
        menu.findItem(R.id.search_everywhere).isVisible = isManualSearch && !localSearch.searchAllAccounts()
    }
            return true
        } else {
            return super.onOptionsItemSelected(item)

    private fun hideMenu(menu: Menu) {
        menu.findItem(R.id.search).isVisible = false
        menu.findItem(R.id.search_remote).isVisible = false
        menu.findItem(R.id.set_sort).isVisible = false
        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_trash).isVisible = false
        menu.findItem(R.id.expunge).isVisible = false
        menu.findItem(R.id.search_everywhere).isVisible = false
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.search_remote -> onRemoteSearch()
            R.id.compose -> onCompose()
            R.id.set_sort_date -> changeSort(SortType.SORT_DATE)
            R.id.set_sort_arrival -> changeSort(SortType.SORT_ARRIVAL)
            R.id.set_sort_subject -> changeSort(SortType.SORT_SUBJECT)
            R.id.set_sort_sender -> changeSort(SortType.SORT_SENDER)
            R.id.set_sort_flag -> changeSort(SortType.SORT_FLAGGED)
            R.id.set_sort_unread -> changeSort(SortType.SORT_UNREAD)
            R.id.set_sort_attach -> changeSort(SortType.SORT_ATTACHMENT)
            R.id.select_all -> selectAll()
            R.id.mark_all_as_read -> confirmMarkAllAsRead()
            R.id.send_messages -> onSendPendingMessages()
            R.id.empty_trash -> onEmptyTrash()
            R.id.expunge -> onExpunge()
            else -> return super.onOptionsItemSelected(item)
        }

        return true
    }

    fun onSendPendingMessages() {
    private fun onSendPendingMessages() {
        messagingController.sendPendingMessages(account, null)
    }

@@ -1416,7 +1425,7 @@ class MessageListFragment :
        return currentFolder.databaseId == folderId
    }

    val isRemoteFolder: Boolean
    private val isRemoteFolder: Boolean
        get() {
            if (localSearch.isManualSearch || isOutbox) return false

@@ -1428,15 +1437,15 @@ class MessageListFragment :
            }
        }

    val isManualSearch: Boolean
    private val isManualSearch: Boolean
        get() = localSearch.isManualSearch

    fun shouldShowExpungeAction(): Boolean {
    private fun shouldShowExpungeAction(): Boolean {
        val account = this.account ?: return false
        return account.expungePolicy == Expunge.EXPUNGE_MANUALLY && messagingController.supportsExpunge(account)
    }

    fun onRemoteSearch() {
    private fun onRemoteSearch() {
        // Remote search is useless without the network.
        if (hasConnectivity == true) {
            onRemoteSearchRequested()
@@ -1445,7 +1454,7 @@ class MessageListFragment :
        }
    }

    val isRemoteSearchAllowed: Boolean
    private val isRemoteSearchAllowed: Boolean
        get() = isManualSearch && !isRemoteSearch && isSingleFolderMode && messagingController.isPushCapable(account)

    fun onSearchRequested(query: String): Boolean {
@@ -1453,7 +1462,7 @@ class MessageListFragment :
        return fragmentListener.startSearch(query, account, folderId)
    }

    fun setMessageList(messageListInfo: MessageListInfo) {
    private fun setMessageList(messageListInfo: MessageListInfo) {
        val messageListItems = messageListInfo.messageListItems
        if (isThreadDisplay && messageListItems.isEmpty()) {
            handler.goBack()
@@ -1493,7 +1502,7 @@ class MessageListFragment :
            savedListState = null
        }

        fragmentListener.updateMenu()
        invalidateMenu()

        currentFolder?.let { currentFolder ->
            currentFolder.moreMessages = messageListInfo.hasMoreMessages
@@ -1564,10 +1573,10 @@ class MessageListFragment :
        }
    }

    val isMarkAllAsReadSupported: Boolean
    private val isMarkAllAsReadSupported: Boolean
        get() = isSingleAccountMode && isSingleFolderMode && !isOutbox

    fun confirmMarkAllAsRead() {
    private fun confirmMarkAllAsRead() {
        if (K9.isConfirmMarkAllRead) {
            showDialog(R.id.dialog_confirm_mark_all_as_read)
        } else {
@@ -1591,7 +1600,11 @@ class MessageListFragment :
        resetActionMode()
    }

    val isCheckMailSupported: Boolean
    private fun invalidateMenu() {
        requireActivity().invalidateMenu()
    }

    private val isCheckMailSupported: Boolean
        get() = allAccounts || !isSingleAccountMode || !isSingleFolderMode || isRemoteFolder

    private val isCheckMailAllowed: Boolean
@@ -1949,7 +1962,6 @@ class MessageListFragment :
        fun startSearch(query: String, account: Account?, folderId: Long?): Boolean
        fun remoteSearchStarted()
        fun goBack()
        fun updateMenu()
        fun onFolderNotFoundError()

        companion object {
+7 −4
Original line number Diff line number Diff line
@@ -240,7 +240,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
        mAccount = Preferences.getPreferences(getApplicationContext()).getAccount(mMessageReference.getAccountUuid());
        messageLoaderHelper.asyncStartOrResumeLoadingMessage(messageReference, null);

        mFragmentListener.updateMenu();
        invalidateMenu();
    }

    private void hideKeyboard() {
@@ -281,7 +281,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
            mMessageView.getMessageHeaderView().setCryptoStatusLoading();
        }
        displaySubject(message.getSubject());
        mFragmentListener.updateMenu();
        invalidateMenu();
    }

    private void displaySubject(String subject) {
@@ -517,7 +517,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
                    Collections.singletonList(mMessage), Flag.SEEN, !mMessage.isSet(Flag.SEEN));

            mMessageView.setHeaders(mMessage, mAccount, true);
            mFragmentListener.updateMenu();
            invalidateMenu();
        }
    }

@@ -773,7 +773,6 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
        void onReply(MessageReference messageReference, @Nullable Parcelable decryptionResultForReply);
        void setProgress(boolean b);
        void showNextMessageOrReturn();
        void updateMenu();
    }

    public boolean isInitialized() {
@@ -884,6 +883,10 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
        return new AttachmentController(mController, this, attachment);
    }

    private void invalidateMenu() {
        requireActivity().invalidateMenu();
    }

    private enum FolderOperation {
        COPY, MOVE
    }