Loading app/core/src/main/java/com/fsck/k9/Account.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading app/core/src/main/java/com/fsck/k9/mailstore/K9BackendStorage.kt +12 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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>) { Loading @@ -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) Loading @@ -56,6 +63,8 @@ class K9BackendStorage( db.update("folders", values, "server_id = ?", arrayOf(folderServerId)) } specialFolderUpdater.updateSpecialFolders() } override fun getExtraString(name: String): String? { Loading app/core/src/main/java/com/fsck/k9/mailstore/K9BackendStorageFactory.kt 0 → 100644 +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) } } app/core/src/main/java/com/fsck/k9/mailstore/KoinModule.kt +1 −0 Original line number Diff line number Diff line Loading @@ -8,4 +8,5 @@ val mailStoreModule = applicationContext { bean { StorageManager.getInstance(get()) } bean { SearchStatusManager() } bean { SpecialFolderSelectionStrategy() } bean { K9BackendStorageFactory(get(), get()) } } app/core/src/main/java/com/fsck/k9/mailstore/SpecialFolderUpdater.kt 0 → 100644 +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
app/core/src/main/java/com/fsck/k9/Account.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading
app/core/src/main/java/com/fsck/k9/mailstore/K9BackendStorage.kt +12 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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>) { Loading @@ -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) Loading @@ -56,6 +63,8 @@ class K9BackendStorage( db.update("folders", values, "server_id = ?", arrayOf(folderServerId)) } specialFolderUpdater.updateSpecialFolders() } override fun getExtraString(name: String): String? { Loading
app/core/src/main/java/com/fsck/k9/mailstore/K9BackendStorageFactory.kt 0 → 100644 +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) } }
app/core/src/main/java/com/fsck/k9/mailstore/KoinModule.kt +1 −0 Original line number Diff line number Diff line Loading @@ -8,4 +8,5 @@ val mailStoreModule = applicationContext { bean { StorageManager.getInstance(get()) } bean { SearchStatusManager() } bean { SpecialFolderSelectionStrategy() } bean { K9BackendStorageFactory(get(), get()) } }
app/core/src/main/java/com/fsck/k9/mailstore/SpecialFolderUpdater.kt 0 → 100644 +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) } }