Load JoinedRoom in home screen, pass it to the room flow (#5817)

* Load `JoinedRoom` in `HomeFlowNode.navigateToRoom`, then pass it to the next navigation nodes

* Add delayed loading indicator for cases when loading the room takes too long

* Avoid an extra FFI call in `RustRoomFactory`.

Use `RoomInfo.membership` instead.

Also use `computation` dispatcher, since it should reduce the delay when switching contexts.

* Remove the dispatcher usage when loading the room in `HomeFlowNode`, we immediately call a method that changes the dispatcher used

* Make sure only a single room is opened at a time
This commit is contained in:
Jorge Martin Espinosa 2025-12-02 16:22:55 +01:00 committed by GitHub
parent eedaeb6b35
commit 2e2d68ba83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 180 additions and 53 deletions

View file

@ -36,6 +36,7 @@ import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.DateDividerMode
import org.matrix.rustcomponents.sdk.Membership
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.RoomInfo
import org.matrix.rustcomponents.sdk.TimelineConfiguration
import org.matrix.rustcomponents.sdk.TimelineFilter
import org.matrix.rustcomponents.sdk.TimelineFocus
@ -60,7 +61,7 @@ class RustRoomFactory(
private val roomInfoMapper: RoomInfoMapper,
private val analyticsService: AnalyticsService,
) {
private val dispatcher = dispatchers.io.limitedParallelism(1)
private val dispatcher = dispatchers.computation.limitedParallelism(1)
private val mutex = Mutex()
private val isDestroyed: AtomicBoolean = AtomicBoolean(false)
@ -86,24 +87,21 @@ class RustRoomFactory(
return@withContext null
}
val room = awaitRoomInRoomList(roomId) ?: return@withContext null
getBaseRoom(room)
getBaseRoom(sdkRoom = room, roomInfo = room.roomInfo())
}
}
private suspend fun getBaseRoom(sdkRoom: Room): RustBaseRoom {
val initialRoomInfo = sdkRoom.roomInfo()
return RustBaseRoom(
sessionId = sessionId,
deviceId = deviceId,
innerRoom = sdkRoom,
coroutineDispatchers = dispatchers,
roomSyncSubscriber = roomSyncSubscriber,
roomMembershipObserver = roomMembershipObserver,
roomInfoMapper = roomInfoMapper,
initialRoomInfo = roomInfoMapper.map(initialRoomInfo),
sessionCoroutineScope = sessionCoroutineScope,
)
}
private fun getBaseRoom(sdkRoom: Room, roomInfo: RoomInfo) = RustBaseRoom(
sessionId = sessionId,
deviceId = deviceId,
innerRoom = sdkRoom,
coroutineDispatchers = dispatchers,
roomSyncSubscriber = roomSyncSubscriber,
roomMembershipObserver = roomMembershipObserver,
roomInfoMapper = roomInfoMapper,
initialRoomInfo = roomInfoMapper.map(roomInfo),
sessionCoroutineScope = sessionCoroutineScope,
)
suspend fun getJoinedRoomOrPreview(roomId: RoomId, serverNames: List<String>): GetRoomResult? = withContext(dispatcher) {
mutex.withLock {
@ -113,10 +111,11 @@ class RustRoomFactory(
}
val sdkRoom = awaitRoomInRoomList(roomId) ?: return@withLock null
val roomInfo = sdkRoom.roomInfo()
val parentTransaction = analyticsService.getLongRunningTransaction(AnalyticsLongRunningTransaction.OpenRoom)
if (sdkRoom.membership() == Membership.JOINED) {
if (roomInfo.membership == Membership.JOINED) {
analyticsService.recordTransaction(
name = "Get joined room",
operation = "RustRoomFactory.getJoinedRoomOrPreview",
@ -140,10 +139,9 @@ class RustRoomFactory(
)
}
val baseRoom = transaction.recordChildTransaction(operation = "getBaseRoom", description = "Get room from SDK") { getBaseRoom(sdkRoom) }
GetRoomResult.Joined(
JoinedRustRoom(
baseRoom = baseRoom,
baseRoom = getBaseRoom(sdkRoom, roomInfo),
notificationSettingsService = notificationSettingsService,
roomContentForwarder = roomContentForwarder,
liveInnerTimeline = timeline,
@ -169,7 +167,7 @@ class RustRoomFactory(
GetRoomResult.NotJoined(
NotJoinedRustRoom(
sessionId = sessionId,
localRoom = getBaseRoom(sdkRoom),
localRoom = getBaseRoom(sdkRoom, roomInfo),
previewInfo = RoomPreviewInfoMapper.map(preview.info()),
)
)