Display comprehensive call information and history when users select calls from the calls tab in your React chat app.

Overview

The Calls Log Details feature provides users with detailed information about specific calls, including call status, participants, duration, recordings, and call history.
  • Provides detailed information about specific calls when selected from the calls tab.
  • Enables users to review call details, understand outcomes, view participants, and access recordings for reference.
  • Users can view call details with tabbed navigation showing participants, recordings, and call history.

Prerequisites

  • React v18.2.0+
  • CometChat React UI Kit v6.1.0+
  • CometChat Chat SDK JavaScript v4.0.13+
  • CometChat Calls SDK JavaScript v4.0.11+
  • Project setup with initialized CometChat credentials (App ID, Auth Key, Region)
  • TypeScript support (recommended)
  • Call functionality implemented
  • Calls tab navigation configured

Components

Component / ClassRole
CometChatCallDetailsMain container for call details display
CometChatCallDetailsInfoShows call status, duration, and info
CometChatCallDetailsParticipantsDisplays call participants
CometChatCallDetailsRecordingShows call recordings if available
CometChatCallDetailsHistoryDisplays call history
CometChatCallLogsCalls list component in the calls tab

Integration Steps

1. Calls Tab Integration Setup

File: CometChatSelector.tsx
{activeTab == "calls" ? (
    <CometChatCallLogs
        activeCall={activeItem as CometChat.Call}
        onItemClick={(e: CometChat.Call) => {
            onSelectorItemClicked(e, "updateSelectedItemCall");
        }}
    />
) : null}

2. Call Details Component Integration

File: CometChatHome.tsx
const CallDetailsView = () => {
    if (!selectedItem || !(selectedItem instanceof CometChat.Call)) return null;
    
    return (
        <CometChatCallDetails
            selectedItem={selectedItem}
            onBack={() => {
                setSelectedItem(undefined);
                setAppState({ type: "updateSelectedItemCall", payload: undefined });
            }}
        />
    );
}

3. Call Details Main Component Implementation

File: CometChatCallLogDetails.tsx
export const CometChatCallDetails = (props: { selectedItem: any, onBack?: () => void }) => {
    const { selectedItem, onBack } = props;
    const callDetailTabItems = [
        getLocalizedString("participants"), 
        getLocalizedString("recording"), 
        getLocalizedString("history")
    ];
    const [activeTab, setActiveTab] = useState("Participants");
    const [user, setUser] = useState<CometChat.User>();
    const [subtitleText, setSubtitleText] = useState<string>();

    return (
        <div className="cometchat-call-log-details">
            <div className="cometchat-call-log-details__header">
                <div className="cometchat-call-log-details__header-back" onClick={onBack} />
                {getLocalizedString("call_details")}
            </div>
            <div className="cometchat-call-log-details__call-log-item">
                <CometChatListItem 
                    avatarName={user?.getName()}
                    avatarURL={user?.getAvatar()}
                    title={user?.getName() || ""} 
                    subtitleView={getSubtitleView()} 
                    trailingView={getTrailingView()}
                />
            </div>
            <CometChatCallDetailsInfo call={selectedItem} />
            <div className="cometchat-call-log-details__tabs">
                {callDetailTabItems.map((tabItem) => (
                    <div
                        onClick={() => setActiveTab(tabItem)}
                        className={activeTab === tabItem ? "cometchat-call-log-details__tabs-tab-item-active" : "cometchat-call-log-details__tabs-tab-item"}
                    >
                        {tabItem}
                    </div>
                ))}
            </div>
            {activeTab === "Participants" ? <CometChatCallDetailsParticipants call={selectedItem} />
                : activeTab === "Recording" ? <CometChatCallDetailsRecording call={selectedItem} />
                    : activeTab === "History" ? <CometChatCallDetailsHistory call={selectedItem} />
                        : null
            }
        </div>
    );
}

4. Call Information Display Component

