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.LinkedList
import java.util.UUID import java.util.UUID
import java.util.concurrent.CopyOnWriteArraySet 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 import timber.log.Timber
class Preferences internal constructor( class Preferences internal constructor(
private val context: Context, private val context: Context,
private val storagePersister: StoragePersister, private val storagePersister: StoragePersister,
private val localStoreProvider: LocalStoreProvider, private val localStoreProvider: LocalStoreProvider,
private val accountPreferenceSerializer: AccountPreferenceSerializer private val accountPreferenceSerializer: AccountPreferenceSerializer,
private val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO
) : AccountManager { ) : AccountManager {
private val accountLock = Any() 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 { fun newAccount(): Account {
val accountUuid = UUID.randomUUID().toString() val accountUuid = UUID.randomUUID().toString()
val account = Account(accountUuid) 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
import com.fsck.k9.Account.FolderMode import com.fsck.k9.Account.FolderMode
import com.fsck.k9.AccountsChangeListener
import com.fsck.k9.mail.FolderClass import com.fsck.k9.mail.FolderClass
import com.fsck.k9.preferences.AccountManager import com.fsck.k9.preferences.AccountManager
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
@ -16,6 +15,7 @@ import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.distinctUntilChanged 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.launch import kotlinx.coroutines.launch
import com.fsck.k9.mail.FolderType as RemoteFolderType import com.fsck.k9.mail.FolderType as RemoteFolderType
@ -229,22 +229,7 @@ class FolderRepository(
} }
private fun Account.getFolderPushModeFlow(): Flow<FolderMode> { private fun Account.getFolderPushModeFlow(): Flow<FolderMode> {
val account = this@getFolderPushModeFlow return accountManager.getAccountFlow(uuid).map { it.folderPushMode }
return callbackFlow {
send(account.folderPushMode)
val listener = AccountsChangeListener {
launch {
send(account.folderPushMode)
}
}
accountManager.addOnAccountsChangeListener(listener)
awaitClose {
accountManager.removeOnAccountsChangeListener(listener)
}
}.distinctUntilChanged()
.flowOn(ioDispatcher)
} }
private val RemoteFolderDetails.effectivePushClass: FolderClass 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.Account
import com.fsck.k9.AccountRemovedListener import com.fsck.k9.AccountRemovedListener
import com.fsck.k9.AccountsChangeListener import com.fsck.k9.AccountsChangeListener
import kotlinx.coroutines.flow.Flow
interface AccountManager { interface AccountManager {
fun getAccount(accountUuid: String): Account? fun getAccount(accountUuid: String): Account?
fun getAccountFlow(accountUuid: String): Flow<Account>
fun addAccountRemovedListener(listener: AccountRemovedListener) fun addAccountRemovedListener(listener: AccountRemovedListener)
fun moveAccount(account: Account, newPosition: Int) fun moveAccount(account: Account, newPosition: Int)
fun addOnAccountsChangeListener(accountsChangeListener: AccountsChangeListener) fun addOnAccountsChangeListener(accountsChangeListener: AccountsChangeListener)