Overview

CometChatGroupMembers is a versatile Widget designed to showcase all users who are either added to or invited to a group, thereby enabling them to participate in group discussions, access shared content, and engage in collaborative activities. CometChatGroupMembers have the capability to communicate in real-time through messaging, voice and video calls, and various other interactions. Additionally, they can interact with each other, share files, and join calls based on the permissions established by the group administrator or owner.
The CometChatGroupMembers widget is composed of the following BaseWidgets:
WidgetsDescription
CometChatListBaseCometChatListBase serves as a container widget equipped with a title (navigationBar), search functionality (search-bar), background settings, and a container for embedding a list widget.
CometChatListItemThis widget renders information extracted from a User object onto a tile, featuring a title, subtitle, leading widget, and trailing widget. experience, facilitating seamless navigation and interaction within the widget.

Usage

Integration

CometChatGroupMembers , as a Composite Widget, offers flexible integration options, allowing it to be launched directly via button clicks or any user-triggered action. You can launch CometChatGroupMembers directly using Navigator.push , or you can define it as a widget within the build method of your State class.
1. Using Navigator to Launch CometChatGroupMembers
Navigator.push(context, MaterialPageRoute(builder: (context) => CometChatGroupMembers(group: Group(guid: "", name: "", type: "")))); // A group object is required to launch this widget.
2. Embedding CometChatGroupMembers as a Widget in the build Method
import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart';
import 'package:flutter/material.dart';

class GroupMembers extends StatefulWidget {
  const GroupMembers({super.key});

  @override
  State<GroupMembers> createState() => _GroupMembersState();
}

class _GroupMembersState extends State<GroupMembers> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SafeArea(
            child: CometChatGroupMembers(
              group: Group(guid: "", name: "", type: ""),
            ) // A group object is required to launch this widget.
        )
    );
  }
}

Actions

Actions dictate how a widget functions. They are divided into two types: Predefined and User-defined. You can override either type, allowing you to tailor the behavior of the widget to fit your specific needs.
1. onItemTap
This method proves valuable when users seek to override onItemClick functionality within CometChatGroupMembers , empowering them with greater control and customization options. The onItemTap action doesn’t have a predefined behavior. You can override this action using the following code snippet.
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  onItemTap: (groupMember) {
    // TODO("Not yet implemented")
  },
)

2. onItemLongPress
This method becomes invaluable when users seek to override long-click functionality within CometChatGroupMembers , offering them enhanced control and flexibility in their interactions. The onItemLongPress action doesn’t have a predefined behavior. You can override this action using the following code snippet.
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  onItemLongPress: (groupMember) {
    // TODO("Not yet implemented")
  },
)

3. onBack
Enhance your application’s functionality by leveraging the onBack feature. This capability allows you to customize the behavior associated with navigating back within your app. Utilize the provided code snippet to override default behaviors and tailor the user experience according to your specific requirements.
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  onBack: () {
    // TODO("Not yet implemented")
  },
)

4. onError
You can customize this behavior by using the provided code snippet to override the onError and improve error handling.
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  onError: (e) {
    // TODO("Not yet implemented")
  },
)

5. onSelection
When the onSelection event is triggered, it furnishes the list of selected members. This event can be invoked by any button or action within the interface. You have the flexibility to implement custom actions or behaviors based on the selected members. This action does not come with any predefined behavior. However, you have the flexibility to override this event and tailor it to suit your needs using the following code snippet.
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  selectionMode: SelectionMode.multiple,
  activateSelection: ActivateSelection.onClick,
  onSelection: (groupMembersList) {
    // TODO("Not yet implemented")
  },
)

onLoad
Invoked when the list is successfully fetched and loaded, helping track component readiness..
CometChatGroupMembers(
     onLoad: (list) {
          // print("members loaded: ${list.length}");
        },
)

onEmpty
Called when the list is empty, enabling custom handling such as showing a placeholder message.
CometChatGroupMembers(
      onEmpty: () {
          // print("Group Members empty");
        },
)

Filters

