Use member count instead of counting members (#530)

Use member count instead of counting members

For the room details screen, use the member count as supplied by
matrix instead of waiting for the entire member list to be
retrieved and then manually adding up all the relevant users.

This removes the loading state of the member count, relying on
a spinner on the member list itself if the user actually wants
to see the members. (The performance of that will be improved
separately on the rust side in the future)

Closes #505
This commit is contained in:
Chris Smith 2023-06-06 11:40:17 +01:00 committed by GitHub
parent 044a3c991e
commit 7308428596
20 changed files with 29 additions and 127 deletions

View file

@ -27,12 +27,10 @@ import androidx.compose.runtime.remember
import io.element.android.features.leaveroom.api.LeaveRoomEvent
import io.element.android.features.leaveroom.api.LeaveRoomPresenter
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembershipState
import io.element.android.libraries.matrix.api.room.StateEventType
import io.element.android.libraries.matrix.ui.room.getDirectRoomMember
import javax.inject.Inject
@ -51,7 +49,6 @@ class RoomDetailsPresenter @Inject constructor(
}
val membersState by room.membersStateFlow.collectAsState()
val memberCount by getMemberCount(membersState)
val canInvite by getCanInvite(membersState)
val canEditName by getCanSendStateEvent(membersState, StateEventType.ROOM_NAME)
val canEditAvatar by getCanSendStateEvent(membersState, StateEventType.ROOM_AVATAR)
@ -85,7 +82,7 @@ class RoomDetailsPresenter @Inject constructor(
roomAlias = room.alias,
roomAvatarUrl = room.avatarUrl,
roomTopic = topicState,
memberCount = memberCount,
memberCount = room.joinedMemberCount,
isEncrypted = room.isEncrypted,
canInvite = canInvite,
canEdit = canEditAvatar || canEditName || canEditTopic,
@ -131,18 +128,4 @@ class RoomDetailsPresenter @Inject constructor(
}
return canSendEvent
}
@Composable
private fun getMemberCount(membersState: MatrixRoomMembersState): State<Async<Int>> {
return remember(membersState) {
derivedStateOf {
when (membersState) {
MatrixRoomMembersState.Unknown -> Async.Uninitialized
is MatrixRoomMembersState.Pending -> Async.Loading(prevState = membersState.prevRoomMembers?.size)
is MatrixRoomMembersState.Error -> Async.Failure(membersState.failure, prevState = membersState.prevRoomMembers?.size)
is MatrixRoomMembersState.Ready -> Async.Success(membersState.roomMembers.count { it.membership == RoomMembershipState.JOIN })
}
}
}
}
}

View file

@ -18,7 +18,6 @@ package io.element.android.features.roomdetails.impl
import io.element.android.features.leaveroom.api.LeaveRoomState
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsState
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.matrix.api.room.RoomMember
data class RoomDetailsState(
@ -27,7 +26,7 @@ data class RoomDetailsState(
val roomAlias: String?,
val roomAvatarUrl: String?,
val roomTopic: RoomTopicState,
val memberCount: Async<Int>,
val memberCount: Long,
val isEncrypted: Boolean,
val roomType: RoomDetailsType,
val roomMemberDetailsState: RoomMemberDetailsState?,

View file

@ -19,7 +19,6 @@ package io.element.android.features.roomdetails.impl
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.leaveroom.api.LeaveRoomState
import io.element.android.features.roomdetails.impl.members.details.aRoomMemberDetailsState
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembershipState
@ -32,7 +31,6 @@ open class RoomDetailsStateProvider : PreviewParameterProvider<RoomDetailsState>
aRoomDetailsState().copy(roomTopic = RoomTopicState.CanAddTopic),
aRoomDetailsState().copy(isEncrypted = false),
aRoomDetailsState().copy(roomAlias = null),
aRoomDetailsState().copy(memberCount = Async.Failure(Throwable())),
aDmRoomDetailsState().copy(roomName = "Daniel"),
aDmRoomDetailsState(isDmMemberIgnored = true).copy(roomName = "Daniel"),
aRoomDetailsState().copy(canInvite = true),
@ -73,7 +71,7 @@ fun aRoomDetailsState() = RoomDetailsState(
"|| MAI iki/Marketing " +
"|| MAI iki/Marketing..."
),
memberCount = Async.Success(32),
memberCount = 32,
isEncrypted = true,
canInvite = false,
canEdit = false,

View file

@ -59,7 +59,6 @@ import io.element.android.features.roomdetails.impl.blockuser.BlockUserDialogs
import io.element.android.features.roomdetails.impl.blockuser.BlockUserSection
import io.element.android.features.roomdetails.impl.members.details.RoomMemberHeaderSection
import io.element.android.features.roomdetails.impl.members.details.RoomMemberMainActionsSection
import io.element.android.libraries.architecture.isLoading
import io.element.android.libraries.designsystem.ElementTextStyles
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarData
@ -145,10 +144,8 @@ fun RoomDetailsView(
}
if (state.roomType is RoomDetailsType.Room) {
val memberCount = state.memberCount.dataOrNull()
MembersSection(
memberCount = memberCount,
isLoading = state.memberCount.isLoading(),
memberCount = state.memberCount,
openRoomMemberList = openRoomMemberList,
)
@ -273,8 +270,7 @@ internal fun TopicSection(
@Composable
internal fun MembersSection(
memberCount: Int?,
isLoading: Boolean,
memberCount: Long,
openRoomMemberList: () -> Unit,
modifier: Modifier = Modifier,
) {
@ -282,9 +278,8 @@ internal fun MembersSection(
PreferenceText(
title = stringResource(R.string.screen_room_details_people_title),
icon = Icons.Outlined.Person,
currentValue = memberCount?.toString(),
currentValue = memberCount.toString(),
onClick = openRoomMemberList,
loadingCurrentValue = isLoading,
)
}
}