Imported from cometchat/cometchat-skills (
skills/cometchat-flutter-v6-users-groups/SKILL.md). Install upstream withnpx skills add cometchat/cometchat-skills --skill cometchat-flutter-v6-users-groups. Copyright stays with the author (MIT).
Ground truth:
cometchat_chat_uikit: ^6.0— pub-cache source +ui-kit/flutter. Official docs: https://www.cometchat.com/docs/ui-kit/flutter/overview · Docs MCP:claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp(or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
CometChat Flutter UIKit — Users & Groups
Components for displaying and managing users, groups, and group members.
CometChatUsers
Displays a searchable, alphabetically-sorted list of users.
// MessagesScreen below is a user-defined wrapper around CometChatMessageHeader +
// CometChatMessageList + CometChatMessageComposer (no CometChatMessages exists in v6) —
// see the cometchat-flutter-v6-messages skill for the canonical pattern.
CometChatUsers(
onItemTap: (context, user) {
Navigator.push(context, MaterialPageRoute(
builder: (_) => MessagesScreen(user: user),
));
},
usersStyle: CometChatUsersStyle(
backgroundColor: colorPalette.background1,
),
usersStatusVisibility: true,
showBackButton: true,
onBack: () => Navigator.pop(context),
)
Custom Request Builder
CometChatUsers(
usersRequestBuilder: UsersRequestBuilder()
..limit = 30
..friendsOnly = true
..roles = ['default']
..searchKeyword = 'john',
)
View Slots
CometChatUsers(
listItemView: (user) => MyCustomUserItem(user),
subtitleView: (context, user) => Text(user.status ?? 'offline'),
trailingView: (context, user) => Icon(Icons.chat),
)
CometChatGroups
Displays a searchable list of groups with type indicators (public/private/password).
CometChatGroups(
onItemTap: (context, group) {
Navigator.push(context, MaterialPageRoute(
builder: (_) => MessagesScreen(group: group),
));
},
groupsStyle: CometChatGroupsStyle(
backgroundColor: colorPalette.background1,
),
groupTypeVisibility: true,
)
Custom Request Builder
CometChatGroups(
groupsRequestBuilder: GroupsRequestBuilder()
..limit = 30
..joinedOnly = true
..searchKeyword = 'team'
..withTags = true
..tags = ['project'],
)
CometChatGroupMembers
Displays members of a specific group with role indicators and management actions.
CometChatGroupMembers(
group: group,
// ⚠️ Note: this prop is `style` (NOT `groupMembersStyle`) — the only
// V6 list component that breaks the {component}Style naming convention.
style: CometChatGroupMembersStyle(
backgroundColor: colorPalette.background1,
),
)
Group Member Actions
The component supports scope changes, kick, and ban based on the logged-in user's role:
| Logged-in Role | Can Change Scope | Can Kick | Can Ban |
|---|---|---|---|
| Owner | ✅ All members | ✅ All | ✅ All |
| Admin | ✅ Participants only | ✅ Participants | ✅ Participants |
| Participant | ❌ | ❌ | ❌ |
Architecture (All Three)
All follow the same Clean Architecture + BLoC pattern:
{component}/
├── bloc/{component}_bloc.dart # State management + SDK listeners
├── domain/usecases/ # Get{Component}sUseCase, etc.
├── data/repositories/ # SDK wrapper
├── di/{component}_service_locator.dart # Singleton DI
└── widgets/ # List item, empty/error/loading views
BLoC State Pattern
All three use the same state pattern:
// Status-based states
{Component}Initial → {Component}Loading → {Component}Loaded / {Component}Empty / {Component}Error
// Loaded state has:
final List<{Entity}> items;
final bool hasMore;
final Set<String> selectedItems; // For selection mode
final bool isLoadingMore;
Selection Mode
All list components support selection:
CometChatUsers(
selectionMode: SelectionMode.multiple,
// ⚠️ CometChatUsers.onSelection passes TWO args (List<User>?, BuildContext).
// CometChatGroups.onSelection passes ONE (List<Group>?). The signatures differ.
onSelection: (selectedUsers, context) {
// Handle selected users
},
activateSelection: ActivateSelection.onLongClick,
)
Gotchas
CometChatGroupMembershas been fully migrated to BLoC + Clean Architecture (bloc/, data/, di/, domain/, widgets/). AGroupMembersBlocAdapterwraps the BLoC to implement the legacyCometChatGroupMembersControllerProtocolfor backward compatibility. The oldcometchat_group_members_controller.dartfile still exists but the BLoC is the active implementation.- Group type icons (lock for private, shield for password) are controlled by
groupTypeVisibility. Setting it tofalsehides all type indicators. friendsOnly: trueonUsersRequestBuilderonly works if your CometChat plan supports the friends feature.- When a user is blocked, they still appear in
CometChatUsersunless you setincludeBlockedUsers: falseon the conversations BLoC or filter in the request builder.
Anti-Patterns
// ❌ WRONG — not handling group join for password-protected groups
onItemTap: (context, group) => Navigator.push(context, MaterialPageRoute(
builder: (_) => MessagesScreen(group: group), // Fails if not joined
))
// ✅ CORRECT — check membership, handle password groups
onItemTap: (context, group) {
if (group.hasJoined) {
Navigator.push(context, MaterialPageRoute(
builder: (_) => MessagesScreen(group: group),
));
} else if (group.type == GroupTypeConstants.password) {
Navigator.push(context, MaterialPageRoute(
builder: (_) => JoinProtectedGroupScreen(group: group),
));
} else {
// Join public group first, then navigate
}
}
// ❌ WRONG — hardcoded role check strings
if (member.scope == 'admin') { ... }
// ✅ CORRECT — use SDK constants
if (member.scope == GroupMemberScope.admin) { ... }
// ❌ WRONG — creating ServiceLocator per widget instance
final locator = GroupsServiceLocator(); // New instance each time
// ✅ CORRECT — use singleton
final locator = GroupsServiceLocator.instance;
locator.setup();
Checklist
-
onItemTaphandles group join state (joined vs password vs public) - Group member actions respect role hierarchy
- Selection mode configured if multi-select needed
- Request builder customized for app's user/group filtering needs
- ServiceLocator accessed via
.instancesingleton - Colors from
CometChatThemeHelper, not hardcoded