Use the right live timeline instance in RustRoomFactory (#4745)

This commit is contained in:
Jorge Martin Espinosa
2025-05-20 17:33:25 +02:00
committed by GitHub
parent 1a6596a89a
commit 01abba6205

View File

@@ -9,7 +9,6 @@ package io.element.android.libraries.matrix.impl.room
import io.element.android.appconfig.TimelineConfig
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.core.data.tryOrNull
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.core.RoomId
@@ -21,6 +20,7 @@ import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.roomlist.awaitLoaded
import io.element.android.libraries.matrix.impl.room.preview.RoomPreviewInfoMapper
import io.element.android.libraries.matrix.impl.roomlist.fullRoomWithTimeline
import io.element.android.libraries.matrix.impl.roomlist.roomOrNull
import io.element.android.services.toolbox.api.systemclock.SystemClock
import kotlinx.coroutines.CoroutineScope
@@ -30,10 +30,10 @@ import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.Client
import org.matrix.rustcomponents.sdk.Membership
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.RoomListItem
import timber.log.Timber
import java.util.concurrent.atomic.AtomicBoolean
import org.matrix.rustcomponents.sdk.Room as SdkRoom
import org.matrix.rustcomponents.sdk.RoomListService as InnerRoomListService
class RustRoomFactory(
@@ -56,11 +56,6 @@ class RustRoomFactory(
private val mutex = Mutex()
private val isDestroyed: AtomicBoolean = AtomicBoolean(false)
private data class RustRoomReferences(
val roomListItem: RoomListItem,
val room: SdkRoom,
)
private val roomInfoMapper = RoomInfoMapper()
private val eventFilters = TimelineConfig.excludedEvents
@@ -84,17 +79,22 @@ class RustRoomFactory(
Timber.d("Room factory is destroyed, returning null for $roomId")
return@withContext null
}
val roomReferences = awaitRoomReferences(roomId) ?: return@withContext null
getBaseRoom(roomReferences)
val roomListItem = awaitRoomListItem(roomId) ?: return@withContext null
getBaseRoom(roomListItem)
}
}
private suspend fun getBaseRoom(roomReferences: RustRoomReferences): RustBaseRoom? {
val initialRoomInfo = roomReferences.room.roomInfo()
private suspend fun getBaseRoom(roomListItem: RoomListItem): RustBaseRoom? {
val sdkRoom = innerClient.getRoom(roomListItem.id()) ?: return null
return getBaseRoom(sdkRoom)
}
private suspend fun getBaseRoom(sdkRoom: Room): RustBaseRoom {
val initialRoomInfo = sdkRoom.roomInfo()
return RustBaseRoom(
sessionId = sessionId,
deviceId = deviceId,
innerRoom = roomReferences.room,
innerRoom = sdkRoom,
coroutineDispatchers = dispatchers,
roomSyncSubscriber = roomSyncSubscriber,
roomMembershipObserver = roomMembershipObserver,
@@ -110,22 +110,18 @@ class RustRoomFactory(
Timber.d("Room factory is destroyed, returning null for $roomId")
return@withContext null
}
val roomReferences = awaitRoomReferences(roomId) ?: return@withContext null
if (roomReferences.room.membership() == Membership.JOINED) {
val baseRoom = getBaseRoom(roomReferences) ?: return@withContext null
val roomListItem = awaitRoomListItem(roomId) ?: return@withContext null
if (roomListItem.membership() == Membership.JOINED) {
// Init the live timeline in the SDK from the RoomListItem
if (!roomReferences.roomListItem.isTimelineInitialized()) {
roomReferences.roomListItem.initTimeline(eventFilters, "LIVE")
}
val sdkRoom = roomListItem.fullRoomWithTimeline(eventFilters)
GetRoomResult.Joined(
JoinedRustRoom(
baseRoom = baseRoom,
baseRoom = getBaseRoom(sdkRoom),
notificationSettingsService = notificationSettingsService,
roomContentForwarder = roomContentForwarder,
liveInnerTimeline = roomReferences.room.timeline(),
liveInnerTimeline = sdkRoom.timeline(),
coroutineDispatchers = dispatchers,
systemClock = systemClock,
featureFlagService = featureFlagService,
@@ -133,7 +129,7 @@ class RustRoomFactory(
)
} else {
val preview = try {
roomReferences.roomListItem.previewRoom(via = emptyList())
roomListItem.previewRoom(via = emptyList())
} catch (e: Exception) {
Timber.e(e, "Failed to get room preview for $roomId")
return@withContext null
@@ -142,7 +138,7 @@ class RustRoomFactory(
GetRoomResult.NotJoined(
NotJoinedRustRoom(
sessionId = sessionId,
localRoom = getBaseRoom(roomReferences),
localRoom = getBaseRoom(roomListItem),
previewInfo = RoomPreviewInfoMapper.map(preview.info()),
)
)
@@ -150,36 +146,23 @@ class RustRoomFactory(
}
}
private fun getRoomReferences(roomId: RoomId): RustRoomReferences? {
val roomListItem = innerRoomListService.roomOrNull(roomId.value)
/**
* Get the Rust room list item for a room, retrying after the room list is loaded if necessary.
*/
private suspend fun awaitRoomListItem(roomId: RoomId): RoomListItem? {
var roomListItem = innerRoomListService.roomOrNull(roomId.value)
if (roomListItem == null) {
// ... otherwise, lets wait for the SS to load all rooms and check again.
roomListService.allRooms.awaitLoaded()
roomListItem = innerRoomListService.roomOrNull(roomId.value)
}
if (roomListItem == null) {
Timber.d("Room not found for $roomId")
return null
}
val room = tryOrNull {
innerClient.getRoom(roomId.value)
} ?: error("Failed to get room for room id: $roomId")
Timber.d("Got room for $roomId")
return RustRoomReferences(
roomListItem = roomListItem,
room = room,
)
}
/**
* Get the Rust room references for a room, retrying after the room list is loaded if necessary.
*/
private suspend fun awaitRoomReferences(roomId: RoomId): RustRoomReferences? {
var roomReferences = getRoomReferences(roomId)
if (roomReferences == null) {
// ... otherwise, lets wait for the SS to load all rooms and check again.
roomListService.allRooms.awaitLoaded()
roomReferences = getRoomReferences(roomId)
}
return roomReferences
return roomListItem
}
}