Filters allow you to customize the data displayed in a list within a Widget . You can filter the list based on your specific criteria, allowing for a more customized. Filters can be applied using RequestBuilders of Chat SDK.
1. GroupMembersRequestBuilder
PropertyDescriptionCode
GUIDGroup ID for the group whose members are to be fetched.guid: String
LimitNumber of results to limit the query.limit: int?
Search KeywordKeyword for searching members within the group.searchKeyword: String?
ScopesList of scopes for filtering members (e.g., moderators).scopes: List<String>?
Example In the example below, we are applying a filter to the Group List based on limit and scope.
CometChatGroupMembers(
    group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
    groupMembersRequestBuilder: GroupMembersRequestBuilder("")
      ..limit = 10
)
2. GroupMembersProtocol
The GroupMembersProtocol uses GroupsRequestBuilder enables you to filter and customize the search list based on available parameters in GroupsRequestBuilder. This feature allows you to keep uniformity between the displayed Group Members List and Searched Group Members List. Here is the complete example for reference: Example
custom_protocol_builder.dart
import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart';

class CustomProtocolBuilder extends GroupMembersBuilderProtocol {
  const CustomProtocolBuilder(super.builder);

  @override
  GroupMembersRequest getRequest() {
      return requestBuilder.build();
  }

  @override
  GroupMembersRequest getSearchRequest(String val) {
      requestBuilder.searchKeyword = val;
      return requestBuilder.build();
  }
}
main.dart
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  groupMembersProtocol: CustomProtocolBuilder(GroupMembersRequestBuilder("")..searchKeyword = "searchKeyword"),
)

Events

Events are emitted by a Widget . By using event you can extend existing functionality. Being global events, they can be applied in Multiple Locations and are capable of being Added or Removed. Events emitted by the Join Group widget is as follows.
EventDescription
ccGroupMemberBannedTriggers when the group member banned from the group successfully
ccGroupMemberKickedTriggers when the group member kicked from the group successfully
ccGroupMemberScopeChangedTriggers when the group member scope is changed in the group
Example
your_screen.dart
import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart';
import 'package:cometchat_sdk/models/action.dart' as cc;
import 'package:flutter/material.dart';

class YourScreen extends StatefulWidget {
  const YourScreen({super.key});

  @override
  State<YourScreen> createState() => _YourScreenState();
}

class _YourScreenState extends State<YourScreen> with CometChatGroupEventListener {

  @override
  void initState() {
    super.initState();
    CometChatGroupEvents.addGroupsListener("listenerId", this); // Add the listener
  }

  @override
  void dispose(){
    super.dispose();
    CometChatGroupEvents.removeGroupsListener("listenerId"); // Remove the listener
  }

  @override
  void ccGroupMemberScopeChanged(cc.Action message, User updatedUser, String scopeChangedTo, String scopeChangedFrom, Group group) {
    // TODO("Not yet implemented")
  }

  @override
  void ccGroupMemberBanned(cc.Action message, User bannedUser, User bannedBy, Group bannedFrom) {
    // TODO("Not yet implemented")
  }

  @override
  void ccGroupMemberKicked(cc.Action message, User kickedUser, User kickedBy, Group kickedFrom) {
    // TODO("Not yet implemented")
  }

  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }

}

Customization

To fit your app’s design requirements, you can customize the appearance of the Groups widget. We provide exposed methods that allow you to modify the experience and behavior according to your specific needs.

Style

You can set the CometChatGroupMembersStyle to the CometChatGroupMembers Widget to customize the styling.
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  style: CometChatGroupMembersStyle(
    titleStyle: TextStyle(color: Color(0xFFF76808)),
    separatorColor:  Color(0xFFF76808),
    ownerMemberScopeBackgroundColor:  Color(0xFFF76808),
    adminMemberScopeBackgroundColor: Color(0xFFFEEDE1),
    adminMemberScopeBorder: Border.all(color: Color(0xFFF76808)),
    adminMemberScopeTextColor: Color(0xFFF76808),
    moderatorMemberScopeBackgroundColor: Color(0xFFFEEDE1),
    moderatorMemberScopeTextColor: Color(0xFFF76808),
    backIconColor: Color(0xFFF76808),
  ),
)

