GroupChatInfoView: keep Invite + owner in card, render members as lazy items

fa29bb7a7 put filteredMembers.value.forEach inside the same SectionView as
the Invite button and the owner row to get a unified card visual. That
sacrificed lazy rendering — all members composed at once, hurting big-group
scroll perf. Founder asked to bring lazy back.

Compromise: keep Invite + (search row) + owner row inside the SectionView
card (the 'hero' rows). Move the rest of the members out to a sibling
items(filteredMembers.value, key = { it.groupMemberId }) call in the
parent LazyColumn — bare SectionItemViewLongClickable rows below the card,
lazy-composed by LazyColumn.
This commit is contained in:
another-simple-pixel
2026-05-18 04:24:04 -07:00
parent f7cdcac576
commit afa57462a1
@@ -721,33 +721,35 @@ fun ModalData.GroupChatInfoLayout(
SectionItemView(minHeight = 54.dp, padding = PaddingValues(horizontal = DEFAULT_PADDING)) {
MemberRow(groupInfo.membership, user = true)
}
filteredMembers.value.forEach { member ->
val showMenu = remember(member.groupMemberId) { mutableStateOf(false) }
val canBeSelected = groupInfo.membership.memberRole >= member.memberRole && member.memberRole < GroupMemberRole.Moderator
SectionItemViewLongClickable(
click = {
if (selectedItems.value != null) {
if (canBeSelected) {
toggleItemSelection(member.groupMemberId, selectedItems)
}
} else {
showMemberInfo(member, null)
}
},
longClick = { showMenu.value = true },
minHeight = 54.dp,
padding = PaddingValues(horizontal = DEFAULT_PADDING)
) {
Box(contentAlignment = Alignment.CenterStart) {
androidx.compose.animation.AnimatedVisibility(selectedItems.value != null, enter = fadeIn(), exit = fadeOut()) {
SelectedListItem(Modifier.alpha(if (canBeSelected) 1f else 0f).padding(start = 2.dp), member.groupMemberId, selectedItems)
}
val selectionOffset by animateDpAsState(if (selectedItems.value != null) 20.dp + 22.dp * fontSizeMultiplier else 0.dp)
DropDownMenuForMember(chat.remoteHostId, member, groupInfo, selectedItems, showMenu)
Box(Modifier.padding(start = selectionOffset)) {
MemberRow(member)
}
}
}
}
if (!groupInfo.nextConnectPrepared && !groupInfo.useRelays) {
items(filteredMembers.value, key = { it.groupMemberId }) { member ->
val showMenu = remember(member.groupMemberId) { mutableStateOf(false) }
val canBeSelected = groupInfo.membership.memberRole >= member.memberRole && member.memberRole < GroupMemberRole.Moderator
SectionItemViewLongClickable(
click = {
if (selectedItems.value != null) {
if (canBeSelected) {
toggleItemSelection(member.groupMemberId, selectedItems)
}
} else {
showMemberInfo(member, null)
}
},
longClick = { showMenu.value = true },
minHeight = 54.dp,
padding = PaddingValues(horizontal = DEFAULT_PADDING)
) {
Box(contentAlignment = Alignment.CenterStart) {
androidx.compose.animation.AnimatedVisibility(selectedItems.value != null, enter = fadeIn(), exit = fadeOut()) {
SelectedListItem(Modifier.alpha(if (canBeSelected) 1f else 0f).padding(start = 2.dp), member.groupMemberId, selectedItems)
}
val selectionOffset by animateDpAsState(if (selectedItems.value != null) 20.dp + 22.dp * fontSizeMultiplier else 0.dp)
DropDownMenuForMember(chat.remoteHostId, member, groupInfo, selectedItems, showMenu)
Box(Modifier.padding(start = selectionOffset)) {
MemberRow(member)
}
}
}