diff --git a/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixClientsHolder.kt b/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixClientsHolder.kt index ac0eb60763..3e36e7d692 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixClientsHolder.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixClientsHolder.kt @@ -22,9 +22,9 @@ import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.SingleIn import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.core.SessionId -import io.element.android.libraries.matrix.api.MatrixClientProvider import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock @@ -36,7 +36,7 @@ private const val SAVE_INSTANCE_KEY = "io.element.android.x.di.MatrixClientsHold @SingleIn(AppScope::class) @ContributesBinding(AppScope::class) -class MatrixClientsHolder @Inject constructor(private val authenticationService: MatrixAuthenticationService): MatrixClientProvider { +class MatrixClientsHolder @Inject constructor(private val authenticationService: MatrixAuthenticationService) : MatrixClientProvider { private val sessionIdsToMatrixClient = ConcurrentHashMap() private val restoreMutex = Mutex() @@ -49,15 +49,13 @@ class MatrixClientsHolder @Inject constructor(private val authenticationService: sessionIdsToMatrixClient.remove(sessionId) } - fun isEmpty(): Boolean = sessionIdsToMatrixClient.isEmpty() - fun getOrNull(sessionId: SessionId): MatrixClient? { return sessionIdsToMatrixClient[sessionId] } override suspend fun getOrRestore(sessionId: SessionId): Result { return restoreMutex.withLock { - when (val matrixClient = sessionIdsToMatrixClient[sessionId]) { + when (val matrixClient = getOrNull(sessionId)) { null -> restore(sessionId) else -> Result.success(matrixClient) } @@ -97,5 +95,4 @@ class MatrixClientsHolder @Inject constructor(private val authenticationService: Timber.e("Fail to restore session") } } - } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/root/RootNavState.kt b/appnav/src/main/kotlin/io/element/android/appnav/root/RootNavState.kt index 55edf96aee..ed3ac15972 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/root/RootNavState.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/root/RootNavState.kt @@ -16,7 +16,17 @@ package io.element.android.appnav.root +/** + * [RootNavState] produced by [RootNavStateFlowFactory]. + */ data class RootNavState( + /** + * This value is incremented when a clear cache is done. + * Can be useful to track to force ui state to re-render + */ val cacheIndex: Int, + /** + * true if we are currently loggedIn. + */ val isLoggedIn: Boolean ) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/root/RootNavStateFlowFactory.kt b/appnav/src/main/kotlin/io/element/android/appnav/root/RootNavStateFlowFactory.kt index 84f50a835e..0e8d93b0c9 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/root/RootNavStateFlowFactory.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/root/RootNavStateFlowFactory.kt @@ -31,6 +31,10 @@ import javax.inject.Inject private const val SAVE_INSTANCE_KEY = "io.element.android.x.RootNavStateFlowFactory.SAVE_INSTANCE_KEY" +/** + * This class is responsible for creating a flow of [RootNavState]. + * It gathers data from multiple datasource and creates a unique one. + */ class RootNavStateFlowFactory @Inject constructor( private val authenticationService: MatrixAuthenticationService, private val cacheService: CacheService, @@ -41,11 +45,24 @@ class RootNavStateFlowFactory @Inject constructor( private var currentCacheIndex = 0 fun create(savedStateMap: SavedStateMap?): Flow { - /** - * A flow of integer, where each time a clear cache is done, we have a new incremented value. - */ + return combine( + cacheIndexFlow(savedStateMap), + isUserLoggedInFlow(), + ) { cacheIndex, isLoggedIn -> + RootNavState(cacheIndex = cacheIndex, isLoggedIn = isLoggedIn) + } + } + + fun saveIntoSavedState(stateMap: MutableSavedStateMap) { + stateMap[SAVE_INSTANCE_KEY] = currentCacheIndex + } + + /** + * @return a flow of integer, where each time a clear cache is done, we have a new incremented value. + */ + private fun cacheIndexFlow(savedStateMap: SavedStateMap?): Flow { val initialCacheIndex = savedStateMap.getCacheIndexOrDefault() - val cacheIndexFlow = cacheService.clearedCacheEventFlow + return cacheService.clearedCacheEventFlow .onEach { sessionId -> matrixClientsHolder.remove(sessionId) } @@ -53,17 +70,6 @@ class RootNavStateFlowFactory @Inject constructor( .onEach { cacheIndex -> currentCacheIndex = cacheIndex } - - return combine( - cacheIndexFlow, - isUserLoggedInFlow(), - ) { navId, isLoggedIn -> - RootNavState(navId, isLoggedIn) - } - } - - fun saveIntoSavedState(stateMap: MutableSavedStateMap) { - stateMap[SAVE_INSTANCE_KEY] = currentCacheIndex } private fun isUserLoggedInFlow(): Flow { @@ -76,6 +82,9 @@ class RootNavStateFlowFactory @Inject constructor( .distinctUntilChanged() } + /** + * @return a flow of integer that increments the value by one each time a new element is emitted upstream. + */ private fun Flow.toIndexFlow(initialValue: Int): Flow = flow { var index = initialValue emit(initialValue)