Skip to main content
The raise hand feature allows participants to signal that they want attention during a call, useful for Q&A sessions or large meetings.

Raise Hand

Signal to other participants that you want attention:
import { CometChatCalls } from '@cometchat/calls-sdk-react-native';

CometChatCalls.raiseHand();

Lower Hand

Lower your raised hand:
CometChatCalls.lowerHand();

Listen for Hand Raised Events

Local Events

Listen for when the raise hand button is clicked:
CometChatCalls.addEventListener('onRaiseHandButtonClicked', () => {
  console.log('Raise hand button clicked');
});

Participant Events

Listen for when other participants raise or lower their hands:
CometChatCalls.addEventListener('onParticipantHandRaised', (participant) => {
  console.log(`${participant.name} raised their hand`);
});

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

Complete Example

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

interface Participant {
  pid: string;
  name: string;
}

function RaiseHandFeature() {
  const [isHandRaised, setIsHandRaised] = useState(false);
  const [raisedHands, setRaisedHands] = useState<Participant[]>([]);

  useEffect(() => {
    const unsubscribeRaised = CometChatCalls.addEventListener(
      'onParticipantHandRaised',
      (participant: Participant) => {
        setRaisedHands((prev) => {
          if (prev.find((p) => p.pid === participant.pid)) {
            return prev;
          }
          return [...prev, participant];
        });
      }
    );

    const unsubscribeLowered = CometChatCalls.addEventListener(
      'onParticipantHandLowered',
      (participant: Participant) => {
        setRaisedHands((prev) =>
          prev.filter((p) => p.pid !== participant.pid)
        );
      }
    );

    const unsubscribeLeft = CometChatCalls.addEventListener(
      'onParticipantLeft',
      (participant: Participant) => {
        setRaisedHands((prev) =>
          prev.filter((p) => p.pid !== participant.pid)
        );
      }
    );

    return () => {
      unsubscribeRaised();
      unsubscribeLowered();
      unsubscribeLeft();
    };
  }, []);

  const toggleHand = () => {
    if (isHandRaised) {
      CometChatCalls.lowerHand();
      setIsHandRaised(false);
    } else {
      CometChatCalls.raiseHand();
      setIsHandRaised(true);
    }
  };

  const renderRaisedHand = ({ item }: { item: Participant }) => (
    <View style={styles.raisedHandItem}>
      <Text style={styles.handIcon}></Text>
      <Text style={styles.participantName}>{item.name}</Text>
    </View>
  );

  return (
    <View style={styles.container}>
      <TouchableOpacity
        style={[styles.button, isHandRaised && styles.activeButton]}
        onPress={toggleHand}
      >
        <Text style={styles.buttonIcon}>{isHandRaised ? '✋' : '🤚'}</Text>
        <Text style={styles.buttonText}>
          {isHandRaised ? 'Lower Hand' : 'Raise Hand'}
        </Text>
      </TouchableOpacity>

      {raisedHands.length > 0 && (
        <View style={styles.raisedHandsList}>
          <Text style={styles.listTitle}>
            Raised Hands ({raisedHands.length})
          </Text>
          <FlatList
            data={raisedHands}
            keyExtractor={(item) => item.pid}
            renderItem={renderRaisedHand}
            horizontal
            showsHorizontalScrollIndicator={false}
          />
        </View>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 16,
  },
  button: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#333',
    paddingHorizontal: 20,
    paddingVertical: 12,
    borderRadius: 8,
    gap: 8,
  },
  activeButton: {
    backgroundColor: '#f59e0b',
  },
  buttonIcon: {
    fontSize: 20,
  },
  buttonText: {
    color: '#fff',
    fontSize: 14,
    fontWeight: '600',
  },
  raisedHandsList: {
    marginTop: 16,
  },
  listTitle: {
    color: '#fff',
    fontSize: 14,
    fontWeight: '600',
    marginBottom: 8,
  },
  raisedHandItem: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#333',
    paddingHorizontal: 12,
    paddingVertical: 8,
    borderRadius: 20,
    marginRight: 8,
    gap: 6,
  },
  handIcon: {
    fontSize: 16,
  },
  participantName: {
    color: '#fff',
    fontSize: 14,
  },
});

export default RaiseHandFeature;