From 4d7f874eec737ecbdb7a94bdf0116d6de4c51ff4 Mon Sep 17 00:00:00 2001 From: SiteRelEnby <125829806+SiteRelEnby@users.noreply.github.com> Date: Sun, 28 Jun 2026 20:51:05 -0400 Subject: [PATCH] fix(members): exclude archived members from the roster and counts The list endpoint returns archived members, but the Members tab (PeopleScreen) showed them in the roster and counted them, and the Settings member-count stat counted them too. Filter archived out of the People roster + its count, and the Settings member count. Archived members remain viewable in Settings > System > Archived members. (The archive PR filtered the secondary MembersScreen, not the live PeopleScreen Members tab.) --- .../systems/lupine/sheaf/ui/people/PeopleScreen.kt | 14 ++++++++++---- .../lupine/sheaf/ui/settings/SettingsViewModel.kt | 4 +++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sheaf/app/src/main/java/systems/lupine/sheaf/ui/people/PeopleScreen.kt b/sheaf/app/src/main/java/systems/lupine/sheaf/ui/people/PeopleScreen.kt index ff5952c..0254688 100644 --- a/sheaf/app/src/main/java/systems/lupine/sheaf/ui/people/PeopleScreen.kt +++ b/sheaf/app/src/main/java/systems/lupine/sheaf/ui/people/PeopleScreen.kt @@ -64,9 +64,15 @@ fun PeopleScreen( onDispose { lifecycleOwner.lifecycle.removeObserver(observer) } } - val filteredMembers = remember(memberQuery, membersState.members) { - if (memberQuery.isBlank()) membersState.members - else membersState.members.filter { + // The list endpoint returns archived members too; keep them out of the + // roster (and its count). Archived members are viewed/restored from + // Settings > System > Archived members. + val activeMembers = remember(membersState.members) { + membersState.members.filter { !it.isArchived } + } + val filteredMembers = remember(memberQuery, activeMembers) { + if (memberQuery.isBlank()) activeMembers + else activeMembers.filter { it.displayNameOrName.contains(memberQuery.trim(), ignoreCase = true) || it.pronouns?.contains(memberQuery.trim(), ignoreCase = true) == true } @@ -153,7 +159,7 @@ fun PeopleScreen( isLoading = membersState.isLoading, error = membersState.error, members = filteredMembers, - rawMemberCount = membersState.members.size, + rawMemberCount = activeMembers.size, query = memberQuery, onQueryChange = { memberQuery = it }, showSearch = searchOpen, diff --git a/sheaf/app/src/main/java/systems/lupine/sheaf/ui/settings/SettingsViewModel.kt b/sheaf/app/src/main/java/systems/lupine/sheaf/ui/settings/SettingsViewModel.kt index acaccfc..d6ba3f0 100644 --- a/sheaf/app/src/main/java/systems/lupine/sheaf/ui/settings/SettingsViewModel.kt +++ b/sheaf/app/src/main/java/systems/lupine/sheaf/ui/settings/SettingsViewModel.kt @@ -135,7 +135,9 @@ class SettingsViewModel @Inject constructor( _state.update { it.copy(isLoading = false, error = e.toUserMessage()) } return@launch } - val memberCount = runCatching { api.listMembers().size }.getOrDefault(0) + // Exclude archived members; the list endpoint returns them but + // they aren't part of the active roster the count represents. + val memberCount = runCatching { api.listMembers().count { !it.isArchived } }.getOrDefault(0) val groupCount = runCatching { api.listGroups().size }.getOrDefault(0) val frontingCount = runCatching { api.getCurrentFronts().flatMap { it.memberIds }.toSet().size