[Room member list] Display room member list (#276)

* Implement room member list

* Move timeline initialization back to `TimelinePresenter`.

* Fix crash when the `innerRoom` inside a `RustMatrixRoom` is destroyed but `syncUpdateFlow` is still running.

* Address review comments
This commit is contained in:
Jorge Martin Espinosa
2023-04-04 18:07:57 +02:00
committed by GitHub
parent f0b95d30be
commit d7a6779343
62 changed files with 1159 additions and 157 deletions

View File

@@ -17,6 +17,7 @@
package io.element.android.libraries.matrix.impl.room
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.core.data.tryOrNull
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.MatrixRoom
@@ -24,10 +25,12 @@ import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
import io.element.android.libraries.matrix.impl.timeline.RustMatrixTimeline
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.SlidingSyncRoom
@@ -43,10 +46,32 @@ class RustMatrixRoom(
private val coroutineDispatchers: CoroutineDispatchers,
) : MatrixRoom {
private var loadMembersJob: Job? = null
private var cachedMembers: List<RoomMember> = emptyList()
override suspend fun members(): List<RoomMember> {
return cachedMembers.ifEmpty {
if (loadMembersJob == null) {
loadMembersJob = coroutineScope.launch(coroutineDispatchers.io) {
cachedMembers = tryOrNull {
innerRoom.members().map(RoomMemberMapper::map)
} ?: emptyList()
}
}
loadMembersJob?.join()
loadMembersJob = null
cachedMembers
}
}
override suspend fun memberCount(): Int {
return members().size
}
override fun syncUpdateFlow(): Flow<Long> {
return slidingSyncUpdateFlow
.filter {
it.rooms.contains(innerRoom.id())
it.rooms.contains(roomId.value)
}
.map {
System.currentTimeMillis()
@@ -95,9 +120,6 @@ class RustMatrixRoom(
return innerRoom.avatarUrl()
}
override val members: List<RoomMember>
get() = innerRoom.members().map(RoomMemberMapper::map)
override val isEncrypted: Boolean
get() = innerRoom.isEncrypted()

View File

@@ -87,14 +87,6 @@ class RustMatrixTimeline(
override fun initialize() {
Timber.v("Init timeline for room ${matrixRoom.roomId}")
coroutineScope.launch {
matrixRoom.fetchMembers()
.onFailure {
Timber.e(it, "Fail to fetch members for room ${matrixRoom.roomId}")
}.onSuccess {
Timber.v("Success fetching members for room ${matrixRoom.roomId}")
}
}
coroutineScope.launch {
val result = addListener(innerTimelineListener)
result