> ## Documentation Index
> Fetch the complete documentation index at: https://www.cometchat.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Participant Management

> CometChat Calling SDK v5 - Participant Management for React Native

Manage call participants by muting, pinning, and monitoring their status during a call.

## Get Participant List

Listen for participant list changes:

```tsx theme={null}
import { CometChatCalls } from '@cometchat/calls-sdk-react-native';

CometChatCalls.addEventListener('onParticipantListChanged', (participants) => {
  console.log('Participants:', participants);
  participants.forEach((participant) => {
    console.log(`- ${participant.name} (${participant.uid})`);
  });
});
```

## Participant Object

Each participant contains:

| Property | Type   | Description                         |
| -------- | ------ | ----------------------------------- |
| `pid`    | string | Participant ID (unique per session) |
| `uid`    | string | User ID                             |
| `name`   | string | Display name                        |
| `avatar` | string | Avatar URL (optional)               |

## Pin Participant

Pin a participant to the main view in Sidebar or Spotlight layouts:

```tsx theme={null}
// Pin a participant's video
CometChatCalls.pinParticipant(participantId, 'human');

// Pin a participant's screen share
CometChatCalls.pinParticipant(participantId, 'screen-share');
```

| Parameter       | Type   | Description                                            |
| --------------- | ------ | ------------------------------------------------------ |
| `participantId` | string | The participant's `pid`                                |
| `type`          | string | `'human'` for video, `'screen-share'` for screen share |

## Unpin Participant

Remove the pinned participant:

```tsx theme={null}
CometChatCalls.unpinParticipant();
```

## Mute Participant

Mute another participant's audio (requires moderator permissions):

```tsx theme={null}
CometChatCalls.muteParticipant(participantId);
```

## Pause Participant Video

Pause another participant's video (requires moderator permissions):

```tsx theme={null}
CometChatCalls.pauseParticipantVideo(participantId);
```

## Participant Events

### Join and Leave

```tsx theme={null}
CometChatCalls.addEventListener('onParticipantJoined', (participant) => {
  console.log(`${participant.name} joined the call`);
});

CometChatCalls.addEventListener('onParticipantLeft', (participant) => {
  console.log(`${participant.name} left the call`);
});
```

### Audio State

```tsx theme={null}
CometChatCalls.addEventListener('onParticipantAudioMuted', (participant) => {
  console.log(`${participant.name} muted their audio`);
});

CometChatCalls.addEventListener('onParticipantAudioUnmuted', (participant) => {
  console.log(`${participant.name} unmuted their audio`);
});
```

### Video State

```tsx theme={null}
CometChatCalls.addEventListener('onParticipantVideoPaused', (participant) => {
  console.log(`${participant.name} paused their video`);
});

CometChatCalls.addEventListener('onParticipantVideoResumed', (participant) => {
  console.log(`${participant.name} resumed their video`);
});
```

### Hand Raised

```tsx theme={null}
CometChatCalls.addEventListener('onParticipantHandRaised', (participant) => {
  console.log(`${participant.name} raised their hand`);
});

CometChatCalls.addEventListener('onParticipantHandLowered', (participant) => {
  console.log(`${participant.name} lowered their hand`);
});
```

### Screen Sharing

```tsx theme={null}
CometChatCalls.addEventListener('onParticipantStartedScreenShare', (participant) => {
  console.log(`${participant.name} started screen sharing`);
});

CometChatCalls.addEventListener('onParticipantStoppedScreenShare', (participant) => {
  console.log(`${participant.name} stopped screen sharing`);
});
```

### Dominant Speaker

```tsx theme={null}
CometChatCalls.addEventListener('onDominantSpeakerChanged', (participant) => {
  console.log(`Dominant speaker: ${participant.name}`);
});
```

## Using OngoingCallListener

Handle participant events through the call settings listener:

```tsx theme={null}
const callListener = new CometChatCalls.OngoingCallListener({
  onUserJoined: (user) => {
    console.log('User joined:', user.name);
  },
  onUserLeft: (user) => {
    console.log('User left:', user.name);
  },
  onUserListUpdated: (userList) => {
    console.log('Participant count:', userList.length);
  },
  onUserMuted: (user) => {
    console.log('User muted:', user.name);
  },
});

const callSettings = new CometChatCalls.CallSettingsBuilder()
  .setCallEventListener(callListener)
  .build();
```

