import React, { useState, useEffect, useCallback } from 'react';
import { View, StyleSheet, ActivityIndicator, Text } from 'react-native';
import { CometChatCalls } from '@cometchat/calls-sdk-react-native';
interface CallScreenProps {
sessionId: string;
isAudioOnly?: boolean;
onCallEnd?: () => void;
}
function CallScreen({ sessionId, isAudioOnly = false, onCallEnd }: CallScreenProps) {
const [callToken, setCallToken] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(true);
const handleCallEnd = useCallback(() => {
console.log('Call ended');
onCallEnd?.();
}, [onCallEnd]);
// Plain session settings object
const sessionSettings = {
sessionType: isAudioOnly ? 'VOICE' : 'VIDEO',
layout: 'TILE',
hideLeaveSessionButton: false,
hideToggleAudioButton: false,
hideToggleVideoButton: isAudioOnly,
hideSwitchCameraButton: isAudioOnly,
hideAudioModeButton: false,
startAudioMuted: false,
startVideoPaused: false,
audioMode: 'SPEAKER',
hideRecordingButton: false,
idleTimeoutPeriodBeforePrompt: 180000,
};
useEffect(() => {
async function initializeCall() {
try {
setIsLoading(true);
setError(null);
// Generate call token
const { token } = await CometChatCalls.generateToken(sessionId);
setCallToken(token);
} catch (err: any) {
console.error('Failed to initialize call:', err);
setError(err.errorDescription || 'Failed to initialize call');
} finally {
setIsLoading(false);
}
}
initializeCall();
}, [sessionId]);
useEffect(() => {
// Subscribe to call events
const controller = new AbortController();
const { signal } = controller;
CometChatCalls.addEventListener('onParticipantJoined', (participant) => {
console.log('Participant joined:', participant.name);
}, { signal });
CometChatCalls.addEventListener('onParticipantLeft', (participant) => {
console.log('Participant left:', participant.name);
}, { signal });
CometChatCalls.addEventListener('onParticipantListChanged', (participants) => {
console.log('Participants:', participants.length);
}, { signal });
CometChatCalls.addEventListener('onSessionLeft', () => {
handleCallEnd();
}, { signal });
CometChatCalls.addEventListener('onLeaveSessionButtonClicked', () => {
console.log('Leave session button clicked');
CometChatCalls.leaveSession();
}, { signal });
CometChatCalls.addEventListener('onSessionTimedOut', () => {
console.log('Session timed out');
handleCallEnd();
}, { signal });
CometChatCalls.addEventListener('onRecordingStarted', () => {
console.log('Recording started');
}, { signal });
CometChatCalls.addEventListener('onRecordingStopped', () => {
console.log('Recording stopped');
}, { signal });
return () => controller.abort();
}, [handleCallEnd]);
if (isLoading) {
return (
<View style={styles.centered}>
<ActivityIndicator size="large" />
<Text style={styles.loadingText}>Joining call...</Text>
</View>
);
}
if (error) {
return (
<View style={styles.centered}>
<Text style={styles.errorText}>{error}</Text>
</View>
);
}
if (!callToken) {
return null;
}
return (
<View style={styles.container}>
<CometChatCalls.Component
callToken={callToken}
sessionSettings={sessionSettings}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#000',
},
centered: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#000',
},
loadingText: {
color: '#fff',
marginTop: 16,
fontSize: 16,
},
errorText: {
color: '#ff4444',
fontSize: 16,
textAlign: 'center',
paddingHorizontal: 20,
},
});
export default CallScreen;