> ## 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.

# Events

> CometChat Calling SDK v5 - Events for Flutter

Handle call session events to build responsive UIs. The SDK provides five event listener interfaces to monitor session status, participant activities, media changes, button clicks, and layout changes. Unlike Android, Flutter listeners are not lifecycle-aware and must be manually removed in `dispose()` to prevent memory leaks.

## Get CallSession Instance

The `CallSession` is a singleton that manages the active call. All event listener registrations and session control methods are accessed through this instance.

```dart theme={null}
CallSession? callSession = CallSession.getInstance();
```

<Warning>
  Flutter listeners are **not** lifecycle-aware. You must manually remove all listeners in your widget's `dispose()` method to prevent memory leaks. Failing to do so may cause callbacks to fire on disposed widgets.
</Warning>

***

## Session Events

Monitor the call session lifecycle including join/leave events and connection status.

```dart theme={null}
final sessionStatusListener = SessionStatusListener(
  onSessionJoined: () {
    // Successfully connected to the session
  },
  onSessionLeft: () {
    // Navigate away
  },
  onSessionTimedOut: () {
    // Session ended due to inactivity
  },
  onConnectionLost: () {
    // Network interrupted, attempting reconnection
  },
  onConnectionRestored: () {
    // Connection restored after being lost
  },
  onConnectionClosed: () {
    // Connection permanently closed
  },
);

CallSession.getInstance()?.addSessionStatusListener(sessionStatusListener);
```

| Event                  | Description                                          |
| ---------------------- | ---------------------------------------------------- |
| `onSessionJoined`      | Successfully connected and joined the session        |
| `onSessionLeft`        | Left the session via `leaveSession()` or was removed |
| `onSessionTimedOut`    | Session ended due to inactivity timeout              |
| `onConnectionLost`     | Network interrupted, SDK attempting reconnection     |
| `onConnectionRestored` | Connection restored after being lost                 |
| `onConnectionClosed`   | Connection permanently closed, cannot reconnect      |

Remove the listener when no longer needed:

```dart theme={null}
@override
void dispose() {
  CallSession.getInstance()?.removeSessionStatusListener(sessionStatusListener);
  super.dispose();
}
```

***

## Participant Events

Monitor participant activities including join/leave, audio/video state, hand raise, screen sharing, and recording.

```dart theme={null}
final participantEventListener = ParticipantEventListener(
  onParticipantJoined: (Participant participant) {
    // A participant joined the call
  },
  onParticipantLeft: (Participant participant) {
    // A participant left the call
  },
  onParticipantListChanged: (List<Participant> participants) {
    // Participant list updated
  },
  onParticipantAudioMuted: (Participant participant) {},
  onParticipantAudioUnmuted: (Participant participant) {},
  onParticipantVideoPaused: (Participant participant) {},
  onParticipantVideoResumed: (Participant participant) {},
  onParticipantHandRaised: (Participant participant) {},
  onParticipantHandLowered: (Participant participant) {},
  onParticipantStartedScreenShare: (Participant participant) {},
  onParticipantStoppedScreenShare: (Participant participant) {},
  onParticipantStartedRecording: (Participant participant) {},
  onParticipantStoppedRecording: (Participant participant) {},
  onDominantSpeakerChanged: (Participant participant) {},
);

CallSession.getInstance()?.addParticipantEventListener(participantEventListener);
```

| Event                             | Parameter           | Description                              |
| --------------------------------- | ------------------- | ---------------------------------------- |
| `onParticipantJoined`             | `Participant`       | A participant connected to the call      |
| `onParticipantLeft`               | `Participant`       | A participant disconnected from the call |
| `onParticipantListChanged`        | `List<Participant>` | Participant list updated                 |
| `onParticipantAudioMuted`         | `Participant`       | A participant muted their microphone     |
| `onParticipantAudioUnmuted`       | `Participant`       | A participant unmuted their microphone   |
| `onParticipantVideoPaused`        | `Participant`       | A participant turned off their camera    |
| `onParticipantVideoResumed`       | `Participant`       | A participant turned on their camera     |
| `onParticipantHandRaised`         | `Participant`       | A participant raised their hand          |
| `onParticipantHandLowered`        | `Participant`       | A participant lowered their hand         |
| `onParticipantStartedScreenShare` | `Participant`       | A participant started screen sharing     |
| `onParticipantStoppedScreenShare` | `Participant`       | A participant stopped screen sharing     |
| `onParticipantStartedRecording`   | `Participant`       | A participant started recording          |
| `onParticipantStoppedRecording`   | `Participant`       | A participant stopped recording          |
| `onDominantSpeakerChanged`        | `Participant`       | The active speaker changed               |

Remove the listener when no longer needed:

```dart theme={null}
@override
void dispose() {
  CallSession.getInstance()?.removeParticipantEventListener(participantEventListener);
  super.dispose();
}
```

***

## Media Events

Monitor your local media state changes including audio/video status, recording, and device changes.

```dart theme={null}
final mediaEventsListener = MediaEventsListener(
  onAudioMuted: () {
    // Your microphone was muted
  },
  onAudioUnMuted: () {
    // Your microphone was unmuted
  },
  onVideoPaused: () {
    // Your camera was turned off
  },
  onVideoResumed: () {
    // Your camera was turned on
  },
  onRecordingStarted: () {
    // Call recording started
  },
  onRecordingStopped: () {
    // Call recording stopped
  },
  onScreenShareStarted: () {
    // You started screen sharing
  },
  onScreenShareStopped: () {
    // You stopped screen sharing
  },
  onAudioModeChanged: (AudioMode audioMode) {
    // Audio output device changed
  },
  onCameraFacingChanged: (CameraFacing facing) {
    // Camera switched between front and rear
  },
);

CallSession.getInstance()?.addMediaEventsListener(mediaEventsListener);
```

