├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── screenshot ├── screenshot_1.png └── screenshot_2.png └── src ├── components ├── App.css ├── App.js ├── Chat.js └── Login.js ├── config.js └── index.js /README.md: -------------------------------------------------------------------------------- 1 | # React Chat Widget App With CometChat Pro 2 | 3 | This example shows how to build a React chat application using CometChat Pro SDK and React Hooks. 4 | 5 | SCREENSHOTS 6 | 7 | ![Login](screenshot/screenshot_1.png) 8 | ![Chat Interface](screenshot/screenshot_2.png) 9 | 10 | Jump straight into the code or read the accompanying step-by-step guide here on our blog. 11 | 12 | ## Technology 13 | This demo uses: 14 | 15 | * [CometChat Pro JavaScript SDK](https://github.com/cometchat-pro/javascript-chat-sdk) 16 | * React 17 | 18 | ## Running the demo locally 19 | * Download the repository [here](https://github.com/nsebhastian/react-hooks-cometchat) or by running `git clone https://github.com/nsebhastian/react-hooks-cometchat.git` 20 | * run `npm install` 21 | * You need to sign up for CometChat PRO and create your application first 22 | * Create an ApiKey. You can use auth-only permission for this application 23 | * Put your AppID and ApiKey into `src/config.js` file 24 | * run `npm start` 25 | * A browser will open `localhost:3000` 26 | 27 | ## Useful links 28 | 29 | * [📚Tutorial](https://prodocs.cometchat.com/docs) 30 | 31 | ## Other examples 32 | 33 | * [ReactJS Chat app](https://github.com/cometchat-pro/javascript-reactjs-chat-app) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cometchat-react-hooks", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@cometchat-pro/chat": "^1.2.0", 7 | "bootstrap": "^4.3.1", 8 | "react": "^16.8.4", 9 | "react-dom": "^16.8.4", 10 | "react-md-spinner": "^0.3.0", 11 | "react-notifications": "^1.4.3", 12 | "react-scripts": "2.1.5" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": "react-app" 22 | }, 23 | "browserslist": [ 24 | ">0.2%", 25 | "not dead", 26 | "not ie <= 11", 27 | "not op_mini all" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cometchat-pro-tutorials/build-chat-app-with-react-hooks/42ca57cb2e79a9345ec20eaaba3fe9b98552d8ff/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | React App 12 | 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /screenshot/screenshot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cometchat-pro-tutorials/build-chat-app-with-react-hooks/42ca57cb2e79a9345ec20eaaba3fe9b98552d8ff/screenshot/screenshot_1.png -------------------------------------------------------------------------------- /screenshot/screenshot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cometchat-pro-tutorials/build-chat-app-with-react-hooks/42ca57cb2e79a9345ec20eaaba3fe9b98552d8ff/screenshot/screenshot_2.png -------------------------------------------------------------------------------- /src/components/App.css: -------------------------------------------------------------------------------- 1 | .container { 2 | margin-top: 5%; 3 | margin-bottom: 5%; 4 | } 5 | .login-form { 6 | padding: 5%; 7 | box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 9px 26px 0 rgba(0, 0, 0, 0.19); 8 | } 9 | .login-form h3 { 10 | text-align: center; 11 | color: #333; 12 | } 13 | 14 | .login-container form { 15 | padding: 10%; 16 | } 17 | 18 | .message { 19 | overflow: hidden; 20 | } 21 | 22 | .balon1 { 23 | float: right; 24 | background: #35cce6; 25 | border-radius: 10px; 26 | } 27 | 28 | .balon2 { 29 | float: left; 30 | background: #f4f7f9; 31 | border-radius: 10px; 32 | } 33 | -------------------------------------------------------------------------------- /src/components/App.js: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import 'bootstrap/dist/css/bootstrap.css'; 3 | import 'react-notifications/lib/notifications.css'; 4 | import './App.css'; 5 | import {NotificationContainer} from 'react-notifications'; 6 | 7 | import Login from './Login'; 8 | import Chat from './Chat'; 9 | 10 | const App = () => { 11 | const [user, setUser] = useState(null); 12 | 13 | const renderApp = () => { 14 | // Render Chat component when user state is not null 15 | if (user) { 16 | return ; 17 | } else { 18 | return ; 19 | } 20 | }; 21 | 22 | return ( 23 |
24 | 25 | {renderApp()} 26 |
27 | ); 28 | }; 29 | 30 | export default App; 31 | -------------------------------------------------------------------------------- /src/components/Chat.js: -------------------------------------------------------------------------------- 1 | import React, {useState, useEffect} from 'react'; 2 | 3 | import MDSpinner from 'react-md-spinner'; 4 | import {CometChat} from '@cometchat-pro/chat'; 5 | 6 | const MESSAGE_LISTENER_KEY = 'listener-key'; 7 | const limit = 30; 8 | 9 | const Chat = ({user}) => { 10 | const [friends, setFriends] = useState([]); 11 | const [selectedFriend, setSelectedFriend] = useState(null); 12 | const [chat, setChat] = useState([]); 13 | const [chatIsLoading, setChatIsLoading] = useState(false); 14 | const [friendisLoading, setFriendisLoading] = useState(true); 15 | const [message, setMessage] = useState(''); 16 | 17 | useEffect(() => { 18 | // this useEffect will fetch all users available for chat 19 | // only run on mount 20 | let usersRequest = new CometChat.UsersRequestBuilder() 21 | .setLimit(limit) 22 | .build(); 23 | 24 | usersRequest.fetchNext().then( 25 | userList => { 26 | console.log('User list received:', userList); 27 | setFriends(userList); 28 | setFriendisLoading(false); 29 | }, 30 | error => { 31 | console.log('User list fetching failed with error:', error); 32 | } 33 | ); 34 | 35 | return () => { 36 | CometChat.removeMessageListener(MESSAGE_LISTENER_KEY); 37 | CometChat.logout(); 38 | }; 39 | }, []); 40 | 41 | useEffect(() => { 42 | // will run when selectedFriend variable value is updated 43 | // fetch previous messages, remove listener if any 44 | // create new listener for incoming message 45 | 46 | if (selectedFriend) { 47 | let messagesRequest = new CometChat.MessagesRequestBuilder() 48 | .setUID(selectedFriend) 49 | .setLimit(limit) 50 | .build(); 51 | 52 | messagesRequest.fetchPrevious().then( 53 | messages => { 54 | setChat(messages); 55 | setChatIsLoading(false); 56 | scrollToBottom(); 57 | }, 58 | error => { 59 | console.log('Message fetching failed with error:', error); 60 | } 61 | ); 62 | 63 | CometChat.removeMessageListener(MESSAGE_LISTENER_KEY); 64 | 65 | CometChat.addMessageListener( 66 | MESSAGE_LISTENER_KEY, 67 | new CometChat.MessageListener({ 68 | onTextMessageReceived: message => { 69 | console.log('Incoming Message Log', {message}); 70 | if (selectedFriend === message.sender.uid) { 71 | setChat(prevState => [...prevState, message]); 72 | } 73 | }, 74 | }) 75 | ); 76 | } 77 | }, [selectedFriend]); 78 | 79 | const handleSubmit = event => { 80 | event.preventDefault(); 81 | 82 | let textMessage = new CometChat.TextMessage( 83 | selectedFriend, 84 | message, 85 | CometChat.MESSAGE_TYPE.TEXT, 86 | CometChat.RECEIVER_TYPE.USER 87 | ); 88 | 89 | CometChat.sendMessage(textMessage).then( 90 | message => { 91 | console.log('Message sent successfully:', message); 92 | setChat([...chat, message]); 93 | }, 94 | error => { 95 | console.log('Message sending failed with error:', error); 96 | } 97 | ); 98 | setMessage(''); 99 | }; 100 | 101 | const selectFriend = uid => { 102 | setSelectedFriend(uid); 103 | setChat([]); 104 | setChatIsLoading(true); 105 | }; 106 | 107 | const scrollToBottom = () => { 108 | let node = document.getElementById('ccChatBoxEnd'); 109 | node.scrollIntoView(); 110 | }; 111 | 112 | return ( 113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |

Friend List

121 |
122 |
125 | 131 |
132 |
133 |
134 |
135 |

Who you gonna chat with?

136 |
137 |
140 | 145 |
146 |
147 |
148 |
149 | { 154 | setMessage(event.target.value); 155 | }} 156 | value={message} 157 | placeholder='Type a message...' 158 | /> 159 |
160 |
161 | 167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | ); 176 | }; 177 | 178 | const ChatBox = props => { 179 | const {chat, chatIsLoading, user} = props; 180 | if (chatIsLoading) { 181 | return ( 182 |
183 | 184 |
185 | ); 186 | } else { 187 | return ( 188 |
189 | {chat.map(chat => ( 190 |
191 |
195 | {chat.text} 196 |
197 |
198 | ))} 199 |
200 |
201 | ); 202 | } 203 | }; 204 | 205 | const FriendList = props => { 206 | const {friends, friendisLoading, selectedFriend} = props; 207 | if (friendisLoading) { 208 | return ( 209 |
210 | 211 |
212 | ); 213 | } else { 214 | return ( 215 |
    216 | {friends.map(friend => ( 217 |
  • props.selectFriend(friend.uid)}> 223 | {friend.name} 224 |
  • 225 | ))} 226 |
227 | ); 228 | } 229 | }; 230 | 231 | export default Chat; 232 | -------------------------------------------------------------------------------- /src/components/Login.js: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import {NotificationManager} from 'react-notifications'; 3 | import {CometChat} from '@cometchat-pro/chat'; 4 | import config from '../config'; 5 | 6 | const Login = props => { 7 | const [uidValue, setUidValue] = useState(''); 8 | const [isSubmitting, setIsSubmitting] = useState(false); 9 | 10 | const handleSubmit = event => { 11 | event.preventDefault(); 12 | setIsSubmitting(true); 13 | CometChat.login(uidValue, config.apiKey).then( 14 | User => { 15 | NotificationManager.success('You are now logged in', 'Login Success'); 16 | console.log('Login Successful:', {User}); 17 | props.setUser(User); 18 | }, 19 | error => { 20 | NotificationManager.error('Please try again', 'Login Failed'); 21 | console.log('Login failed with exception:', {error}); 22 | setIsSubmitting(false); 23 | } 24 | ); 25 | }; 26 | 27 | return ( 28 |
29 |
30 |

Login to Awesome Chat

31 |
32 |
33 | setUidValue(event.target.value)} 40 | /> 41 |
42 |
43 | 49 |
50 |
51 |
52 |
53 | ); 54 | }; 55 | 56 | export default Login; 57 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | appID: '5586b97392140', 3 | apiKey: 'fc9ca3d5484dd862444e3ccde68df873c4861a91', 4 | }; 5 | 6 | export default config; 7 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import {CometChat} from '@cometchat-pro/chat'; 4 | 5 | import App from './components/App'; 6 | import config from './config'; 7 | 8 | CometChat.init(config.appID); 9 | 10 | ReactDOM.render(, document.getElementById('root')); 11 | --------------------------------------------------------------------------------