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.viewModelScope
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.search.SearchAccount
import app.k9mail.legacy.ui.folder.DisplayUnifiedInbox
import app.k9mail.legacy.ui.folder.FolderList
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -20,7 +22,7 @@ import kotlinx.coroutines.launch
@OptIn(ExperimentalCoroutinesApi::class)
class FoldersViewModel(
private val folderRepository: FolderRepository,
private val folderRepository: DisplayFolderRepository,
private val messageCountsProvider: MessageCountsProvider,
private val isShowUnifiedInbox: () -> Boolean,
private val getUnifiedInboxTitle: () -> String,

View File

@ -1,5 +1,6 @@
package com.fsck.k9.mailstore
import app.k9mail.legacy.mailstore.DisplayFolderRepository
import app.k9mail.legacy.mailstore.FolderRepository
import app.k9mail.legacy.mailstore.MessageListRepository
import app.k9mail.legacy.mailstore.MessageStoreManager
@ -9,7 +10,18 @@ import com.fsck.k9.message.extractors.MessagePreviewCreator
import org.koin.dsl.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 { StorageManager.getInstance(get()) }
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.FolderDetails
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.folder.RemoteFolder
import app.k9mail.legacy.message.controller.MessagingControllerRegistry
import app.k9mail.legacy.message.controller.SimpleMessagingListener
import app.k9mail.legacy.mailstore.FolderTypeMapper.folderTypeOf
import app.k9mail.legacy.mailstore.RemoteFolderTypeMapper.toFolderType
import com.fsck.k9.mail.FolderClass
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
@ -25,7 +22,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import com.fsck.k9.mail.FolderType as RemoteFolderType
@Suppress("TooManyFunctions")
@OptIn(ExperimentalCoroutinesApi::class)
@ -34,74 +30,6 @@ class FolderRepository(
private val accountManager: AccountManager,
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? {
val messageStore = messageStoreManager.getMessageStore(account)
return messageStore.getFolder(folderId) { folder ->
@ -259,28 +187,6 @@ class FolderRepository(
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> {
return accountManager.getAccountFlow(uuid).map { it.folderPushMode }
}
@ -292,11 +198,6 @@ class FolderRepository(
get() = if (syncClass == FolderClass.INHERITED) displayClass else syncClass
}
private data class AccountContainer(
val account: Account,
val folderDisplayMode: FolderMode,
)
data class RemoteFolderDetails(
val folder: RemoteFolder,
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.FolderMode
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.flow.MutableSharedFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.launch
@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 foldersFlow = inputFlow
.flatMapLatest { (account, displayMode) ->

View File

@ -5,9 +5,11 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import app.k9mail.legacy.account.Account
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>> {
return folderRepository.getDisplayFoldersFlow(account.uuid).asLiveData()
}