| Event                   | Parameter      | Description                            |
| ----------------------- | -------------- | -------------------------------------- |
| `onAudioMuted`          | -              | Your microphone was muted              |
| `onAudioUnMuted`        | -              | Your microphone was unmuted            |
| `onVideoPaused`         | -              | Your camera was turned off             |
| `onVideoResumed`        | -              | Your camera was turned on              |
| `onRecordingStarted`    | -              | Call recording started                 |
| `onRecordingStopped`    | -              | Call recording stopped                 |
| `onScreenShareStarted`  | -              | You started screen sharing             |
| `onScreenShareStopped`  | -              | You stopped screen sharing             |
| `onAudioModeChanged`    | `AudioMode`    | Audio output device changed            |
| `onCameraFacingChanged` | `CameraFacing` | Camera switched between front and rear |

<AccordionGroup>
  <Accordion title="AudioMode Values">
    | Value                 | Description                                     |
    | --------------------- | ----------------------------------------------- |
    | `AudioMode.speaker`   | Audio routed through device loudspeaker         |
    | `AudioMode.earpiece`  | Audio routed through phone earpiece             |
    | `AudioMode.bluetooth` | Audio routed through connected Bluetooth device |
  </Accordion>

  <Accordion title="CameraFacing Values">
    | Value                | Description                            |
    | -------------------- | -------------------------------------- |
    | `CameraFacing.front` | Front-facing (selfie) camera is active |
    | `CameraFacing.rear`  | Rear-facing (main) camera is active    |
  </Accordion>
</AccordionGroup>

Remove the listener when no longer needed:

```dart theme={null}
@override
void dispose() {
  CallSession.getInstance()?.removeMediaEventsListener(mediaEventsListener);
  super.dispose();
}
```

***

## Button Click Events

Intercept UI button clicks from the default call interface to add custom behavior or analytics.

```dart theme={null}
final buttonClickListener = ButtonClickListener(
  onLeaveSessionButtonClicked: () {
    // Leave button tapped
  },
  onToggleAudioButtonClicked: () {
    // Mute/unmute button tapped
  },
  onToggleVideoButtonClicked: () {
    // Video on/off button tapped
  },
  onSwitchCameraButtonClicked: () {},
  onRaiseHandButtonClicked: () {},
  onShareInviteButtonClicked: () {},
  onChangeLayoutButtonClicked: () {},
  onParticipantListButtonClicked: () {},
  onChatButtonClicked: () {},
  onRecordingToggleButtonClicked: () {},
);

CallSession.getInstance()?.addButtonClickListener(buttonClickListener);
```

| Event                            | Description                        |
| -------------------------------- | ---------------------------------- |
| `onLeaveSessionButtonClicked`    | Leave/end call button was tapped   |
| `onToggleAudioButtonClicked`     | Mute/unmute button was tapped      |
| `onToggleVideoButtonClicked`     | Video on/off button was tapped     |
| `onSwitchCameraButtonClicked`    | Camera switch button was tapped    |
| `onRaiseHandButtonClicked`       | Raise hand button was tapped       |
| `onShareInviteButtonClicked`     | Share/invite button was tapped     |
| `onChangeLayoutButtonClicked`    | Layout change button was tapped    |
| `onParticipantListButtonClicked` | Participant list button was tapped |
| `onChatButtonClicked`            | In-call chat button was tapped     |
| `onRecordingToggleButtonClicked` | Recording toggle button was tapped |

<Note>
  Button click events fire before the SDK's default action executes. Use these to add custom logic alongside default behavior.
</Note>

Remove the listener when no longer needed:

```dart theme={null}
@override
void dispose() {
  CallSession.getInstance()?.removeButtonClickListener(buttonClickListener);
  super.dispose();
}
```

***

## Layout Events

Monitor layout changes including layout type switches and Picture-in-Picture mode transitions.

```dart theme={null}
final layoutListener = LayoutListener(
  onCallLayoutChanged: (LayoutType layoutType) {
    // Layout changed (tile, spotlight)
  },
  onParticipantListVisible: () {
    // Participant list panel opened
  },
  onParticipantListHidden: () {
    // Participant list panel closed
  },
  onPictureInPictureLayoutEnabled: () {
    // Entered PiP mode
  },
  onPictureInPictureLayoutDisabled: () {
    // Exited PiP mode
  },
);

CallSession.getInstance()?.addLayoutListener(layoutListener);
```

| Event                              | Parameter    | Description                          |
| ---------------------------------- | ------------ | ------------------------------------ |
| `onCallLayoutChanged`              | `LayoutType` | Call layout changed                  |
| `onParticipantListVisible`         | -            | Participant list panel was opened    |
| `onParticipantListHidden`          | -            | Participant list panel was closed    |
| `onPictureInPictureLayoutEnabled`  | -            | Call entered Picture-in-Picture mode |
| `onPictureInPictureLayoutDisabled` | -            | Call exited Picture-in-Picture mode  |

<Accordion title="LayoutType Values">
  | Value                  | Description                                           | Best For                         |
  | ---------------------- | ----------------------------------------------------- | -------------------------------- |
  | `LayoutType.tile`      | Grid layout with equally-sized tiles                  | Group discussions, team meetings |
  | `LayoutType.spotlight` | Large view for active speaker, small tiles for others | Presentations, one-on-one calls  |
</Accordion>

Remove the listener when no longer needed:

```dart theme={null}
@override
void dispose() {
  CallSession.getInstance()?.removeLayoutListener(layoutListener);
  super.dispose();
}
```
