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

Commit 5cd28280 authored by cketti's avatar cketti
Browse files

Update special folders when folders change on server

parent 5e00abfa
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchSpecification.Attribute;
import com.fsck.k9.search.SearchSpecification.SearchCondition;
import com.fsck.k9.search.SearchSpecification.SearchField;
import org.jetbrains.annotations.NotNull;
import timber.log.Timber;

import static com.fsck.k9.Preferences.getEnumStringPref;
@@ -1055,22 +1056,27 @@ public class Account implements BaseAccount, StoreConfig {
        return spamFolder != null;
    }

    @NotNull
    public SpecialFolderSelection getDraftsFolderSelection() {
        return draftsFolderSelection;
    }

    @NotNull
    public synchronized SpecialFolderSelection getSentFolderSelection() {
        return sentFolderSelection;
    }

    @NotNull
    public synchronized SpecialFolderSelection getTrashFolderSelection() {
        return trashFolderSelection;
    }

    @NotNull
    public synchronized SpecialFolderSelection getArchiveFolderSelection() {
        return archiveFolderSelection;
    }

    @NotNull
    public synchronized SpecialFolderSelection getSpamFolderSelection() {
        return spamFolderSelection;
    }
+12 −3
Original line number Diff line number Diff line
@@ -8,12 +8,13 @@ import com.fsck.k9.Preferences
import com.fsck.k9.backend.api.BackendFolder
import com.fsck.k9.backend.api.BackendStorage
import com.fsck.k9.backend.api.FolderInfo
import com.fsck.k9.mail.Folder.FolderType
import com.fsck.k9.mail.Folder.FolderType as RemoteFolderType

class K9BackendStorage(
        private val preferences: Preferences,
        private val account: Account,
        private val localStore: LocalStore
        private val localStore: LocalStore,
        private val specialFolderUpdater: SpecialFolderUpdater
) : BackendStorage {
    private val database = localStore.database

@@ -38,6 +39,10 @@ class K9BackendStorage(

        val localFolders = folders.map { localStore.getFolder(it.serverId, it.name, it.type) }
        localStore.createFolders(localFolders, account.displayCount)

        if (folders.any { it.type != FolderType.REGULAR }) {
            specialFolderUpdater.updateSpecialFolders()
        }
    }

    override fun deleteFolders(folderServerIds: List<String>) {
@@ -45,9 +50,11 @@ class K9BackendStorage(
                .filterNot { account.isSpecialFolder(it) }
                .map { localStore.getFolder(it) }
                .forEach { it.delete() }

        specialFolderUpdater.updateSpecialFolders()
    }

    override fun changeFolder(folderServerId: String, name: String, type: FolderType) {
    override fun changeFolder(folderServerId: String, name: String, type: RemoteFolderType) {
        database.execute(false) { db ->
            val values = ContentValues().apply {
                put("name", name)
@@ -56,6 +63,8 @@ class K9BackendStorage(

            db.update("folders", values, "server_id = ?", arrayOf(folderServerId))
        }

        specialFolderUpdater.updateSpecialFolders()
    }

    override fun getExtraString(name: String): String? {
+15 −0
Original line number Diff line number Diff line
package com.fsck.k9.mailstore

import com.fsck.k9.Account
import com.fsck.k9.Preferences

class K9BackendStorageFactory(
        private val preferences: Preferences,
        private val folderRepositoryManager: FolderRepositoryManager
) {
    fun createBackendStorage(account: Account): K9BackendStorage {
        val folderRepository = folderRepositoryManager.getFolderRepository(account)
        val specialFolderUpdater = SpecialFolderUpdater(preferences, folderRepository, account)
        return K9BackendStorage(preferences, account, account.localStore, specialFolderUpdater)
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -8,4 +8,5 @@ val mailStoreModule = applicationContext {
    bean { StorageManager.getInstance(get()) }
    bean { SearchStatusManager() }
    bean { SpecialFolderSelectionStrategy() }
    bean { K9BackendStorageFactory(get(), get()) }
}
+82 −0
Original line number Diff line number Diff line
package com.fsck.k9.mailstore

import com.fsck.k9.Account
import com.fsck.k9.Account.SpecialFolderSelection
import com.fsck.k9.Preferences

/**
 * Updates special folders in [Account] if they are marked as [SpecialFolderSelection.AUTOMATIC] or if they are marked
 * as [SpecialFolderSelection.MANUAL] but have been deleted from the server.
 */
class SpecialFolderUpdater(
        private val preferences: Preferences,
        private val folderRepository: FolderRepository,
        private val account: Account
) {
    fun updateSpecialFolders() {
        val (folders, automaticSpecialFolders) = folderRepository.getRemoteFolderInfo()

        updateInbox(folders)
        updateSpecialFolder(FolderType.ARCHIVE, folders, automaticSpecialFolders)
        updateSpecialFolder(FolderType.DRAFTS, folders, automaticSpecialFolders)
        updateSpecialFolder(FolderType.SENT, folders, automaticSpecialFolders)
        updateSpecialFolder(FolderType.SPAM, folders, automaticSpecialFolders)
        updateSpecialFolder(FolderType.TRASH, folders, automaticSpecialFolders)

        saveAccount()
    }

    private fun updateInbox(folders: List<Folder>) {
        account.inboxFolder = folders.first { it.type == FolderType.INBOX }.serverId
    }

    private fun updateSpecialFolder(
            type: FolderType,
            folders: List<Folder>,
            automaticSpecialFolders: Map<FolderType, Folder?>
    ) {
        when (getSpecialFolderSelection(type)) {
            SpecialFolderSelection.AUTOMATIC -> {
                setSpecialFolder(type, automaticSpecialFolders[type]?.serverId, SpecialFolderSelection.AUTOMATIC)
            }
            SpecialFolderSelection.MANUAL -> {
                if (folders.none { it.serverId == getSpecialFolder(type) }) {
                    setSpecialFolder(type, null, SpecialFolderSelection.MANUAL)
                }
            }
        }
    }

    private fun getSpecialFolderSelection(type: FolderType) = when (type) {
        FolderType.ARCHIVE -> account.archiveFolderSelection
        FolderType.DRAFTS -> account.draftsFolderSelection
        FolderType.SENT -> account.sentFolderSelection
        FolderType.SPAM -> account.spamFolderSelection
        FolderType.TRASH -> account.trashFolderSelection
        else -> throw AssertionError("Unsupported: $type")
    }

    private fun getSpecialFolder(type: FolderType): String? = when (type) {
        FolderType.ARCHIVE -> account.archiveFolder
        FolderType.DRAFTS -> account.draftsFolder
        FolderType.SENT -> account.sentFolder
        FolderType.SPAM -> account.spamFolder
        FolderType.TRASH -> account.trashFolder
        else -> throw AssertionError("Unsupported: $type")
    }

    private fun setSpecialFolder(type: FolderType, folder: String?, selection: SpecialFolderSelection) {
        when (type) {
            FolderType.ARCHIVE -> account.setArchiveFolder(folder, selection)
            FolderType.DRAFTS -> account.setDraftsFolder(folder, selection)
            FolderType.SENT -> account.setSentFolder(folder, selection)
            FolderType.SPAM -> account.setSpamFolder(folder, selection)
            FolderType.TRASH -> account.setTrashFolder(folder, selection)
            else -> throw AssertionError("Unsupported: $type")
        }
    }

    private fun saveAccount() {
        account.save(preferences)
    }
}
Loading