Room member moderation: kick, ban and unban (#2496)
* Room member moderation: kick, ban and unban --------- Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
parent
47539479dd
commit
134cacb024
113 changed files with 1410 additions and 83 deletions
|
|
@ -70,6 +70,8 @@ import kotlinx.coroutines.flow.SharedFlow
|
|||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.shareIn
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -159,6 +161,12 @@ class RustMatrixRoom(
|
|||
|
||||
override val syncUpdateFlow: StateFlow<Long> = _syncUpdateFlow.asStateFlow()
|
||||
|
||||
init {
|
||||
timeline.membershipChangeEventReceived
|
||||
.onEach { roomMemberListFetcher.fetchRoomMembers() }
|
||||
.launchIn(roomCoroutineScope)
|
||||
}
|
||||
|
||||
override suspend fun subscribeToSync() = roomSyncSubscriber.subscribe(roomId)
|
||||
|
||||
override suspend fun unsubscribeFromSync() = roomSyncSubscriber.unsubscribe(roomId)
|
||||
|
|
@ -340,6 +348,12 @@ class RustMatrixRoom(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun canUserKick(userId: UserId): Result<Boolean> {
|
||||
return runCatching {
|
||||
innerRoom.canUserKick(userId.value)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun canUserBan(userId: UserId): Result<Boolean> {
|
||||
return runCatching {
|
||||
innerRoom.canUserBan(userId.value)
|
||||
|
|
@ -469,6 +483,24 @@ class RustMatrixRoom(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun kickUser(userId: UserId, reason: String?): Result<Unit> = withContext(roomDispatcher) {
|
||||
runCatching {
|
||||
innerRoom.kickUser(userId.value, reason)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun banUser(userId: UserId, reason: String?): Result<Unit> = withContext(roomDispatcher) {
|
||||
runCatching {
|
||||
innerRoom.banUser(userId.value, reason)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun unbanUser(userId: UserId, reason: String?): Result<Unit> = withContext(roomDispatcher) {
|
||||
runCatching {
|
||||
innerRoom.unbanUser(userId.value, reason)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun setIsFavorite(isFavorite: Boolean): Result<Unit> = withContext(roomDispatcher) {
|
||||
runCatching {
|
||||
innerRoom.setIsFavourite(isFavorite, null)
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ internal class RoomMemberListFetcher(
|
|||
if (_membersFlow.value !is MatrixRoomMembersState.Ready) {
|
||||
fetchCachedRoomMembers()
|
||||
} else {
|
||||
Timber.i("No need to load cached members found for room $roomId")
|
||||
Timber.i("Cached members not found for $roomId")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import kotlinx.coroutines.CoroutineStart
|
|||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
|
|
@ -55,6 +56,8 @@ class AsyncMatrixTimeline(
|
|||
}
|
||||
private val closeSignal = CompletableDeferred<Unit>()
|
||||
|
||||
override val membershipChangeEventReceived = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
val delegateTimeline = timeline.await()
|
||||
|
|
@ -64,6 +67,9 @@ class AsyncMatrixTimeline(
|
|||
delegateTimeline.paginationState
|
||||
.onEach { _paginationState.value = it }
|
||||
.launchIn(this)
|
||||
delegateTimeline.membershipChangeEventReceived
|
||||
.onEach { membershipChangeEventReceived.emit(it) }
|
||||
.launchIn(this)
|
||||
|
||||
launch {
|
||||
withContext(NonCancellable) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
package io.element.android.libraries.matrix.impl.timeline
|
||||
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
|
|
@ -31,6 +34,9 @@ internal class MatrixTimelineDiffProcessor(
|
|||
) {
|
||||
private val mutex = Mutex()
|
||||
|
||||
private val _membershipChangeEventReceived = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
|
||||
val membershipChangeEventReceived: Flow<Unit> = _membershipChangeEventReceived
|
||||
|
||||
suspend fun postItems(items: List<TimelineItem>) {
|
||||
updateTimelineItems {
|
||||
Timber.v("Update timeline items from postItems (with ${items.size} items) on ${Thread.currentThread()}")
|
||||
|
|
@ -63,6 +69,11 @@ internal class MatrixTimelineDiffProcessor(
|
|||
}
|
||||
TimelineChange.PUSH_BACK -> {
|
||||
val item = diff.pushBack()?.asMatrixTimelineItem() ?: return
|
||||
if (item is MatrixTimelineItem.Event && item.event.content is RoomMembershipContent) {
|
||||
// TODO - This is a temporary solution to notify the room screen about membership changes
|
||||
// Ideally, this should be implemented by the Rust SDK
|
||||
_membershipChangeEventReceived.tryEmit(Unit)
|
||||
}
|
||||
add(item)
|
||||
}
|
||||
TimelineChange.PUSH_FRONT -> {
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ class RustMatrixTimeline(
|
|||
)
|
||||
}
|
||||
|
||||
override val membershipChangeEventReceived: Flow<Unit> = timelineDiffProcessor.membershipChangeEventReceived
|
||||
|
||||
init {
|
||||
Timber.d("Initialize timeline for room ${matrixRoom.roomId}")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue