0
0
mirror of https://github.com/thunderbird/thunderbird-android.git synced 2024-09-19 19:52:14 +02:00

Move DisplayFolder related implementation to from FolderRepository to DisplayFolderRepository

This commit is contained in:
Wolf-Martell Montwé 2024-09-10 15:01:01 +02:00
parent 46547c98fc
commit bdf4c1764d
No known key found for this signature in database
GPG Key ID: 6D45B21512ACBF72
8 changed files with 166 additions and 108 deletions

View File

@ -5,9 +5,11 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import app.k9mail.legacy.account.Account import app.k9mail.legacy.account.Account
import app.k9mail.legacy.mailstore.FolderRepository import app.k9mail.legacy.mailstore.DisplayFolderRepository
import app.k9mail.legacy.message.controller.MessageCountsProvider import app.k9mail.legacy.message.controller.MessageCountsProvider
import app.k9mail.legacy.search.SearchAccount import app.k9mail.legacy.search.SearchAccount
import app.k9mail.legacy.ui.folder.DisplayUnifiedInbox
import app.k9mail.legacy.ui.folder.FolderList
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -20,7 +22,7 @@ import kotlinx.coroutines.launch
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
class FoldersViewModel( class FoldersViewModel(
private val folderRepository: FolderRepository, private val folderRepository: DisplayFolderRepository,
private val messageCountsProvider: MessageCountsProvider, private val messageCountsProvider: MessageCountsProvider,
private val isShowUnifiedInbox: () -> Boolean, private val isShowUnifiedInbox: () -> Boolean,
private val getUnifiedInboxTitle: () -> String, private val getUnifiedInboxTitle: () -> String,

View File

@ -1,5 +1,6 @@
package com.fsck.k9.mailstore package com.fsck.k9.mailstore
import app.k9mail.legacy.mailstore.DisplayFolderRepository
import app.k9mail.legacy.mailstore.FolderRepository import app.k9mail.legacy.mailstore.FolderRepository
import app.k9mail.legacy.mailstore.MessageListRepository import app.k9mail.legacy.mailstore.MessageListRepository
import app.k9mail.legacy.mailstore.MessageStoreManager import app.k9mail.legacy.mailstore.MessageStoreManager
@ -9,7 +10,18 @@ import com.fsck.k9.message.extractors.MessagePreviewCreator
import org.koin.dsl.module import org.koin.dsl.module
val mailStoreModule = module { val mailStoreModule = module {
single { FolderRepository(messageStoreManager = get(), accountManager = get()) } single {
FolderRepository(
messageStoreManager = get(),
accountManager = get(),
)
}
single {
DisplayFolderRepository(
messageStoreManager = get(),
accountManager = get(),
)
}
single { MessageViewInfoExtractorFactory(get(), get(), get()) } single { MessageViewInfoExtractorFactory(get(), get(), get()) }
single { StorageManager.getInstance(get()) } single { StorageManager.getInstance(get()) }
single { SpecialFolderSelectionStrategy() } single { SpecialFolderSelectionStrategy() }

View File

@ -0,0 +1,103 @@
package app.k9mail.legacy.mailstore
import app.k9mail.core.mail.folder.api.Folder
import app.k9mail.core.mail.folder.api.FolderType
import app.k9mail.legacy.account.Account
import app.k9mail.legacy.account.Account.FolderMode
import app.k9mail.legacy.account.AccountManager
import app.k9mail.legacy.di.DI
import app.k9mail.legacy.folder.DisplayFolder
import app.k9mail.legacy.mailstore.FolderTypeMapper.folderTypeOf
import app.k9mail.legacy.message.controller.MessagingControllerRegistry
import app.k9mail.legacy.message.controller.SimpleMessagingListener
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
class DisplayFolderRepository(
private val messageStoreManager: MessageStoreManager,
private val accountManager: AccountManager,
private val coroutineContext: CoroutineContext = Dispatchers.IO,
) {
private val sortForDisplay =
compareByDescending<DisplayFolder> { it.folder.type == FolderType.INBOX }
.thenByDescending { it.folder.type == FolderType.OUTBOX }
.thenByDescending { it.folder.type != FolderType.REGULAR }
.thenByDescending { it.isInTopGroup }
.thenBy(String.CASE_INSENSITIVE_ORDER) { it.folder.name }
private fun getDisplayFolders(account: Account, displayMode: FolderMode?): List<DisplayFolder> {
val messageStore = messageStoreManager.getMessageStore(account.uuid)
return messageStore.getDisplayFolders(
displayMode = displayMode ?: account.folderDisplayMode,
outboxFolderId = account.outboxFolderId,
) { folder ->
DisplayFolder(
folder = Folder(
id = folder.id,
name = folder.name,
type = folderTypeOf(account, folder.id),
isLocalOnly = folder.isLocalOnly,
),
isInTopGroup = folder.isInTopGroup,
unreadMessageCount = folder.unreadMessageCount,
starredMessageCount = folder.starredMessageCount,
)
}.sortedWith(sortForDisplay)
}
fun getDisplayFoldersFlow(account: Account, displayMode: FolderMode): Flow<List<DisplayFolder>> {
val messagingController = DI.get<MessagingControllerRegistry>()
val messageStore = messageStoreManager.getMessageStore(account.uuid)
return callbackFlow {
send(getDisplayFolders(account, displayMode))
val folderStatusChangedListener = object : SimpleMessagingListener() {
override fun folderStatusChanged(statusChangedAccount: Account, folderId: Long) {
if (statusChangedAccount.uuid == account.uuid) {
trySendBlocking(getDisplayFolders(account, displayMode))
}
}
}
messagingController.addListener(folderStatusChangedListener)
val folderSettingsChangedListener = FolderSettingsChangedListener {
trySendBlocking(getDisplayFolders(account, displayMode))
}
messageStore.addFolderSettingsChangedListener(folderSettingsChangedListener)
awaitClose {
messagingController.removeListener(folderStatusChangedListener)
messageStore.removeFolderSettingsChangedListener(folderSettingsChangedListener)
}
}.buffer(capacity = Channel.CONFLATED)
.distinctUntilChanged()
.flowOn(coroutineContext)
}
fun getDisplayFoldersFlow(accountUuid: String): Flow<List<DisplayFolder>> {
return accountManager.getAccountFlow(accountUuid)
.map { latestAccount ->
AccountContainer(latestAccount, latestAccount.folderDisplayMode)
}
.distinctUntilChanged()
.flatMapLatest { (account, folderDisplayMode) ->
getDisplayFoldersFlow(account, folderDisplayMode)
}
}
}
private data class AccountContainer(
val account: Account,
val folderDisplayMode: FolderMode,
)

View File

@ -2,15 +2,12 @@ package app.k9mail.legacy.mailstore
import app.k9mail.core.mail.folder.api.Folder import app.k9mail.core.mail.folder.api.Folder
import app.k9mail.core.mail.folder.api.FolderDetails import app.k9mail.core.mail.folder.api.FolderDetails
import app.k9mail.core.mail.folder.api.FolderType
import app.k9mail.legacy.account.Account import app.k9mail.legacy.account.Account
import app.k9mail.legacy.account.Account.FolderMode import app.k9mail.legacy.account.Account.FolderMode
import app.k9mail.legacy.account.AccountManager import app.k9mail.legacy.account.AccountManager
import app.k9mail.legacy.di.DI
import app.k9mail.legacy.folder.DisplayFolder
import app.k9mail.legacy.folder.RemoteFolder import app.k9mail.legacy.folder.RemoteFolder
import app.k9mail.legacy.message.controller.MessagingControllerRegistry import app.k9mail.legacy.mailstore.FolderTypeMapper.folderTypeOf
import app.k9mail.legacy.message.controller.SimpleMessagingListener import app.k9mail.legacy.mailstore.RemoteFolderTypeMapper.toFolderType
import com.fsck.k9.mail.FolderClass import com.fsck.k9.mail.FolderClass
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -25,7 +22,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import com.fsck.k9.mail.FolderType as RemoteFolderType
@Suppress("TooManyFunctions") @Suppress("TooManyFunctions")
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
@ -34,74 +30,6 @@ class FolderRepository(
private val accountManager: AccountManager, private val accountManager: AccountManager,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO,
) { ) {
private val sortForDisplay =
compareByDescending<DisplayFolder> { it.folder.type == FolderType.INBOX }
.thenByDescending { it.folder.type == FolderType.OUTBOX }
.thenByDescending { it.folder.type != FolderType.REGULAR }
.thenByDescending { it.isInTopGroup }
.thenBy(String.CASE_INSENSITIVE_ORDER) { it.folder.name }
fun getDisplayFolders(account: Account, displayMode: FolderMode?): List<DisplayFolder> {
val messageStore = messageStoreManager.getMessageStore(account)
return messageStore.getDisplayFolders(
displayMode = displayMode ?: account.folderDisplayMode,
outboxFolderId = account.outboxFolderId,
) { folder ->
DisplayFolder(
folder = Folder(
id = folder.id,
name = folder.name,
type = folderTypeOf(account, folder.id),
isLocalOnly = folder.isLocalOnly,
),
isInTopGroup = folder.isInTopGroup,
unreadMessageCount = folder.unreadMessageCount,
starredMessageCount = folder.starredMessageCount,
)
}.sortedWith(sortForDisplay)
}
fun getDisplayFoldersFlow(account: Account, displayMode: FolderMode): Flow<List<DisplayFolder>> {
val messagingController = DI.get<MessagingControllerRegistry>()
val messageStore = messageStoreManager.getMessageStore(account)
return callbackFlow {
send(getDisplayFolders(account, displayMode))
val folderStatusChangedListener = object : SimpleMessagingListener() {
override fun folderStatusChanged(statusChangedAccount: Account, folderId: Long) {
if (statusChangedAccount.uuid == account.uuid) {
trySendBlocking(getDisplayFolders(account, displayMode))
}
}
}
messagingController.addListener(folderStatusChangedListener)
val folderSettingsChangedListener = FolderSettingsChangedListener {
trySendBlocking(getDisplayFolders(account, displayMode))
}
messageStore.addFolderSettingsChangedListener(folderSettingsChangedListener)
awaitClose {
messagingController.removeListener(folderStatusChangedListener)
messageStore.removeFolderSettingsChangedListener(folderSettingsChangedListener)
}
}.buffer(capacity = Channel.CONFLATED)
.distinctUntilChanged()
.flowOn(ioDispatcher)
}
fun getDisplayFoldersFlow(accountUuid: String): Flow<List<DisplayFolder>> {
return accountManager.getAccountFlow(accountUuid)
.map { latestAccount ->
AccountContainer(latestAccount, latestAccount.folderDisplayMode)
}
.distinctUntilChanged()
.flatMapLatest { (account, folderDisplayMode) ->
getDisplayFoldersFlow(account, folderDisplayMode)
}
}
fun getFolder(account: Account, folderId: Long): Folder? { fun getFolder(account: Account, folderId: Long): Folder? {
val messageStore = messageStoreManager.getMessageStore(account) val messageStore = messageStoreManager.getMessageStore(account)
return messageStore.getFolder(folderId) { folder -> return messageStore.getFolder(folderId) { folder ->
@ -259,28 +187,6 @@ class FolderRepository(
messageStore.setNotificationsEnabled(folderId, enable) messageStore.setNotificationsEnabled(folderId, enable)
} }
private fun folderTypeOf(account: Account, folderId: Long) = when (folderId) {
account.inboxFolderId -> FolderType.INBOX
account.outboxFolderId -> FolderType.OUTBOX
account.sentFolderId -> FolderType.SENT
account.trashFolderId -> FolderType.TRASH
account.draftsFolderId -> FolderType.DRAFTS
account.archiveFolderId -> FolderType.ARCHIVE
account.spamFolderId -> FolderType.SPAM
else -> FolderType.REGULAR
}
private fun RemoteFolderType.toFolderType(): FolderType = when (this) {
RemoteFolderType.REGULAR -> FolderType.REGULAR
RemoteFolderType.INBOX -> FolderType.INBOX
RemoteFolderType.OUTBOX -> FolderType.REGULAR // We currently don't support remote Outbox folders
RemoteFolderType.DRAFTS -> FolderType.DRAFTS
RemoteFolderType.SENT -> FolderType.SENT
RemoteFolderType.TRASH -> FolderType.TRASH
RemoteFolderType.SPAM -> FolderType.SPAM
RemoteFolderType.ARCHIVE -> FolderType.ARCHIVE
}
private fun Account.getFolderPushModeFlow(): Flow<FolderMode> { private fun Account.getFolderPushModeFlow(): Flow<FolderMode> {
return accountManager.getAccountFlow(uuid).map { it.folderPushMode } return accountManager.getAccountFlow(uuid).map { it.folderPushMode }
} }
@ -292,11 +198,6 @@ class FolderRepository(
get() = if (syncClass == FolderClass.INHERITED) displayClass else syncClass get() = if (syncClass == FolderClass.INHERITED) displayClass else syncClass
} }
private data class AccountContainer(
val account: Account,
val folderDisplayMode: FolderMode,
)
data class RemoteFolderDetails( data class RemoteFolderDetails(
val folder: RemoteFolder, val folder: RemoteFolder,
val isInTopGroup: Boolean, val isInTopGroup: Boolean,

View File

@ -0,0 +1,18 @@
package app.k9mail.legacy.mailstore
import app.k9mail.core.mail.folder.api.FolderType
import app.k9mail.legacy.account.Account
object FolderTypeMapper {
fun folderTypeOf(account: Account, folderId: Long) = when (folderId) {
account.inboxFolderId -> FolderType.INBOX
account.outboxFolderId -> FolderType.OUTBOX
account.sentFolderId -> FolderType.SENT
account.trashFolderId -> FolderType.TRASH
account.draftsFolderId -> FolderType.DRAFTS
account.archiveFolderId -> FolderType.ARCHIVE
account.spamFolderId -> FolderType.SPAM
else -> FolderType.REGULAR
}
}

View File

@ -0,0 +1,18 @@
package app.k9mail.legacy.mailstore
import app.k9mail.core.mail.folder.api.FolderType
import com.fsck.k9.mail.FolderType as RemoteFolderType
object RemoteFolderTypeMapper {
fun RemoteFolderType.toFolderType(): FolderType = when (this) {
RemoteFolderType.REGULAR -> FolderType.REGULAR
RemoteFolderType.INBOX -> FolderType.INBOX
RemoteFolderType.OUTBOX -> FolderType.REGULAR // We currently don't support remote Outbox folders
RemoteFolderType.DRAFTS -> FolderType.DRAFTS
RemoteFolderType.SENT -> FolderType.SENT
RemoteFolderType.TRASH -> FolderType.TRASH
RemoteFolderType.SPAM -> FolderType.SPAM
RemoteFolderType.ARCHIVE -> FolderType.ARCHIVE
}
}

View File

@ -7,14 +7,16 @@ import androidx.lifecycle.viewModelScope
import app.k9mail.legacy.account.Account import app.k9mail.legacy.account.Account
import app.k9mail.legacy.account.Account.FolderMode import app.k9mail.legacy.account.Account.FolderMode
import app.k9mail.legacy.folder.DisplayFolder import app.k9mail.legacy.folder.DisplayFolder
import app.k9mail.legacy.mailstore.FolderRepository import app.k9mail.legacy.mailstore.DisplayFolderRepository
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
class ChooseFolderViewModel(private val folderRepository: FolderRepository) : ViewModel() { class ChooseFolderViewModel(
private val folderRepository: DisplayFolderRepository,
) : ViewModel() {
private val inputFlow = MutableSharedFlow<DisplayMode>(replay = 1) private val inputFlow = MutableSharedFlow<DisplayMode>(replay = 1)
private val foldersFlow = inputFlow private val foldersFlow = inputFlow
.flatMapLatest { (account, displayMode) -> .flatMapLatest { (account, displayMode) ->

View File

@ -5,9 +5,11 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData import androidx.lifecycle.asLiveData
import app.k9mail.legacy.account.Account import app.k9mail.legacy.account.Account
import app.k9mail.legacy.folder.DisplayFolder import app.k9mail.legacy.folder.DisplayFolder
import app.k9mail.legacy.mailstore.FolderRepository import app.k9mail.legacy.mailstore.DisplayFolderRepository
class ManageFoldersViewModel(private val folderRepository: FolderRepository) : ViewModel() { class ManageFoldersViewModel(
private val folderRepository: DisplayFolderRepository,
) : ViewModel() {
fun getFolders(account: Account): LiveData<List<DisplayFolder>> { fun getFolders(account: Account): LiveData<List<DisplayFolder>> {
return folderRepository.getDisplayFoldersFlow(account.uuid).asLiveData() return folderRepository.getDisplayFoldersFlow(account.uuid).asLiveData()
} }