mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 12:07:28 +00:00
Dismiss the swipe avatar announcement in the app coroutine scope
HomeView sends HomeEvent.DismissSwipeAvatarAnnouncement right before switching account. Switching account replaces the LoggedInFlow root node, which destroys HomePresenter and cancels its composition coroutine scope, so the dismissal could be cancelled before the announcement status was stored. Use the app coroutine scope instead, which survives the account switch. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+8
-3
@@ -28,6 +28,7 @@ import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState
|
||||
import io.element.android.libraries.di.annotations.AppCoroutineScope
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||
import io.element.android.libraries.indicator.api.IndicatorService
|
||||
@@ -35,6 +36,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.sessionstorage.api.SessionStore
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@@ -56,13 +58,15 @@ class HomePresenter(
|
||||
private val sessionStore: SessionStore,
|
||||
private val announcementService: AnnouncementService,
|
||||
private val featureFlagService: FeatureFlagService,
|
||||
@AppCoroutineScope
|
||||
private val appCoroutineScope: CoroutineScope,
|
||||
) : Presenter<HomeState> {
|
||||
private val currentUserWithNeighborsBuilder = CurrentUserWithNeighborsBuilder()
|
||||
|
||||
@OptIn(FlowPreview::class, ExperimentalCoroutinesApi::class)
|
||||
@Composable
|
||||
override fun present(): HomeState {
|
||||
val coroutineState = rememberCoroutineScope()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val matrixUser by client.userProfile.collectAsState()
|
||||
|
||||
val totalUnreadCount by produceState(client.totalUnreadCount().getOrDefault(0).toInt()) {
|
||||
@@ -126,10 +130,11 @@ class HomePresenter(
|
||||
is HomeEvent.SelectHomeNavigationBarItem -> {
|
||||
currentHomeNavigationBarItemOrdinal = event.item.ordinal
|
||||
}
|
||||
HomeEvent.DismissSwipeAvatarAnnouncement -> coroutineState.launch {
|
||||
// The user is switching account, which destroys this presenter, so use the app scope to not be cancelled.
|
||||
HomeEvent.DismissSwipeAvatarAnnouncement -> appCoroutineScope.launch {
|
||||
announcementService.onAnnouncementDismissed(Announcement.SwipeAvatarToSwitchAccount)
|
||||
}
|
||||
HomeEvent.DismissMultiAccountAnnouncement -> coroutineState.launch {
|
||||
HomeEvent.DismissMultiAccountAnnouncement -> coroutineScope.launch {
|
||||
announcementService.onAnnouncementDismissed(Announcement.MultiAccount)
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -39,8 +39,10 @@ import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import io.element.android.tests.testutils.lambda.value
|
||||
import io.element.android.tests.testutils.test
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.advanceTimeBy
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
@@ -292,6 +294,7 @@ class HomePresenterTest {
|
||||
announcementService = FakeAnnouncementService(
|
||||
onAnnouncementDismissedResult = onAnnouncementDismissedResult,
|
||||
),
|
||||
appCoroutineScope = this,
|
||||
)
|
||||
presenter.test {
|
||||
val state = expectMostRecentItem()
|
||||
@@ -313,7 +316,7 @@ class HomePresenterTest {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun createHomePresenter(
|
||||
internal fun TestScope.createHomePresenter(
|
||||
client: MatrixClient = FakeMatrixClient(),
|
||||
syncService: SyncService = FakeSyncService(),
|
||||
snackbarDispatcher: SnackbarDispatcher = SnackbarDispatcher(),
|
||||
@@ -323,6 +326,7 @@ internal fun createHomePresenter(
|
||||
sessionStore: SessionStore = InMemorySessionStore(),
|
||||
announcementService: AnnouncementService = FakeAnnouncementService(),
|
||||
featureFlagService: FeatureFlagService = FakeFeatureFlagService(),
|
||||
appCoroutineScope: CoroutineScope = backgroundScope,
|
||||
) = HomePresenter(
|
||||
client = client,
|
||||
syncService = syncService,
|
||||
@@ -334,4 +338,5 @@ internal fun createHomePresenter(
|
||||
sessionStore = sessionStore,
|
||||
announcementService = announcementService,
|
||||
featureFlagService = featureFlagService,
|
||||
appCoroutineScope = appCoroutineScope,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user