Welcome to the Mfereji React SDK documentation. This guide will help you get started with integrating the Mfereji SDK into your React application to enable chat functionalities.
To install the Mfereji SDK, run one of the following commands:
To learn more about the SDK, visit the Mfereji SDK page.
npm install chatsasa-react-sdk
# or
yarn add chatsasa-react-sdk
Initialize the Mfereji SDK in your application:
import Mfereji from 'chatsasa-react-sdk';
const chatSDK = new Mfereji({
appId: 'YOUR_APP_ID',
chatApiToken: 'YOUR_CHAT_API_TOKEN',
});
Here's how you can use various methods provided by the SDK:
chatSDK.fetchUserProfile()
.then(profile => console.log(profile))
.catch(err => console.error(err));
chatSDK.fetchAllChannels()
.then(({ channels }) => console.log(channels))
.catch(err => console.error(err));
chatSDK.sendMessage(channelId, userId, 'Hello, World!')
.then(message => console.log(message))
.catch(err => console.error(err));
chatSDK.fetchMessages(channelId)
.then(messages => console.log(messages))
.catch(err => console.error(err));
Connect to real-time service and subscribe to events:
chatSDK.connect();
chatSDK.on('new_message', (data) => {
console.log('New message:', data);
});
chatSDK.on('typing', (data) => {
console.log('Typing event:', data);
});
chatSDK.on('reaction', (data) => {
console.log('Reaction event:', data);
});
// To unsubscribe from events
chatSDK.off('new_message', callback);
// Disconnect from real-time service
chatSDK.disconnect();
Here's a basic example of how to use the SDK in a React component:
import React, { useEffect, useState } from "react";
import Mfereji from "chatsasa-react-sdk";
// Initialize Mfereji SDK with your app ID and API token
const chatSDK = new Mfereji({
appId: 'YOUR_APP_ID',
chatApiToken: 'YOUR_CHAT_API_TOKEN',
});
function App() {
const [profile, setProfile] = useState(null);
const [channels, setChannels] = useState([]);
const [currentChannel, setCurrentChannel] = useState(null);
const [messages, setMessages] = useState([]);
const [messageText, setMessageText] = useState("");
const [loading, setLoading] = useState(true);
const [showModal, setShowModal] = useState(false);
const [users, setUsers] = useState([]);
const [selectedUser, setSelectedUser] = useState(null);
const [newChatMessage, setNewChatMessage] = useState("");
useEffect(() => {
chatSDK.fetchUserProfile().then((response) => {
if (response.user) {
setProfile(response.user);
} else {
console.error("Error fetching user profile:", response.error);
}
});
}, []);
useEffect(() => {
if (profile?.userId) {
chatSDK.fetchAllChannels(profile.userId).then((response) => {
if (response.channels) {
setChannels(response.channels);
setLoading(false);
} else {
console.error("Error fetching channels:", response.error);
}
});
}
}, [profile]);
useEffect(() => {
if (currentChannel) {
chatSDK.fetchMessages(currentChannel.channelId).then((response) => {
if (response.messages) {
setMessages(response.messages);
} else {
console.error("Error fetching messages:", response.error);
}
});
}
}, [currentChannel]);
useEffect(() => {
if (showModal) {
chatSDK
.fetchUsers()
.then((data) => setUsers(data.users))
.catch((err) => console.error(err));
}
}, [showModal]);
const handleSendMessage = () => {
if (messageText.trim() !== "" && currentChannel && profile) {
chatSDK
.sendMessage(currentChannel.channelId, profile.userId, messageText)
.then((response) => {
if (response.message) {
setMessages((prevMessages) => [...prevMessages, response.message]);
setMessageText("");
} else {
console.error("Error sending message:", response.error);
}
})
.catch((err) => console.error(err));
}
};
const handleStartNewChat = () => {
if (newChatMessage.trim() !== "" && selectedUser) {
chatSDK
.initiateChat(selectedUser.userId, profile.userId)
.then((response) => {
if (response.channel) {
setChannels((prevChannels) => [...prevChannels, response.channel]);
setCurrentChannel(response.channel);
setMessages([{ message: newChatMessage, user: profile }]);
setShowModal(false);
setSelectedUser(null);
setNewChatMessage("");
} else {
console.error("Error starting a new chat:", response.error);
}
});
}
};
const getCounterpartyName = (channel) => {
if (channel.channelUsers && channel.channelUsers.length > 0) {
const counterparty = channel.channelUsers.find(
(user) => user.userId !== profile?.userId
);
return counterparty
? `${counterparty.firstName} ${counterparty.lastName}`
: "Unknown";
}
return "Unknown";
};
return (
<div
style={{
fontFamily: "Arial",
height: "100vh",
display: "flex",
flexDirection: "column",
}}
>
<header
style={{
padding: "20px",
backgroundColor: "#007bff",
color: "white",
textAlign: "center",
}}
>
<h1>Simple Chat App</h1>
{profile && (
<h2>
Welcome, {profile.firstName} {profile.lastName}
</h2>
)}
</header>
<div style={{ display: "flex", flexGrow: 1 }}>
<div
style={{
width: "25%",
borderRight: "1px solid #ddd",
paddingRight: "10px",
backgroundColor: "#f4f4f4",
height: "100%",
}}
>
<h3 style={{ padding: "10px" }}>Channels</h3>
{loading ? (
<div>Loading channels...</div>
) : channels.length > 0 ? (
channels.map((channel) => (
<div
key={channel.channelId}
onClick={() => setCurrentChannel(channel)}
style={{
padding: "10px",
cursor: "pointer",
backgroundColor:
currentChannel?.channelId === channel.channelId
? "#ddd"
: "white",
borderBottom: "1px solid #ccc",
}}
>
{getCounterpartyName(channel)}
</div>
))
) : (
<div style={{ textAlign: "center", padding: "20px" }}>
<p>No channels available.</p>
<button
onClick={() => setShowModal(true)}
style={{
padding: "10px 20px",
backgroundColor: "#007bff",
color: "white",
border: "none",
borderRadius: "5px",
cursor: "pointer",
}}
>
Start New Chat
</button>
</div>
)}
</div>
<div
style={{
width: "75%",
height: "100%",
display: "flex",
flexDirection: "column",
}}
>
{currentChannel ? (
<>
<div
style={{
padding: "20px",
backgroundColor: "#f1f1f1",
borderBottom: "1px solid #ddd",
display: "flex",
alignItems: "center",
}}
>
<strong>{getCounterpartyName(currentChannel)}</strong>
</div>
<div
style={{
flexGrow: 1,
overflowY: "scroll",
padding: "20px",
backgroundColor: "#ffffff",
}}
>
{messages.map((msg, index) => (
<div key={index} style={{ marginBottom: "10px" }}>
<strong>{msg.user?.firstName || msg.userId}:</strong>{" "}
{msg.message}
</div>
))}
</div>
<div
style={{
display: "flex",
padding: "10px 20px",
borderTop: "1px solid #ddd",
backgroundColor: "#f9f9f9",
}}
>
<input
type="text"
value={messageText}
onChange={(e) => setMessageText(e.target.value)}
placeholder="Type your message..."
style={{
flexGrow: 1,
padding: "10px",
borderRadius: "5px",
border: "1px solid #ddd",
marginRight: "10px",
}}
/>
<button
onClick={handleSendMessage}
style={{
padding: "10px 20px",
backgroundColor: "#28a745",
color: "white",
border: "none",
borderRadius: "5px",
}}
>
Send
</button>
</div>
</>
) : (
<div style={{ textAlign: "center", padding: "50px" }}>
<p>Select a channel to start messaging</p>
</div>
)}
</div>
</div>
{showModal && (
<div
style={{
position: "fixed",
top: "0",
left: "0",
width: "100%",
height: "100%",
backgroundColor: "rgba(0, 0, 0, 0.5)",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<div
style={{
backgroundColor: "white",
padding: "20px",
borderRadius: "5px",
width: "400px",
textAlign: "center",
}}
>
<h3>Select a user to start a new chat</h3>
{users.map((user) => (
<div
key={user.userId}
style={{
padding: "10px",
cursor: "pointer",
borderBottom: "1px solid #ddd",
}}
onClick={() => setSelectedUser(user)}
>
{user.firstName} {user.lastName} - {user.userIdentifier}
</div>
))}
{selectedUser && (
<div style={{ marginTop: "20px" }}>
<input
type="text"
placeholder={`Message ${selectedUser.firstName}`}
value={newChatMessage}
onChange={(e) => setNewChatMessage(e.target.value)}
style={{
width: "80%",
padding: "10px",
borderRadius: "5px",
border: "1px solid #ddd",
marginBottom: "10px",
}}
/>
<button
onClick={handleStartNewChat}
style={{
padding: "10px 20px",
backgroundColor: "#28a745",
color: "white",
border: "none",
borderRadius: "5px",
}}
>
Start Chat
</button>
</div>
)}
<button
onClick={() => setShowModal(false)}
style={{
marginTop: "10px",
padding: "10px 20px",
backgroundColor: "#dc3545",
color: "white",
border: "none",
borderRadius: "5px",
cursor: "pointer",
}}
>
Close
</button>
</div>
</div>
)}
</div>
);
}
export default App;