Functionality

These are a set of small functional customizations that allow you to fine-tune the overall experience of the widget. With these, you can change text, set custom icons, and toggle the visibility of UI elements.
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  hideSeparator: true,
  hideSearch: true,
  showBackButton: false
)

List of properties exposed by CometChatGroupMembers

PropertyData TypeDescription
groupMembersProtocolGroupMembersBuilderProtocol?Custom request builder protocol for fetching group members.
groupMembersRequestBuilderGroupMembersRequestBuilder?Custom request builder for fetching group members.
subtitleViewWidget? Function(BuildContext, GroupMember)?Widget to set subtitle for each group member.
hideSeparatorbool?Toggle visibility of separator.
listItemViewWidget Function(GroupMember)?Custom view for each group member item.
styleCometChatGroupMembersStyle?Sets style for [CometChatGroupMembers].
controllerScrollController?Sets controller for the list.
optionsList<CometChatOption>? Function(Group, GroupMember, CometChatGroupMembersController, BuildContext)?Options visible at the slide of each group member.
searchPlaceholderString?Placeholder text for the search input.
backButtonWidget?Widget for the back button in the app bar.
showBackButtonboolFlag to show/hide the back button.
searchBoxIconWidget?Widget for the search box icon.
hideSearchboolFlag to show/hide the search input box.
selectionModeSelectionMode?Specifies mode group members module is opening in.
onSelectionFunction(List<GroupMember>?)?Callback for handling group member selection.
loadingStateViewWidgetBuilder?View displayed during loading state.
emptyStateViewWidgetBuilder?View displayed when the list is empty.
errorStateViewWidgetBuilder?View displayed when an error occurs.
hideErrorbool?Toggle visibility of error dialog.
stateCallBackFunction(CometChatGroupMembersController)?Callback to access controller functions from the parent.
appBarOptionsList<Widget>?Options available in the app bar.
groupGroupGroup object passed to fetch members.
trailingViewFunction(BuildContext, GroupMember)?Custom widget for the trailing section of the group member list item.
submitIconWidget?Widget for the submit icon.
selectIconWidget?Widget for the selection icon.
onBackVoidCallback?Callback triggered when going back.
onItemTapFunction(GroupMember)?Callback triggered when tapping a group member item.
onItemLongPressFunction(GroupMember)?Callback triggered on long press of a group member item.
activateSelectionActivateSelection?Lets the widget know if group members can be selected.
onErrorOnError?Callback for handling errors.
heightdouble?Height of the widget.
widthdouble?Width of the widget.
controllerTagString?Tag for accessing the widget’s GetXController.
hideAppbarbool?Flag to hide the app bar.
searchKeywordString?Keyword to fetch the initial list with.
onLoadOnLoad<GroupMember>?Callback triggered when the list is loaded.
onEmptyOnEmpty?Callback triggered when the list is empty.
leadingStateViewWidget? Function(BuildContext, GroupMember)?Widget for the leading section of each group member.
titleViewWidget? Function(BuildContext, GroupMember)?Custom title view for each group member.
hideUserStatusbool?Flag to hide the user status indicator on the avatar.
hideBanMemberOptionbool?Flag to hide the ban member option.
hideKickMemberOptionbool?Flag to hide the kick member option.
hideScopeChangeOptionbool?Flag to hide the scope change option.
setOptionsList<CometChatOption>? Function(Group, GroupMember, CometChatGroupMembersController, BuildContext)?List of actions available on long press of group member item.
addOptionsList<CometChatOption>? Function(Group, GroupMember, CometChatGroupMembersController, BuildContext)?Adds to the current list of actions on long press of a group member item.

Advanced

For advanced-level customization, you can set custom widgets to the widget. This lets you tailor each aspect of the widget to fit your exact needs and application aesthetics. You can create and define your own widgets and then incorporate those into the widget. The CometChatGroupMembers widget does not provide additional functionalities beyond this level of customization.

setOptions

