Merge pull request #353 from vector-im/feature/fga/some_room_related_fixes
Feature/fga/some room related fixes
This commit is contained in:
commit
ca6a47edcd
67 changed files with 674 additions and 392 deletions
|
|
@ -198,7 +198,7 @@ class RustMatrixClient constructor(
|
|||
val slidingSyncRoom = slidingSync.getRoom(roomId.value) ?: return null
|
||||
val fullRoom = slidingSyncRoom.fullRoom() ?: return null
|
||||
return RustMatrixRoom(
|
||||
currentUserId = sessionId,
|
||||
sessionId = sessionId,
|
||||
slidingSyncUpdateFlow = slidingSyncObserverProxy.updateSummaryFlow,
|
||||
slidingSyncRoom = slidingSyncRoom,
|
||||
innerRoom = fullRoom,
|
||||
|
|
@ -212,6 +212,18 @@ class RustMatrixClient constructor(
|
|||
return roomId?.let { getRoom(it) }
|
||||
}
|
||||
|
||||
override suspend fun ignoreUser(userId: UserId): Result<Unit> = withContext(dispatchers.io) {
|
||||
runCatching {
|
||||
client.ignoreUser(userId.value)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun unignoreUser(userId: UserId): Result<Unit> = withContext(dispatchers.io) {
|
||||
runCatching {
|
||||
client.unignoreUser(userId.value)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun createRoom(createRoomParams: CreateRoomParameters): Result<RoomId> = withContext(dispatchers.io) {
|
||||
runCatching {
|
||||
val rustParams = RustCreateRoomParameters(
|
||||
|
|
|
|||
|
|
@ -17,17 +17,19 @@
|
|||
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.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
|
||||
import io.element.android.libraries.matrix.api.room.roomMembers
|
||||
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.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
|
|
@ -38,10 +40,9 @@ import org.matrix.rustcomponents.sdk.SlidingSyncRoom
|
|||
import org.matrix.rustcomponents.sdk.UpdateSummary
|
||||
import org.matrix.rustcomponents.sdk.genTransactionId
|
||||
import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown
|
||||
import org.matrix.rustcomponents.sdk.RoomMember as RustRoomMember
|
||||
|
||||
class RustMatrixRoom(
|
||||
private val currentUserId: UserId,
|
||||
override val sessionId: SessionId,
|
||||
private val slidingSyncUpdateFlow: Flow<UpdateSummary>,
|
||||
private val slidingSyncRoom: SlidingSyncRoom,
|
||||
private val innerRoom: Room,
|
||||
|
|
@ -49,6 +50,11 @@ class RustMatrixRoom(
|
|||
private val coroutineDispatchers: CoroutineDispatchers,
|
||||
) : MatrixRoom {
|
||||
|
||||
override val membersStateFlow: StateFlow<MatrixRoomMembersState>
|
||||
get() = _membersStateFlow
|
||||
|
||||
private var _membersStateFlow = MutableStateFlow<MatrixRoomMembersState>(MatrixRoomMembersState.Unknown)
|
||||
|
||||
private val timeline by lazy {
|
||||
RustMatrixTimeline(
|
||||
matrixRoom = this,
|
||||
|
|
@ -59,33 +65,6 @@ class RustMatrixRoom(
|
|||
)
|
||||
}
|
||||
|
||||
private var membersFlow = MutableStateFlow<List<RoomMember>>(emptyList())
|
||||
|
||||
override fun members(): Flow<List<RoomMember>> {
|
||||
return membersFlow.onSubscription { updateMembers() }
|
||||
}
|
||||
|
||||
override fun updateMembers() {
|
||||
val updatedMembers = tryOrNull {
|
||||
innerRoom.members().map(RoomMemberMapper::map)
|
||||
} ?: emptyList()
|
||||
membersFlow.tryEmit(updatedMembers)
|
||||
}
|
||||
|
||||
override fun getMember(userId: UserId): Flow<RoomMember?> {
|
||||
return membersFlow.map { members -> members.find { it.userId == userId } }
|
||||
}
|
||||
|
||||
override fun getDmMember(): Flow<RoomMember?> {
|
||||
return membersFlow.map { members ->
|
||||
if (members.size == 2 && isDirect && isEncrypted) {
|
||||
members.find { it.userId != currentUserId }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun syncUpdateFlow(): Flow<Long> {
|
||||
return slidingSyncUpdateFlow
|
||||
.filter {
|
||||
|
|
@ -148,9 +127,16 @@ class RustMatrixRoom(
|
|||
override val isDirect: Boolean
|
||||
get() = innerRoom.isDirect()
|
||||
|
||||
override suspend fun fetchMembers(): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
override suspend fun updateMembers(): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
val currentState = _membersStateFlow.value
|
||||
val currentMembers = currentState.roomMembers()
|
||||
_membersStateFlow.value = MatrixRoomMembersState.Pending(prevRoomMembers = currentMembers)
|
||||
runCatching {
|
||||
innerRoom.fetchMembers()
|
||||
innerRoom.members().map(RoomMemberMapper::map)
|
||||
}.map {
|
||||
_membersStateFlow.value = MatrixRoomMembersState.Ready(it)
|
||||
}.onFailure {
|
||||
_membersStateFlow.value = MatrixRoomMembersState.Error(prevRoomMembers = currentMembers, failure = it)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -206,31 +192,15 @@ class RustMatrixRoom(
|
|||
}
|
||||
|
||||
override suspend fun acceptInvitation(): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
kotlin.runCatching {
|
||||
runCatching {
|
||||
innerRoom.acceptInvitation()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun rejectInvitation(): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
kotlin.runCatching {
|
||||
runCatching {
|
||||
innerRoom.rejectInvitation()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override suspend fun ignoreUser(userId: UserId): Result<Unit> {
|
||||
return runCatching {
|
||||
getRustMember(userId)?.ignore() ?: error("No member with userId $userId exists in room $roomId")
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun unignoreUser(userId: UserId): Result<Unit> {
|
||||
return runCatching {
|
||||
getRustMember(userId)?.unignore() ?: error("No member with userId $userId exists in room $roomId")
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRustMember(userId: UserId): RustRoomMember? {
|
||||
return innerRoom.members().find { it.userId() == userId.value }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import org.matrix.rustcomponents.sdk.SlidingSyncRoom
|
|||
import org.matrix.rustcomponents.sdk.TimelineItem
|
||||
import org.matrix.rustcomponents.sdk.TimelineListener
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class RustMatrixTimeline(
|
||||
private val matrixRoom: MatrixRoom,
|
||||
|
|
@ -51,6 +52,8 @@ class RustMatrixTimeline(
|
|||
private val coroutineDispatchers: CoroutineDispatchers,
|
||||
) : MatrixTimeline {
|
||||
|
||||
private val isInit = AtomicBoolean(false)
|
||||
|
||||
private val timelineItems: MutableStateFlow<List<MatrixTimelineItem>> =
|
||||
MutableStateFlow(emptyList())
|
||||
|
||||
|
|
@ -95,6 +98,7 @@ class RustMatrixTimeline(
|
|||
withContext(coroutineDispatchers.diffUpdateDispatcher) {
|
||||
this@RustMatrixTimeline.timelineItems.value = matrixTimelineItems
|
||||
}
|
||||
isInit.set(true)
|
||||
}
|
||||
.onFailure {
|
||||
Timber.e("Failed adding timeline listener on room with identifier: ${matrixRoom.roomId})")
|
||||
|
|
@ -105,6 +109,7 @@ class RustMatrixTimeline(
|
|||
override fun dispose() {
|
||||
Timber.v("Dispose timeline for room ${matrixRoom.roomId}")
|
||||
listenerTokens.dispose()
|
||||
isInit.set(false)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -125,6 +130,9 @@ class RustMatrixTimeline(
|
|||
override suspend fun paginateBackwards(requestSize: Int, untilNumberOfItems: Int): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
runCatching {
|
||||
Timber.v("Start back paginating for room ${matrixRoom.roomId} ")
|
||||
if (!isInit.get()) {
|
||||
throw IllegalStateException("Timeline is not init yet")
|
||||
}
|
||||
val paginationOptions = PaginationOptions.UntilNumItems(
|
||||
eventLimit = requestSize.toUShort(),
|
||||
items = untilNumberOfItems.toUShort()
|
||||
|
|
@ -141,15 +149,24 @@ class RustMatrixTimeline(
|
|||
runCatching {
|
||||
val settings = RoomSubscription(
|
||||
requiredState = listOf(
|
||||
RequiredState(key = "m.room.topic", value = ""),
|
||||
RequiredState(key = "m.room.canonical_alias", value = ""),
|
||||
RequiredState(key = "m.room.topic", value = ""),
|
||||
RequiredState(key = "m.room.join_rules", value = ""),
|
||||
),
|
||||
timelineLimit = null
|
||||
)
|
||||
val result = slidingSyncRoom.subscribeAndAddTimelineListener(timelineListener, settings)
|
||||
launch {
|
||||
fetchMembers()
|
||||
}
|
||||
listenerTokens += result.taskHandle
|
||||
result.items
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fetchMembers() = withContext(coroutineDispatchers.io) {
|
||||
runCatching {
|
||||
innerRoom.fetchMembers()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue