room members list redesign

This commit is contained in:
Mauro Romito
2025-11-20 20:11:55 +01:00
committed by Mauro
parent bfa287b3f8
commit cb28597eb6
33 changed files with 156 additions and 93 deletions
@@ -22,7 +22,7 @@ struct RoomMembersListScreen: View {
.tag(RoomMembersListScreenMode.banned)
}
.pickerStyle(.segmented)
.padding(.horizontal, 16)
.padding(ListRowPadding.insets)
}
if context.mode == .members {
@@ -38,15 +38,14 @@ struct RoomMembersListScreen: View {
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
.frame(maxWidth: .infinity)
.background(.compound.bgCanvasDefault)
}
}
.compoundList()
.searchable(text: $context.searchQuery,
placement: .navigationBarDrawer(displayMode: .always),
prompt: L10n.commonSearchForSomeone)
.compoundSearchField()
.autocorrectionDisabled()
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
.navigationTitle(L10n.commonPeople)
.navigationBarTitleDisplayMode(.inline)
.sheet(item: $context.manageMemeberViewModel) {
@@ -59,41 +58,44 @@ struct RoomMembersListScreen: View {
// MARK: - Private
@ViewBuilder
var roomMembers: some View {
LazyVStack(alignment: .leading, spacing: 12) {
membersSection(entries: context.viewState.visibleInvitedMembers, sectionTitle: L10n.screenRoomMemberListPendingHeaderTitle)
membersSection(entries: context.viewState.visibleJoinedMembers, sectionTitle: L10n.screenRoomMemberListHeaderTitle(Int(context.viewState.joinedMembersCount)))
}
membersSection(entries: context.viewState.visibleInvitedMembers, section: .invited)
membersSection(entries: context.viewState.visibleJoinedMembers, section: .joined)
}
var bannedUsers: some View {
LazyVStack(alignment: .leading, spacing: 12) {
membersSection(entries: context.viewState.visibleBannedMembers)
}
membersSection(entries: context.viewState.visibleBannedMembers, section: .banned)
}
@ViewBuilder
private func membersSection(entries: [RoomMemberListScreenEntry], sectionTitle: String? = nil) -> some View {
private func membersSection(entries: [RoomMemberListScreenEntry], section: MembersSection) -> some View {
if !entries.isEmpty {
Section {
ForEach(entries, id: \.member.id) { entry in
RoomMembersListScreenMemberCell(listEntry: entry, context: context)
LazyVStack(alignment: .leading, spacing: 0) {
ForEach(entries, id: \.member.id) { entry in
ListRow(kind: .custom {
RoomMembersListScreenMemberCell(listEntry: entry, isLast: entries.last == entry, context: context)
})
}
}
.background(.compound.bgCanvasDefault)
.clipShape(sectionShape)
} header: {
if let sectionTitle {
Text(sectionTitle)
.foregroundColor(.compound.textSecondary)
.font(.compound.bodyLG)
.padding(.top, 12)
} else {
// Put something in here to maintain constant top padding.
Spacer().frame(height: 0)
}
section.header(count: entries.count)
}
.padding(.horizontal, 16)
}
}
private var sectionShape: AnyShape {
if #available(iOS 26, *) {
AnyShape(ConcentricRectangle(corners: .concentric(minimum: 26)))
} else {
AnyShape(RoundedRectangle(cornerRadius: 8))
}
}
@ToolbarContentBuilder
private var toolbar: some ToolbarContent {
ToolbarItem(placement: .confirmationAction) {
@@ -106,6 +108,40 @@ struct RoomMembersListScreen: View {
}
}
private enum MembersSection {
case joined
case invited
case banned
private func sectionTitle(count: Int) -> String {
switch self {
case .banned:
L10n.screenRoomMemberListBannedHeaderTitle(count)
case .invited:
L10n.screenRoomMemberListHeaderTitle(count)
case .joined:
L10n.screenRoomMemberListPendingHeaderTitle(count)
}
}
@ViewBuilder
private func text(count: Int) -> some View {
switch self {
case .invited, .joined:
Text(sectionTitle(count: count))
case .banned:
Text(sectionTitle(count: count))
.foregroundStyle(.compound.bgCriticalPrimary)
}
}
func header(count: Int) -> some View {
text(count: count)
.compoundListSectionHeader()
.frame(maxWidth: .infinity, alignment: .leading)
}
}
// MARK: - Previews
struct RoomMembersListScreen_Previews: PreviewProvider, TestablePreview {