When clearing cache, ensure that SessionPreferencesStore is removed from the cache.

Fixes blank screen after clear cache.
Also cleanup the codebase.
This commit is contained in:
Benoit Marty 2024-07-08 16:48:40 +02:00
parent 8dae7f2f69
commit a83c5d4bd7
4 changed files with 12 additions and 11 deletions

View file

@ -42,6 +42,7 @@ dependencies {
implementation(projects.libraries.architecture) implementation(projects.libraries.architecture)
implementation(projects.libraries.deeplink) implementation(projects.libraries.deeplink)
implementation(projects.libraries.matrix.api) implementation(projects.libraries.matrix.api)
implementation(projects.libraries.preferences.api)
implementation(projects.libraries.push.api) implementation(projects.libraries.push.api)
implementation(projects.libraries.pushproviders.api) implementation(projects.libraries.pushproviders.api)
implementation(projects.libraries.designsystem) implementation(projects.libraries.designsystem)

View file

@ -23,6 +23,7 @@ import io.element.android.features.login.api.LoginUserStory
import io.element.android.features.preferences.api.CacheService import io.element.android.features.preferences.api.CacheService
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.ui.media.ImageLoaderHolder import io.element.android.libraries.matrix.ui.media.ImageLoaderHolder
import io.element.android.libraries.preferences.api.store.SessionPreferencesStoreFactory
import io.element.android.libraries.sessionstorage.api.LoggedInState import io.element.android.libraries.sessionstorage.api.LoggedInState
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
@ -42,6 +43,7 @@ class RootNavStateFlowFactory @Inject constructor(
private val matrixClientsHolder: MatrixClientsHolder, private val matrixClientsHolder: MatrixClientsHolder,
private val imageLoaderHolder: ImageLoaderHolder, private val imageLoaderHolder: ImageLoaderHolder,
private val loginUserStory: LoginUserStory, private val loginUserStory: LoginUserStory,
private val sessionPreferencesStoreFactory: SessionPreferencesStoreFactory,
) { ) {
private var currentCacheIndex = 0 private var currentCacheIndex = 0
@ -73,6 +75,8 @@ class RootNavStateFlowFactory @Inject constructor(
matrixClientsHolder.remove(sessionId) matrixClientsHolder.remove(sessionId)
// Ensure image loader will be recreated with the new MatrixClient // Ensure image loader will be recreated with the new MatrixClient
imageLoaderHolder.remove(sessionId) imageLoaderHolder.remove(sessionId)
// Also remove cached value for SessionPreferencesStore
sessionPreferencesStoreFactory.remove(sessionId)
} }
.toIndexFlow(initialCacheIndex) .toIndexFlow(initialCacheIndex)
.onEach { cacheIndex -> .onEach { cacheIndex ->

View file

@ -45,7 +45,7 @@ import io.element.android.libraries.di.SessionScope
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -93,11 +93,9 @@ class FtueFlowNode @AssistedInject constructor(
}) })
analyticsService.didAskUserConsent() analyticsService.didAskUserConsent()
.drop(1) // We only care about consent passing from not asked to asked state .distinctUntilChanged()
.onEach { didAskUserConsent -> .onEach {
if (didAskUserConsent) { lifecycleScope.launch { moveToNextStep() }
lifecycleScope.launch { moveToNextStep() }
}
} }
.launchIn(lifecycleScope) .launchIn(lifecycleScope)
} }

View file

@ -35,6 +35,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -70,6 +71,7 @@ class DefaultFtueService @Inject constructor(
.launchIn(sessionCoroutineScope) .launchIn(sessionCoroutineScope)
analyticsService.didAskUserConsent() analyticsService.didAskUserConsent()
.distinctUntilChanged()
.onEach { updateState() } .onEach { updateState() }
.launchIn(sessionCoroutineScope) .launchIn(sessionCoroutineScope)
} }
@ -120,10 +122,7 @@ class DefaultFtueService @Inject constructor(
emit(SessionVerifiedStatus.NotVerified) emit(SessionVerifiedStatus.NotVerified)
} }
.first() .first()
// For some obscure reason we need to call this *before* we check the `readyVerifiedSessionStatus`, otherwise there's a deadlock return readyVerifiedSessionStatus == SessionVerifiedStatus.NotVerified && !canSkipVerification()
// It seems like a DataStore bug
val skipVerification = canSkipVerification()
return readyVerifiedSessionStatus == SessionVerifiedStatus.NotVerified && !skipVerification
} }
private suspend fun canSkipVerification(): Boolean { private suspend fun canSkipVerification(): Boolean {
@ -131,7 +130,6 @@ class DefaultFtueService @Inject constructor(
} }
private suspend fun needsAnalyticsOptIn(): Boolean { private suspend fun needsAnalyticsOptIn(): Boolean {
// We need this function to not be suspend, so we need to load the value through runBlocking
return analyticsService.didAskUserConsent().first().not() return analyticsService.didAskUserConsent().first().not()
} }