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:
parent
46547c98fc
commit
bdf4c1764d
@ -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,
|
||||
|
@ -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() }
|
||||
|
@ -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,
|
||||
)
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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) ->
|
||||
|
@ -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()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user