Defines a set of available actions that users can perform when they interact with a group member item.
  • Provide actions like “View Profile”, “Send Message”, “Remove from Group”.
  • Restrict certain actions to admins (e.g., “Promote to Admin”, “Ban User”).
By customizing these options, developers can provide a streamlined and contextually relevant user experience
CometChatGroupMembers(
  setOptions: (group, groupMember, controller, context) {
    // return options
  },
)

addOptions

Adds custom actions to the existing options available when interacting with a group member.
  • Extend functionality by adding “Block User”, “Report User”, or “View Activity”.
  • Customize actions based on member roles.
CometChatGroupMembers(
  addOptions: (group, groupMember, controller, context) {
    // return options
  },
)

loadingStateView

Displays a custom loading view while group members are being fetched.
  • Show a loading spinner with “Fetching group members…”.
  • Implement a skeleton loader for a smoother UI experience.
CometChatGroupMembers(
    loadingStateView: (context) {
      // return loading view
  },
)

emptyStateView

Configures a view to be displayed when no group members are found.
  • Display a message like “No members in this group yet.”.
  • Show a button to Invite Members.
CometChatGroupMembers(
    emptyStateView: (context) {
      // return empty view
  },
)

errorStateView

Defines a custom error state view when there is an issue loading group members.
  • Display a retry button with “Failed to load members. Tap to retry.”.
  • Show an illustration for a better user experience.
CometChatGroupMembers(
    errorStateView: (context) {
      // return error view
  },
)

leadingView

Sets a custom leading view for each group member item, usually used for profile images or avatars.
  • Show a circular avatar with an online/offline indicator.
  • Add a role-based badge (Admin, Moderator, Member).
CometChatGroupMembers(
    leadingView: (context, groupMember) {
       // return leading view
    },
)

titleView

Customizes the title view, typically displaying the member’s name.
  • Customize fonts, colors, or styles for usernames.
  • Add role-specific indicators like “(Group Admin)”.
CometChatGroupMembers(
    titleView: (context, groupMember) {
      // return title view
    },
)

ListItemView

With this function, you can assign a custom ListItem to the CometChatGroupMembers Widget.
widget
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  listItemView: (groupMember) {
    return Placeholder(); // Replace this placeholder with your custom widget.
  },
)
Here is the complete example for reference: Example You can indeed create a custom widget named custom_list_item.dart for more complex or unique list items.
custom_list_item.dart
   Widget _getTailView(GroupMember groupMember, Group group) {
    Color? backgroundColor;
    BoxBorder? border;
    String scope = groupMember.scope ?? GroupMemberScope.participant;
    Color? textColor;
    TextStyle? textStyle;

    if (groupMember.uid == group.owner) {
      scope = GroupMemberScope.owner;
      backgroundColor = Color(0xFF6852D6);
      textColor = Colors.white;
    } else if (scope == GroupMemberScope.admin) {
      backgroundColor = Color(0xFFEDEAFA);
      border = Border.all(color: Color(0xFF6852D6), width: 1);
      textColor = Color(0xFF6852D6);
    } else if (scope == GroupMemberScope.moderator) {
      backgroundColor = Color(0xFFEDEAFA);
      textColor = Color(0xFF6852D6);
    } else {
      return const SizedBox();
    }

    return Container(
      alignment: Alignment.center,
      padding: EdgeInsets.symmetric(horizontal: 12, vertical: 4 ?? 0),
      decoration: BoxDecoration(
        color: backgroundColor,
        border: border,
        borderRadius: BorderRadius.circular(1000),
      ),
      child: Text(
        scope.capitalizeFirst ?? "",
        style: TextStyle(
                fontSize: 12, fontWeight: FontWeight.w400, color: textColor)
            .merge(textStyle)
            .copyWith(color: textColor),
      ),
    );
  }

  Widget getCustomListItemView(
    GroupMember member,
    Group group,
    BuildContext context,
  ) {
    Widget? subtitle;
    Widget? tail;
    Color? backgroundColor;
    Widget? icon;

    tail = _getTailView(member, group);

    StatusIndicatorUtils statusIndicatorUtils =
        StatusIndicatorUtils.getStatusIndicatorFromParams(
      context: context,
      groupMember: member,
      onlineStatusIndicatorColor: Color(0xFF09C26F),
      usersStatusVisibility: true,
    );

    backgroundColor = statusIndicatorUtils.statusIndicatorColor;
    icon = statusIndicatorUtils.icon;

    return Padding(
      padding: EdgeInsets.symmetric(vertical: 8, horizontal: 16),
      child: CometChatListItem(
          id: member.uid,
          avatarName: member.name,
          avatarURL: member.avatar,
          title: member.name,
          key: UniqueKey(),
          subtitleView: subtitle,
          tailView: tail,
          avatarStyle: const CometChatAvatarStyle(
            borderRadius: BorderRadius.all(Radius.circular(12)),
          ),
          avatarHeight: 40,
          avatarWidth: 40,
          statusIndicatorColor: backgroundColor,
          statusIndicatorIcon: icon,
          hideSeparator: true,
          style: ListItemStyle(
            background: Colors.transparent,
            titleStyle: TextStyle(
                fontSize: 16,
                fontWeight: FontWeight.w500,
                color: Color(0xFF141414)),
          )),
    );
  }
