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

Extract getting DisplayAccounts into use case

This commit is contained in:
Wolf-Martell Montwé 2024-09-10 12:08:21 +02:00
parent 8f42956022
commit 643c0f1b3b
No known key found for this signature in database
GPG Key ID: 6D45B21512ACBF72
4 changed files with 93 additions and 58 deletions

View File

@ -1,5 +1,7 @@
package app.k9mail.feature.navigation.drawer package app.k9mail.feature.navigation.drawer
import app.k9mail.feature.navigation.drawer.domain.DomainContract.UseCase
import app.k9mail.feature.navigation.drawer.domain.usecase.GetDisplayAccounts
import app.k9mail.feature.navigation.drawer.legacy.AccountsViewModel import app.k9mail.feature.navigation.drawer.legacy.AccountsViewModel
import app.k9mail.feature.navigation.drawer.legacy.FoldersViewModel import app.k9mail.feature.navigation.drawer.legacy.FoldersViewModel
import app.k9mail.feature.navigation.drawer.ui.DrawerViewModel import app.k9mail.feature.navigation.drawer.ui.DrawerViewModel
@ -11,16 +13,20 @@ import org.koin.dsl.module
val navigationDrawerModule: Module = module { val navigationDrawerModule: Module = module {
viewModel { DrawerViewModel() } single<UseCase.GetDisplayAccounts> {
GetDisplayAccounts(
viewModel {
AccountsViewModel(
accountManager = get(), accountManager = get(),
messageCountsProvider = get(), messageCountsProvider = get(),
messageListRepository = get(), messageListRepository = get(),
) )
} }
viewModel {
AccountsViewModel(
getDisplayAccounts = get(),
)
}
viewModel { viewModel {
val coreResourceProvider = get<CoreResourceProvider>() val coreResourceProvider = get<CoreResourceProvider>()
@ -32,4 +38,6 @@ val navigationDrawerModule: Module = module {
getUnifiedInboxDetail = { coreResourceProvider.searchUnifiedInboxDetail() }, getUnifiedInboxDetail = { coreResourceProvider.searchUnifiedInboxDetail() },
) )
} }
viewModel { DrawerViewModel() }
} }

View File

@ -0,0 +1,13 @@
package app.k9mail.feature.navigation.drawer.domain
import app.k9mail.feature.navigation.drawer.domain.entity.DisplayAccount
import kotlinx.coroutines.flow.Flow
interface DomainContract {
interface UseCase {
fun interface GetDisplayAccounts {
fun execute(): Flow<List<DisplayAccount>>
}
}
}

View File

@ -0,0 +1,65 @@
package app.k9mail.feature.navigation.drawer.domain.usecase
import app.k9mail.feature.navigation.drawer.domain.DomainContract.UseCase
import app.k9mail.feature.navigation.drawer.domain.entity.DisplayAccount
import app.k9mail.legacy.account.Account
import app.k9mail.legacy.account.AccountManager
import app.k9mail.legacy.mailstore.MessageListChangedListener
import app.k9mail.legacy.mailstore.MessageListRepository
import app.k9mail.legacy.message.controller.MessageCounts
import app.k9mail.legacy.message.controller.MessageCountsProvider
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
class GetDisplayAccounts(
private val accountManager: AccountManager,
private val messageCountsProvider: MessageCountsProvider,
private val messageListRepository: MessageListRepository,
private val coroutineContext: CoroutineContext = Dispatchers.IO,
) : UseCase.GetDisplayAccounts {
@OptIn(ExperimentalCoroutinesApi::class)
override fun execute(): Flow<List<DisplayAccount>> {
return accountManager.getAccountsFlow()
.flatMapLatest { accounts ->
val messageCountsFlows: List<Flow<MessageCounts>> = accounts.map { account ->
getMessageCountsFlow(account)
}
combine(messageCountsFlows) { messageCountsList ->
messageCountsList.mapIndexed { index, messageCounts ->
DisplayAccount(
account = accounts[index],
unreadMessageCount = messageCounts.unread,
starredMessageCount = messageCounts.starred,
)
}
}
}
}
private fun getMessageCountsFlow(account: Account): Flow<MessageCounts> {
return callbackFlow {
send(messageCountsProvider.getMessageCounts(account))
val listener = MessageListChangedListener {
launch {
send(messageCountsProvider.getMessageCounts(account))
}
}
messageListRepository.addListener(account.uuid, listener)
awaitClose {
messageListRepository.removeListener(listener)
}
}.flowOn(coroutineContext)
}
}

View File

@ -3,62 +3,11 @@ package app.k9mail.feature.navigation.drawer.legacy
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData import androidx.lifecycle.asLiveData
import app.k9mail.feature.navigation.drawer.domain.DomainContract.UseCase
import app.k9mail.feature.navigation.drawer.domain.entity.DisplayAccount import app.k9mail.feature.navigation.drawer.domain.entity.DisplayAccount
import app.k9mail.legacy.account.Account
import app.k9mail.legacy.account.AccountManager
import app.k9mail.legacy.mailstore.MessageListChangedListener
import app.k9mail.legacy.mailstore.MessageListRepository
import app.k9mail.legacy.message.controller.MessageCounts
import app.k9mail.legacy.message.controller.MessageCountsProvider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
@OptIn(ExperimentalCoroutinesApi::class)
class AccountsViewModel( class AccountsViewModel(
accountManager: AccountManager, getDisplayAccounts: UseCase.GetDisplayAccounts,
private val messageCountsProvider: MessageCountsProvider,
private val messageListRepository: MessageListRepository,
) : ViewModel() { ) : ViewModel() {
private val displayAccountFlow: Flow<List<DisplayAccount>> = accountManager.getAccountsFlow() val displayAccountsLiveData: LiveData<List<DisplayAccount>> = getDisplayAccounts.execute().asLiveData()
.flatMapLatest { accounts ->
val messageCountsFlows: List<Flow<MessageCounts>> = accounts.map { account ->
getMessageCountsFlow(account)
}
combine(messageCountsFlows) { messageCountsList ->
messageCountsList.mapIndexed { index, messageCounts ->
DisplayAccount(
account = accounts[index],
unreadMessageCount = messageCounts.unread,
starredMessageCount = messageCounts.starred,
)
}
}
}
private fun getMessageCountsFlow(account: Account): Flow<MessageCounts> {
return callbackFlow {
send(messageCountsProvider.getMessageCounts(account))
val listener = MessageListChangedListener {
launch {
send(messageCountsProvider.getMessageCounts(account))
}
}
messageListRepository.addListener(account.uuid, listener)
awaitClose {
messageListRepository.removeListener(listener)
}
}.flowOn(Dispatchers.IO)
}
val displayAccountsLiveData: LiveData<List<DisplayAccount>> = displayAccountFlow.asLiveData()
} }