Merge pull request #5360 from k9mail/account_flow

Add AccountManager.getAccountFlow()
This commit is contained in:
cketti 2021-06-23 12:59:59 +02:00 committed by GitHub
commit 145eba5e2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 18 deletions

View file

@ -13,13 +13,24 @@ import java.util.HashMap
import java.util.LinkedList
import java.util.UUID
import java.util.concurrent.CopyOnWriteArraySet
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.sendBlocking
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flowOn
import timber.log.Timber
class Preferences internal constructor(
private val context: Context,
private val storagePersister: StoragePersister,
private val localStoreProvider: LocalStoreProvider,
private val accountPreferenceSerializer: AccountPreferenceSerializer
private val accountPreferenceSerializer: AccountPreferenceSerializer,
private val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO
) : AccountManager {
private val accountLock = Any()
@ -107,6 +118,33 @@ class Preferences internal constructor(
}
}
@OptIn(ExperimentalCoroutinesApi::class)
override fun getAccountFlow(accountUuid: String): Flow<Account> {
return callbackFlow<Account> {
val initialAccount = getAccount(accountUuid) ?: return@callbackFlow
send(initialAccount)
val listener = AccountsChangeListener {
val account = getAccount(accountUuid)
if (account != null) {
try {
sendBlocking(account)
} catch (e: Exception) {
Timber.w(e, "Error while trying to send to channel")
}
} else {
channel.close()
}
}
addOnAccountsChangeListener(listener)
awaitClose {
removeOnAccountsChangeListener(listener)
}
}.buffer(capacity = Channel.CONFLATED)
.flowOn(backgroundDispatcher)
}
fun newAccount(): Account {
val accountUuid = UUID.randomUUID().toString()
val account = Account(accountUuid)

View file

@ -2,7 +2,6 @@ package com.fsck.k9.mailstore
import com.fsck.k9.Account
import com.fsck.k9.Account.FolderMode
import com.fsck.k9.AccountsChangeListener
import com.fsck.k9.mail.FolderClass
import com.fsck.k9.preferences.AccountManager
import kotlinx.coroutines.CoroutineDispatcher
@ -16,6 +15,7 @@ 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
import kotlinx.coroutines.launch
import com.fsck.k9.mail.FolderType as RemoteFolderType
@ -229,22 +229,7 @@ class FolderRepository(
}
private fun Account.getFolderPushModeFlow(): Flow<FolderMode> {
val account = this@getFolderPushModeFlow
return callbackFlow {
send(account.folderPushMode)
val listener = AccountsChangeListener {
launch {
send(account.folderPushMode)
}
}
accountManager.addOnAccountsChangeListener(listener)
awaitClose {
accountManager.removeOnAccountsChangeListener(listener)
}
}.distinctUntilChanged()
.flowOn(ioDispatcher)
return accountManager.getAccountFlow(uuid).map { it.folderPushMode }
}
private val RemoteFolderDetails.effectivePushClass: FolderClass

View file

@ -3,9 +3,11 @@ package com.fsck.k9.preferences
import com.fsck.k9.Account
import com.fsck.k9.AccountRemovedListener
import com.fsck.k9.AccountsChangeListener
import kotlinx.coroutines.flow.Flow
interface AccountManager {
fun getAccount(accountUuid: String): Account?
fun getAccountFlow(accountUuid: String): Flow<Account>
fun addAccountRemovedListener(listener: AccountRemovedListener)
fun moveAccount(account: Account, newPosition: Int)
fun addOnAccountsChangeListener(accountsChangeListener: AccountsChangeListener)