main.dart
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  listItemView: (member) {
      return getCustomListItemView(member, controller.group!, context);
   },
)

SubtitleView

You can customize the subtitle view for each item to meet your specific preferences and needs.
widget
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  subtitleView: (context, groupMember) {
    return Placeholder(); // Replace this placeholder with your custom widget.
  },
)
Here is the complete example for reference: Example
main.dart
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  subtitleView: (context, member) {
                            String subtitle = "";

                            final dateTime = member.joinedAt ?? DateTime.now();
                            subtitle = "Joined at ${DateFormat('dd/MM/yyyy').format(dateTime)}";

                            return Text(subtitle,
                              style: TextStyle(
                                color: Color(0xFF727272),
                                fontSize: 14,
                                fontWeight: FontWeight.w400,
                              ),
                            );
                          },
)

AppBarOptions

You can set the Custom appBarOptions to the CometChatGroupMembers widget.
widget
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  appBarOptions: [
    Placeholder(),
    Placeholder(),
    Placeholder()
  ] // Replace this list of placeholder widgets with your list of custom widgets.
)
Here is the complete example for reference: Example
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  appBarOptions: [
    IconButton(
        onPressed: () {},
        icon: Icon(
                Icons.person_add_alt_1,
                color: Color(0xFF6852D6),
                ),
        ),
  ],  // Replaced the list of placeholder widgets with a list of custom widgets.
)

trailingView

Used to generate a custom trailing widget for the CometChatGroupMembers widget. You can add a Tail widget using the following method.
widget
CometChatGroupMembers(
  group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
  trailingView: (context, groupMembers) {
    return Placeholder(); // Replace this placeholder with your custom widget.
  },
)
Here is the complete example for reference: Example
main.dart
  CometChatGroupMembers(
      group: Group(guid: "", name: "", type: ""), // A group object is required to launch this widget.
      trailingView: (context, groupMember) {
        Color? backgroundColor = Color(0xFFEDEAFA);
        BoxBorder? border = Border.all(color: Color(0xFF6852D6), width: 1);
        String scope = groupMember.scope ?? GroupMemberScope.participant;
        Color? textColor = Color(0xFF6852D6);

        if (groupMember.uid == group.owner){
          scope = GroupMemberScope.owner;
        }

        return Container(
          alignment: Alignment.center,
          padding: EdgeInsets.symmetric(
              horizontal: 12, vertical:4 ?? 0),
          decoration: BoxDecoration(
            color: backgroundColor,
            border: border,
            borderRadius:
            BorderRadius.circular(1000),
          ),
          child: Text(
              scope.capitalizeFirst ?? "",
              style:TextStyle(
                  fontSize: 12,
                  fontWeight: FontWeight.w400,
                  color: textColor)
          ),
        );
      },
    );