Documentation Index
Fetch the complete documentation index at: https://cometchat-22654f5b-react-uikit-v7.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Goal
By the end of this guide you will have a chat interface where users can block and unblock other users, with a confirmation dialog before blocking, the composer automatically hidden for blocked users, and an unblock prompt displayed in its place — all coordinated through UI events so every component stays in sync.
Prerequisites
- Completed the Quick Start guide
- A running
CometChatProvider setup with valid credentials
- An existing one-on-one chat screen using
CometChatMessageList and CometChatMessageComposer
Components Used
| Component / API | Purpose |
|---|
CometChatConfirmDialog | Compound dialog for block confirmation |
CometChatMessageList | Displays messages in the conversation |
CometChatMessageComposer | Text input for sending messages |
useCometChatEvents | Subscribe to UI events |
usePublishEvent | Publish UI events |
CometChat.blockUsers() | SDK method to block a user |
CometChat.unblockUsers() | SDK method to unblock a user |
ui:user/blocked | UI event fired after blocking |
ui:user/unblocked | UI event fired after unblocking |
Step 1: Block User
Call CometChat.blockUsers() with the target UID. On success, update the user object and publish the ui:user/blocked event so other components (thread panel, details panel) can react.
File: ChatView.tsx
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { usePublishEvent } from "@cometchat/chat-uikit-react";
const publish = usePublishEvent();
async function handleBlock(user: CometChat.User) {
try {
await CometChat.blockUsers([user.getUid()]);
user.setBlockedByMe(true);
setIsBlocked(true);
setShowBlockDialog(false);
publish({ type: "ui:user/blocked", user });
} catch (error) {
console.error("Error blocking user:", error);
}
}
Step 2: Unblock User
Call CometChat.unblockUsers() to reverse the block. Publish ui:user/unblocked so all listening components restore their normal state.
File: ChatView.tsx
async function handleUnblock(user: CometChat.User) {
try {
await CometChat.unblockUsers([user.getUid()]);
user.setBlockedByMe(false);
setIsBlocked(false);
publish({ type: "ui:user/unblocked", user });
} catch (error) {
console.error("Error unblocking user:", error);
}
}
Step 3: Confirmation Dialog
Show a CometChatConfirmDialog before blocking. Render it conditionally based on a showBlockDialog state flag.
File: ChatView.tsx
import { useState } from "react";
import { CometChatConfirmDialog } from "@cometchat/chat-uikit-react";
const [showBlockDialog, setShowBlockDialog] = useState(false);
// In your JSX:
{showBlockDialog && (
<CometChatConfirmDialog.Root isOpen={true} onClose={() => setShowBlockDialog(false)}>
<CometChatConfirmDialog.Icon />
<CometChatConfirmDialog.Content
title="Block Contact"
messageText="Are you sure you want to block this user? They won't be able to send you messages."
/>
<CometChatConfirmDialog.Actions
confirmButtonText="Block"
onConfirm={() => handleBlock(user)}
onCancel={() => setShowBlockDialog(false)}
/>
</CometChatConfirmDialog.Root>
)}
Step 4: Listen for Block/Unblock Events
Use useCometChatEvents to subscribe to block/unblock events. This keeps the composer visibility in sync even when the block action originates from a different component (e.g., a details panel).
File: ChatView.tsx
import { useCometChatEvents } from "@cometchat/chat-uikit-react";
import type { CometChatEvent } from "@cometchat/chat-uikit-react";
useCometChatEvents(
(event: CometChatEvent) => {
if (!user) return;
if (event.type === "ui:user/blocked" && event.user.getUid() === user.getUid()) {
setIsBlocked(true);
}
if (event.type === "ui:user/unblocked" && event.user.getUid() === user.getUid()) {
setIsBlocked(false);
}
},
[user?.getUid()]
);
Step 5: Blocked Composer State
Conditionally render the composer or a blocked prompt based on the isBlocked state. The blocked prompt includes an inline unblock action.
File: ChatView.tsx
import { CometChatMessageComposer } from "@cometchat/chat-uikit-react";
// In your JSX:
{!isBlocked ? (
<CometChatMessageComposer user={user} />
) : (
<div style={{ padding: "16px", textAlign: "center", background: "#f5f5f5" }}>
<p>Cannot send a message to a blocked user.</p>
<span
onClick={() => handleUnblock(user)}
role="button"
tabIndex={0}
style={{ color: "#3399ff", cursor: "pointer" }}
>
Click to unblock.
</span>
</div>
)}
Complete Example
File: ChatView.tsx
import { useState, useEffect } from "react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import {
CometChatProvider,
CometChatMessageList,
CometChatMessageComposer,
CometChatMessageHeader,
CometChatConfirmDialog,
usePublishEvent,
useCometChatEvents,
} from "@cometchat/chat-uikit-react";
import type { CometChatEvent } from "@cometchat/chat-uikit-react";
import "@cometchat/chat-uikit-react/styles";
function ChatView({ targetUid }: { targetUid: string }) {
const [user, setUser] = useState<CometChat.User | null>(null);
const [isBlocked, setIsBlocked] = useState(false);
const [showBlockDialog, setShowBlockDialog] = useState(false);
const publish = usePublishEvent();
useEffect(() => {
async function fetchUser() {
try {
const fetchedUser = await CometChat.getUser(targetUid);
setUser(fetchedUser);
setIsBlocked(fetchedUser.getBlockedByMe());
} catch (error) {
console.error("Error fetching user:", error);
}
}
fetchUser();
}, [targetUid]);
useCometChatEvents(
(event: CometChatEvent) => {
if (!user) return;
if (event.type === "ui:user/blocked" && event.user.getUid() === user.getUid()) {
setIsBlocked(true);
}
if (event.type === "ui:user/unblocked" && event.user.getUid() === user.getUid()) {
setIsBlocked(false);
}
},
[user?.getUid()]
);
async function handleBlock() {
if (!user) return;
try {
await CometChat.blockUsers([user.getUid()]);
user.setBlockedByMe(true);
setIsBlocked(true);
setShowBlockDialog(false);
publish({ type: "ui:user/blocked", user });
} catch (error) {
console.error("Error blocking user:", error);
}
}
async function handleUnblock() {
if (!user) return;
try {
await CometChat.unblockUsers([user.getUid()]);
user.setBlockedByMe(false);
setIsBlocked(false);
publish({ type: "ui:user/unblocked", user });
} catch (error) {
console.error("Error unblocking user:", error);
}
}
if (!user) return <div>Loading...</div>;
return (
<div style={{ display: "flex", flexDirection: "column", height: "100vh" }}>
{/* Confirmation dialog */}
{showBlockDialog && (
<CometChatConfirmDialog.Root isOpen={true} onClose={() => setShowBlockDialog(false)}>
<CometChatConfirmDialog.Icon />
<CometChatConfirmDialog.Content
title="Block Contact"
messageText="Are you sure you want to block this user? They won't be able to send you messages."
/>
<CometChatConfirmDialog.Actions
confirmButtonText="Block"
onConfirm={handleBlock}
onCancel={() => setShowBlockDialog(false)}
/>
</CometChatConfirmDialog.Root>
)}
{/* Header with block/unblock action */}
<CometChatMessageHeader
user={user}
auxiliaryButtonView={
<button
onClick={isBlocked ? handleUnblock : () => setShowBlockDialog(true)}
style={{ background: "none", border: "none", cursor: "pointer", fontSize: "14px", color: isBlocked ? "#3399ff" : "#f44336" }}
>
{isBlocked ? "Unblock" : "Block"}
</button>
}
/>
{/* Message list */}
<div style={{ flex: 1, overflow: "hidden" }}>
<CometChatMessageList user={user} />
</div>
{/* Composer or blocked prompt */}
{!isBlocked ? (
<CometChatMessageComposer user={user} />
) : (
<div style={{ padding: "16px", textAlign: "center", background: "#f5f5f5" }}>
<p>Cannot send a message to a blocked user.</p>
<span
onClick={handleUnblock}
role="button"
tabIndex={0}
style={{ color: "#3399ff", cursor: "pointer" }}
>
Click to unblock.
</span>
</div>
)}
</div>
);
}
function App() {
return (
<CometChatProvider
appId="YOUR_APP_ID"
region="YOUR_REGION"
authKey="YOUR_AUTH_KEY"
>
<ChatView targetUid="user-to-chat-with" />
</CometChatProvider>
);
}
export default App;
Next Steps