File: CometChatCallLogInfo.tsx
export const CometChatCallDetailsInfo = (props: { call: any }) => {
    const { call } = props;
    const [loggedInUser, setLoggedInUser] = useState<CometChat.User | null>(null);

    const getCallStatus = (call: CometChat.Call, loggedInUser: CometChat.User): string => {
        const isSentByMe = (call: any, loggedInUser: CometChat.User) => {
            const senderUid: string = call.initiator?.getUid();
            return !senderUid || senderUid === loggedInUser?.getUid();
        }
        const callStatus: string = call.getStatus();
        const isSentByMeFlag: boolean = isSentByMe(call, loggedInUser!);
        
        switch (callStatus) {
            case CometChatUIKitConstants.calls.initiated: {
                return isSentByMeFlag ? getLocalizedString("calls_outgoing_call") : getLocalizedString('calls_incoming_call');
            }
            case CometChatUIKitConstants.calls.ended: {
                return isSentByMeFlag ? getLocalizedString("calls_outgoing_call") : getLocalizedString('calls_incoming_call');
            }
            // ... other status cases
        }
    }

    return (
        <div className="cometchat-call-log-info">
            <CometChatListItem
                title={getCallStatus(call, loggedInUser!)}
                avatarURL={getAvatarUrlForCall(call)}
                subtitleView={getListItemSubtitleView(call)}
                trailingView={getListItemTailView(call)}
            />
        </div>
    );
}

Implementation Flow

  • Fetch Data / Call Selection
const onSelectorItemClicked = (e: CometChat.Conversation | CometChat.User | CometChat.Group | CometChat.Call, type: string) => {
    if (type === "updateSelectedItemCall") {
        setSelectedItem(e as CometChat.Call);
        setAppState({ type: "updateSelectedItemCall", payload: e as CometChat.Call });
    }
}
  • Load Call Data / Associated Information
useEffect(() => {
    const loggedInUser = CometChatUIKitLoginListener.getLoggedInUser();
    const callUser = verifyCallUser(selectedItem, loggedInUser!);
    
    if (selectedItem.receiverType === CometChatUIKitConstants.MessageReceiverType.user) {
        CometChat.getUser(callUser.uid).then((response: CometChat.User) => {
            setUser(response);
        });
    }
}, [selectedItem]);
  • Display Call Details / Tab Navigation
const [activeTab, setActiveTab] = useState("Participants");

const renderTabContent = () => {
    switch (activeTab) {
        case "Participants":
            return <CometChatCallDetailsParticipants call={selectedItem} />;
        case "Recording":
            return <CometChatCallDetailsRecording call={selectedItem} />;
        case "History":
            return <CometChatCallDetailsHistory call={selectedItem} />;
        default:
            return null;
    }
}
  • Live Updates / User Status Monitoring
useEffect(() => {
    let isBlocked = new MessageUtils().getUserStatusVisible(user);
    const userListenerId = "users_custom" + Date.now();
    
    if (isBlocked) {
        setSubtitleText("");
        return;
    }
    
    setSubtitleText(user?.getStatus());
    
    CometChat.addUserListener(
        userListenerId,
        new CometChat.UserListener({
            onUserOnline: (onlineUser: CometChat.User) => {
                if (user?.getUid() === onlineUser.getUid()) {
                    setSubtitleText(onlineUser?.getStatus());
                }
            },
            onUserOffline: (offlineUser: CometChat.User) => {
                if (user?.getUid() === offlineUser?.getUid()) {
                    setSubtitleText(offlineUser?.getStatus());
                }
            },
        })
    );
    
    return () => {
        CometChat.removeUserListener(userListenerId);
    };
}, [user]);

Customization Options

  • Styling overrides via CSS
  • Custom tab configurations
  • Custom call status labels and icons
  • User profile customization
  • Duration and date formatting
  • Icon replacements

Filtering / Edge Cases

  • Different call types (audio/video/group)
  • Call status variations (missed, rejected, busy, etc.)
  • Unavailable users
  • Missing duration or recording data
  • Large call history handling

Error Handling & Data Validation

  • Includes try-catch blocks for duration, history, and call list fetching.

Summary / Feature Matrix

FeatureComponent / MethodFile Reference
Calls tab integrationCometChatCallLogsCometChatSelector.tsx
Call details displayCometChatCallDetailsCometChatCallLogDetails.tsx
Call informationCometChatCallDetailsInfoCometChatCallLogInfo.tsx
Call participantsCometChatCallDetailsParticipantsCometChatCallLogParticipants.tsx
Call recordingsCometChatCallDetailsRecordingCometChatCallLogRecordings.tsx
Call historyCometChatCallDetailsHistoryCometChatCallLogHistory.tsx
Tab navigationactiveTab stateCometChatCallLogDetails.tsx
User status monitoringCometChat.addUserListener()CometChatCallLogDetails.tsx