Simplify syncing the room list when receiving a push (#4915)

This commit is contained in:
Jorge Martin Espinosa 2025-06-24 10:24:05 +02:00 committed by GitHub
parent 21e04e1fb3
commit fb1d0760b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 7 additions and 62 deletions

View file

@ -8,21 +8,15 @@
package io.element.android.libraries.push.impl.push
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.core.coroutine.parallelMap
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
import io.element.android.services.appnavstate.api.ActiveRoomsHolder
import io.element.android.services.appnavstate.api.AppForegroundStateService
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull
import timber.log.Timber
import javax.inject.Inject
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
class SyncOnNotifiableEvent @Inject constructor(
@ -30,7 +24,6 @@ class SyncOnNotifiableEvent @Inject constructor(
private val featureFlagService: FeatureFlagService,
private val appForegroundStateService: AppForegroundStateService,
private val dispatchers: CoroutineDispatchers,
private val activeRoomsHolder: ActiveRoomsHolder,
) {
suspend operator fun invoke(notifiableEvents: List<NotifiableEvent>) = withContext(dispatchers.io) {
if (!featureFlagService.isFeatureEnabled(FeatureFlags.SyncOnPush)) {
@ -41,6 +34,7 @@ class SyncOnNotifiableEvent @Inject constructor(
val eventsBySession = notifiableEvents.groupBy { it.sessionId }
appForegroundStateService.updateIsSyncingNotificationEvent(true)
Timber.d("Starting opportunistic room list sync | In foreground: ${appForegroundStateService.isInForeground.value}")
for ((sessionId, events) in eventsBySession) {
val client = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: continue
@ -49,38 +43,13 @@ class SyncOnNotifiableEvent @Inject constructor(
client.roomListService.subscribeToVisibleRooms(eventsByRoomId.keys.toList())
if (!appForegroundStateService.isInForeground.value) {
for ((roomId, eventsInRoom) in eventsByRoomId) {
val activeRoom = activeRoomsHolder.getActiveRoomMatching(sessionId, roomId)
val room = activeRoom ?: client.getJoinedRoom(roomId)
if (room != null) {
eventsInRoom.parallelMap { event ->
room.waitsUntilEventIsKnown(event.eventId, timeout = 10.seconds)
}
}
if (room != null && activeRoom == null) {
// Destroy the room we just instantiated to reset its live timeline
room.destroy()
}
}
// Give the sync some time to complete in background
delay(10.seconds)
}
}
} finally {
Timber.d("Finished opportunistic room list sync")
appForegroundStateService.updateIsSyncingNotificationEvent(false)
}
}
private suspend fun JoinedRoom.waitsUntilEventIsKnown(eventId: EventId, timeout: Duration) {
withTimeoutOrNull(timeout) {
liveTimeline.timelineItems.first { timelineItems ->
timelineItems.any { timelineItem ->
when (timelineItem) {
is MatrixTimelineItem.Event -> timelineItem.eventId == eventId
else -> false
}
}
}
}
}
}