├── .gitignore
├── README.md
├── backend
├── .gitignore
├── configs
│ └── users.js
├── package-lock.json
├── package.json
└── server.js
├── react-app
├── .gitignore
├── README.md
├── development.env
├── package-lock.json
├── package.json
├── production.env
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── __tests__
│ ├── ChatBox.test.js
│ ├── NavBar.test.js
│ └── UserList.test.js
│ ├── components
│ ├── ChatBox.js
│ ├── ErrorModal.js
│ ├── LoadingModal.js
│ ├── NavBar.js
│ └── UserList.js
│ ├── dummy-users-for-jest.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── requests.js
│ ├── serviceWorker.js
│ ├── setupTests.js
│ └── static
│ └── images
│ └── avatar
│ ├── 1.jpg
│ ├── 2.jpg
│ ├── 3.jpg
│ ├── 4.jpg
│ ├── 5.jpg
│ ├── 6.jpg
│ ├── 7.jpg
│ └── 8.jpg
└── screenshot.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /react-app/node_modules
5 | /backend/node_modules
6 | /react-app/.pnp
7 | /react-app/.pnp.js
8 |
9 | # testing
10 | /react-app/coverage
11 |
12 | # production
13 | /react-app/build
14 |
15 | # misc
16 | /react-app/.DS_Store
17 | /react-app/.env.local
18 | /react-app/.env.development.local
19 | /react-app/.env.test.local
20 | /react-app/.env.production.local
21 |
22 | /react-app/npm-debug.log*
23 | /react-app/yarn-debug.log*
24 | /react-app/yarn-error.log*
25 |
26 |
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Socket IO Chat-app Example
2 | A simple real-time chat application implementation using Socket.io, Node and React.
3 |
4 | 
5 |
6 | see a live demo [here](https://evening-coast-74033.herokuapp.com/)
7 |
8 | ## Setup and run
9 | * Make sure you have port 3000 and 8002 free in your machine.
10 | * Run `npm i` in both /backend and /react-app directories.
11 | * Open two terminal windows and navigate to both of these directories and run `npm start`
12 |
13 | ## Instructions to run this app
14 | For signing in differently in the app, you can use two different browser tabs opening the same application and can chat in real-time. There is no session maintained so on every page visit it will ask for signing-in. ( For example you can select Alexa in one tab to sign in and TARS in second tab and then you can send message to TARS from Alexa's tab and you should see an unread message on TARS tab ).
15 |
16 | Messages are stored in browser memory so on subsequent refreshes messages will be lost. we could've stored messages on server' DB though, but DB is not in the scenario.
17 |
--------------------------------------------------------------------------------
/backend/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/backend/configs/users.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | {
3 | id: 1,
4 | name: 'Alexa'
5 | },
6 | {
7 | id: 2,
8 | name: 'Google Assistant'
9 | },
10 | {
11 | id: 3,
12 | name: 'Siri'
13 | },
14 | {
15 | id: 4,
16 | name: 'TARS'
17 | },
18 | {
19 | id: 5,
20 | name: 'CASE'
21 | },
22 | {
23 | id: 6,
24 | name: 'KIPP'
25 | },
26 | {
27 | id: 7,
28 | name: 'Jarvis'
29 | }
30 | ]
--------------------------------------------------------------------------------
/backend/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cool-chat-backend",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.5",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
10 | "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
11 | "requires": {
12 | "mime-types": "~2.1.18",
13 | "negotiator": "0.6.1"
14 | }
15 | },
16 | "after": {
17 | "version": "0.8.2",
18 | "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
19 | "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
20 | },
21 | "array-flatten": {
22 | "version": "1.1.1",
23 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
24 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
25 | },
26 | "arraybuffer.slice": {
27 | "version": "0.0.7",
28 | "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
29 | "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
30 | },
31 | "backo2": {
32 | "version": "1.0.2",
33 | "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
34 | "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
35 | },
36 | "base64-arraybuffer": {
37 | "version": "0.1.4",
38 | "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
39 | "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
40 | },
41 | "base64id": {
42 | "version": "2.0.0",
43 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
44 | "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
45 | },
46 | "blob": {
47 | "version": "0.0.5",
48 | "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
49 | "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
50 | },
51 | "body-parser": {
52 | "version": "1.18.3",
53 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
54 | "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
55 | "requires": {
56 | "bytes": "3.0.0",
57 | "content-type": "~1.0.4",
58 | "debug": "2.6.9",
59 | "depd": "~1.1.2",
60 | "http-errors": "~1.6.3",
61 | "iconv-lite": "0.4.23",
62 | "on-finished": "~2.3.0",
63 | "qs": "6.5.2",
64 | "raw-body": "2.3.3",
65 | "type-is": "~1.6.16"
66 | },
67 | "dependencies": {
68 | "debug": {
69 | "version": "2.6.9",
70 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
71 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
72 | "requires": {
73 | "ms": "2.0.0"
74 | }
75 | }
76 | }
77 | },
78 | "bytes": {
79 | "version": "3.0.0",
80 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
81 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
82 | },
83 | "component-bind": {
84 | "version": "1.0.0",
85 | "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
86 | "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
87 | },
88 | "component-emitter": {
89 | "version": "1.3.0",
90 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
91 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
92 | },
93 | "component-inherit": {
94 | "version": "0.0.3",
95 | "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
96 | "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
97 | },
98 | "content-disposition": {
99 | "version": "0.5.2",
100 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
101 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
102 | },
103 | "content-type": {
104 | "version": "1.0.4",
105 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
106 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
107 | },
108 | "cookie": {
109 | "version": "0.3.1",
110 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
111 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
112 | },
113 | "cookie-signature": {
114 | "version": "1.0.6",
115 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
116 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
117 | },
118 | "cors": {
119 | "version": "2.8.5",
120 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
121 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
122 | "requires": {
123 | "object-assign": "^4",
124 | "vary": "^1"
125 | }
126 | },
127 | "debug": {
128 | "version": "4.1.1",
129 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
130 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
131 | "requires": {
132 | "ms": "^2.1.1"
133 | },
134 | "dependencies": {
135 | "ms": {
136 | "version": "2.1.3",
137 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
138 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
139 | }
140 | }
141 | },
142 | "depd": {
143 | "version": "1.1.2",
144 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
145 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
146 | },
147 | "destroy": {
148 | "version": "1.0.4",
149 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
150 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
151 | },
152 | "ee-first": {
153 | "version": "1.1.1",
154 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
155 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
156 | },
157 | "encodeurl": {
158 | "version": "1.0.2",
159 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
160 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
161 | },
162 | "engine.io": {
163 | "version": "3.5.0",
164 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz",
165 | "integrity": "sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==",
166 | "requires": {
167 | "accepts": "~1.3.4",
168 | "base64id": "2.0.0",
169 | "cookie": "~0.4.1",
170 | "debug": "~4.1.0",
171 | "engine.io-parser": "~2.2.0",
172 | "ws": "~7.4.2"
173 | },
174 | "dependencies": {
175 | "cookie": {
176 | "version": "0.4.1",
177 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
178 | "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
179 | }
180 | }
181 | },
182 | "engine.io-client": {
183 | "version": "3.5.0",
184 | "resolved": "http://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.0.tgz",
185 | "integrity": "sha512-12wPRfMrugVw/DNyJk34GQ5vIVArEcVMXWugQGGuw2XxUSztFNmJggZmv8IZlLyEdnpO1QB9LkcjeWewO2vxtA==",
186 | "requires": {
187 | "component-emitter": "~1.3.0",
188 | "component-inherit": "0.0.3",
189 | "debug": "~3.1.0",
190 | "engine.io-parser": "~2.2.0",
191 | "has-cors": "1.1.0",
192 | "indexof": "0.0.1",
193 | "parseqs": "0.0.6",
194 | "parseuri": "0.0.6",
195 | "ws": "~7.4.2",
196 | "xmlhttprequest-ssl": "~1.5.4",
197 | "yeast": "0.1.2"
198 | },
199 | "dependencies": {
200 | "debug": {
201 | "version": "3.1.0",
202 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
203 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
204 | "requires": {
205 | "ms": "2.0.0"
206 | }
207 | }
208 | }
209 | },
210 | "engine.io-parser": {
211 | "version": "2.2.1",
212 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz",
213 | "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==",
214 | "requires": {
215 | "after": "0.8.2",
216 | "arraybuffer.slice": "~0.0.7",
217 | "base64-arraybuffer": "0.1.4",
218 | "blob": "0.0.5",
219 | "has-binary2": "~1.0.2"
220 | }
221 | },
222 | "escape-html": {
223 | "version": "1.0.3",
224 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
225 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
226 | },
227 | "etag": {
228 | "version": "1.8.1",
229 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
230 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
231 | },
232 | "express": {
233 | "version": "4.16.4",
234 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
235 | "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
236 | "requires": {
237 | "accepts": "~1.3.5",
238 | "array-flatten": "1.1.1",
239 | "body-parser": "1.18.3",
240 | "content-disposition": "0.5.2",
241 | "content-type": "~1.0.4",
242 | "cookie": "0.3.1",
243 | "cookie-signature": "1.0.6",
244 | "debug": "2.6.9",
245 | "depd": "~1.1.2",
246 | "encodeurl": "~1.0.2",
247 | "escape-html": "~1.0.3",
248 | "etag": "~1.8.1",
249 | "finalhandler": "1.1.1",
250 | "fresh": "0.5.2",
251 | "merge-descriptors": "1.0.1",
252 | "methods": "~1.1.2",
253 | "on-finished": "~2.3.0",
254 | "parseurl": "~1.3.2",
255 | "path-to-regexp": "0.1.7",
256 | "proxy-addr": "~2.0.4",
257 | "qs": "6.5.2",
258 | "range-parser": "~1.2.0",
259 | "safe-buffer": "5.1.2",
260 | "send": "0.16.2",
261 | "serve-static": "1.13.2",
262 | "setprototypeof": "1.1.0",
263 | "statuses": "~1.4.0",
264 | "type-is": "~1.6.16",
265 | "utils-merge": "1.0.1",
266 | "vary": "~1.1.2"
267 | },
268 | "dependencies": {
269 | "debug": {
270 | "version": "2.6.9",
271 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
272 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
273 | "requires": {
274 | "ms": "2.0.0"
275 | }
276 | }
277 | }
278 | },
279 | "finalhandler": {
280 | "version": "1.1.1",
281 | "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
282 | "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
283 | "requires": {
284 | "debug": "2.6.9",
285 | "encodeurl": "~1.0.2",
286 | "escape-html": "~1.0.3",
287 | "on-finished": "~2.3.0",
288 | "parseurl": "~1.3.2",
289 | "statuses": "~1.4.0",
290 | "unpipe": "~1.0.0"
291 | },
292 | "dependencies": {
293 | "debug": {
294 | "version": "2.6.9",
295 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
296 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
297 | "requires": {
298 | "ms": "2.0.0"
299 | }
300 | }
301 | }
302 | },
303 | "forwarded": {
304 | "version": "0.1.2",
305 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
306 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
307 | },
308 | "fresh": {
309 | "version": "0.5.2",
310 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
311 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
312 | },
313 | "has-binary2": {
314 | "version": "1.0.3",
315 | "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
316 | "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
317 | "requires": {
318 | "isarray": "2.0.1"
319 | }
320 | },
321 | "has-cors": {
322 | "version": "1.1.0",
323 | "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
324 | "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
325 | },
326 | "http-errors": {
327 | "version": "1.6.3",
328 | "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
329 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
330 | "requires": {
331 | "depd": "~1.1.2",
332 | "inherits": "2.0.3",
333 | "setprototypeof": "1.1.0",
334 | "statuses": ">= 1.4.0 < 2"
335 | }
336 | },
337 | "iconv-lite": {
338 | "version": "0.4.23",
339 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
340 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
341 | "requires": {
342 | "safer-buffer": ">= 2.1.2 < 3"
343 | }
344 | },
345 | "indexof": {
346 | "version": "0.0.1",
347 | "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
348 | "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
349 | },
350 | "inherits": {
351 | "version": "2.0.3",
352 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
353 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
354 | },
355 | "ipaddr.js": {
356 | "version": "1.8.0",
357 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
358 | "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4="
359 | },
360 | "isarray": {
361 | "version": "2.0.1",
362 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
363 | "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
364 | },
365 | "media-typer": {
366 | "version": "0.3.0",
367 | "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
368 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
369 | },
370 | "merge-descriptors": {
371 | "version": "1.0.1",
372 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
373 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
374 | },
375 | "methods": {
376 | "version": "1.1.2",
377 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
378 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
379 | },
380 | "mime": {
381 | "version": "1.4.1",
382 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
383 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
384 | },
385 | "mime-db": {
386 | "version": "1.37.0",
387 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
388 | "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg=="
389 | },
390 | "mime-types": {
391 | "version": "2.1.21",
392 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
393 | "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
394 | "requires": {
395 | "mime-db": "~1.37.0"
396 | }
397 | },
398 | "ms": {
399 | "version": "2.0.0",
400 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
401 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
402 | },
403 | "negotiator": {
404 | "version": "0.6.1",
405 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
406 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
407 | },
408 | "object-assign": {
409 | "version": "4.1.1",
410 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
411 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
412 | },
413 | "on-finished": {
414 | "version": "2.3.0",
415 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
416 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
417 | "requires": {
418 | "ee-first": "1.1.1"
419 | }
420 | },
421 | "parseqs": {
422 | "version": "0.0.6",
423 | "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
424 | "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w=="
425 | },
426 | "parseuri": {
427 | "version": "0.0.6",
428 | "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
429 | "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow=="
430 | },
431 | "parseurl": {
432 | "version": "1.3.2",
433 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
434 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
435 | },
436 | "path-to-regexp": {
437 | "version": "0.1.7",
438 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
439 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
440 | },
441 | "proxy-addr": {
442 | "version": "2.0.4",
443 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
444 | "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
445 | "requires": {
446 | "forwarded": "~0.1.2",
447 | "ipaddr.js": "1.8.0"
448 | }
449 | },
450 | "qs": {
451 | "version": "6.5.2",
452 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
453 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
454 | },
455 | "range-parser": {
456 | "version": "1.2.0",
457 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
458 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
459 | },
460 | "raw-body": {
461 | "version": "2.3.3",
462 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
463 | "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
464 | "requires": {
465 | "bytes": "3.0.0",
466 | "http-errors": "1.6.3",
467 | "iconv-lite": "0.4.23",
468 | "unpipe": "1.0.0"
469 | }
470 | },
471 | "safe-buffer": {
472 | "version": "5.1.2",
473 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
474 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
475 | },
476 | "safer-buffer": {
477 | "version": "2.1.2",
478 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
479 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
480 | },
481 | "send": {
482 | "version": "0.16.2",
483 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
484 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
485 | "requires": {
486 | "debug": "2.6.9",
487 | "depd": "~1.1.2",
488 | "destroy": "~1.0.4",
489 | "encodeurl": "~1.0.2",
490 | "escape-html": "~1.0.3",
491 | "etag": "~1.8.1",
492 | "fresh": "0.5.2",
493 | "http-errors": "~1.6.2",
494 | "mime": "1.4.1",
495 | "ms": "2.0.0",
496 | "on-finished": "~2.3.0",
497 | "range-parser": "~1.2.0",
498 | "statuses": "~1.4.0"
499 | },
500 | "dependencies": {
501 | "debug": {
502 | "version": "2.6.9",
503 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
504 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
505 | "requires": {
506 | "ms": "2.0.0"
507 | }
508 | }
509 | }
510 | },
511 | "serve-static": {
512 | "version": "1.13.2",
513 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
514 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
515 | "requires": {
516 | "encodeurl": "~1.0.2",
517 | "escape-html": "~1.0.3",
518 | "parseurl": "~1.3.2",
519 | "send": "0.16.2"
520 | }
521 | },
522 | "setprototypeof": {
523 | "version": "1.1.0",
524 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
525 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
526 | },
527 | "socket.io": {
528 | "version": "2.4.0",
529 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.0.tgz",
530 | "integrity": "sha512-9UPJ1UTvKayuQfVv2IQ3k7tCQC/fboDyIK62i99dAQIyHKaBsNdTpwHLgKJ6guRWxRtC9H+138UwpaGuQO9uWQ==",
531 | "requires": {
532 | "debug": "~4.1.0",
533 | "engine.io": "~3.5.0",
534 | "has-binary2": "~1.0.2",
535 | "socket.io-adapter": "~1.1.0",
536 | "socket.io-client": "2.4.0",
537 | "socket.io-parser": "~3.4.0"
538 | }
539 | },
540 | "socket.io-adapter": {
541 | "version": "1.1.2",
542 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz",
543 | "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g=="
544 | },
545 | "socket.io-client": {
546 | "version": "2.4.0",
547 | "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz",
548 | "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==",
549 | "requires": {
550 | "backo2": "1.0.2",
551 | "component-bind": "1.0.0",
552 | "component-emitter": "~1.3.0",
553 | "debug": "~3.1.0",
554 | "engine.io-client": "~3.5.0",
555 | "has-binary2": "~1.0.2",
556 | "indexof": "0.0.1",
557 | "parseqs": "0.0.6",
558 | "parseuri": "0.0.6",
559 | "socket.io-parser": "~3.3.0",
560 | "to-array": "0.1.4"
561 | },
562 | "dependencies": {
563 | "debug": {
564 | "version": "3.1.0",
565 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
566 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
567 | "requires": {
568 | "ms": "2.0.0"
569 | }
570 | },
571 | "socket.io-parser": {
572 | "version": "3.3.2",
573 | "resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz",
574 | "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==",
575 | "requires": {
576 | "component-emitter": "~1.3.0",
577 | "debug": "~3.1.0",
578 | "isarray": "2.0.1"
579 | }
580 | }
581 | }
582 | },
583 | "socket.io-parser": {
584 | "version": "3.4.1",
585 | "resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz",
586 | "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==",
587 | "requires": {
588 | "component-emitter": "1.2.1",
589 | "debug": "~4.1.0",
590 | "isarray": "2.0.1"
591 | },
592 | "dependencies": {
593 | "component-emitter": {
594 | "version": "1.2.1",
595 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
596 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
597 | }
598 | }
599 | },
600 | "statuses": {
601 | "version": "1.4.0",
602 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
603 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
604 | },
605 | "to-array": {
606 | "version": "0.1.4",
607 | "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
608 | "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
609 | },
610 | "type-is": {
611 | "version": "1.6.16",
612 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
613 | "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
614 | "requires": {
615 | "media-typer": "0.3.0",
616 | "mime-types": "~2.1.18"
617 | }
618 | },
619 | "unpipe": {
620 | "version": "1.0.0",
621 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
622 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
623 | },
624 | "utils-merge": {
625 | "version": "1.0.1",
626 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
627 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
628 | },
629 | "vary": {
630 | "version": "1.1.2",
631 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
632 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
633 | },
634 | "ws": {
635 | "version": "7.4.6",
636 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
637 | "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
638 | },
639 | "xmlhttprequest-ssl": {
640 | "version": "1.5.5",
641 | "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
642 | "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
643 | },
644 | "yeast": {
645 | "version": "0.1.2",
646 | "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
647 | "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
648 | }
649 | }
650 | }
651 |
--------------------------------------------------------------------------------
/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cool-chat-backend",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node server.js"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "cors": "^2.8.5",
14 | "express": "^4.16.4",
15 | "socket.io": "^2.4.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/backend/server.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const app = express();
3 | const port = 8002;
4 | var server = require("http").Server(app);
5 | const io = require("socket.io")(server);
6 | const users = require("./configs/users");
7 | const cors = require("cors");
8 |
9 | app.use(cors());
10 |
11 | var clients = {};
12 |
13 | io.on("connection", function(client) {
14 | client.on("sign-in", e => {
15 | let user_id = e.id;
16 | if (!user_id) return;
17 | client.user_id = user_id;
18 | if (clients[user_id]) {
19 | clients[user_id].push(client);
20 | } else {
21 | clients[user_id] = [client];
22 | }
23 | });
24 |
25 | client.on("message", e => {
26 | let targetId = e.to;
27 | let sourceId = client.user_id;
28 | if(targetId && clients[targetId]) {
29 | clients[targetId].forEach(cli => {
30 | cli.emit("message", e);
31 | });
32 | }
33 |
34 | if(sourceId && clients[sourceId]) {
35 | clients[sourceId].forEach(cli => {
36 | cli.emit("message", e);
37 | });
38 | }
39 | });
40 |
41 | client.on("disconnect", function() {
42 | if (!client.user_id || !clients[client.user_id]) {
43 | return;
44 | }
45 | let targetClients = clients[client.user_id];
46 | for (let i = 0; i < targetClients.length; ++i) {
47 | if (targetClients[i] == client) {
48 | targetClients.splice(i, 1);
49 | }
50 | }
51 | });
52 | });
53 |
54 | app.get("/users", (req, res) => {
55 | res.send({ data: users });
56 | });
57 |
58 | server.listen(port, () =>
59 | console.log(`Example app listening on port ${port}!`)
60 | );
61 |
--------------------------------------------------------------------------------
/react-app/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/react-app/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
2 |
3 | ## Available Scripts
4 |
5 | In the project directory, you can run:
6 |
7 | ### `npm start`
8 |
9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
11 |
12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console.
14 |
15 | ### `npm test`
16 |
17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
19 |
20 | ### `npm run build`
21 |
22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance.
24 |
25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed!
27 |
28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
29 |
30 | ### `npm run eject`
31 |
32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
33 |
34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
35 |
36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
37 |
38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
39 |
40 | ## Learn More
41 |
42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
43 |
44 | To learn React, check out the [React documentation](https://reactjs.org/).
45 |
--------------------------------------------------------------------------------
/react-app/development.env:
--------------------------------------------------------------------------------
1 | SERVER_URI=http://localhost:8002
--------------------------------------------------------------------------------
/react-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cool-chat",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "axios": "^0.21.2",
7 | "fsevents": "^2.1.2",
8 | "react": "^16.13.1",
9 | "react-app-env": "^1.2.3",
10 | "react-bootstrap": "^0.32.4",
11 | "react-chat-elements": "^10.8.0",
12 | "react-dom": "^16.13.1",
13 | "react-notifications": "^1.6.0",
14 | "react-scripts": "^3.4.1",
15 | "socket.io-client": "^2.3.0"
16 | },
17 | "scripts": {
18 | "start": "react-app-env start",
19 | "build": "react-app-env build",
20 | "test": "react-scripts test",
21 | "eject": "react-scripts eject"
22 | },
23 | "eslintConfig": {
24 | "extends": "react-app"
25 | },
26 | "browserslist": [
27 | ">0.2%",
28 | "not dead",
29 | "not ie <= 11",
30 | "not op_mini all"
31 | ],
32 | "devDependencies": {
33 | "enzyme": "^3.11.0",
34 | "enzyme-adapter-react-15": "^1.4.1",
35 | "enzyme-adapter-react-16": "^1.15.2",
36 | "jest-enzyme": "^7.1.2"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-app/production.env:
--------------------------------------------------------------------------------
1 | SERVER_URI=http://13.233.166.21:8002
2 |
--------------------------------------------------------------------------------
/react-app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stack-guru/ReactChatApp-SocketIo/11d005fa540d996c7c00174b33f8984c90f4c79a/react-app/public/favicon.ico
--------------------------------------------------------------------------------
/react-app/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
63 |
{this.props.targetUser.name}
78 |Select a friend to start a chat.
117 |