## Complete Example

```tsx theme={null}
import React, { useState, useEffect } from 'react';
import { View, FlatList, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { CometChatCalls } from '@cometchat/calls-sdk-react-native';

interface Participant {
  pid: string;
  uid: string;
  name: string;
  avatar?: string;
}

function ParticipantList() {
  const [participants, setParticipants] = useState<Participant[]>([]);
  const [pinnedId, setPinnedId] = useState<string | null>(null);

  useEffect(() => {
    const unsubscribeList = CometChatCalls.addEventListener(
      'onParticipantListChanged',
      (list: Participant[]) => {
        setParticipants(list);
      }
    );

    const unsubscribeJoin = CometChatCalls.addEventListener(
      'onParticipantJoined',
      (participant: Participant) => {
        console.log(`${participant.name} joined`);
      }
    );

    const unsubscribeLeave = CometChatCalls.addEventListener(
      'onParticipantLeft',
      (participant: Participant) => {
        console.log(`${participant.name} left`);
        // Unpin if the pinned participant left
        if (pinnedId === participant.pid) {
          setPinnedId(null);
        }
      }
    );

    return () => {
      unsubscribeList();
      unsubscribeJoin();
      unsubscribeLeave();
    };
  }, [pinnedId]);

  const handlePin = (participant: Participant) => {
    if (pinnedId === participant.pid) {
      CometChatCalls.unpinParticipant();
      setPinnedId(null);
    } else {
      CometChatCalls.pinParticipant(participant.pid, 'human');
      setPinnedId(participant.pid);
    }
  };

  const handleMute = (participant: Participant) => {
    CometChatCalls.muteParticipant(participant.pid);
  };

  const renderParticipant = ({ item }: { item: Participant }) => (
    <View style={styles.participantItem}>
      <View style={styles.avatar}>
        <Text style={styles.avatarText}>
          {item.name.charAt(0).toUpperCase()}
        </Text>
      </View>
      <Text style={styles.name}>{item.name}</Text>
      <View style={styles.actions}>
        <TouchableOpacity
          style={[styles.actionButton, pinnedId === item.pid && styles.activeButton]}
          onPress={() => handlePin(item)}
        >
          <Text style={styles.actionText}>
            {pinnedId === item.pid ? 'Unpin' : 'Pin'}
          </Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.actionButton}
          onPress={() => handleMute(item)}
        >
          <Text style={styles.actionText}>Mute</Text>
        </TouchableOpacity>
      </View>
    </View>
  );

  return (
    <View style={styles.container}>
      <Text style={styles.header}>
        Participants ({participants.length})
      </Text>
      <FlatList
        data={participants}
        keyExtractor={(item) => item.pid}
        renderItem={renderParticipant}
        ListEmptyComponent={
          <Text style={styles.emptyText}>No other participants</Text>
        }
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#1a1a1a',
  },
  header: {
    color: '#fff',
    fontSize: 18,
    fontWeight: '600',
    padding: 16,
    borderBottomWidth: 1,
    borderBottomColor: '#333',
  },
  participantItem: {
    flexDirection: 'row',
    alignItems: 'center',
    padding: 12,
    borderBottomWidth: 1,
    borderBottomColor: '#333',
  },
  avatar: {
    width: 40,
    height: 40,
    borderRadius: 20,
    backgroundColor: '#6851D6',
    justifyContent: 'center',
    alignItems: 'center',
  },
  avatarText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: '600',
  },
  name: {
    flex: 1,
    color: '#fff',
    fontSize: 16,
    marginLeft: 12,
  },
  actions: {
    flexDirection: 'row',
    gap: 8,
  },
  actionButton: {
    backgroundColor: '#333',
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderRadius: 4,
  },
  activeButton: {
    backgroundColor: '#6851D6',
  },
  actionText: {
    color: '#fff',
    fontSize: 12,
  },
  emptyText: {
    color: '#666',
    textAlign: 'center',
    padding: 20,
  },
});

export default ParticipantList;
```

## Related Documentation

* [Events](/calls/react-native/events) - All participant events
* [Call Layouts](/calls/react-native/call-layouts) - Layout options for participants
* [Custom Participant List](/calls/react-native/custom-participant-list) - Build custom UI
