Improve handling members
This commit is contained in:
parent
5104fc8ac1
commit
a1869a3019
15 changed files with 107 additions and 139 deletions
|
|
@ -102,7 +102,7 @@ class CreateRoomRootPresenterTests {
|
|||
}.test {
|
||||
val initialState = awaitItem()
|
||||
val matrixUser = MatrixUser(UserId("@name:domain"))
|
||||
val fakeDmResult = FakeMatrixRoom(RoomId("!fakeDmResult:domain"))
|
||||
val fakeDmResult = FakeMatrixRoom(roomId = RoomId("!fakeDmResult:domain"))
|
||||
|
||||
fakeMatrixClient.givenFindDmResult(fakeDmResult)
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
|||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemEventFactory @Inject constructor(
|
||||
|
|
@ -42,6 +43,7 @@ class TimelineItemEventFactory @Inject constructor(
|
|||
val senderDisplayName: String?
|
||||
val senderAvatarUrl: String?
|
||||
|
||||
Timber.v("SenderProfile($currentSender) = ${currentTimelineItem.event.senderProfile}")
|
||||
when (val senderProfile = currentTimelineItem.event.senderProfile) {
|
||||
ProfileTimelineDetails.Unavailable,
|
||||
ProfileTimelineDetails.Pending,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package io.element.android.features.roomdetails.impl
|
|||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
|
|
@ -25,17 +26,16 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||
import androidx.compose.runtime.setValue
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.architecture.executeResult
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
||||
import io.element.android.libraries.matrix.api.room.getDmMember
|
||||
import io.element.android.libraries.matrix.api.room.memberCount
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomDetailsPresenter @Inject constructor(
|
||||
private val sessionId: SessionId,
|
||||
private val room: MatrixRoom,
|
||||
private val roomMembershipObserver: RoomMembershipObserver,
|
||||
) : Presenter<RoomDetailsState> {
|
||||
|
|
@ -50,15 +50,14 @@ class RoomDetailsPresenter @Inject constructor(
|
|||
mutableStateOf<RoomDetailsError?>(null)
|
||||
}
|
||||
|
||||
var memberCount: Async<Int> by remember { mutableStateOf(Async.Loading()) }
|
||||
val memberCount: MutableState<Async<Int>> = remember {
|
||||
mutableStateOf(Async.Uninitialized)
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
withContext(Dispatchers.IO) {
|
||||
memberCount = runCatching { room.memberCount() }
|
||||
.fold(
|
||||
onSuccess = { Async.Success(it) },
|
||||
onFailure = { Async.Failure(it) }
|
||||
)
|
||||
}
|
||||
suspend {
|
||||
room.updateMembers()
|
||||
.map { room.memberCount() }
|
||||
}.executeResult(memberCount)
|
||||
}
|
||||
|
||||
val dmMember = room.getDmMember()
|
||||
|
|
@ -72,7 +71,7 @@ class RoomDetailsPresenter @Inject constructor(
|
|||
when (event) {
|
||||
is RoomDetailsEvent.LeaveRoom -> {
|
||||
if (event.needsConfirmation) {
|
||||
leaveRoomWarning = LeaveRoomWarning.computeLeaveRoomWarning(room.isPublic, memberCount)
|
||||
leaveRoomWarning = LeaveRoomWarning.computeLeaveRoomWarning(room.isPublic, memberCount.value)
|
||||
} else {
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
room.leave()
|
||||
|
|
@ -96,7 +95,7 @@ class RoomDetailsPresenter @Inject constructor(
|
|||
roomAlias = room.alias,
|
||||
roomAvatarUrl = room.avatarUrl,
|
||||
roomTopic = room.topic,
|
||||
memberCount = memberCount,
|
||||
memberCount = memberCount.value,
|
||||
isEncrypted = room.isEncrypted,
|
||||
displayLeaveRoomWarning = leaveRoomWarning,
|
||||
error = error,
|
||||
|
|
|
|||
|
|
@ -44,15 +44,6 @@ interface RoomMemberBindsModule {
|
|||
@ContributesTo(RoomScope::class)
|
||||
object RoomMemberProvidesModule {
|
||||
|
||||
@Provides
|
||||
fun provideRoomDetailsPresenter(
|
||||
matrixClient: MatrixClient,
|
||||
room: MatrixRoom,
|
||||
roomMembershipObserver: RoomMembershipObserver,
|
||||
): RoomDetailsPresenter {
|
||||
return RoomDetailsPresenter(matrixClient.sessionId, room, roomMembershipObserver)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideRoomMemberDetailsPresenterFactory(
|
||||
room: MatrixRoom,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import io.element.android.anvilannotations.ContributesNode
|
|||
import io.element.android.libraries.di.RoomScope
|
||||
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.getMember
|
||||
import io.element.android.libraries.matrix.ui.model.MatrixUser
|
||||
import timber.log.Timber
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class RoomUserListDataSource @Inject constructor(
|
|||
) : UserListDataSource {
|
||||
|
||||
override suspend fun search(query: String): List<MatrixUser> {
|
||||
return room.members().filter { member ->
|
||||
return room.membersFlow.value.filter { member ->
|
||||
if (query.isBlank()) {
|
||||
true
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ import io.element.android.libraries.matrix.api.room.RoomMembershipState
|
|||
import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_NAME
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
|
|
@ -50,7 +49,7 @@ class RoomDetailsPresenterTests {
|
|||
@Test
|
||||
fun `present - initial state is created from room info`() = runTest {
|
||||
val room = aMatrixRoom()
|
||||
val presenter = RoomDetailsPresenter(A_SESSION_ID, room, roomMembershipObserver)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -59,7 +58,7 @@ class RoomDetailsPresenterTests {
|
|||
Truth.assertThat(initialState.roomName).isEqualTo(room.name)
|
||||
Truth.assertThat(initialState.roomAvatarUrl).isEqualTo(room.avatarUrl)
|
||||
Truth.assertThat(initialState.roomTopic).isEqualTo(room.topic)
|
||||
Truth.assertThat(initialState.memberCount).isEqualTo(Async.Loading(null))
|
||||
Truth.assertThat(initialState.memberCount).isEqualTo(Async.Uninitialized)
|
||||
Truth.assertThat(initialState.isEncrypted).isEqualTo(room.isEncrypted)
|
||||
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
|
|
@ -69,12 +68,12 @@ class RoomDetailsPresenterTests {
|
|||
@Test
|
||||
fun `present - room member count is calculated asynchronously`() = runTest {
|
||||
val room = aMatrixRoom()
|
||||
val presenter = RoomDetailsPresenter(A_SESSION_ID, room, roomMembershipObserver)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
Truth.assertThat(initialState.memberCount).isEqualTo(Async.Loading(null))
|
||||
Truth.assertThat(initialState.memberCount).isEqualTo(Async.Uninitialized)
|
||||
|
||||
val finalState = awaitItem()
|
||||
Truth.assertThat(finalState.memberCount).isEqualTo(Async.Success(0))
|
||||
|
|
@ -84,7 +83,7 @@ class RoomDetailsPresenterTests {
|
|||
@Test
|
||||
fun `present - initial state with no room name`() = runTest {
|
||||
val room = aMatrixRoom(name = null)
|
||||
val presenter = RoomDetailsPresenter(A_SESSION_ID, room, roomMembershipObserver)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -100,7 +99,7 @@ class RoomDetailsPresenterTests {
|
|||
val room = aMatrixRoom(name = null).apply {
|
||||
givenFetchMemberResult(Result.failure(Throwable()))
|
||||
}
|
||||
val presenter = RoomDetailsPresenter(A_SESSION_ID, room, roomMembershipObserver)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -114,7 +113,7 @@ class RoomDetailsPresenterTests {
|
|||
@Test
|
||||
fun `present - Leave with confirmation on private room shows a specific warning`() = runTest {
|
||||
val room = aMatrixRoom(isPublic = false)
|
||||
val presenter = RoomDetailsPresenter(A_SESSION_ID, room, roomMembershipObserver)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -131,7 +130,7 @@ class RoomDetailsPresenterTests {
|
|||
@Test
|
||||
fun `present - Leave with confirmation on empty room shows a specific warning`() = runTest {
|
||||
val room = aMatrixRoom(members = listOf(aRoomMember()))
|
||||
val presenter = RoomDetailsPresenter(A_SESSION_ID, room, roomMembershipObserver)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -148,7 +147,7 @@ class RoomDetailsPresenterTests {
|
|||
@Test
|
||||
fun `present - Leave with confirmation shows a generic warning`() = runTest {
|
||||
val room = aMatrixRoom()
|
||||
val presenter = RoomDetailsPresenter(A_SESSION_ID, room, roomMembershipObserver)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -165,7 +164,7 @@ class RoomDetailsPresenterTests {
|
|||
@Test
|
||||
fun `present - Leave without confirmation leaves the room`() = runTest {
|
||||
val room = aMatrixRoom()
|
||||
val presenter = RoomDetailsPresenter(A_SESSION_ID, room, roomMembershipObserver)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -189,7 +188,7 @@ class RoomDetailsPresenterTests {
|
|||
val room = aMatrixRoom().apply {
|
||||
givenLeaveRoomError(Throwable())
|
||||
}
|
||||
val presenter = RoomDetailsPresenter(A_SESSION_ID, room, roomMembershipObserver)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -218,10 +217,10 @@ fun aMatrixRoom(
|
|||
) = FakeMatrixRoom(
|
||||
roomId = roomId,
|
||||
name = name,
|
||||
initialMembers = members,
|
||||
displayName = displayName,
|
||||
topic = topic,
|
||||
avatarUrl = avatarUrl,
|
||||
members = members,
|
||||
isEncrypted = isEncrypted,
|
||||
isPublic = isPublic,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue