Merge pull request #5360 from k9mail/account_flow
Add AccountManager.getAccountFlow()
This commit is contained in:
commit
145eba5e2e
3 changed files with 43 additions and 18 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue